diff options
author | bbiff <bbiff@yandex-team.com> | 2022-09-11 00:15:54 +0300 |
---|---|---|
committer | bbiff <bbiff@yandex-team.com> | 2022-09-11 00:15:54 +0300 |
commit | 67576a8962c2506b8ee10da48dffba311acb0042 (patch) | |
tree | 51a695bbddbb9be4e5a0cc5c7ec558ca233c2be5 /library/cpp/protobuf/json/json2proto.cpp | |
parent | a8945929eb162f6910b228697c3d2db3b7cb2ca9 (diff) | |
download | ydb-67576a8962c2506b8ee10da48dffba311acb0042.tar.gz |
support duration and timestamp as string in json2proto
Diffstat (limited to 'library/cpp/protobuf/json/json2proto.cpp')
-rw-r--r-- | library/cpp/protobuf/json/json2proto.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/library/cpp/protobuf/json/json2proto.cpp b/library/cpp/protobuf/json/json2proto.cpp index 92bfe9755b..903ffa1a85 100644 --- a/library/cpp/protobuf/json/json2proto.cpp +++ b/library/cpp/protobuf/json/json2proto.cpp @@ -3,6 +3,7 @@ #include <library/cpp/json/json_value.h> +#include <google/protobuf/util/time_util.h> #include <google/protobuf/message.h> #include <google/protobuf/descriptor.h> @@ -77,6 +78,52 @@ static TString GetFieldName(const google::protobuf::FieldDescriptor& field, return name; } + +static void JsonString2Duration(const NJson::TJsonValue& json, + google::protobuf::Message& proto, + const google::protobuf::FieldDescriptor& field, + const NProtobufJson::TJson2ProtoConfig& config) { + using namespace google::protobuf; + if (!json.GetString() && !config.CastRobust) { + ythrow yexception() << "Invalid type of JSON field '" << field.name() << "': " + << "IsString() failed while " + << "CPPTYPE_STRING is expected."; + } + TString jsonString = json.GetStringRobust(); + + Duration durationFromString; + + if (!util::TimeUtil::FromString(jsonString, &durationFromString)) { + ythrow yexception() << "error while parsing google.protobuf.Duration from string on field '" << + field.name() << "'"; + } + + proto.CopyFrom(durationFromString); + +} + +static void JsonString2Timestamp(const NJson::TJsonValue& json, + google::protobuf::Message& proto, + const google::protobuf::FieldDescriptor& field, + const NProtobufJson::TJson2ProtoConfig& config) { + using namespace google::protobuf; + if (!json.GetString() && !config.CastRobust) { + ythrow yexception() << "Invalid type of JSON field '" << field.name() << "': " + << "IsString() failed while " + << "CPPTYPE_STRING is expected."; + } + TString jsonString = json.GetStringRobust(); + + Timestamp timestampFromString; + + if (!util::TimeUtil::FromString(jsonString, ×tampFromString)) { + ythrow yexception() << "error while parsing google.protobuf.Timestamp from string on field '" << + field.name() << "'"; + } + + proto.CopyFrom(timestampFromString); +} + static void JsonString2Field(const NJson::TJsonValue& json, google::protobuf::Message& proto, @@ -110,6 +157,24 @@ JsonString2Field(const NJson::TJsonValue& json, reflection->SetString(&proto, &field, value); } +static bool +HandleString2TimeConversion(const NJson::TJsonValue& json, + google::protobuf::Message& proto, + const google::protobuf::FieldDescriptor& field, + const NProtobufJson::TJson2ProtoConfig& config) { + using namespace google::protobuf; + auto type = proto.GetDescriptor()->well_known_type(); + + if (type == Descriptor::WellKnownType::WELLKNOWNTYPE_DURATION) { + JsonString2Duration(json, proto, field, config); + return true; + } else if (type == Descriptor::WellKnownType::WELLKNOWNTYPE_TIMESTAMP) { + JsonString2Timestamp(json, proto, field, config); + return true; + } + return false; +} + static const NProtoBuf::EnumValueDescriptor* FindEnumValue(const NProtoBuf::EnumDescriptor* enumField, TStringBuf target, bool (*equals)(TStringBuf, TStringBuf)) { @@ -215,6 +280,12 @@ Json2SingleField(const NJson::TJsonValue& json, case FieldDescriptor::CPPTYPE_MESSAGE: { Message* innerProto = reflection->MutableMessage(&proto, &field); Y_ASSERT(!!innerProto); + + if (config.AllowString2TimeConversion && + HandleString2TimeConversion(fieldJson, *innerProto, field, config)) { + break; + } + NProtobufJson::MergeJson2Proto(fieldJson, *innerProto, config); break; |