diff options
author | Alexander Smirnov <alex@ydb.tech> | 2025-01-10 00:22:26 +0000 |
---|---|---|
committer | Alexander Smirnov <alex@ydb.tech> | 2025-01-10 00:22:26 +0000 |
commit | cba921b5ec4600bec70a6ec9a076708aaef9b611 (patch) | |
tree | 27fe2aebe9148f81ba1c9a89bd1669f3d5297902 /library/cpp | |
parent | 046fc2f028484e755d2e45ce1f9637cd5ac83e35 (diff) | |
parent | fab0037c69a3d2c1d81904e6174dcb4317ba02a2 (diff) | |
download | ydb-cba921b5ec4600bec70a6ec9a076708aaef9b611.tar.gz |
Merge branch 'rightlib' into merge-libs-250110-0021
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/protobuf/yql/descriptor.cpp | 22 | ||||
-rw-r--r-- | library/cpp/protobuf/yql/descriptor.h | 5 | ||||
-rw-r--r-- | library/cpp/yt/string/format-inl.h | 2 | ||||
-rw-r--r-- | library/cpp/yt/string/unittests/format_ut.cpp | 7 |
4 files changed, 33 insertions, 3 deletions
diff --git a/library/cpp/protobuf/yql/descriptor.cpp b/library/cpp/protobuf/yql/descriptor.cpp index 2d5a154fc17..e5e1c8e28bd 100644 --- a/library/cpp/protobuf/yql/descriptor.cpp +++ b/library/cpp/protobuf/yql/descriptor.cpp @@ -19,6 +19,7 @@ #include <google/protobuf/text_format.h> #include <google/protobuf/io/zero_copy_stream_impl_lite.h> +#include <google/protobuf/io/coded_stream.h> using namespace NProtoBuf; @@ -73,6 +74,7 @@ TDynamicInfoRef TDynamicInfo::Create(const TStringBuf& typeConfig) { info->SkipBytes_ = data.SkipBytes; info->OptionalLists_ = data.OptionalLists; info->SyntaxAware_ = data.SyntaxAware; + info->Deterministic_ = data.Deterministic; return info; } @@ -146,7 +148,16 @@ TString TDynamicInfo::Serialize(const Message& proto) { switch (ProtoFormat_) { case PF_PROTOBIN: { result.ReserveAndResize(proto.ByteSize()); - if (!proto.SerializeToArray(result.begin(), result.size())) { + bool success = false; + if (Deterministic_) { + io::ArrayOutputStream arrOut(result.begin(), result.size()); + io::CodedOutputStream codedOut(&arrOut); + codedOut.SetSerializationDeterministic(true); + success = proto.SerializeToCodedStream(&codedOut); + } else { + success = proto.SerializeToArray(result.begin(), result.size()); + } + if (!success) { ythrow yexception() << "can't serialize protobin message"; } break; @@ -159,7 +170,9 @@ TString TDynamicInfo::Serialize(const Message& proto) { } case PF_JSON: { NJson::TJsonValue value; - NProtobufJson::Proto2Json(proto, value); + NProtobufJson::TProto2JsonConfig config; + config.SetSortMapKeys(Deterministic_); + NProtobufJson::Proto2Json(proto, value, config); result = NJson::WriteJson(value); break; } @@ -225,6 +238,10 @@ TString GenerateProtobufTypeConfig( ret["view"]["yt_mode"] = true; } + if (options.Deterministic) { + ret["view"]["deterministic"] = true; + } + return NJson::WriteJson(ret, false); } @@ -268,6 +285,7 @@ TProtoTypeConfig ParseTypeConfig(const TStringBuf& config) { result.OptionalLists = value["lists"]["optional"].GetBooleanSafe(true); result.SyntaxAware = value["syntax"]["aware"].GetBooleanSafe(false); result.YtMode = value["view"]["yt_mode"].GetBooleanSafe(false); + result.Deterministic = value["view"]["deterministic"].GetBooleanSafe(false); if (protoFormat == "protobin") { result.ProtoFormat = PF_PROTOBIN; diff --git a/library/cpp/protobuf/yql/descriptor.h b/library/cpp/protobuf/yql/descriptor.h index bbed6850ec1..f5f51add0bc 100644 --- a/library/cpp/protobuf/yql/descriptor.h +++ b/library/cpp/protobuf/yql/descriptor.h @@ -50,6 +50,8 @@ struct TProtoTypeConfig { bool OptionalLists = false; //! Заполнять ли пустые Optional типы дефолтным значением (только для proto3). bool SyntaxAware = false; + //! Использовать ли детерминированную сериализацию + bool Deterministic = false; }; struct TProtoTypeConfigOptions { @@ -69,6 +71,8 @@ struct TProtoTypeConfigOptions { bool OptionalLists = false; //! Заполнять ли пустые Optional типы дефолтным значением (только для proto3). bool SyntaxAware = false; + //! Использовать ли детерминированную сериализацию + bool Deterministic = false; TProtoTypeConfigOptions& SetProtoFormat(EProtoFormat value) { ProtoFormat = value; @@ -158,4 +162,5 @@ private: ui32 SkipBytes_; bool OptionalLists_; bool SyntaxAware_; + bool Deterministic_; }; diff --git a/library/cpp/yt/string/format-inl.h b/library/cpp/yt/string/format-inl.h index e90d68bfe12..b18c435cb86 100644 --- a/library/cpp/yt/string/format-inl.h +++ b/library/cpp/yt/string/format-inl.h @@ -722,7 +722,7 @@ void FormatValue(TStringBuilderBase* builder, const std::tuple<Ts...>& value, TS [&] <size_t... Idx> (std::index_sequence<Idx...>) { ([&] { FormatValue(builder, std::get<Idx>(value), spec); - if constexpr (Idx != sizeof...(Ts)) { + if constexpr (Idx != sizeof...(Ts) - 1) { builder->AppendString(TStringBuf(", ")); } } (), ...); diff --git a/library/cpp/yt/string/unittests/format_ut.cpp b/library/cpp/yt/string/unittests/format_ut.cpp index 8aca8c8e290..e6b5eb7cfec 100644 --- a/library/cpp/yt/string/unittests/format_ut.cpp +++ b/library/cpp/yt/string/unittests/format_ut.cpp @@ -239,6 +239,13 @@ TEST(TFormatTest, Pointers) } } +TEST(TFormatTest, Tuples) +{ + EXPECT_EQ("{}", Format("%v", std::tuple())); + EXPECT_EQ("{1, 2, 3}", Format("%v", std::tuple(1, 2, 3))); + EXPECT_EQ("{1, 2}", Format("%v", std::pair(1, 2))); +} + TEST(TFormatTest, LazyMultiValueFormatter) { int i = 1; |