如何在 C# 中将 .proto 文件解析为 FileDescriptor?
How to parse .proto file into a FileDescriptor in C#?
我的目标与this issue on github中所述完全相同:
how to read an existing .proto file and get a FileDescriptor from it
我无法使用建议的“解决方法”,原因有两个:
- 我有“普通”.proto 文件,即:
- 它们是文本文件,就像旧的一样 addressbook.proto
- 他们不是 self-describing
- 我不想将 protoc 编译器作为外部应用程序调用。
this is possible with protobuf-net图书馆:
Without a compiled schema, you would need a runtime .proto parser. [...] protobuf-net includes one (protobuf-net.Reflection)
我找到了Parsers.cs
谢谢 Marc,但我该如何 use/do 呢?
这是正确的切入点吗?
某处有最小的工作示例吗?
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 可序列化的,如果您需要 compiled/binary 模式)
我的目标与this issue on github中所述完全相同:
how to read an existing .proto file and get a FileDescriptor from it
我无法使用建议的“解决方法”,原因有两个:
- 我有“普通”.proto 文件,即:
- 它们是文本文件,就像旧的一样 addressbook.proto
- 他们不是 self-describing
- 我不想将 protoc 编译器作为外部应用程序调用。
Without a compiled schema, you would need a runtime .proto parser. [...] protobuf-net includes one (protobuf-net.Reflection)
我找到了Parsers.cs
谢谢 Marc,但我该如何 use/do 呢? 这是正确的切入点吗? 某处有最小的工作示例吗?
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 可序列化的,如果您需要 compiled/binary 模式)