问题
My goal is exactly the same as stated in this issue on github:
how to read an existing .proto file and get a FileDescriptor from it
I cannot use the suggested "workaround", for 2 reasons:
- I have "plain" .proto files, i.e.:
- they are text files, just like good old addressbook.proto
- they are not self-describing
- I do not want to invoke the protoc compiler as an external application.
According to Marc this is possible with protobuf-net library:
Without a compiled schema, you would need a runtime .proto parser. [...] protobuf-net includes one (protobuf-net.Reflection)
I found Parsers.cs
Thanks Marc, but how do I use/do this? Is this the right entry point? Is there a minimal working example somewhere?
回答1:
var set = new FileDescriptorSet(); set.Add("my.proto", true); set.Process();
That's all you need; note that if you want to provide the actual contents (rather than having the library do the file access), there is an optional TextReader
parameter. If you need imports:
set.AddImportPath(...);
Once you've called Process
, the .Files
should be populated along with the .MessageTypes
of each file, etc.
For a more complete example:
var http = new HttpClient(); var proto = await http.GetStringAsync( "https://raw.githubusercontent.com/protocolbuffers/protobuf/master/examples/addressbook.proto"); var fds = new FileDescriptorSet(); fds.Add("addressbook.proto", true, new StringReader(proto)); fds.Process(); var errors = fds.GetErrors(); Console.WriteLine($"Errors: {errors.Length}"); foreach(var file in fds.Files) { Console.WriteLine(); Console.WriteLine(file.Name); foreach (var topLevelMessage in file.MessageTypes) { Console.WriteLine($"{topLevelMessage.Name} has {topLevelMessage.Fields.Count} fields"); } }
Which outputs:
addressbook.proto Person has 5 fields AddressBook has 1 fields google/protobuf/timestamp.proto Timestamp has 2 fields
Notice that you didn't have to provide timestamp.proto
or an import path for it - the library embeds a number of the common imports, and makes them available automatically.
(each file is a FileDescriptorProto
; the group of files in a logical parse operation is the FileDescriptorSet
- which is the root object used from descriptor.proto; note that all of the objects in this graph are also protobuf serializable, if you need a compiled/binary schema)
来源:https://stackoverflow.com/questions/62575156/how-to-parse-proto-file-into-a-filedescriptor-in-c