I'm having trouble getting the following code to work. Using
protoc.exe, I generated a file with the descriptor data using the --
descriptor_set_out file. I've written some Java code to read the
file, and try to instantiate a default instance of one of the objects
in the descriptor, so that I write it out to an XML file using the
protobuf-format-java library.
Here's my code. The variable "descriptorData" contains the binary
content of the descriptor file, without any modifications:
DescriptorProtos.FileDescriptorSet fdSet =
FileDescriptorSet.newBuilder().mergeFrom(descriptorData).build();
FileDescriptorProto fdp = fdSet.getFile(0);
List<DescriptorProto> messageTypes = fdp.getMessageTypeList();
for(DescriptorProto type : messageTypes)
{
System.out.println("Type is: " + type.getName());
FileDescriptor fd = type.getDescriptorForType().getFile();
DynamicMessage dm =
DynamicMessage.getDefaultInstance(type.getDescriptorForType());
System.out.println(XmlFormat.printToString(dm));
}
I've tried numerous combinations of the above code, but each time I
get the following output:
Type is: Type1
<DescriptorProto></DescriptorProto>
Type is: Type2
<DescriptorProto></DescriptorProto>
Type is: Type3
<DescriptorProto></DescriptorProto>
Type is: Type4
<DescriptorProto></DescriptorProto>
Type is: Type5
<DescriptorProto></DescriptorProto>
Type is: Type6
<DescriptorProto></DescriptorProto>
The proto file has Type1, Type2, Type3, etc, defined as messages. The
fact that type.getName() does return the type names from my proto
file, leads me to believe I'm heading in the right direction.
However, the DynamicMessage type that is created (and serialized to
XML) seems to indicate that I'm not passing the right descriptor
instance in to create the object.
Any thoughts?
Thanks,
Kevin
--
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.
I did make some more progress today, along the lines of what you said
below. I'm seeing an issue where calling
DynamicMessage.getDefaultInstance(type) is not filling in the default
values. This is with 2.3.0 of GPB.
My proto file:
message StringTableEntry
{
required string lang = 1 [default = "en-US"];
required string value = 2 [default = ""];
}
When I instantiate an instance of StringTableEntry, using
DynamicMessage, the required fields are not in the message instance.
From reading the documentation, it sounds like the default values
should show up if I create an object. My code for creation is this:
FileDescriptor fd =
FileDescriptor.buildFrom(fdSet.getFile(0), fds);
List<Descriptor> messageTypes = fd.getMessageTypes();
for(Descriptor type : messageTypes)
{
DynamicMessage dm =
DynamicMessage.newBuilder(type).getDefaultInstanceForType();
//DynamicMessage dm =
DynamicMessage.getDefaultInstance(type);
Map<FieldDescriptor, Object> dmFields =
dm.getAllFields();
for(Entry<FieldDescriptor, Object> entry : dmFields.entrySet())
{
System.out.println("default value for this field: " +
entry.getValue().toString());
entry.setValue("Data");
}
System.out.println(XmlFormat.printToString(dm));
}
When instantiating the object, using either the commented or
uncommented out lines of code above, fails to contain the required
fields with their default values. If I poke around the 'type'
variable in the debugger, I can see that the 2 fields are in the
descriptor, and the default values are there as well. But the
instance of the message does not contain those two fields
(dmFields.entrySet() returns null, and the code inside the
"for(Entry<FieldDescriptor, Object> entry : dmFields.entrySet())" loop
does not execute).
It seems like I could write a routine to set the default values based
on the Descriptor data, but I think that getDefaultInstance should do
that for me.
Thoughts?
Thanks,
Kevin
On Mar 22, 4:02 pm, Kenton Varda <ken...@google.com> wrote:
> DescriptorProto.getDescriptorForType() returns the Descriptor for
> DescriptorProto, not for the type which that DescriptorProto is describing.
> Remember that DescriptorProto is just a protocol message like any other --
> it does not have any special methods that recognize its higher-level
> meaning.
>
> To convert DescriptorProtos to Descriptors, you need to use
> FileDescriptor.buildFrom().
>
> On Sun, Mar 21, 2010 at 5:20 PM, Kevin Tambascio
> <kevin.tambas...@gmail.com>wrote:
> > protobuf+u...@googlegroups.com<protobuf%2Bunsubscribe@googlegroups.c om>
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.
This description in the MessageLite documentation is what led me to
believe the default values would be there. I figured I was
misinterpreting the documentation, or the meaning behind the default
value:
getDefaultInstanceForType
MessageLite getDefaultInstanceForType()
Get an instance of the type with all fields set to their default
values. This may or may not be a singleton. This differs from the
getDefaultInstance() method of generated message classes in that this
method is an abstract method of the MessageLite interface whereas
getDefaultInstance() is a static method of a specific class. They
return the same thing.
http://code.google.com/apis/protocolbuffers/docs/reference/java/index.html
Thanks for your help,
Kevin
On Mar 22, 7:07 pm, Kenton Varda <ken...@google.com> wrote:
> "required" means "If this field is not explicitly set before build() is
> called, or if parseFrom() parses a message missing this field, throw an
> exception.". It does NOT mean "Automatically fill in this field.". Please
> point me at any documentation which suggests the latter meaning so I can fix
> it.
>
> The default value is the value returned by the field's getter when the field
> has not been explicitly assigned any other value.
>
> getAllFields() only returns field which have been explicitly set.
>
> On Mon, Mar 22, 2010 at 2:42 PM, Kevin Tambascio
> <kevin.tambas...@gmail.com>wrote:
> > <protobuf%2Bunsubscr...@googlegroups.c om>
To unsubscribe from this group, send email to protobuf+u...@googlegroups.com.