Search code examples
protocol-buffersprotocol-buffers-3

How to define a nullable repeated field in protobuf 3


In protobuf 3 how do you define a nullable repeated field? The user needs to know whether or not the field was ever set. The optional keyword does not work for repeated fields. For example lets say we have a repeated field:

message Result {
  repeated string url = 1;
}

How can the user tell if url is set to it's default value of an empty array or never been set? In Java I would want to know the difference between new String[0] and null.

Edit: Looks like protobuf calls this Field Presence and there is not a direct way to express this in a repeated field.

Another thought I had was to use oneof but protobuf 3 does not support the repeat fields directly.

You then add your oneof fields to the oneof definition. You can add fields of any type, except map fields and repeated fields.


Solution

  • That's not a thing that protobuf can express directly; to tell whether individual elements are null or not, you would need to add a layer, which is exactly what StringValue in wrappers.proto does, so:

    syntax = "proto3";
    import "google/protobuf/wrappers.proto";
    message Result {
        repeated StringValue urls = 1;
    }
    

    To tell whether the collection is null or not, again, you'd need to add a layer, perhaps:

    syntax = "proto3";
    message Result {
        HazUrls maybe = 1;
    }
    message HazUrls {
        repeated string urls = 1;
    }
    

    Then result.maybe can be null or can be a message that has a set of urls (which can be zero length)

    And if you need to tell whether the collection is null and whether any of the elements are null, you need to combine the two. This starts adding a lot of layers very quickly!