如何在java中设置protobuf DynamicMessage的扩展名?

时间:2013-09-27 15:28:56

标签: java protocol-buffers

我正在运行时加载的DynamicMessage文件中构建java中的.proto

我的问题是设置此类消息的扩展名。

我有:

    包含类型的
  • Descriptors.Descriptor和为其创建的DynamicMessage
  • Descriptors.Descriptor扩展类型并为其创建DynamicMessage

现在我不知道如何设置包含消息的扩展名。

如果我要求字段列表,则包含描述符仅列出没有扩展名字段的字段。这是有道理的。

扩展描述符只包含扩展类型的字段(它没有包含类型的字段)。

请告知我如何将这些结合在一起。

要了解上下文,您可能需要查看我之前关于此主题的问题,该问题与扩展无关:Protocol buffer objects generated at runtime

修改

事实上,我正在寻找所生成消息的.setExtension的类比。我注意到只有GeneratedMessage延伸ExtendableMessage,但我相信一定有办法:)

2 个答案:

答案 0 :(得分:6)

扩展由FieldDescriptor描述,就像常规字段一样,因此在使用动态接口时,实际上使用完全相同的方法来访问任何一个。

请记住,扩展实际上是从扩展类型或扩展类型独立声明的。例如,这是有效的:

message Foo { extensions 1000 to max; }
message Bar { ... }
extend Foo {
  optional Bar ext1 = 1234;
  optional Bar ext2 = 2345;
}

请注意,我们向Foo类型的Bar声明了两个扩展名。因此,仅仅知道您正在寻找Bar类型的扩展名还不够 - 您必须指定哪一个。

在任何情况下,FileDescriptorDescriptor等各种描述符类型都有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");