@@ -147,59 +147,78 @@ inline void AddJsonObjectToProtoAsMap(
147
147
const google::protobuf::Reflection* reflection,
148
148
grpc::protobuf::Message* message,
149
149
const JSON& jsonObject,
150
+ ui32 depth,
150
151
std::function<const MAP (const JSON&)> extractMap,
151
- std::function<const TString(const JSON&)> valueToString
152
+ std::function<const TString(const JSON&)> valueToString,
153
+ std::function<void(const JSON&, grpc::protobuf::Message*, ui32)> jsonObjectToMessage
152
154
) {
153
155
const auto & protoMap = reflection->GetMutableRepeatedFieldRef <google::protobuf::Message>(message, fieldDescriptor);
154
156
for (const auto & [key, value] : extractMap (jsonObject)) {
155
- std::unique_ptr<google::protobuf::Message> stringStringEntry (
157
+ std::unique_ptr<google::protobuf::Message> mapEntry (
156
158
google::protobuf::MessageFactory::generated_factory ()
157
159
->GetPrototype (fieldDescriptor->message_type ())
158
160
->New (message->GetArena ())
159
161
);
160
- stringStringEntry
162
+ mapEntry
161
163
->GetReflection ()
162
- ->SetString (stringStringEntry.get (), fieldDescriptor->message_type ()->field (0 ), key);
163
- stringStringEntry
164
- ->GetReflection ()
165
- ->SetString (stringStringEntry.get (), fieldDescriptor->message_type ()->field (1 ), valueToString (value));
166
- protoMap.Add (*stringStringEntry);
164
+ ->SetString (mapEntry.get (), fieldDescriptor->message_type ()->field (0 ), key);
165
+
166
+ auto valueField = fieldDescriptor->message_type ()->field (1 );
167
+ if (valueField->cpp_type () == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE) {
168
+ auto *msg = mapEntry->GetReflection ()->MutableMessage (mapEntry.get (), valueField);
169
+ jsonObjectToMessage (value, msg, depth);
170
+ } else if (valueField->cpp_type () == google::protobuf::FieldDescriptor::CPPTYPE_STRING) {
171
+ mapEntry->GetReflection ()->SetString (mapEntry.get (), valueField, valueToString (value));
172
+ } else {
173
+ throw NKikimr::NSQS::TSQSException (NKikimr::NSQS::NErrors::INVALID_PARAMETER_VALUE)
174
+ << " Only String and Object can be converted to protobuf map" ;
175
+ }
176
+ protoMap.Add (std::move (*mapEntry));
167
177
}
168
178
}
169
179
180
+ void JsonToProto (const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth = 0 );
181
+
170
182
inline void AddJsonObjectToProtoAsMap (
171
183
const google::protobuf::FieldDescriptor* fieldDescriptor,
172
184
const google::protobuf::Reflection* reflection,
173
185
grpc::protobuf::Message* message,
174
- const NJson::TJsonValue& jsonObject
186
+ const NJson::TJsonValue& jsonObject,
187
+ ui32 depth
175
188
) {
176
189
AddJsonObjectToProtoAsMap<NJson::TJsonValue, NJson::TJsonValue::TMapType>(
177
190
fieldDescriptor,
178
191
reflection,
179
192
message,
180
193
jsonObject,
194
+ depth,
181
195
[](auto & json) { return json.GetMap (); },
182
- [](auto & value) -> const TString { return value.GetString (); }
196
+ [](auto & value) -> const TString { return value.GetString (); },
197
+ [](auto & json, auto message, auto depth) { JsonToProto (json, message, depth); }
183
198
);
184
199
}
200
+ void NlohmannJsonToProto (const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth = 0 );
185
201
186
202
inline void AddJsonObjectToProtoAsMap (
187
203
const google::protobuf::FieldDescriptor* fieldDescriptor,
188
204
const google::protobuf::Reflection* reflection,
189
205
grpc::protobuf::Message* message,
190
- const nlohmann::basic_json<>& jsonObject
206
+ const nlohmann::basic_json<>& jsonObject,
207
+ ui32 depth
191
208
) {
192
209
AddJsonObjectToProtoAsMap<nlohmann::basic_json<>, std::map<TString, nlohmann::basic_json<>>>(
193
210
fieldDescriptor,
194
211
reflection,
195
212
message,
196
213
jsonObject,
214
+ depth,
197
215
[](auto & json) { return json.template get <std::map<TString, nlohmann::basic_json<>>>(); },
198
- [](auto & value) -> const TString { return value.template get <TString>(); }
216
+ [](auto & value) -> const TString { return value.template get <TString>(); },
217
+ [](auto & json, auto message, auto depth) { NlohmannJsonToProto (json, message, depth); }
199
218
);
200
219
}
201
220
202
- inline void JsonToProto (const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth = 0 ) {
221
+ inline void JsonToProto (const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth) {
203
222
Y_ENSURE (depth < 101 , " Json depth is > 100" );
204
223
Y_ENSURE_EX (
205
224
!jsonValue.IsNull (),
@@ -348,7 +367,7 @@ inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message*
348
367
break ;
349
368
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
350
369
if (fieldDescriptor->is_map ()) {
351
- AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value);
370
+ AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value, depth );
352
371
} else {
353
372
auto *msg = reflection->MutableMessage (message, fieldDescriptor);
354
373
JsonToProto (value, msg, depth + 1 );
@@ -366,7 +385,7 @@ inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message*
366
385
}
367
386
}
368
387
369
- inline void NlohmannJsonToProto (const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth = 0 ) {
388
+ inline void NlohmannJsonToProto (const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth) {
370
389
Y_ENSURE (depth < 101 , " Json depth is > 100" );
371
390
Y_ENSURE_EX (
372
391
!jsonValue.is_null (),
@@ -518,7 +537,7 @@ inline void NlohmannJsonToProto(const nlohmann::json& jsonValue, NProtoBuf::Mess
518
537
break ;
519
538
case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
520
539
if (fieldDescriptor->is_map ()) {
521
- AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value);
540
+ AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value, depth );
522
541
} else {
523
542
auto *msg = reflection->MutableMessage (message, fieldDescriptor);
524
543
NlohmannJsonToProto (value, msg, depth + 1 );
0 commit comments