@@ -147,59 +147,78 @@ inline void AddJsonObjectToProtoAsMap(
147147 const google::protobuf::Reflection* reflection,
148148 grpc::protobuf::Message* message,
149149 const JSON& jsonObject,
150+ ui32 depth,
150151 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
152154) {
153155 const auto & protoMap = reflection->GetMutableRepeatedFieldRef <google::protobuf::Message>(message, fieldDescriptor);
154156 for (const auto & [key, value] : extractMap (jsonObject)) {
155- std::unique_ptr<google::protobuf::Message> stringStringEntry (
157+ std::unique_ptr<google::protobuf::Message> mapEntry (
156158 google::protobuf::MessageFactory::generated_factory ()
157159 ->GetPrototype (fieldDescriptor->message_type ())
158160 ->New (message->GetArena ())
159161 );
160- stringStringEntry
162+ mapEntry
161163 ->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));
167177 }
168178}
169179
180+ void JsonToProto (const NJson::TJsonValue& jsonValue, NProtoBuf::Message* message, ui32 depth = 0 );
181+
170182inline void AddJsonObjectToProtoAsMap (
171183 const google::protobuf::FieldDescriptor* fieldDescriptor,
172184 const google::protobuf::Reflection* reflection,
173185 grpc::protobuf::Message* message,
174- const NJson::TJsonValue& jsonObject
186+ const NJson::TJsonValue& jsonObject,
187+ ui32 depth
175188) {
176189 AddJsonObjectToProtoAsMap<NJson::TJsonValue, NJson::TJsonValue::TMapType>(
177190 fieldDescriptor,
178191 reflection,
179192 message,
180193 jsonObject,
194+ depth,
181195 [](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); }
183198 );
184199}
200+ void NlohmannJsonToProto (const nlohmann::json& jsonValue, NProtoBuf::Message* message, ui32 depth = 0 );
185201
186202inline void AddJsonObjectToProtoAsMap (
187203 const google::protobuf::FieldDescriptor* fieldDescriptor,
188204 const google::protobuf::Reflection* reflection,
189205 grpc::protobuf::Message* message,
190- const nlohmann::basic_json<>& jsonObject
206+ const nlohmann::basic_json<>& jsonObject,
207+ ui32 depth
191208) {
192209 AddJsonObjectToProtoAsMap<nlohmann::basic_json<>, std::map<TString, nlohmann::basic_json<>>>(
193210 fieldDescriptor,
194211 reflection,
195212 message,
196213 jsonObject,
214+ depth,
197215 [](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); }
199218 );
200219}
201220
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) {
203222 Y_ENSURE (depth < 101 , " Json depth is > 100" );
204223 Y_ENSURE_EX (
205224 !jsonValue.IsNull (),
@@ -348,7 +367,7 @@ inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message*
348367 break ;
349368 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
350369 if (fieldDescriptor->is_map ()) {
351- AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value);
370+ AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value, depth + 1 );
352371 } else {
353372 auto *msg = reflection->MutableMessage (message, fieldDescriptor);
354373 JsonToProto (value, msg, depth + 1 );
@@ -366,7 +385,7 @@ inline void JsonToProto(const NJson::TJsonValue& jsonValue, NProtoBuf::Message*
366385 }
367386}
368387
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) {
370389 Y_ENSURE (depth < 101 , " Json depth is > 100" );
371390 Y_ENSURE_EX (
372391 !jsonValue.is_null (),
@@ -518,7 +537,7 @@ inline void NlohmannJsonToProto(const nlohmann::json& jsonValue, NProtoBuf::Mess
518537 break ;
519538 case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
520539 if (fieldDescriptor->is_map ()) {
521- AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value);
540+ AddJsonObjectToProtoAsMap (fieldDescriptor, reflection, message, value, depth );
522541 } else {
523542 auto *msg = reflection->MutableMessage (message, fieldDescriptor);
524543 NlohmannJsonToProto (value, msg, depth + 1 );
0 commit comments