Protobuf ignoring bool and ints values due to default
Asked Answered
S

3

6

I am converting a json file to string and then the string is converted to proto3 file.

Here is the json file:

{    "a": false,
     "b": 0
}

Here is how I convert my json file to string:

String json =Files.lines(Paths.get(filePath)).collect(Collectors.joining());

Here is how I convert my string to proto3 file:

    JsonFormat.parser().ignoringUnknownFields().merge(json,messageBuilder);
   MyProto proto = messageBuilder.build();

I have boolean and int fields in my json , the values of some of them are required to be default values (false for boolean and 0 for int).

When I deserialise the above file to proto3 java file then both the above fields are ignored , and my json becomes empty even though I have explicitly set the values(as you can see it in the above json file).

I know that proto3 ignores the default values while deserializing/serializing , however is there any way not to ignore fields which are explicitly set even though they are the default values?

Scheldt answered 11/7, 2018 at 11:53 Comment(0)
S
4

Used proto2 instead of proto3 . Proto2 has this behaviour - if a field is explicitly set , even though it is default value of the field , it is serialized and deserialized .

Scheldt answered 15/7, 2018 at 17:10 Comment(0)
E
3

No, the Protobuf language guide states explicitly that this is not possible:

Note that for scalar message fields, once a message is parsed there's no way of telling whether a field was explicitly set to the default value (for example whether a boolean was set to false) or just not set at all: you should bear this in mind when defining your message types. For example, don't have a boolean that switches on some behaviour when set to false if you don't want that behaviour to also happen by default. Also note that if a scalar message field is set to its default, the value will not be serialized on the wire.

If you really must know wether the default value was set explicitly or not you have encode that information in a separate field.

Extinct answered 12/7, 2018 at 14:55 Comment(1)
Or use an Int32Value or StringValue etc.Holotype
A
3

Since version 3.15, protobuf3 allows for explicit presence tracking via the optional keyword.

That is, given

message MyProto
{
    optional int32 field = 1;
}

protoc will generate a has_field()/hasField() (depending on language) function to check if the field has been explicitly set.

(Note: protobuf3 fields are optional by default, the optional keyword makes them "nullable").

Another option is to use the "well known" wrapper messages:

import "google/protobuf/wrappers.proto"

message MyProto
{
    Int32Value field = 1;
}

However, their use is deprecated.

Agriculture answered 11/5, 2023 at 19:56 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.