Jon Emerson
Jon Emerson

Reputation: 231

Google Protobufs in Java: How do you get a Message.Builder from a FieldDescriptor?

I have a FieldDescriptor for a message field defined in my protocol buffer. I want to start constructing a value for that field, but I'm stuck trying to get a Message.Builder for that FieldDescriptor. The code I'm writing is extremely generic - It's designed to serialize between MongoDB and Protocol Buffers - so I can't use any specialized logic for the Objects I happen to be using today.

The FieldDescriptor's JavaType is MESSAGE. It's MessageType is a bit better, as it contains the message's Type, but the Type is in protocol buffer namespace, so I still can't use reflection to get a Message for it (at least not cleanly).

I'm not sure what else to do. Anyone know how to construct a Message.Builder from a FieldDescriptor?

Upvotes: 2

Views: 8174

Answers (1)

Kenton Varda
Kenton Varda

Reputation: 45151

If you have an instance of the containing type's builder, you can get the builder for the field with:

containingBuilder.getFieldBuilder(fieldDescriptor)

or you can get a new builder for a message of the field's type (but not specifically the field of the existing instance):

containingBuilder.newBuilderForField(fieldDescriptor)

If you don't have an instance of the containing type at all, but you know the containing class, you can do:

ContainingType.getDefaultInstanceForType()
              .getField(fieldDescriptor)
              .newBuilderForType()

If you don't even know the containing class (perhaps it isn't even in your jar), and all you have is a descriptor, then you can use DynamicMessage:

DynamicMessage.newBuilder(fieldDescriptor)

However, note that DynamicMessage only emulates the reflection interface of the real class; it is not actually an instance of the real class (as would be generated by protoc). Also, it is a lot slower than the real class.

Upvotes: 9

Related Questions