简体   繁体   English

如何将.proto 文件解析为 C# 中的 FileDescriptor?

[英]How to parse .proto file into a FileDescriptor in C#?

My goal is exactly the same as stated in this issue on github :我的目标与本期 github中所述的完全相同:

how to read an existing.proto file and get a FileDescriptor from it如何读取现有的.proto 文件并从中获取 FileDescriptor

I cannot use the suggested "workaround", for 2 reasons:我不能使用建议的“解决方法”,原因有两个:

  • I have "plain".proto files, ie:我有“普通”.proto 文件,即:
  • I do not want to invoke the protoc compiler as an external application.我不想将 protoc 编译器作为外部应用程序调用。

According to Marc this is possible with protobuf-net library:根据 Marc的说法,这可以通过protobuf-net库实现:

Without a compiled schema, you would need a runtime.proto parser.如果没有编译的模式,您将需要一个 runtime.proto 解析器。 [...] protobuf-net includes one ( protobuf-net.Reflection ) [...] protobuf-net 包括一个( protobuf-net.Reflection

I found Parsers.cs我找到Parsers.cs

Thanks Marc, but how do I use/do this?谢谢 Marc,但我该如何使用/执行此操作? Is this the right entry point?这是正确的切入点吗? Is there a minimal working example somewhere?某处有最小的工作示例吗?

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.请注意,如果您想提供实际内容(而不是让库进行文件访问),则有一个可选的TextReader参数。 If you need imports:如果您需要进口:

set.AddImportPath(...);

Once you've called Process , the .Files should be populated along with the .MessageTypes of each file, etc.一旦你调用了Process.Files应该与每个文件的.MessageTypes一起填充,等等。

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.请注意,您不必为它提供timestamp.proto或导入路径 - 该库嵌入了许多常见的导入,并使其自动可用。

(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) (每个文件都是一个FileDescriptorProto ;逻辑解析操作中的文件组是FileDescriptorSet - 这是从descriptor.proto使用的根 object ;请注意,此图中的所有对象也是 protobuf 可序列化的,如果您需要编译/二进制模式)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM