Java - DynamicMessage and FileDescriptorProto

2,906 views
Skip to first unread message

yoave

unread,
Jul 18, 2011, 11:20:58 AM7/18/11
to Protocol Buffers, yo...@qwilt.com
Hi all,

I've got 2 questions:

1. how do I generate a Descriptor from a FileDescriptorProto in Java?
In cpp, I'm using DescriptorPool class's 'BuildFile()'
functionality.

2. how do I generate a Dynamic Message from a Descriptor in Java?
In cpp, I'm using DynamicMessageFactory class's 'GetPrototype()'
functionality.

thanks

Pherl Liu

unread,
Jul 22, 2011, 5:37:01 PM7/22/11
to yoave, Protocol Buffers, yo...@qwilt.com
Take a look at com.google.protobuf.Descriptors and com.google.protobuf.DynamicMessage

On Mon, Jul 18, 2011 at 8:20 AM, yoave <eina...@gmail.com> wrote:
Hi all,

I've got 2 questions:

1. how do I generate a Descriptor from a FileDescriptorProto in Java?
  In cpp, I'm using DescriptorPool class's 'BuildFile()'
functionality.

Descriptors.FileDescriptor.buildFrom()

2. how do I generate a Dynamic Message from a Descriptor in Java?
  In cpp, I'm using DynamicMessageFactory class's 'GetPrototype()'
functionality.

DynamicMessage.newBuilder(descirptor)
 

thanks

--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To post to this group, send email to prot...@googlegroups.com.
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/protobuf?hl=en.


Giancarlo Frison

unread,
Jul 26, 2011, 3:21:28 AM7/26/11
to Protocol Buffers
There is this example that I'm approaching to re-implement
http://flori.posterous.com/dynamically-creating-protocol-buffer-objects

a question:

How to handle repeated fields? How can you describe them in the
fieldDescriptor?

Pherl Liu

unread,
Jul 26, 2011, 2:21:11 PM7/26/11
to Giancarlo Frison, Protocol Buffers
Not sure if I understand your question correctly. You can set the label in FieldDescriptorProto:

LABEL_OPTIONAL = 1;
LABEL_REQUIRED      = 2;
LABEL_REPEATED      = 3;

Giancarlo Frison

unread,
Jul 27, 2011, 4:35:20 AM7/27/11
to Protocol Buffers
Thank you very much Pherl!

An another question. What about not-primitive fields, or message
fields?

when I add fields I do:

DescriptorProtos.DescriptorProto.Builder desBuilder
....
DescriptorProtos.FieldDescriptorProto.Builder fd1Builder =
DescriptorProtos.FieldDescriptorProto.newBuilder()
.setName(fieldName).setNumber(i+
+).setType(type).setLabel(label);
desBuilder.addField(fd1Builder.build());

with message typed field I set type as
'DescriptorProtos.FieldDescriptorProto.Type.TYPE_MESSAGE'. How do I
describe the field type?
I mean, I suppose to describe the field with a inner
'DescriptorProtos.DescriptorProto.Builder', is it correct? How I can
do to describe a complex type field?

Thanks!

On Jul 26, 8:21 pm, Pherl Liu <liuj...@google.com> wrote:
> Not sure if I understand your question correctly. You can set the label in
> FieldDescriptorProto:
>
> LABEL_OPTIONAL = 1;
>
> LABEL_REQUIRED      = 2;LABEL_REPEATED      = 3;
>

Robert

unread,
Jul 27, 2011, 9:56:03 AM7/27/11
to Protocol Buffers
Hi,

you either call setType() for primitive types or setTypeName(String)
for referenced messages.
You pass in the name of the message.

Kind regards,
Robert

Giancarlo Frison

unread,
Jul 27, 2011, 10:36:07 AM7/27/11
to Protocol Buffers
if I call setTypeName(messageName), how protobuf match the name with
related Descriptor?
How can I map messageName and the descriptor of the type?

Jason Hsueh

unread,
Jul 27, 2011, 1:17:45 PM7/27/11
to Giancarlo Frison, Protocol Buffers
The descriptor building libraries handle cross linking. The message type name must be defined in either the same file, or be available through one of the file's imports.

Robert

unread,
Jul 27, 2011, 1:56:41 PM7/27/11
to Protocol Buffers
You have to define the name when constructing the DescriptorProto.
I have done this myself lately but unfortunately I am currently not in
the office.
But I can send you an example tomorrow of you like.

Kind regards
Robert

Pherl Liu

unread,
Jul 27, 2011, 2:10:35 PM7/27/11
to Giancarlo Frison, Protocol Buffers
Take a look at the buildFrom() method. You need to provide an array of FileDescriptor as dependencies. If one of your message field is a complex type, you should build that complex type first, and pass the built FileDescriptor object to the buildFrom() in the dependencies array.

Giancarlo Frison

unread,
Jul 28, 2011, 8:35:39 AM7/28/11
to Protocol Buffers
on the field type descriptor previously create i set name as:
b2.setName(typename)

in the container class (which has reference the b2 field) I setup the
field as:
fb = DescriptorProtos.FieldDescriptorProto.newBuilder()
.setName(fieldName).setNumber(i+
+).setLabel(label).setTypeName(typename);
b1.addField(fb.build());

For creating the b1 descriptor, first I generate the descriptor of b2
then:
d1 = b1.build();
fdp1 =
DescriptorProtos.FileDescriptorProto.newBuilder().addMessageType(d1).build();

but I get an error because fdp1.getDependenciesCount()==0
(Descriptors.java:233) Dependencies passed to
FileDescriptor.buildFrom() don't match those listed in the
FileDescriptorProto.

thrown here:
dynamicDescriptor = Descriptors.FileDescriptor.buildFrom(fdp1, fds);

(fds is array of 1, the b2 descriptor)

Why the d1 builder doesn't have the dependency defined adding the
complex typed field?

Thanks!!

Ps.: Robert, it's very kind of you whether send me the related
snippet. Thank you


On Jul 27, 8:10 pm, Pherl Liu <liuj...@google.com> wrote:
> Take a look at the buildFrom() method. You need to provide an array of
> FileDescriptor as dependencies. If one of your message field is a complex
> type, you should build that complex type first, and pass the built
> FileDescriptor object to the buildFrom() in the dependencies array.
>

Robert

unread,
Jul 28, 2011, 10:16:51 AM7/28/11
to Protocol Buffers
Hi,

I do only create one FileDescriptor instance that contains all message
definitions, because they are all constructed dynamically.
For creating the FileDescriptorProtoBuilder I call:
FileDescriptorProto.Builder fileDescriptorProtoBuilder =
FileDescriptorProto.newBuilder();
Then I create all the message protos by calling (here A and B):
DescriptorProto.Builder messageProtoBuilderA =
DescriptorProto.newBuilder();
messageProtoBuilderA.setName( "A" );
DescriptorProto.Builder messageProtoBuilderB =
DescriptorProto.newBuilder();
messageProtoBuilderB.setName( "B" );

If message A references message B using field f I call:
messageProtoBuilderA.addFieldBuilder()
.setName("f")
.setNumber(2)
.setTypeName("B");

Then I add the message protos to the file descriptor:
fileDescriptorProtoBuilder.addMessageType(messageProtoBuilderA);
fileDescriptorProtoBuilder.addMessageType(messageProtoBuilderB);

Finally I create the file descriptor using:
FileDescriptorProto fileDescriptorProto =
fileDescriptorProtoBuilder.build();
FileDescriptor fileDescriptor =
FileDescriptor.buildFrom(fileDescriptorProto, new FileDescriptor[0]);

Now I can create concrete messages by calling:
Builder messageA =
DynamicMessage.newBuilder( fileDescriptor.findMessageTypeByName("A") );
Builder messageB =
DynamicMessage.newBuilder( fileDescriptor.findMessageTypeByName("B") );

messageA.setField(
fileDescriptor.findMessageTypeByName("A").findFieldByName("f"),
messageB.build() );

I hope I did not add any errors when abstracting the code and that I
understood your problem correctly.

Kind regards,
Robert



On 28 Jul., 14:35, Giancarlo Frison <gfri...@chelab.com> wrote:
> on the field type descriptor previously create i set name as:
> b2.setName(typename)
>
> in the container class (which has reference the b2 field) I setup the
> field as:
> fb = DescriptorProtos.FieldDescriptorProto.newBuilder()
>                 .setName(fieldName).setNumber(i+
> +).setLabel(label).setTypeName(typename);
> b1.addField(fb.build());
>
> For creating the b1 descriptor, first I generate the descriptor of b2
> then:
> d1 = b1.build();
> fdp1 =
> DescriptorProtos.FileDescriptorProto.newBuilder().addMessageType(d1).build(­);
> > >http://groups.google.com/group/protobuf?hl=en.- Zitierten Text ausblenden -
>
> - Zitierten Text anzeigen -

Giancarlo Frison

unread,
Jul 28, 2011, 12:04:22 PM7/28/11
to Protocol Buffers
Perfect, it works!

Thank you Robert, Pherl and everyone for the help.
> > > >http://groups.google.com/group/protobuf?hl=en.-Zitierten Text ausblenden -
Reply all
Reply to author
Forward
0 new messages