aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/protobuf/yql/descriptor.h
blob: bbed6850ec1048988b766a5b13482ab26136e1cb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#pragma once

#include <google/protobuf/descriptor.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/descriptor.pb.h>

#include <library/cpp/protobuf/dynamic_prototype/dynamic_prototype.h>

#include <util/generic/ptr.h>

enum EProtoFormat {
    PF_PROTOBIN = 0,
    PF_PROTOTEXT = 1,
    PF_JSON = 2,
};

enum class EEnumFormat {
    Number = 0,
    Name = 1,
    FullName = 2,
};

enum class ERecursionTraits {
    //! Падать, если на входе имеется рекурсивно определённый тип.
    Fail = 0,
    //! Игнорировать все поля с рекурсивно определённым типом.
    Ignore = 1,
    //! Возвращать поля с рекурсивным типом в виде сериализованной строки
    Bytes = 2,
};

struct TProtoTypeConfig {
    //! Имя сообщения.
    TString MessageName;
    //! Сериализованные метаданные.
    TString Metadata;
    //! Количество байт, которые надо отступить
    //! от начала каждого блока данных.
    ui32 SkipBytes = 0;
    //! Формат сериализации proto-сообщений.
    EProtoFormat ProtoFormat = PF_PROTOBIN;
    //! Формат представление значений Enum.
    EEnumFormat EnumFormat = EEnumFormat::Number;
    //! Способ интерпретации рекурсивно определённых типов.
    ERecursionTraits Recursion = ERecursionTraits::Fail;
    //! Выдать бинарными строками, если SERIALIZATION_PROTOBUF.
    //! Если SERIALIZATION_YT, то для рекурсивных структур поведение зависит от Recursion.
    bool YtMode = false;
    //! Заворачивать ли списочные типы в Optional.
    bool OptionalLists = false;
    //! Заполнять ли пустые Optional типы дефолтным значением (только для proto3).
    bool SyntaxAware = false;
};

struct TProtoTypeConfigOptions {
    //! Количество байт, которые надо отступить
    //! от начала каждого блока данных.
    ui32 SkipBytes = 0;
    //! Формат сериализации proto-сообщений.
    EProtoFormat ProtoFormat = PF_PROTOBIN;
    //! Формат представление значений Enum.
    EEnumFormat EnumFormat = EEnumFormat::Number;
    //! Способ интерпретации рекурсивно определённых типов.
    ERecursionTraits Recursion = ERecursionTraits::Fail;
    //! Выдать бинарными строками, если SERIALIZATION_PROTOBUF.
    //! Если SERIALIZATION_YT, то для рекурсивных структур поведение зависит от Recursion.
    bool YtMode = false;
    //! Заворачивать ли списочные типы в Optional.
    bool OptionalLists = false;
    //! Заполнять ли пустые Optional типы дефолтным значением (только для proto3).
    bool SyntaxAware = false;

    TProtoTypeConfigOptions& SetProtoFormat(EProtoFormat value) {
        ProtoFormat = value;
        return *this;
    }

    TProtoTypeConfigOptions& SetSkipBytes(ui32 value) {
        SkipBytes = value;
        return *this;
    }

    TProtoTypeConfigOptions& SetEnumFormat(EEnumFormat value) {
        EnumFormat = value;
        return *this;
    }

    TProtoTypeConfigOptions& SetRecursionTraits(ERecursionTraits value) {
        Recursion = value;
        return *this;
    }

    TProtoTypeConfigOptions& SetYtMode(bool value) {
        YtMode = value;
        return *this;
    }

    TProtoTypeConfigOptions& SetOptionalLists(bool value) {
        OptionalLists = value;
        return *this;
    }

    TProtoTypeConfigOptions& SetSyntaxAware(bool value) {
        SyntaxAware = value;
        return *this;
    }
};

TString GenerateProtobufTypeConfig(
    const NProtoBuf::Descriptor* descriptor,
    const TProtoTypeConfigOptions& options = TProtoTypeConfigOptions());

template <typename T>
inline TString GenerateProtobufTypeConfig(
    const TProtoTypeConfigOptions& options = TProtoTypeConfigOptions()) {
    return GenerateProtobufTypeConfig(T::descriptor(), options);
}

TProtoTypeConfig ParseTypeConfig(const TStringBuf& config);

using TDynamicInfoRef = TIntrusivePtr<class TDynamicInfo>;

class TDynamicInfo: public TSimpleRefCount<TDynamicInfo> {
public:
    TDynamicInfo(TDynamicPrototypePtr);
    ~TDynamicInfo();

    static TDynamicInfoRef Create(const TStringBuf& typeConfig);

    const NProtoBuf::Descriptor* Descriptor() const;

    //! Текущий формат представление значений Enum.
    EEnumFormat GetEnumFormat() const;

    //! Текущий способ интерпретации рекурсивно определённых типов.
    ERecursionTraits GetRecursionTraits() const;

    bool GetYtMode() const;

    bool GetOptionalLists() const;

    bool GetSyntaxAware() const;

    TAutoPtr<NProtoBuf::Message> MakeProto();

    //! \param data сериализованное protobuf-сообщение.
    TAutoPtr<NProtoBuf::Message> Parse(const TStringBuf& data);

    //! \param proto protobuf-сообщение.
    TString Serialize(const NProtoBuf::Message& proto);

private:
    TDynamicPrototypePtr DynamicPrototype;
    EEnumFormat EnumFormat_;
    EProtoFormat ProtoFormat_;
    ERecursionTraits Recursion_;
    bool YtMode_;
    ui32 SkipBytes_;
    bool OptionalLists_;
    bool SyntaxAware_;
};