Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set enum value in google-protobufjs

Hi have a proto file as follows:

enum Type
{
    A = 0;
    B = 1;
    C = 2;
}

message Message
{
    User to = 1;
    User from = 2;
    Type type = 3;
}

I use protoc compiler to convert it to javascript utility classes. Using this generated javascript file I set up Message object in my application as follows:

const message = new Main.Message()
message.setTo(this.user1) // saved user
message.setFrom(this.user3) // saved user
message.setType(0) // trying to set type to A

const buffer = message.serializeBinary()
socket.send(buffer)

The issue I am facing is in message object both to and from fields get updated properly, but type remains null! I am unable to figure out a solution for this.

Is this because in Message proto, expected type is as Enum? But it javascript it is not possible. How to set expected enum values while creating protobuf for dispatch?

Note:

I've noticed that, this issue happens only when I try to set zero value to Enum type!

like image 678
demonofthemist Avatar asked Nov 15 '18 07:11

demonofthemist


1 Answers

Enums in protobuffer use 0 as a default (aka unknown) value; from Protocol Buffers docs on Enums:

every enum definition must contain a constant that maps to zero as its first element. This is because:

  • There must be a zero value, so that we can use 0 as a numeric default value.

  • The zero value needs to be the first element, for compatibility with the proto2 semantics where the first enum value is always the default.

More on defaults:

When a message is parsed, if the encoded message does not contain a particular singular element, the corresponding field in the parsed object is set to the default value for that field:

  • For enums, the default value is the first defined enum value, which must be 0.

Default enums are not even sent on wire. You can check that by examining your buffer after serializing a message with a zero-value enum. Since default value is indistinguishable from an unset value, the way it's going to look after being deserialized is really on the decoder side.

You can't do much about it other than not defining any meaningful values as 0 in your enums and use throw-away values instead, like NONE or UNSPECIFIED:

enum Type
{
    NONE = 0;
    A = 1;
    B = 2;
    C = 3;
}
like image 123
shkaper Avatar answered Sep 25 '22 20:09

shkaper