是否可以使用 protobuf-net 为扩展名为“FieldOptions"的 proto2 文件生成 C# 文件? [英] Is it possible to generate C# files using protobuf-net for proto2 files with extension of 'FieldOptions'?

查看:131
本文介绍了是否可以使用 protobuf-net 为扩展名为“FieldOptions"的 proto2 文件生成 C# 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用 proto2 语法的 proto 文件.我正在尝试使用 protogen 自动生成 C# 文件.虽然我可以生成没有任何错误的文件,但在构建项目时出现错误(C# 文件是 Visual Studio 中 .Net 5 项目的一部分).错误看起来像:

I have a proto file with proto2 syntax. I am trying to auto-generate C# file using the protogen. Although I can generate the file without any errors, I get an error while building the project (the C# file is part of a .Net 5 project in Visual Studio). The error looks like :

错误 CS0400:在全局命名空间中找不到类型或命名空间名称Google"(您是否缺少程序集引用?)

error CS0400: The type or namespace name 'Google' could not be found in the global namespace (are you missing an assembly reference?)

我在正确的路径中添加了 'descriptor.proto' 但它似乎对 protogen 自动生成 C# 文件的方式没有任何影响.

I have added the 'descriptor.proto' in the correct path but it does not seem to make any difference in how protogen auto-generates the C# file.

myproto.proto

syntax = "proto2";

import "google/protobuf/descriptor.proto";

package test;

extend google.protobuf.FieldOptions {
  optional string sampleValue = 50004;
}

message TestMessage {
  required string id = 1;
  optional float value = 2;
  optional string sample_val = 3;
}

myproto.cs

// <auto-generated>
//   This file was generated by a tool; you should avoid making direct changes.
//   Consider using 'partial classes' to extend these types
//   Input: myproto.proto
// </auto-generated>

#region Designer generated code
#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
namespace Test
{

    [global::ProtoBuf.ProtoContract()]
    public partial class TestMessage : global::ProtoBuf.IExtensible
    {
        private global::ProtoBuf.IExtension __pbn__extensionData;
        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);

        [global::ProtoBuf.ProtoMember(1, Name = @"id", IsRequired = true)]
        public string Id { get; set; }

        [global::ProtoBuf.ProtoMember(2, Name = @"value")]
        public float Value
        {
            get => __pbn__Value.GetValueOrDefault();
            set => __pbn__Value = value;
        }
        public bool ShouldSerializeValue() => __pbn__Value != null;
        public void ResetValue() => __pbn__Value = null;
        private float? __pbn__Value;

        [global::ProtoBuf.ProtoMember(3, Name = @"sample_val")]
        [global::System.ComponentModel.DefaultValue("")]
        public string SampleVal
        {
            get => __pbn__SampleVal ?? "";
            set => __pbn__SampleVal = value;
        }
        public bool ShouldSerializeSampleVal() => __pbn__SampleVal != null;
        public void ResetSampleVal() => __pbn__SampleVal = null;
        private string __pbn__SampleVal;

    }

    public static partial class Extensions
    {
        public static string GetsampleValue(this global::Google.Protobuf.Reflection.FieldOptions obj)
            => obj == null ? default : global::ProtoBuf.Extensible.GetValue<string>(obj, 50004);

        public static void SetsampleValue(this global::Google.Protobuf.Reflection.FieldOptions obj, string value)
            => global::ProtoBuf.Extensible.AppendValue<string>(obj, 50004, value);

    }
}

#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
#endregion

错误发生在生成的myproto.cs"中的两种方法的静态类 Extensions 中.是不是可以只使用 protobuf-net 包而不使用任何额外的 Google 包?如果不是,那么我必须添加哪个包作为附加依赖项?我可能遗漏了一些微不足道的东西,但我现在似乎无法理解.

The error occurs in the static class Extensions for both methods in the generated 'myproto.cs'. Isn't it possible to use only the protobuf-net package without any additional Google packages? If not then which package do I have to add as additional dependency? I might be missing something trivial but I can't seem to understand as of now.

推荐答案

这里不需要谷歌参考;您已经扩展 FieldOptions,这是与字段相关的描述符元数据类型.protobuf-net 在 protobuf-net.Reflection 包中有一个实现,正好在预期的位置:Google.Protobuf.Reflection.FieldOptions.

No Google reference is needed here; you have extended FieldOptions, which is the descriptor metadata type that relates to fields. protobuf-net has an implementation of that in the protobuf-net.Reflection package, in exactly where this could be expected: Google.Protobuf.Reflection.FieldOptions.

但是!我怀疑这是否会达到您的预期.在这种情况下,您已经定义了一个自定义选项".自定义选项与运行时实例数据无关 - 它们是 .proto DSL 的一部分,通常用于影响代码生成;在你的情况下,它会是这样的:

However! I doubt that this is going to do what you expect. In this scenario, you have defined a "custom option". Custom options aren't related to runtime instance data - they are part of the .proto DSL, and are usually used to influence code generation; in your case, it would be something like:

  optional string sample_val = 3 [sampleValue= "ExtensionTypeName"];

(或类似的东西)

这里的要点是 value ("ExtensionTypeName") 仅适用于讨论 schema 字段,这就是为什么它悬挂在 FieldOptions(代表架构字段定义的实例)之外.它与您在运行时使用 TestMessage 没有任何关系.此外:protobuf-net 目前不会将自定义选项打包到生成的 C# 中(它可以这样做,大概是作为属性中的 base-64 块,或类似的 - 它目前没有).

The point here is that the value ("ExtensionTypeName") only applies when talking about the schema field, which is why it is dangling off of FieldOptions (which represents an instance of a schema field definition). It has nothing whatsoever to do with your TestMessage usage at runtime. Further: protobuf-net does not currently package custom options into the generated C# (it could do, presumably as a base-64 chunk in an attribute, or similar - it just doesn't currently).

所以:退一步:你的扩展sampleValue对你意味着什么,你认为它与哪些实例相关?

So: taking this back a step: what does your extension sampleValue mean to you, and to what instances do you see it relating?

这篇关于是否可以使用 protobuf-net 为扩展名为“FieldOptions"的 proto2 文件生成 C# 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆