从proto文件生成C#代码以及解析自定义选项

10
我正在使用protobuf-net,并尝试做到以下两点:
  1. 从.proto文件生成C#类
  2. 从C#类生成.proto文件
对应的工具是:
  1. protogen.exe 工具
  2. Serializer<T>.GetProto() 方法
但问题在于我需要支持 protobuffer 自定义选项,这似乎不像我想象的那么简单。
让我解释一下:
  1. 从带有自定义选项的消息和字段的.proto文件中,我想生成一个由.NET自定义属性装饰的C#类。
  2. 从用自定义属性装饰的C#类中,我想生成一个带有自定义选项的消息和字段的.proto文件。
基本上说,给定:
message person {
   option (my_message_option) = true;

   optional string firstname = 1 [(my_field_option) = 42];
   optional string lastname = 2 [(my_field_option) = 12];
   optional int age = 3;
}
我想生成:
[ProtoContract, MyMessageOption(true)]
public class Person
{
    [ProtoMember(1), MyFieldOption(42)]
    public string Firstname;

    [ProtoMember(2), MyFieldOption(12)]
    public string Firstname;

    [ProtoMember(3)]
    public string Firstname;
}

……反之亦然。

注:

  • 自定义选项定义(my_message_optionmy_field_option)可能已经存在于proto文件中(例如,my_custom_options.proto),自定义属性类也可以存在于某个地方(MyMessageOptionAttributeMyFieldOptionAttribute)。
  • 我尝试使用protogen.exe和自定义xslt,但是protogen似乎不支持自定义选项。

如何实现最佳方法?解决方案不必依赖protobuf-net。


我想做同样的事情,从一个proto文件生成一个装饰的C#文件(用于protobuf-net)。你能给个例子说明一下你是如何实现的吗?谢谢! - pogorman
2个回答

2

我最终从protobuf-csharp中分叉了ProtoGen项目,公开了一些内部类型(主要是生成器),并通过允许自定义生成器注册使SourceGenerators可扩展。

这样,我就能够使用proto描述符对象模型编写自己的C#生成器。

一个棘手的问题是在启动解析之前注册自定义选项类型:

  1. 生成与您的自定义选项对应的C#类型(使用Protoc.exe然后使用ProtoGen.exe
  2. 使用生成的RegisterAllExtensions方法配置ExtensionRegistry
  3. 使用自己的C#生成器启动代码生成。在每个生成器中,您可以访问上下文Descriptor.Options集合。

1

目前还没有简单的方法来实现这个。需要进行的更改主要是在csharp.xslt文件中。有一个报告了这个问题,但尚未修复。


我已经尝试创建一个特定的XSLT文件,但是我无法访问proto文件中使用的自定义选项。你能想到另一种非基于protobuf-net的解决方案吗? - Romain Verdier
@Romain,这不是我有机会查看的配置,所以:我脑海中没有。如果您通过xml模板(-t:xml或类似内容)运行它,它将向您显示它所知道的内容,这可能表明此数据隐藏在哪里 - 假设它不需要更新描述符。 - Marc Gravell
1
是的,这就是我尝试过的(-t:xml),但所有自定义选项在生成的 XML 文件中都显示为“uninterpreted_option”。 - Romain Verdier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接