Search code examples
c#protocol-buffersprotobuf-csharp-portprotobuf-3

Repeated Int32Value in protobuf3 (nullable int array)


I have the following protobuf message protocol:

message TestMsg
{
  int32 int = 1;
  google.protobuf.Int32Value nullable_int = 2;
  repeated google.protobuf.Int32Value nullable_int_array = 3; // Runtime fail
}

protoc compiles it fine and in C# all Int32Values are int?. But it fail in runtime with a null argument not allowed exception. I can understand repeated does not not allow null messages. But Int32Value is a WellKnownType so the compiler could generate a special NullValue type if needed.

Is this a limitation in protobuf (not allowing Int32Value in repeated) or is it a limitation/bug in the C# code generation and supporting libraries?

What are the options to do nullable int arrays in protobuf protocol, except creating your own message and codegen?


Solution

  • Is this a limitation in protobuf

    Yes. A repeated Int32Value works just like other repeated messages: there's no way of representing a null. Note that on the wire, there's no special handling for Int32Value, and many languages don't have any particular special handling for it at all. And yes, this means that a repeated Int32Value field is pretty pointless. That's a general statement, rather than anything C#-specific.

    If you want to be able to represent a repeated field with some null entries, you'd need to create a message wrapping the wrapper:

    message Int32ValueWrapper
    {
        Int32Value value = 1;
    }
    

    ... then have a repeated Int32ValueWrapper field. That would be populated with Int32ValueWrapper elements all of which would be non-null, but some of which could be empty (so the value field unpopulated).

    It's a tricky situation for the C# code generation, in terms of what it should do... it's a bit of an impedance mismatch, basically.