Search code examples
protobuf-netprotogen

Protobuf-net Protogen generates DataFormat.TwosComplement for int32


I'm using Protogen included in protobuf-net r580 to compile the following .proto file:

message TestMessage2 {
  required int32 someint = 1; 
}

And I found strange the resulting code use TwosComplement wire format:

Private _someint As Integer
<Global.ProtoBuf.ProtoMember(1, IsRequired:=True, Name:="someint", DataFormat:=Global.ProtoBuf.DataFormat.TwosComplement)> _
Public Property someint As Integer

Instead of more optimized default varint type. Is this the intended behavior?


Solution

  • It's the behaviour which matches the "core" protobuf documentation. From the "More Value Types" section:

    Signed Integers

    As you saw in the previous section, all the protocol buffer types associated with wire type 0 are encoded as varints. However, there is an important difference between the signed int types (sint32 and sint64) and the "standard" int types (int32 and int64) when it comes to encoding negative numbers. If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes long – it is, effectively, treated like a very large unsigned integer. If you use one of the signed types, the resulting varint uses ZigZag encoding, which is much more efficient.

    The "default varint type" is the inefficient wire format for values which may well be negative.

    As per the docs, use sint32 to use ZigZag encoding.

    Basically, it looks to me like protobuf-net is behaving absolutely correctly.