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 Name
s 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