Декодировать значения пользовательских опций, когда классы создаются с помощью protobuf-net - PullRequest
0 голосов
/ 06 сентября 2018

Я использую protogbuf-gen для преобразования прототипов в предложения C #. Я хочу преобразовать некоторую опцию из файла прото в некоторый атрибут в моих классах. Итак, у меня есть файл прото с такими параметрами:

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 голосов
/ 06 сентября 2018

Если вы запустите существующий .proto через protogen, вы должны получить среди сгенерированного кода:

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();
...