vendredi 26 juin 2020

Why is Parser of MessageDescriptor null when obtaining it via FileDescriptor.BuildFromByteStrings()?

I have compiled the example addressbook.proto file into a binary file addressbook.proto.bin with the --descriptor_set_out option of protoc. I want to load this file at runtime and use it with the reflection API. At the moment I evaluate what's possible and what's not.

I found this comment on github suggesting that some amount of reflection is possible with FileDescriptor.BuildFromByteStrings() and have written some code based on that:

static void Main(string[] args)
{
    var john = new Person
    {
        Id = 1234,
        Name = "John Doe",
        Email = "jdoe@example.com",
        Phones = { new PhoneNumber { Number = "555-4321", Type = PhoneType.Home } }
    };

    using (var output = File.Create("john"))
    {
        john.WriteTo(output);
    }

    using (var stream = File.OpenRead("addressbook.proto.bin"))
    {
        var descriptorSet = FileDescriptorSet.Parser.ParseFrom(stream);
        var byteStrings = descriptorSet.File.Select(f => f.ToByteString()).ToList();
        var messageDescriptors = FileDescriptor
            .BuildFromByteStrings(byteStrings) // Note: reflection using the returned FileDescriptors is not currently supported.
            .SelectMany(descriptor => descriptor.MessageTypes)
            .ToArray();

        #region this works

        foreach (var messageDescriptor in messageDescriptors)
        {
            Console.WriteLine(messageDescriptor.Name);
        }

        #endregion

        #region this fails

        var personMessageDescriptor = messageDescriptors.First(message => message.Name == "Person");
        using (var input = File.OpenRead("john"))
        {
            Console.WriteLine(
                new JsonFormatter(JsonFormatter.Settings.Default)
                    .Format(personMessageDescriptor.Parser // Parser is null =(
                        .ParseFrom(input)));
        }

        #endregion
    }
}

There's a note in the comment of that method stating:

Note: reflection using the returned FileDescriptors is not currently supported.

However, it is actually possible to list the Names of all MessageTypes jsut fine (see first #region) On the other hand, the Parser property is null.

Is Parser being null the limitation for reflection mentioned in the quoted note above or is it a mistake in my programming?





Aucun commentaire:

Enregistrer un commentaire