On Mon, Aug 19, 2013 at 1:32 PM, Ivan Bazhenov <[email protected]>wrote: > > // register extensions > ExtensionRegistry registry = ExtensionRegistry.newInstance(); > Foobar.registerAllExtensions(registry); > > final DescriptorProtos.FileDescriptorSet fds = > DescriptorProtos.FileDescriptorSet.parseFrom(new > FileInputStream("foobar.desc")); > > Descriptors.Descriptor descriptor = > Descriptors.FileDescriptor.buildFrom(fds.getFile(0), new > Descriptors.FileDescriptor[]{}) > .findMessageTypeByName("Msg"); > > // build Msg from data using dynamically created descriptor > DynamicMessage dynamicMessage = > DynamicMessage.parseFrom(descriptor, msgData, registry); > System.out.println("dynamically created descriptor: " + > JsonFormat.printToString(dynamicMessage)); > // build Msg from data using manually created descriptor > DynamicMessage dynamicMessage1 = > DynamicMessage.parseFrom(Foobar.Msg.getDescriptor(), msgData, registry); > System.out.println("manually created descriptor: " + > JsonFormat.printToString(dynamicMessage1)); > > Result: > dynamically created descriptor: {"foo": {"i": 123, "10001": [456], > "10002": ["simpleName"]}} > manually created descriptor: {"foo": {"i": 123,"Bar.j": 456,"Bar.name": > "simpleName"}} > > So, dynamicMessage1 parsed correctly - it has fields "Bar.j" and > "Bar.name" which were parsed as extensions. > But dynamicMessage parsed incorrectly - those fields parsed as unknown > fields and their names are equal to thier numbers - "10001" and "10002". >
I ran into something similar and, IIRC, the problem here is that the parser calls ExtensionRegistry.findExtensionByNumber(Descriptor containingType, int fieldNumber) to locate possible extensions; this fails to find the extension because containingType is the descriptor instance that was recreated from the serialized form, but the extension registry contains the precompiled descriptor instance which is a different instance. ExtensionRegistry does the lookup by object identity, not by descriptor equality or message name equality, so the extension is not found. The workaround I ended up with was to have a map of message types that are compiled into the receiver, and prefer to use that precompiled code rather than DynamicMessage when a message is encountered that contains a serialized descriptor that appears to match the local message definition. It was sufficient for my purposes to just compare the message names, but you might want a deeper comparison. Oliver -- You received this message because you are subscribed to the Google Groups "Protocol Buffers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/protobuf. For more options, visit https://groups.google.com/groups/opt_out.
