diff options
author | omgronny <omgronny@yandex-team.com> | 2024-11-07 12:27:30 +0300 |
---|---|---|
committer | omgronny <omgronny@yandex-team.com> | 2024-11-07 13:38:40 +0300 |
commit | 13a4f274caef5cfdaf0263b24e4d6bdd5521472b (patch) | |
tree | 1e85ab54821538457f498e1e0d1281b4000d1c9b | |
parent | 338da9a169aaa11be7fa8ca7e6ca87d783a2f75c (diff) | |
download | ydb-13a4f274caef5cfdaf0263b24e4d6bdd5521472b.tar.gz |
YT-23266: Fix skip unknown fields
commit_hash:74f3a55474c94110d8a379b1a2d2f75499ea737a
-rw-r--r-- | yt/yt/core/misc/protobuf_helpers.cpp | 7 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop-inl.h | 34 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop.cpp | 2 | ||||
-rw-r--r-- | yt/yt/core/yson/protobuf_interop.h | 32 | ||||
-rw-r--r-- | yt/yt/core/yson/unittests/protobuf_yson_ut.cpp | 21 |
5 files changed, 68 insertions, 28 deletions
diff --git a/yt/yt/core/misc/protobuf_helpers.cpp b/yt/yt/core/misc/protobuf_helpers.cpp index ff5e4046df..f68eb5de62 100644 --- a/yt/yt/core/misc/protobuf_helpers.cpp +++ b/yt/yt/core/misc/protobuf_helpers.cpp @@ -418,7 +418,7 @@ void ToProto(NYT::NProto::TExtensionSet* protoExtensionSet, const TExtensionSet& } } -void Serialize(const TExtensionSet& extensionSet, NYson::IYsonConsumer* consumer) +void Serialize(const TExtensionSet& extensionSet, NYson::IYsonConsumer* consumer, const TProtobufParserOptions& parserOptions = {}) { BuildYsonFluently(consumer) .DoMapFor(extensionSet.Extensions, [&] (TFluentMap fluent, const TExtension& extension) { @@ -433,7 +433,8 @@ void Serialize(const TExtensionSet& extensionSet, NYson::IYsonConsumer* consumer ParseProtobuf( fluent.GetConsumer(), &inputStream, - ReflectProtobufMessageType(extensionDescriptor->MessageDescriptor)); + ReflectProtobufMessageType(extensionDescriptor->MessageDescriptor), + parserOptions); }); }); } @@ -463,7 +464,7 @@ void Deserialize(TExtensionSet& extensionSet, NYTree::INodePtr node) } } -REGISTER_INTERMEDIATE_PROTO_INTEROP_REPRESENTATION(NYT::NProto::TExtensionSet, TExtensionSet) +REGISTER_INTERMEDIATE_PROTO_INTEROP_REPRESENTATION_WITH_OPTIONS(NYT::NProto::TExtensionSet, TExtensionSet) //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/yson/protobuf_interop-inl.h b/yt/yt/core/yson/protobuf_interop-inl.h index 50ec342fe4..af20635494 100644 --- a/yt/yt/core/yson/protobuf_interop-inl.h +++ b/yt/yt/core/yson/protobuf_interop-inl.h @@ -17,6 +17,40 @@ const TProtobufMessageType* ReflectProtobufMessageType() //////////////////////////////////////////////////////////////////////////////// +template <class ProtoType, class Type, bool UseParseOptionsInSerialize> +static const void* DoRegisterIntermediateProtoInteropRepresentation() { + NYT::NYson::AddProtobufConverterRegisterAction([] { + auto* descriptor = ProtoType::default_instance().GetDescriptor(); + NYT::NYson::TProtobufMessageConverter converter; + converter.Serializer = [] ( + NYT::NYson::IYsonConsumer* consumer, + const google::protobuf::Message* message, + const NYson::TProtobufParserOptions& parseOptions = {}) + { + const auto* typedMessage = dynamic_cast<const ProtoType*>(message); + YT_VERIFY(typedMessage); + Type value; + FromProto(&value, *typedMessage); + if constexpr (UseParseOptionsInSerialize) { + Serialize(value, consumer, parseOptions); + } else { + Serialize(value, consumer); + } + }; + converter.Deserializer = [] (google::protobuf::Message* message, const NYT::NYTree::INodePtr& node) { + auto* typedMessage = dynamic_cast<ProtoType*>(message); + YT_VERIFY(typedMessage); + Type value; + Deserialize(value, node); + ToProto(typedMessage, value); + }; + NYT::NYson::RegisterCustomProtobufConverter(descriptor, converter); + }); + return nullptr; +}; + +//////////////////////////////////////////////////////////////////////////////// + std::optional<int> FindProtobufEnumValueByLiteralUntyped( const TProtobufEnumType* type, TStringBuf literal); diff --git a/yt/yt/core/yson/protobuf_interop.cpp b/yt/yt/core/yson/protobuf_interop.cpp index d6952ed4f5..c23dcab2a3 100644 --- a/yt/yt/core/yson/protobuf_interop.cpp +++ b/yt/yt/core/yson/protobuf_interop.cpp @@ -2693,7 +2693,7 @@ private: PooledString_.resize(length); CodedStream_.ReadRaw(PooledString_.data(), PooledString_.size()); Y_UNUSED(message->ParseFromArray(PooledString_.data(), PooledString_.size())); - converter.Serializer(Consumer_, message.get()); + converter.Serializer(Consumer_, message.get(), Options_); YPathStack_.Pop(); } else { LimitStack_.push_back(CodedStream_.PushLimit(static_cast<int>(length))); diff --git a/yt/yt/core/yson/protobuf_interop.h b/yt/yt/core/yson/protobuf_interop.h index 3e6faa6a53..bdc06244da 100644 --- a/yt/yt/core/yson/protobuf_interop.h +++ b/yt/yt/core/yson/protobuf_interop.h @@ -198,7 +198,7 @@ void AddProtobufConverterRegisterAction(std::function<void()> action); struct TProtobufMessageConverter { - std::function<void(IYsonConsumer* consumer, const google::protobuf::Message* message)> Serializer; + std::function<void(IYsonConsumer* consumer, const google::protobuf::Message* message, const TProtobufParserOptions& parserOptions)> Serializer; std::function<void(google::protobuf::Message* message, const NYTree::INodePtr& node)> Deserializer; }; @@ -207,29 +207,13 @@ void RegisterCustomProtobufConverter( const google::protobuf::Descriptor* descriptor, const TProtobufMessageConverter& converter); -#define REGISTER_INTERMEDIATE_PROTO_INTEROP_REPRESENTATION(ProtoType, Type) \ - YT_ATTRIBUTE_USED static const void* PP_ANONYMOUS_VARIABLE(RegisterIntermediateProtoInteropRepresentation) = [] { \ - NYT::NYson::AddProtobufConverterRegisterAction([] { \ - auto* descriptor = ProtoType::default_instance().GetDescriptor(); \ - NYT::NYson::TProtobufMessageConverter converter; \ - converter.Serializer = [] (NYT::NYson::IYsonConsumer* consumer, const google::protobuf::Message* message) { \ - const auto* typedMessage = dynamic_cast<const ProtoType*>(message); \ - YT_VERIFY(typedMessage); \ - Type value; \ - FromProto(&value, *typedMessage); \ - Serialize(value, consumer); \ - }; \ - converter.Deserializer = [] (google::protobuf::Message* message, const NYT::NYTree::INodePtr& node) { \ - auto* typedMessage = dynamic_cast<ProtoType*>(message); \ - YT_VERIFY(typedMessage); \ - Type value; \ - Deserialize(value, node); \ - ToProto(typedMessage, value); \ - }; \ - NYT::NYson::RegisterCustomProtobufConverter(descriptor, converter); \ - }); \ - return nullptr; \ - } (); +#define REGISTER_INTERMEDIATE_PROTO_INTEROP_REPRESENTATION(ProtoType, Type) \ + YT_ATTRIBUTE_USED static const void* PP_ANONYMOUS_VARIABLE(RegisterIntermediateProtoInteropRepresentation) = \ + NYson::DoRegisterIntermediateProtoInteropRepresentation<ProtoType, Type, false>(); + +#define REGISTER_INTERMEDIATE_PROTO_INTEROP_REPRESENTATION_WITH_OPTIONS(ProtoType, Type) \ + YT_ATTRIBUTE_USED static const void* PP_ANONYMOUS_VARIABLE(RegisterIntermediateProtoInteropRepresentationWithOptions) = \ + NYson::DoRegisterIntermediateProtoInteropRepresentation<ProtoType, Type, true>(); //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp index e9c4a9c0b8..7373b8d78c 100644 --- a/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp +++ b/yt/yt/core/yson/unittests/protobuf_yson_ut.cpp @@ -2036,6 +2036,27 @@ TEST(TProtobufToYsonTest, UnknownFields) } } +TEST(TProtobufToYsonTest, UnknownFieldsNested) +{ + TProtobufParserOptions options; + options.SkipUnknownFields = true; + + TEST_PROLOGUE() + codedStream.WriteTag(WireFormatLite::MakeTag(15 /*nested_message1*/, WireFormatLite::WIRETYPE_LENGTH_DELIMITED)); + codedStream.WriteVarint64(3); + codedStream.WriteTag(WireFormatLite::MakeTag(42 /*unknown*/, WireFormatLite::WIRETYPE_VARINT)); + codedStream.WriteVarint64(2); + TEST_EPILOGUE_WITH_OPTIONS(TMessage, options) + + NProto::TMessage message; + TryDeserializeProto(&message, TRef::FromString(protobuf)); + + TString newYsonString; + TStringOutput newYsonOutputStream(newYsonString); + TYsonWriter ysonWriter(&newYsonOutputStream, EYsonFormat::Pretty); + WriteProtobufMessage(&ysonWriter, message, options); +} + TEST(TProtobufToYsonTest, ReservedFields) { TEST_PROLOGUE() |