aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/protobuf/json/proto2json_printer.cpp
diff options
context:
space:
mode:
authorsashashkov <sashashkov@yandex-team.com>2024-06-11 13:03:18 +0300
committersashashkov <sashashkov@yandex-team.com>2024-06-12 10:26:35 +0300
commit67e7cccc330744cdb98035e309f626c1f63afb84 (patch)
treef29f638710ae5223dbb7a56e427aea6c551bdff6 /library/cpp/protobuf/json/proto2json_printer.cpp
parenta26a1f012a93e209458200c2ba8ae484a45a6c54 (diff)
downloadydb-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.cpp40
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;
+ }
+
}