diff options
| author | AlexSm <[email protected]> | 2023-12-22 20:30:08 +0100 | 
|---|---|---|
| committer | GitHub <[email protected]> | 2023-12-22 20:30:08 +0100 | 
| commit | 6b4f46a6883f21c16eef367106167ea59932515e (patch) | |
| tree | 5833709b16bba3948f15e88b9038229c5065605b /library/cpp/protobuf/json | |
| parent | a8b737f2a6df02f6e45ed703246c75f0f4cf7a34 (diff) | |
Import libs 3 (#679)
Diffstat (limited to 'library/cpp/protobuf/json')
| -rw-r--r-- | library/cpp/protobuf/json/json_writer_output.h | 5 | ||||
| -rw-r--r-- | library/cpp/protobuf/json/proto2json_printer.cpp | 10 | ||||
| -rw-r--r-- | library/cpp/protobuf/json/proto2json_printer.h | 2 | ||||
| -rw-r--r-- | library/cpp/protobuf/json/ut/proto2json_ut.cpp | 44 | ||||
| -rw-r--r-- | library/cpp/protobuf/json/ut/string_transform_ut.cpp | 2 | 
5 files changed, 53 insertions, 10 deletions
| diff --git a/library/cpp/protobuf/json/json_writer_output.h b/library/cpp/protobuf/json/json_writer_output.h index 3d8a2daa56c..975245a264b 100644 --- a/library/cpp/protobuf/json/json_writer_output.h +++ b/library/cpp/protobuf/json/json_writer_output.h @@ -86,7 +86,7 @@ namespace NProtobufJson {          {          } -    private: +    protected:          static NJson::TJsonWriterConfig CreateJsonWriterConfig(const TProto2JsonConfig& cfg);      }; @@ -95,7 +95,8 @@ namespace NProtobufJson {          template <typename TConfig>          TJsonStringWriterOutput(TString* str, const TConfig& cfg)              : TEmbedPolicy<TStringOutput>(*str) -            , TJsonWriterOutput(TEmbedPolicy<TStringOutput>::Ptr(), cfg) +            // If Unbuffered = false, TJsonWriter uses its own string and then flushes it into TStringOutput. +            , TJsonWriterOutput(TEmbedPolicy<TStringOutput>::Ptr(), CreateJsonWriterConfig(cfg).SetUnbuffered(true))          {          }      }; diff --git a/library/cpp/protobuf/json/proto2json_printer.cpp b/library/cpp/protobuf/json/proto2json_printer.cpp index 456d1c43c52..aa0823de0ed 100644 --- a/library/cpp/protobuf/json/proto2json_printer.cpp +++ b/library/cpp/protobuf/json/proto2json_printer.cpp @@ -195,6 +195,9 @@ namespace NProtobufJson {          using namespace google::protobuf;          auto type = proto.GetDescriptor()->well_known_type(); +        // XXX static_cast will cause UB if used with dynamic messages +        // (can be created by a DynamicMessageFactory with SetDelegateToGeneratedFactory(false). Unlikely, but still possible). +        // See workaround with CopyFrom in JsonString2Duration, JsonString2Timestamp (json2proto.cpp)          if (type == Descriptor::WellKnownType::WELLKNOWNTYPE_DURATION) {              const auto& duration = static_cast<const Duration&>(proto);              json.Write(util::TimeUtil::ToString(duration)); @@ -210,7 +213,8 @@ namespace NProtobufJson {      void TProto2JsonPrinter::PrintSingleField(const Message& proto,                                                const FieldDescriptor& field,                                                IJsonOutput& json, -                                              TStringBuf key) { +                                              TStringBuf key, +                                              bool inProtoMap) {          Y_ABORT_UNLESS(!field.is_repeated(), "field is repeated.");          if (!key) { @@ -236,7 +240,7 @@ namespace NProtobufJson {          const Reflection* reflection = proto.GetReflection(); -        bool shouldPrintField = reflection->HasField(proto, &field); +        bool shouldPrintField = inProtoMap || reflection->HasField(proto, &field);          if (!shouldPrintField && GetConfig().MissingSingleKeyMode == TProto2JsonConfig::MissingKeyExplicitDefaultThrowRequired) {              if (field.has_default_value()) {                  shouldPrintField = true; @@ -409,7 +413,7 @@ namespace NProtobufJson {          TString key = MakeKey(proto, *keyField);          const FieldDescriptor* valueField = proto.GetDescriptor()->FindFieldByName("value");          Y_ABORT_UNLESS(valueField, "Map entry value field not found."); -        PrintField(proto, *valueField, json, key); +        PrintSingleField(proto, *valueField, json, key, true);      }      TString TProto2JsonPrinter::MakeKey(const NProtoBuf::Message& proto, diff --git a/library/cpp/protobuf/json/proto2json_printer.h b/library/cpp/protobuf/json/proto2json_printer.h index 9dc5aa86c62..a1278193869 100644 --- a/library/cpp/protobuf/json/proto2json_printer.h +++ b/library/cpp/protobuf/json/proto2json_printer.h @@ -39,7 +39,7 @@ namespace NProtobufJson {          void PrintSingleField(const NProtoBuf::Message& proto,                                const NProtoBuf::FieldDescriptor& field,                                IJsonOutput& json, -                              TStringBuf key = {}); +                              TStringBuf key = {}, bool inProtoMap = false);          void PrintKeyValue(const NProtoBuf::Message& proto,                             IJsonOutput& json); diff --git a/library/cpp/protobuf/json/ut/proto2json_ut.cpp b/library/cpp/protobuf/json/ut/proto2json_ut.cpp index f19558e60a4..80dae6f01d8 100644 --- a/library/cpp/protobuf/json/ut/proto2json_ut.cpp +++ b/library/cpp/protobuf/json/ut/proto2json_ut.cpp @@ -981,7 +981,7 @@ Y_UNIT_TEST(TestMapAsObject) {      UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr);  } // TestMapAsObject -Y_UNIT_TEST(TestMapWTF) { +Y_UNIT_TEST(TestMapUsingGeneratedAsJSON) {      TMapType proto;      auto& items = *proto.MutableItems(); @@ -995,7 +995,47 @@ Y_UNIT_TEST(TestMapWTF) {      UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr));      UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr); -} // TestMapWTF +} // TestMapUsingGeneratedAsJSON + +Y_UNIT_TEST(TestMapDefaultValue) { +    TMapType proto; + +    auto& items = *proto.MutableItems(); +    items["key1"] = ""; + +    TString modelStr(R"_({"Items":{"key1":""}})_"); + +    TStringStream jsonStr; + +    TProto2JsonConfig config; +    config.MapAsObject = true; +    UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr, config)); +    UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr); + +    jsonStr.Clear(); +    UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr)); +    UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr); +} // TestMapDefaultValue + +Y_UNIT_TEST(TestMapDefaultMessageValue) { +    TComplexMapType proto; + +    auto& map = *proto.MutableNested(); +    map["key1"];  // Creates an empty nested message + +    TString modelStr(R"_({"Nested":{"key1":{}}})_"); + +    TStringStream jsonStr; + +    TProto2JsonConfig config; +    config.MapAsObject = true; +    UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr, config)); +    UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr); + +    jsonStr.Clear(); +    UNIT_ASSERT_NO_EXCEPTION(Proto2Json(proto, jsonStr)); +    UNIT_ASSERT_JSON_STRINGS_EQUAL(jsonStr.Str(), modelStr); +} // TestMapDefaultMessageValue  Y_UNIT_TEST(TestStringifyNumbers) {  #define TEST_SINGLE(flag, field, value, expectString)                            \ diff --git a/library/cpp/protobuf/json/ut/string_transform_ut.cpp b/library/cpp/protobuf/json/ut/string_transform_ut.cpp index a31dabcb0f0..3a4df5c0227 100644 --- a/library/cpp/protobuf/json/ut/string_transform_ut.cpp +++ b/library/cpp/protobuf/json/ut/string_transform_ut.cpp @@ -33,7 +33,6 @@ Y_UNIT_TEST_SUITE(TDoubleEscapeTransform) {          TString s;          s = "aba\\ca\"ba";          transform.Transform(s); -        Cerr << "###" << s << Endl;          UNIT_ASSERT_EQUAL(s, "aba\\\\\\\\ca\\\\\\\"ba");      }  } @@ -52,7 +51,6 @@ Y_UNIT_TEST_SUITE(TDoubleUnescapeTransform) {          TString s;          s = "abacaba";          transform.Transform(s); -        Cerr << "###" << s << Endl;          UNIT_ASSERT_EQUAL("abacaba", s);      } | 
