我正在运行时加载的DynamicMessage
文件中构建java中的.proto
。
我的问题是设置此类消息的扩展名。
我有:
Descriptors.Descriptor
和为其创建的DynamicMessage
Descriptors.Descriptor
扩展类型并为其创建DynamicMessage
现在我不知道如何设置包含消息的扩展名。
如果我要求字段列表,则包含描述符仅列出没有扩展名字段的字段。这是有道理的。
扩展描述符只包含扩展类型的字段(它没有包含类型的字段)。
请告知我如何将这些结合在一起。
要了解上下文,您可能需要查看我之前关于此主题的问题,该问题与扩展无关:Protocol buffer objects generated at runtime
修改
事实上,我正在寻找所生成消息的.setExtension
的类比。我注意到只有GeneratedMessage
延伸ExtendableMessage
,但我相信一定有办法:)
答案 0 :(得分:6)
扩展由FieldDescriptor
描述,就像常规字段一样,因此在使用动态接口时,实际上使用完全相同的方法来访问任何一个。
请记住,扩展实际上是从扩展类型或扩展类型独立声明的。例如,这是有效的:
message Foo { extensions 1000 to max; }
message Bar { ... }
extend Foo {
optional Bar ext1 = 1234;
optional Bar ext2 = 2345;
}
请注意,我们向Foo
类型的Bar
声明了两个扩展名。因此,仅仅知道您正在寻找Bar
类型的扩展名还不够 - 您必须指定哪一个。
在任何情况下,FileDescriptor
和Descriptor
等各种描述符类型都有findExtensionByName()
个方法,可用于查找扩展描述符。请注意,此方法查找在您调用它的描述符的范围中声明的扩展名 - 它找不到扩展名到该消息类型。也就是说,如果你有:
message Foo { extensions 1000 to max; }
message Bar {
extend Foo {
optional int32 ext1 = 1234;
}
}
extend Foo {
optional int32 ext2 = 2345;
}
要查找扩展程序ext1
,您必须在findExtensionByName("ext1")
上为Descriptor
,而不是的描述符调用Bar
Foo
。要查找ext2
,您必须在文件findExtensionByName("ext2")
上致电FileDescriptor
。
您可能还想查看ExtensionRegistry
类,该类可用于按其完全限定名称查找扩展名(例如"mypackage.Bar.ext1"
),但这需要您首先注册你感兴趣的描述符,所以它可能不会非常有用。
答案 1 :(得分:0)
我还想在C ++中找到一个解决方案,使用以下代码似乎更容易:
const Reflection* reflection = merged_doc_info.GetReflection();<br/>
const FieldDescriptor * ext_fld=reflection->FindKnownExtensionByName("msg.usage");
assert(ext_fld!=0);
reflection->SetUInt32(&merged_doc_info,ext_fld,123);
一种替代方法是模拟protoc命令的作用,生成java代码行 像
msgBuilder.setExtension(msg.usage, "1");