我的目标与 this issue on github 中所述完全相同:
how to read an existing .proto file and get a FileDescriptor from it
我无法使用建议的“解决方法”,原因有两个:
- 我有“普通”.proto 文件,即:
- 它们是文本文件,就像旧的 addressbook.proto 一样
- 他们不是self-describing
- 我不想将协议(protocol)编译器作为外部应用程序调用。
According to Marc这可以通过 protobuf-net 实现图书馆:
Without a compiled schema, you would need a runtime .proto parser. [...] protobuf-net includes one (protobuf-net.Reflection)
我找到了Parsers.cs
谢谢马克,但是我该如何使用/执行此操作? 这是正确的切入点吗? 某处有一个最小的工作示例吗?
最佳答案
var set = new FileDescriptorSet(); set.Add("my.proto", true); set.Process();
这就是你所需要的;请注意,如果您想提供实际内容(而不是让库进行文件访问),则有一个可选的 TextReader
参数。如果您需要进口:
set.AddImportPath(...);
调用 Process
后,.Files
应与每个文件的 .MessageTypes
一起填充,等等。
有关更完整的示例:
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"); } }
哪些输出:
addressbook.proto Person has 5 fields AddressBook has 1 fields google/protobuf/timestamp.proto Timestamp has 2 fields
请注意,您不必提供 timestamp.proto
或其导入路径 - 该库嵌入了许多常见导入,并自动使它们可用。
(每个文件都是一个 FileDescriptorProto
;逻辑解析操作中的文件组是 FileDescriptorSet
- 它是 descriptor.proto 使用的根对象;请注意如果您需要编译/二进制模式,则此图中的所有对象也是 protobuf 可序列化的)
关于c# - 如何在 C# 中将 .proto 文件解析为 FileDescriptor?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62575156/