Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protocol buffers and enums combinations?

This is my proto file :

message MSG {

  required MsgCodes MsgCode = 1;
  optional int64 Serial = 2;        // Unique ID number for this person.
  required int32 From = 3;  
  required int32 To = 4;  
  //bla bla...
        enum MsgCodes
        {
            MSG = 1;
            FILE = 2;
            APPROVE=4;
            ACK=8;
            ERROR_SENDING=16;
            WORLD=32;
        }
}

In my C# I'm trying to :

 msg = msg.ToBuilder().SetMsgCode(msg.MsgCode | MSG.Types.MsgCodes.ACK | MSG.Types.MsgCodes.APPROVE).Build();
 SendToJava(msg);

But the JAVA tells me : missing MsgCode ( which is a required)

Removing the combination - does solve it

But I need to specify combinations

Question

How can I solve it ?

nb :

The weird thing is that if I create a msg and set multiple enums , and then reads it in C# again - it does work...:-(

like image 271
Royi Namir Avatar asked Nov 07 '14 21:11

Royi Namir


People also ask

How does Protobuf define enum?

You can define enum s within a message definition, as in the above example, or outside – these enum s can be reused in any message definition in your .proto file. You can also use an enum type declared in one message as the type of a field in a different message, using the syntax _MessageType_._EnumType_ .

What are protocol buffers used for?

Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. It is useful in developing programs to communicate with each other over a network or for storing data.

Is Protobuf backwards compatible?

The proto-backwards-compatibility plugin is a Maven plugin to run a backwards compatibility check on a set of protobuf IDL files. The plugin can be integrated into various phases of a maven build to check that any changes to a set of . proto files are backwards compatible.

Does Protobuf handle endianness?

Protocol buffers messages always use little-endian encoding.


1 Answers

In Protobufs, an enum-typed field is only allowed to have one of the exact numeric values specified in the enum. That is to say, you cannot use an enum-typed field as a bitfield. If you want a bitfield, you need to use an integer type like int32. This rule actually applies even in languages that have numeric enum types, like C++ -- if an enum-typed protobuf field read from the wire has an invalid value, it will be treated like an unknown field and thus hidden.

If you switch to integers, you of course now have the problem of how to declare flag values. Unfortunately Protobufs provides no good way to define constants. As you suggested in your self-answer, you can use a dummy enum definition as a hack, but note that the numeric value won't necessarily be available in all languages. It works in C++ and Python since they use numeric enums (and apparently C# too?). In Java, Protobuf enums have a .getNumber() method which you can use to get the numeric value; otherwise, normal Java enums are not numeric.

(Aside: I'm the author of most of Google's open source Protobuf code. I'm also the author of Cap'n Proto, a newer non-Google project aimed at replacing Protobufs. Among other advantages, Cap'n Proto supports defining constants in schema files. But, as of this writing C# support is not ready yet (though being worked on!).)

like image 149
Kenton Varda Avatar answered Sep 23 '22 03:09

Kenton Varda