What is the relation between "tag number in .proto file of a field" and "number (used in parsing through switch case) in the generated code"?

Viewed 443

Consider the following proto file.

syntax="proto3";
message MessageWithInternalMessage { 
    string F1 = 1;
    _S1 s2 = 5;
    message _S1 {
        string C1 = 1;
        string C2 = 2;
    }
}

When we generate the code for it. The parsing is done using the readTag() and then a switch statement to set the corresponding field. Or Consider the following snippet.

 while (!done) {
    int tag = input.readTag();
    switch (tag) {
        case 0:
            done = true;
            break;
        default: {
            if (!parseUnknownFieldProto3(input, unknownFields, extensionRegistry, tag)) {
                done = true;
            }
            break;
        }
        case 10: {
            java.lang.String s = input.readStringRequireUtf8();
            f1_ = s;
            break;
        }
        case 42: {
            Test.InternalMessageWithSeciton._S1.Builder subBuilder = null;
            if (s2_ != null) {
            subBuilder = s2_.toBuilder();
            }
            s2_ = input.readMessage(Test.InternalMessageWithSeciton._S1.parser(), extensionRegistry);
            if (subBuilder != null) {
                subBuilder.mergeFrom(s2_);
                s2_ = subBuilder.buildPartial();
            }
            break;
        }
    }
}

My question is what is the relation between the "tag 1 for the field F1" in proto file to "case 10 in generated code" and "tag 5 for the field s2" to "case 42 in generated code".

1 Answers

The encoded format for headers is basically:

header = (fieldNumber << 3) | expectedWireType;

Where the "wire type" is an integer between 0 and 7.

  • 0 = varint - base-128 encoded integer with continuation bit
  • 1 = 64 bit (integer or floating point)
  • 2 = length-prefixed data - a varint of the number of bytes followed by that many bytes (strings, BLOBs, sub-messages, packed arrays)
  • 5 = 32 bit (integer or floating point)

So field 1 as a string is (1 << 3) | 2 which is binary 1010, or: 10. Field 5 as a sub-message is likewise (5 << 3) | 2, or: 42

Related