How to get the type of protobuf message from the field descriptor?

103 views
Skip to first unread message

Iranjeet Singh

unread,
Nov 29, 2019, 3:32:10 AM11/29/19
to Protocol Buffers
I am trying to get the type of a data member inside a protobuf message and call the appropriate message from it.

message ControlMessage{}
message AdminMessage{}
message ExecMessage{}

message IncomingMessage
{
  optional ControlMessage cmsg = 1 ;
  optional AdminMessage amsg   = 2 ;
  optional ExecMessage  emsg   = 3 ;
}
void onMsg(const ControlMessage&){}
void onMsg(const AdminMessage&){}
void onMsg(const ExecMessage&){}

int main()
{
  IncomingMessage msg ;
  msg.mutable_cmsg() ;
  msg.mutable_emsg() ;

  auto metadata = msg.GetMetaData() ;
  auto reflection = metadata.reflection ;
  auto descriptor = metadata.descriptor ;

  std::vector<const FieldDescriptor*> all_fields ;

  reflection->ListFields( msg, &all_fields ) ;

  for(auto msgItr : all_fields)
  {
     // Somehow call the onMsg() overloads
     // for all the fields set inside the msg
     // msgItr is the FieldDescriptor
  }
}

Adam Cozzette

unread,
Dec 2, 2019, 5:46:41 PM12/2/19
to Iranjeet Singh, Protocol Buffers
You can access the messages reflectively and static_cast them to the concrete type. Just make sure you're casting to the correct type since otherwise it will be undefined behavior. Something like this should work:

switch ((*msgItr)->number()) {
  case IncomingMessage::kCmsgFieldNumber:
    onMsg(static_cast<ControlMessage>(reflection->GetMessage(msg, *msgItr)));
  case IncomingMessage::kAmsgFieldNumber:
    ...
}

--
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 protobuf+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/protobuf/fc826c44-e139-4987-8dab-c7da3dc4858d%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages