diff options
author | sashashkov <sashashkov@yandex-team.com> | 2024-06-11 13:03:18 +0300 |
---|---|---|
committer | sashashkov <sashashkov@yandex-team.com> | 2024-06-12 10:26:35 +0300 |
commit | 67e7cccc330744cdb98035e309f626c1f63afb84 (patch) | |
tree | f29f638710ae5223dbb7a56e427aea6c551bdff6 /library/cpp/protobuf/json/proto2json_printer.cpp | |
parent | a26a1f012a93e209458200c2ba8ae484a45a6c54 (diff) | |
download | ydb-67e7cccc330744cdb98035e309f626c1f63afb84.tar.gz |
Implement number stringification for repeated fields as well
4ab5908e416439366466d984fc08db7254401884
Diffstat (limited to 'library/cpp/protobuf/json/proto2json_printer.cpp')
-rw-r--r-- | library/cpp/protobuf/json/proto2json_printer.cpp | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/library/cpp/protobuf/json/proto2json_printer.cpp b/library/cpp/protobuf/json/proto2json_printer.cpp index bf0f9eb60d..5d0e140615 100644 --- a/library/cpp/protobuf/json/proto2json_printer.cpp +++ b/library/cpp/protobuf/json/proto2json_printer.cpp @@ -360,6 +360,19 @@ namespace NProtobufJson { break; \ } +#define REPEATED_INT_FIELD_TO_JSON(EProtoCppType, ProtoGet) \ + case FieldDescriptor::EProtoCppType: { \ + for (size_t i = 0, endI = reflection->FieldSize(proto, &field); i < endI; ++i) { \ + const auto value = reflection->ProtoGet(proto, &field, i); \ + if (NeedStringifyRepeatedNumber(value)) { \ + json.Write(ToString(value)); \ + } else { \ + json.Write(value); \ + } \ + } \ + break; \ + } + const Reflection* reflection = proto.GetReflection(); if (reflection->FieldSize(proto, &field) > 0) { @@ -371,10 +384,10 @@ namespace NProtobufJson { } switch (field.cpp_type()) { - REPEATED_FIELD_TO_JSON(CPPTYPE_INT32, GetRepeatedInt32); - REPEATED_FIELD_TO_JSON(CPPTYPE_INT64, GetRepeatedInt64); - REPEATED_FIELD_TO_JSON(CPPTYPE_UINT32, GetRepeatedUInt32); - REPEATED_FIELD_TO_JSON(CPPTYPE_UINT64, GetRepeatedUInt64); + REPEATED_INT_FIELD_TO_JSON(CPPTYPE_INT32, GetRepeatedInt32); + REPEATED_INT_FIELD_TO_JSON(CPPTYPE_INT64, GetRepeatedInt64); + REPEATED_INT_FIELD_TO_JSON(CPPTYPE_UINT32, GetRepeatedUInt32); + REPEATED_INT_FIELD_TO_JSON(CPPTYPE_UINT64, GetRepeatedUInt64); REPEATED_FIELD_TO_JSON(CPPTYPE_DOUBLE, GetRepeatedDouble); REPEATED_FIELD_TO_JSON(CPPTYPE_FLOAT, GetRepeatedFloat); REPEATED_FIELD_TO_JSON(CPPTYPE_BOOL, GetRepeatedBool); @@ -596,4 +609,23 @@ namespace NProtobufJson { return false; } + template <class T> + bool TProto2JsonPrinter::NeedStringifyRepeatedNumber(T value) const { + constexpr long SAFE_INTEGER_RANGE_FLOAT = 1L << 24; + constexpr long long SAFE_INTEGER_RANGE_DOUBLE = 1LL << 53; + + switch (GetConfig().StringifyNumbersRepeated) { + case TProto2JsonConfig::StringifyLongNumbersNever: + return false; + case TProto2JsonConfig::StringifyLongNumbersForFloat: + return !ValueInRange(value, SAFE_INTEGER_RANGE_FLOAT); + case TProto2JsonConfig::StringifyLongNumbersForDouble: + return !ValueInRange(value, SAFE_INTEGER_RANGE_DOUBLE); + case TProto2JsonConfig::StringifyInt64Always: + return std::is_same_v<T, i64> || std::is_same_v<T, ui64>; + } + + return false; + } + } |