I am using Google Protobuf 3.0.0. and ZeroMQ to achieve a connection between a server and some clients. So, my proto file looks something like this:
// message Request{} omitted
message Response{
enum MessageType{
Type1 = 0;
Type2 = 1;
Type3 = 2;
}
enum ConfirmationCode{
OK = 0;
Error1 = 1;
Error2 = 2;
}
MessageType Type = 1;
repeated someField1 field1 = 2;
// ... some code omitted
ConfirmationCode Confirm = 3;
}
As you can see, in ProtoBuf 3 there are no longer required
or optional
fields and I do not use any defaults.
Now, I ran into some troubles when serializing some Protobuf messages and trying to send them over ZMQ. The serialization done by google::protobuf::message_lite::SerializeToString(...)
does not fail but still, this method and google::protobuf::message_lite::SerializeAsString()
produce empty strings, so I thought that maybe not a single field was set in my response before serializing and I introduced a method similar to the following
void InitResponse(Response& resp)
{
resp.set_confirm(Response_ConfirmationCode_OK);
resp.set_type(Response_MessageType_Type1);
}
to be sure that at least some fields were present. Still, before and after calling this method, my serialized response has a length of 0. I also tried using google::protobuf::Message::DebugString()
but I think this method does not print every field present, since I always end up printing empty strings.
Why do my serialized messages end up empty if the serialization does not fail?
https://developers.google.com/protocol-buffers/docs/proto3#default
For enums, the default value is the first defined enum value, which must be 0.
PB enums aren't the same semantic animal as "usual" enums e.g., C(++). PB is not "just another interpretation" of your app memory. If you do want your app variables to produce a non-zero PB buffer, do not use default values for those variables. It applies to all PB data types, not just enums. A PB message with int=0, float=0.0, bool=false will be a zero buffer, too.