对于背景,“组”是表示子消息的不同方式。它们是这样声明的:
message Foo {
repeated group bar = 1 {
optional int32 baz = 2;
optional string qux = 3;
}
}
从语义上讲,这几乎与以下内容完全相同:
message Foo {
repeated Bar bar = 1;
message Bar {
optional int32 baz = 2;
optional string qux = 3;
}
}
但是,编码略有不同(如下所述)。
在 Protobuf 首次开源时,组已被弃用,因此许多非 Google 实现不支持组。谷歌有一些仍然使用组的非常古老的协议,但谷歌之外的任何人都不应该使用组,所以我猜你正在使用的协议是谷歌的协议之一。(如果没有,也许你只是有损坏的数据。)
我假设您已经阅读了编码文档,但它们没有解释组。
组以“开始组”标记开始编码,然后是子消息内容,然后是相应的“结束组”标记。这是 protobufs 中标签出现在值末尾的唯一情况——在所有其他情况下,标签只出现在开头。
相反,普通的子消息(如上面的第二个示例)使用“长度分隔”线类型进行编码:标签,后跟子消息大小,然后是内容。请注意,以长度分隔的编码意味着您可以跳过子消息而不解析其所有字段;对于组,知道组结束位置的唯一方法是解析每个字段,直到看到结束组标记。