Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protobuf message object creation by name

I have a lot of protobuf messages for which I currently use a manually written lookup function to generate the message by its name. Since the messages get more and more as the project evolves, I'm getting tired of maintaining this lookup code by hand.

So, is there a way to automate this process? Maybe with a protoc plugin that adds some code to the protobuf code so that it may register itself?

like image 342
Marko Avatar asked Apr 30 '15 06:04

Marko


Video Answer


2 Answers

The C++ Protobuf library already maintains a pool of "descriptors" for all types compiled into the binary.

https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.descriptor#DescriptorPool.generated_pool.details

So, you could do:

google::protobuf::Descriptor* desc =
    google::protobuf::DescriptorPool::generated_pool()
        ->FindMessageTypeByName("mypkg.MyType");
assert(desc != NULL);

The library also maintains an object that can be used to construct instances of any compiled-in type, given its descriptor:

https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message#MessageFactory.generated_factory.details

So you'd do:

google::protobuf::Message* message =
    google::protobuf::MessageFactory::generated_factory()
        ->GetPrototype(desc)->New();
like image 136
Kenton Varda Avatar answered Sep 28 '22 19:09

Kenton Varda


Unlikely this approach can not be used as a generic way of creation of any message instance. A message type description appears in the generated_pool() only after a message of this type was instantiated at least once (e.g. at the moment of MyMessageType* msg = new MyMessageType()), thus FindMessageTypeByName never finds a message type of a message that has not been instantiated yet.

like image 28
user8558948 Avatar answered Sep 28 '22 18:09

user8558948