I'm trying to write a C++ program that reads a gzipped binary proto from a file. The outer type of this proto is known at compile time, but it contains extensions that aren't. The extensions are described in a FileDescriptorSet stored into a different file I also have. I want to be able to use TextFormat to dumpl these extensions correctly.
What I've done is load the FileDescriptorSet from the file, create a new DescriptorPool, call BuildFile() on each file in the FileDescriptorSet, create a DynamicMessageFactory, set that in the CodedInputStream, and try to parse the proto. Something like this (error checking removed for readability, but it's there in the actual code, and there are no errors):
google::protobuf::FileDescriptorSet descriptors;
descriptors.ParseFromCodedStream(&descriptors_input)
google::protobuf::DescriptorPool descriptor_pool;
for (auto i = 0; i < descriptors.file_size(); ++i) {
descriptor_pool.BuildFile(descriptors.file(i));
}
google::protobuf::DynamicMessageFactory factory(&descriptor_pool);
factory.SetDelegateToGeneratedFactory(true);
input.SetExtensionRegistry(&descriptor_pool, &factory);
generated::OuterType entry;
entry.ParseFromCodedStream(input);
This roughly works, but the extensions aren't recognised when I use TextFormat to print the proto.
I've debugged this deep into the proto code, and tracked it down to FindPtrOrNull() in map_util.h, called by DescriptorPool::Tables::FindExtension(). The collection has the entry I'm looking for, but using an identical but not-the-same Descriptor. So I think I've run into the warnings explained
here.
I believe this may be because OuterType is part of the FileDescriptorSet I'm loading, so maybe the two descriptors come from 1) generated code, 2) loading the FileDescriptorSet. I've tried to avoid this by not loading the file that describes OuterType, but then I get loading errors complaining that OuterType hasn't been loaded [in the descriptor_pool I'm creating].
I have the feeling this has something to do with using this descriptor pool as an underlay for the built-in pool, but I haven't find anything in the documentation, or any example, that explains how to do this; all the methods I can find are private and/or have warnings of the type "THIS MUST NEVER BE CALLED FROM USER CODE" :(
Any suggestions extremely welcome!
Thanks,
--Gabriel