使用protobuf-net生成类时解码自定义选项值

时间:2018-09-06 13:36:01

标签: protocol-buffers protobuf-net

我正在使用protogbuf-gen将原始文件转换为C#分类。 我想将proto文件中的某些选项转换为我的课程中的某些属性。 所以我有一个带有以下选项的原始文件:

syntax = "proto3";

import "google/protobuf/timestamp.proto";
import "google/protobuf/descriptor.proto";

enum LogOrder {
    NONE = 0;
    FIRST = 1;
    SECOND = 2;
    THIRD = 3;
}

extend google.protobuf.FieldOptions {
    LogOrder shouldBeLogged = 50001;
}

message Person {
    string  id = 1 [(shouldBeLogged)=FIRST];
    int32 business_id = 2 [(shouldBeLogged)=SECOND,deprecated=true];
...

要尝试执行此操作,我必须编写自己的CSharpCodeGenerator子类,其中可以使用重载WriteField中的属性来装饰字段。

public class ServiceCodeGenerator : CSharpCodeGenerator
{
    protected override void WriteField(GeneratorContext ctx, FieldDescriptorProto obj, ref object state, OneOfStub[] oneOfs)
    {
        var bytes = obj.Options?.ExtensionData;
        // if extension data == shouldBeLogged then write somee attribute with a value

        base.WriteField(ctx, obj, ref state, oneOfs);
    }
...

但是,我唯一能得到的是一个字节数组,其中包含[136,181,24,1]之类的内容,其中最后一个字节“ 1”似乎是“ shouldBeLogged”的值。

如何将这些字节转换为对开发人员友好的内容,或者以其他方式访问该选项及其值?

1 个答案:

答案 0 :(得分:1)

如果通过progen来运行现有的.proto,则应该在生成的代码中获得:

public static class Extensions
{
    public static LogOrder GetshouldBeLogged(this global::Google.Protobuf.Reflection.FieldOptions obj)
        => obj == null ? default : global::ProtoBuf.Extensible.GetValue<LogOrder>(obj, 50001);

    public static void SetshouldBeLogged(this global::Google.Protobuf.Reflection.FieldOptions obj, LogOrder value)
        => global::ProtoBuf.Extensible.AppendValue<LogOrder>(obj, 50001, value);

}

这意味着您可以使用:

var shouldBeLogged = obj.Options.GetshouldBeLogged();