使用 com.google.protobuf.Descriptors.Descriptor 创建新的构建器

Pra*_*ath 3 java protocol-buffers

我需要为给定的 com.google.protobuf.Descriptors.Descriptor 创建一个类的 newBuilder() 。

我使用 google proto buffer 创建了一个 jar,用于以下协议:

message Foo
{
  optional uint32 id = 1;
  optional string fooName = 2;
}
message Bar
{
  optional uint32 id = 1;
  optional string barName = 2;
}
Run Code Online (Sandbox Code Playgroud)

从Java方面,基于描述符我需要创建newBuilder()。例如 :

    Message.Builder message;
    if(Descriptor.getName().equals("Foo"))
        message = Foo.newBuilder();
    if(Descriptor.getName().equals("Bar"))
        message = Bar.newBuilder();
Run Code Online (Sandbox Code Playgroud)

但我不想选择 if else 或 switch case。我还尝试了使用 DynamicMessage 的其他方法。

Message.Builder message = DynamicMessage.newBuilder(descriptor);
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我无法将其转换为FooBar类。还有其他方法可以使用描述符或描述符名称创建 newBuilder() 吗?

我盲目地需要给定类名的 newBuilder() ,如下所示:

Message.Builder message = SomeUtilClass.getNewBuilder("Foo");
Run Code Online (Sandbox Code Playgroud)

And*_*ner 5

您无法Builder从 a创建Descriptor。ADescriptor没有关于它需要创建的原型(或构建器)类的类型信息,因为所有Descriptor实例都属于同一类(它是最终的)。

如果您只能使用Descriptor,那么您的if/else表现就差不多了。(我说粗略是因为你可以用地图或开关来代替;但它基本上是相同的)。

更好的方法是使用您尝试创建的原型的默认实例(或该原型的任何其他实例;但默认实例最容易获取)。

Message prototype = Foo.getDefaultInstance();  // Or Bar.getDefaultInstance().
Run Code Online (Sandbox Code Playgroud)

因为从中Message您可以获得构建器和描述符:

Message.Builder builder = prototype.newBuilderForType();
Descriptor descriptor = prototype.getDescriptorForType();
Run Code Online (Sandbox Code Playgroud)