在protobuf文档(https://developers.google.com/protocol-buffers/docs/proto#customoptions)中,它说明了自定义选项:
最后一件事:由于自定义选项是扩展名,因此必须是 分配的字段编号与任何其他字段或扩展名一样在里面 上面的例子中,我们使用了50000-99999范围内的字段编号。 此范围保留供个人内部使用 组织,所以你可以自由使用这个范围内的数字 内部应用程序。如果您打算在公共场合使用自定义选项 但是,确保这一点非常重要 您的字段编号是全球唯一的。获得全球独一无二的 字段编号,请发送请求 protobuf-global-extension-registry@google.com。只需提供您的 项目名称(例如Object-C插件)和您的项目网站(如果 可用)。通常您只需要一个分机号码。
为什么选项字段编号必须是全局唯一的公共应用程序?碰撞会以什么方式成为问题?
答案 0 :(得分:1)
基本上,因为你不知道你得到的数据是否正确。
protobuf二进制有线格式仅存储字段编号和有效负载(对于复杂类型,只是字段编号和子有效负载本身)。没有名称数据。因此:当您存储和检索扩展字段时,您所说的只是"获取字段{字段编号},将其解释为{type}"。如果两个不同的系统使用相同的字段编号扩展相同的数据,那么您无法知道您是否正在获取的数据实际上是那种格式。
通常这不是一个问题 - 因为在同样的数据上很少像这样发生冲突;但自定义选项是不同的!我是图书馆作家;我可能希望通过扩展(例如)MessageOptions
来添加我的架构解析工具识别的自定义选项。 MessageOptions
是DescriptorProto
的扩展点,也就是说:option (foo) = "bar";
内的message
是什么。
为此,我需要为foo
分配一个号码。我随意选择5000
(MessageOptions
定义extensions 1000 to max;
,这样就可以了。一切都很好。我的工具有效。
我不知道,另一个库作者已选择执行类似的操作并且也使用了5000.一旦编译了架构(通过protoc
或类似的),我拥有的只是数字。如果我要求来自字段5000的数据,我不知道我是否获得了我的扩展,或者另一个。意思丢失了。好的,推送我还可以查看dependency
上的FileDescriptorProto
列表,但是......那个命中和未命中。
我不知道字段1
中值5000
的存在是否为:
option (.mystuff.someext) = 1;
VS
option (.anotherlib.whatever) = -1; // stored as sint32
VS
option (.yetanother.library.option) = true;
如果这些扩展程序的编号均为5000,则它们会在电线上显示相同。