Best practice to parse extensions in c++

1,372 views
Skip to first unread message

Johan Philips

unread,
Jul 16, 2010, 3:16:08 AM7/16/10
to Protocol Buffers, johan....@mech.kuleuven.be
Hello

I was wondering what was the best way to parse messages with
extensions in C++. In the documentation I found this sentence:
"Note that you can use the ListFields reflection method (in C++, Java,
and Python) to get a list of all fields present in the message,
including extensions. You might use this as part of a scheme for
registering handlers for diverse message types."

However no further information is given and I am a bit puzzled on how
to use this reflection interface. For now I just check every single
expected extension using the HasExtension but I'd like something more
generic and cleaner which does not explode whenever more message types
are added:

if(msg.HasExtension(RobotDataProtocol::acknowledge_ext)) {
...
} else if(msg.HasExtension(RobotDataProtocol::assistance_ext)) {
...
} else if(msg.HasExtension(RobotDataProtocol::dynamicWindow_ext)) {
... and so on

Should be something like (with parsers a map with a parser for each
known extension)
Parser p = parsers.get(msg.extensionType());
if(p != null)
p.parse(msg);

Any other more generic solution are also highly appreciated!

Kind regards

Johan

Kenton Varda

unread,
Jul 20, 2010, 6:22:34 PM7/20/10
to Johan Philips, Protocol Buffers, johan....@mech.kuleuven.be
IMO you should just include a tag field which contains some unique identifier, as described in the docs you cite.

The reflection interface, if you want to use it, is documented here:


--
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.


Johan Philips

unread,
Jul 21, 2010, 2:10:59 AM7/21/10
to Protocol Buffers


On 21 jul, 00:22, Kenton Varda <ken...@google.com> wrote:
> IMO you should just include a tag field which contains some unique
> identifier, as described in the docs you cite.

So I just shouldn't have used your extensions mechanism but rather
added to each message a unique id? Adding it now seems duplicate work
since the extension, in my opinion, already make the distinction
between messages. I am just not able to figure out how to query a
message about its extension without knowing all possibilities up
front...

Using the Reflection API could I do something like this?

for each defined extension:
fdExtensions.push_back(msgReflection.findKnownExtensionByName(extensionName));

and then in the parse method

for(int i;i< fdExtensions; i++)
if(msgReflection.HasField(msg,fdExtensions[i]) {
Parser p = parsers.get(fdExtensions[i]);
if(p != null) p.parse()
}

Or is their a faster way of determining the message's extension?

kind regards

Johan

Kenton Varda

unread,
Jul 27, 2010, 4:22:28 PM7/27/10
to Johan Philips, Protocol Buffers
On Tue, Jul 20, 2010 at 11:10 PM, Johan Philips <johanp...@gmail.com> wrote:


On 21 jul, 00:22, Kenton Varda <ken...@google.com> wrote:
> IMO you should just include a tag field which contains some unique
> identifier, as described in the docs you cite.

So I just shouldn't have used your extensions mechanism but rather
added to each message a unique id? Adding it now seems duplicate work
since the extension, in my opinion, already make the distinction
between messages.

I agree, but we don't have a good API for querying which extension is set.  We might fix that someday by introducing language-level support for "unions".
 
I am just not able to figure out how to query a
message about its extension without knowing all possibilities up
front...

Using the Reflection API could I do something like this?

for each defined extension:
fdExtensions.push_back(msgReflection.findKnownExtensionByName(extensionName));

and then in the parse method

for(int i;i< fdExtensions; i++)
 if(msgReflection.HasField(msg,fdExtensions[i]) {
   Parser p = parsers.get(fdExtensions[i]);
   if(p != null) p.parse()
 }

Just use:

  vector<FieldDescriptor*> fields;
  msgReflection->ListFields(msg, &fields);
  for (int i = 0; i < fields.size(); i++) {
    if (field[i]->is_extension()) {
      // handle extension
    }
  }

Johan Philips

unread,
Jul 28, 2010, 2:42:34 AM7/28/10
to Protocol Buffers


On 27 jul, 22:22, Kenton Varda <ken...@google.com> wrote:
>
> I agree, but we don't have a good API for querying which extension is set.
>  We might fix that someday by introducing language-level support for
> "unions".

Ok. So my struggle to find this API is more or less justified :-)

> > for each defined extension:
>
> > fdExtensions.push_back(msgReflection.findKnownExtensionByName(extensionName ));
>
> > and then in the parse method
>
> > for(int i;i< fdExtensions; i++)
> >  if(msgReflection.HasField(msg,fdExtensions[i]) {
> >    Parser p = parsers.get(fdExtensions[i]);
> >    if(p != null) p.parse()
> >  }
>
> Just use:
>
>   vector<FieldDescriptor*> fields;
>   msgReflection->ListFields(msg, &fields);
>   for (int i = 0; i < fields.size(); i++) {
>     if (field[i]->is_extension()) {
>       // handle extension
>     }
>   }

Ok thanks! Iterating over the number of fields might be faster than
iterating over the number of extensions as I did in my example.
Reply all
Reply to author
Forward
0 new messages