如何在 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

我无法使用建议的“解决方法”,原因有两个:

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 模式)