1+ #include < ydb/core/protos/config.pb.h>
2+ #include < library/cpp/json/json_value.h>
3+ #include < library/cpp/json/json_writer.h>
4+
5+ #include < google/protobuf/descriptor.h>
6+ #include < google/protobuf/descriptor.pb.h>
7+ #include < google/protobuf/message.h>
8+
9+ using namespace google ::protobuf;
10+
11+ void Proto2Json (const Message& proto, NJson::TJsonValue& json);
12+
13+ void PrintSingleFieldValue (const Message& proto,
14+ const FieldDescriptor& field,
15+ NJson::TJsonValue& json) {
16+ #define FIELD_TO_JSON (EProtoCppType, ProtoGet ) \
17+ case FieldDescriptor::EProtoCppType: { \
18+ json = reflection->ProtoGet (proto, &field); \
19+ break ; \
20+ }
21+
22+ const Reflection* reflection = proto.GetReflection ();
23+ switch (field.cpp_type ()) {
24+ FIELD_TO_JSON (CPPTYPE_INT32, GetInt32);
25+ FIELD_TO_JSON (CPPTYPE_INT64, GetInt64);
26+ FIELD_TO_JSON (CPPTYPE_UINT32, GetUInt32);
27+ FIELD_TO_JSON (CPPTYPE_UINT64, GetUInt64);
28+ FIELD_TO_JSON (CPPTYPE_DOUBLE, GetDouble);
29+ FIELD_TO_JSON (CPPTYPE_FLOAT, GetFloat);
30+ FIELD_TO_JSON (CPPTYPE_BOOL, GetBool);
31+ FIELD_TO_JSON (CPPTYPE_STRING, GetString);
32+
33+ case FieldDescriptor::CPPTYPE_MESSAGE: {
34+ json.SetType (NJson::JSON_MAP);
35+ Proto2Json (reflection->GetMessage (proto, &field), json);
36+ break ;
37+ }
38+
39+ case FieldDescriptor::CPPTYPE_ENUM: {
40+ json = reflection->GetEnum (proto, &field)->name ();
41+ break ;
42+ }
43+
44+ default :
45+ ythrow yexception () << " Unknown protobuf field type: "
46+ << static_cast <int >(field.cpp_type ()) << " ." ;
47+ }
48+ #undef FIELD_TO_JSON
49+ }
50+
51+ void PrintRepeatedFieldValue (const Message& proto,
52+ const FieldDescriptor& field,
53+ NJson::TJsonValue& json, size_t index) {
54+ #define FIELD_TO_JSON (EProtoCppType, ProtoGet ) \
55+ case FieldDescriptor::EProtoCppType: { \
56+ json = reflection->ProtoGet (proto, &field, index); \
57+ break ; \
58+ }
59+
60+ const Reflection* reflection = proto.GetReflection ();
61+ switch (field.cpp_type ()) {
62+ FIELD_TO_JSON (CPPTYPE_INT32, GetRepeatedInt32);
63+ FIELD_TO_JSON (CPPTYPE_INT64, GetRepeatedInt64);
64+ FIELD_TO_JSON (CPPTYPE_UINT32, GetRepeatedUInt32);
65+ FIELD_TO_JSON (CPPTYPE_UINT64, GetRepeatedUInt64);
66+ FIELD_TO_JSON (CPPTYPE_DOUBLE, GetRepeatedDouble);
67+ FIELD_TO_JSON (CPPTYPE_FLOAT, GetRepeatedFloat);
68+ FIELD_TO_JSON (CPPTYPE_BOOL, GetRepeatedBool);
69+ FIELD_TO_JSON (CPPTYPE_STRING, GetRepeatedString);
70+
71+ case FieldDescriptor::CPPTYPE_MESSAGE: {
72+ json.SetType (NJson::JSON_MAP);
73+ Proto2Json (reflection->GetRepeatedMessage (proto, &field, index), json);
74+ break ;
75+ }
76+
77+ case FieldDescriptor::CPPTYPE_ENUM: {
78+ json = reflection->GetRepeatedEnum (proto, &field, index)->name ();
79+ break ;
80+ }
81+
82+ default :
83+ ythrow yexception () << " Unknown protobuf field type: "
84+ << static_cast <int >(field.cpp_type ()) << " ." ;
85+ }
86+ #undef FIELD_TO_JSON
87+ }
88+
89+ void PrintSingleField (const Message& proto,
90+ const FieldDescriptor& field,
91+ NJson::TJsonValue& json, TStringBuf key) {
92+ Y_ABORT_UNLESS (!field.is_repeated (), " field is repeated." );
93+ json[key][" id" ] = field.number ();
94+ PrintSingleFieldValue (proto, field, json[key][" default-value" ]);
95+ }
96+
97+ void PrintRepeatedField (const Message& proto,
98+ const FieldDescriptor& field,
99+ NJson::TJsonValue& json, TStringBuf key) {
100+ Y_ABORT_UNLESS (field.is_repeated (), " field isn't repeated." );
101+ const Reflection* reflection = proto.GetReflection ();
102+ json[key][" id" ] = field.number ();
103+ auto & array = json[key].InsertValue (" default-value" , NJson::TJsonArray ());
104+ for (size_t i = 0 , endI = reflection->FieldSize (proto, &field); i < endI; ++i) {
105+ PrintRepeatedFieldValue (proto, field, array.AppendValue (NJson::JSON_UNDEFINED), i);
106+ }
107+ }
108+
109+ void PrintField (const Message& proto,
110+ const FieldDescriptor& field,
111+ NJson::TJsonValue& json, TStringBuf key) {
112+ if (field.is_repeated ())
113+ PrintRepeatedField (proto, field, json, key);
114+ else
115+ PrintSingleField (proto, field, json, key);
116+ }
117+
118+ void Proto2Json (const Message& proto, NJson::TJsonValue& json) {
119+ const auto * descriptor = proto.GetDescriptor ();
120+ Y_ASSERT (descriptor);
121+
122+ // Iterate over all non-extension fields
123+ for (int f = 0 , endF = descriptor->field_count (); f < endF; ++f) {
124+ const FieldDescriptor* field = descriptor->field (f);
125+ Y_ASSERT (field);
126+ PrintField (proto, *field, json, field->name ());
127+ }
128+
129+ // Check extensions via ListFields
130+ std::vector<const FieldDescriptor*> fields;
131+ auto * ref = proto.GetReflection ();
132+ ref->ListFields (proto, &fields);
133+
134+ for (const auto * field : fields) {
135+ Y_ASSERT (field);
136+ if (field->is_extension ()) {
137+ PrintField (proto, *field, json, field->full_name ());
138+ }
139+ }
140+
141+ }
142+
143+ int main (int argc, const char ** argv) {
144+ Y_UNUSED (argc);
145+ Y_UNUSED (argv);
146+ const auto defaultConf = NKikimrConfig::TAppConfig::default_instance ();
147+ NJson::TJsonValue json;
148+ Proto2Json (defaultConf, json[" proto" ]);
149+ NJson::WriteJson (&Cout, &json, true , true );
150+ }
0 commit comments