"tag number in .proto file of a field"和"number (used in parsing through switch case) in the generated code"有什么关系?

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"?

考虑以下原型文件。

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

当我们为它生成代码时。解析是使用 readTag() 完成的,然后是一个 switch 语句来设置相应的字段。或者考虑以下代码片段。

 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;
        }
    }
}

我的问题是 "tag 1 for the field F1" 在 proto 文件中到 "case 10 in generated code" 和 "tag 5 for the field s2" 到 "case 42 in generated code".

headers的编码格式基本上是:

header = (fieldNumber << 3) | expectedWireType;

其中 "wire type" 是 0 到 7 之间的整数。

  • 0 = varint - 带连续位的 base-128 编码整数
  • 1 = 64 位(整数或浮点数)
  • 2 = length-prefixed 数据 - 后跟那么多字节的字节数的变体(字符串、BLOB、sub-messages、压缩数组)
  • 5 = 32 位(整数或浮点数)

所以作为字符串的字段 1 是 (1 << 3) | 2 是二进制 1010,或:10。作为 sub-message 的字段 5 同样是 (5 << 3) | 2,或:42