从proto文件生成C#,反之亦然解释自定义选项

Rom*_*ier 10 c# code-generation protocol-buffers protobuf-net

我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)

我想生成:

[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;
}
Run Code Online (Sandbox Code Playgroud)

......反之亦然.

备注:

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

实现这一目标的首选方式是什么?解决方案不必依赖protobuf-net.

Rom*_*ier 2

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

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

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

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