Search code examples
c#protocol-buffersprotobuf-csharp-portproto3

Parsing RepeatedFields in proto3


A simple 'Person' object is parsed as

            Person person = new Person
            {
                Id = 1,
                Name = "Foo",
                Email = "foo@bar",
                Phones = { new Person.Types.PhoneNumber { Number = "555-1212" } }
            };
            using (MemoryStream stream = new MemoryStream())
            {
                // Save the person to a stream
                person.WriteTo(stream);
                bytes = stream.ToArray();
            }
            Person copy = Person.Parser.ParseFrom(bytes);

How is a RepeatedField<> parsed?

EDIT: The question is if RepeatedFields can be sent through the wire or do they have to be bundled in a message to be passed around?


Solution

  • Person is a message, so you can read and write a single instance of it, as in your example. repeated Person is a field in a message, not a message itself. You cannot read/write a repeated field, you have to read/write an entire message at a time. (Looking at the Python implementation, it appears that the encoder needs to know how long the message is in order to encode it properly, so this makes sense.)

    However, there are a couple alternatives to the scenario you described:

    1. You could send a bunch of single Person messages, and gather them together at the receiving end in whatever way you need.

    2. You could define a message, let's call it People, containing a single field repeated Person and write that message. In the documentation for encoding, they note that both concatenating the strings of two messages or calling the Message::MergeFrom method will concatenate repeated fields in messages. So, you could send any number of People messages and concatenate or merge them on the receiving end. This would get you a single People message containing every Person that was sent, without having to know up front how many Person messages will be sent.