Dynamically determine the type of a message

10,709 views
Skip to first unread message

fokenrute

unread,
Feb 10, 2010, 6:02:35 PM2/10/10
to Protocol Buffers
Hi, I'm developing a C++ application and I use Protocol Buffers for
network communications.
Somewhere in my app, I receive messages which can be of different
types and I'm searching for a mean to dynamically determine the type
of these messages (which are stored in a buffer). I read something
about the reflexion interface, but I don't konw how to use it to do
what i want.
Thanks in advance for your replies.

Evan Jones

unread,
Feb 10, 2010, 6:07:35 PM2/10/10
to fokenrute, Protocol Buffers
fokenrute wrote:
> Somewhere in my app, I receive messages which can be of different
> types and I'm searching for a mean to dynamically determine the type
> of these messages (which are stored in a buffer). I read something
> about the reflexion interface, but I don't konw how to use it to do
> what i want.

See the techniques section on Union Types:

http://code.google.com/apis/protocolbuffers/docs/techniques.html#union

Hope this helps,

Evan

--
Evan Jones
http://evanjones.ca/

Kenton Varda

unread,
Feb 10, 2010, 6:11:29 PM2/10/10
to fokenrute, Protocol Buffers
http://code.google.com/apis/protocolbuffers/docs/reference/cpp/google.protobuf.message.html


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


fokenrute

unread,
Feb 10, 2010, 6:57:24 PM2/10/10
to Protocol Buffers
> See the techniques section on Union Types:
>
> http://code.google.com/apis/protocolbuffers/docs/techniques.html#union

I read the link you pointed to me, and it appears that Union Types are
not generic enough to suit my needs. Self Describing Messages seems
more like what I need, but they appears to be to heavy to use; I just
need something that takes a buffer (char[] which contains bytes of the
message) as an input and return the message type. Is there something
similar or am I trying to use protoccol buffers the wrong way?

Kenton Varda

unread,
Feb 10, 2010, 7:04:45 PM2/10/10
to fokenrute, Protocol Buffers
On Wed, Feb 10, 2010 at 3:57 PM, fokenrute <foke...@gmail.com> wrote:
I just
need something that takes a buffer (char[] which contains bytes of the
message) as an input and return the message type.

That's not possible.  Serialized messages do not identify their own type.

fokenrute

unread,
Feb 10, 2010, 7:16:57 PM2/10/10
to Protocol Buffers
> That's not possible.  Serialized messages do not identify their own type.

Ok, so, I will likely opt for Enum Types. Thanks for answering.

Alessandro Bellina

unread,
Feb 11, 2010, 7:55:13 AM2/11/10
to Protocol Buffers
Every message has a descriptor object associated. Look in the c++ API
reference (http://code.google.com/apis/protocolbuffers/docs/reference/
cpp/index.html) for it. Once you get the descriptor, you can get a
string type by calling name().

Evan Jones

unread,
Feb 11, 2010, 7:58:36 AM2/11/10
to fokenrute, Protocol Buffers
fokenrute wrote:
> Ok, so, I will likely opt for Enum Types. Thanks for answering.

I think union types are the best choice for a "small" number of possible
messages. However, if you really need to support *any* type of message,
you could consider adding a "header" message of a known type that
includes the fully-qualified message name as returned by
message->GetDescriptor()->full_name(), or some other unique "message
type" indicator.

Good luck,

alexric...@gmail.com

unread,
Feb 11, 2010, 3:44:42 PM2/11/10
to Evan Jones, fokenrute, Protocol Buffers
...


> I think union types are the best choice for a "small" number of possible messages. However, if you really need to support *any* type of message, you could consider adding a "header" message of a known type that includes the fully-qualified message name as returned by message->GetDescriptor()->full_name(), or some other unique "message type" indicator.
>
> Good luck,
>
> Evan
> --
>
> Evan Jones

Union types in combination with 'extensions' seems like the right solution for this problem in almost all cases, whether the number of message types is large or small.

Using a separate header message adds lots of complications as you then need to write additional code to instantiate the 'payload' message type etc... I was using a header message a while back, and migrated to union types with great success. Granted, I do still have a fairly small number of message types, but I am not aware of any issues which would arise from scaling to a very large set of messages. Are there known issues which arise from a union type with a large number of extensions?

Alex

Evan Jones

unread,
Feb 11, 2010, 4:12:51 PM2/11/10
to alexric...@gmail.com, fokenrute, Protocol Buffers
On Feb 11, 2010, at 15:44 , alexric...@gmail.com wrote:
> Are there known issues which arise from a union type with a large
> number of extensions?

The problem that concerns me is that I need to have unique extension
ids. This seems difficult when using Protocol Buffers as an RPC
system, unless I'm thinking about this in the wrong way? I haven't
actually thought about this very hard.

Gonzo

unread,
Mar 4, 2010, 1:13:21 PM3/4/10
to Protocol Buffers
On Feb 11, 5:44 pm, alexrichard...@gmail.com wrote:
>
> Union types in combination with 'extensions' seems like the right solution  
> for this problem in almost all cases, whether the number of message types  
> is large or small.

I am trying to solve a similar problem. Can anybody point me to a
small and (hopefully) working example of this technique (union types +
extensions)?

Thanks and best regards.

Jeremy Swigart

unread,
Feb 25, 2013, 3:55:27 PM2/25/13
to prot...@googlegroups.com, foke...@gmail.com
What about something like this

message UnknownMessage
{
    enum MessageType
    {
        MESSAGE_TYPE_A = 1;
        MESSAGE_TYPE_B = 2;
        MESSAGE_TYPE_C = 3;
    }
   
    required MessageType    msgType = 1;
    required bytes            msgPayload = 2;
Reply all
Reply to author
Forward
0 new messages