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

发布于 2024-10-26 16:53:58 字数 1528 浏览 2 评论 0原文

我正在使用 protobuf-net,并且我正在尝试:

  1. 生成 C#从 .proto 文件生成
  2. .proto 文件 从 C# 类生成 .proto 文件

这非常容易分别使用:

  1. protogen.exe 工具
  2. Serializer.GetProto() 方法

但是问题是我需要支持 protobuffer 自定义选项,但它不支持似乎不像我那么简单。

让我解释一下:

  1. 从包含应用于消息和字段的自定义选项的原始文件中,我想生成一个由 .NET 自定义属性修饰的 C# 类。
  2. 从由自定义属性修饰的 C# 类中,我想生成一个原始文件,其中自定义选项应用于消息和字段。

基本上,给定:

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) 可能已存在 在原型文件中(例如, my_custom_options.proto),以及 自定义属性类也可以 存在于某处 (MyMessageOptionAttributeMyFieldOptionAttribute)。
  • 我尝试使用 protogen.exe 和 自定义 xslt 但 protogen 似乎没有 支持自定义选项。

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

I'm using protobuf-net, and I'm trying to:

  1. Generate a C# class from a .proto file
  2. Generate a .proto file from a C# class

That's pretty easy using respectively:

  1. protogen.exe tool
  2. Serializer<T>.GetProto() method

But the thing is that I need to support protobuffer custom options and it doesn't seem to be as straightforward as I though.

Let me explain:

  1. From a proto file containing custom options applied on messages and fields, I want to generate a C# class decorated by .NET custom attributes.
  2. From a C# class decorated by custom attributes, I would like to generate a proto file where custom options are applied on messages and fields.

Basically, given:

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;
}

I want to generate:

[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;
}

...and vice versa.

Notes :

  • The custom option definitions
    (my_message_option and
    my_field_option) can already exist
    in a protofile (say,
    my_custom_options.proto), and the
    custom attributes classes can also
    exist somewhere
    (MyMessageOptionAttribute and
    MyFieldOptionAttribute).
  • I tried to use protogen.exe and a
    custom xslt but protogen doesn't seem
    to have support for custom options.

What's the preferred way to achieve that? The solution doesn't have to rely on protobuf-net.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ㄖ落Θ余辉 2024-11-02 16:53:58

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

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

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

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

I ended up by forking ProtoGen project from protobuf-csharp to make public some internal types (generators, for the most part) and to make the SourceGenerators extensible by allowing custom generator registrations.

This way, I was able to use the proto descriptor object model to write my own C# generator.

One tricky point is to register your custom options types before launching the parsing :

  1. Generate C# types corresponding to your custom options (using Protoc.exe then ProtoGen.exe)
  2. Configure ExtensionRegistry by using the generated RegisterAllExtensions methods.
  3. Start the code generation using your own C# generators. In each generator you can access to the contextual Descriptor.Options collection.
七色彩虹 2024-11-02 16:53:58

目前没有简单的方法可以做到这一点。所需的更改主要针对 csharp.xslt 文件。已报告与此相关的错误,但尚未报告尚未修复。

There isn't a simple way to do this at the moment. The changes required would primarily be to the csharp.xslt file. There is a bug reported about this but hasn't been fixed yet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文