diff options
Diffstat (limited to 'library/cpp/protobuf/util')
-rw-r--r-- | library/cpp/protobuf/util/cast.h | 82 | ||||
-rw-r--r-- | library/cpp/protobuf/util/is_equal.cpp | 54 | ||||
-rw-r--r-- | library/cpp/protobuf/util/is_equal.h | 16 | ||||
-rw-r--r-- | library/cpp/protobuf/util/is_equal_ut.cpp | 16 | ||||
-rw-r--r-- | library/cpp/protobuf/util/merge.cpp | 26 | ||||
-rw-r--r-- | library/cpp/protobuf/util/merge.h | 14 | ||||
-rw-r--r-- | library/cpp/protobuf/util/merge_ut.cpp | 150 | ||||
-rw-r--r-- | library/cpp/protobuf/util/proto/merge.proto | 20 | ||||
-rw-r--r-- | library/cpp/protobuf/util/repeated_field_utils.h | 28 | ||||
-rw-r--r-- | library/cpp/protobuf/util/simple_reflection.h | 88 | ||||
-rw-r--r-- | library/cpp/protobuf/util/simple_reflection_ut.cpp | 28 | ||||
-rw-r--r-- | library/cpp/protobuf/util/sort.h | 24 | ||||
-rw-r--r-- | library/cpp/protobuf/util/traits.h | 130 | ||||
-rw-r--r-- | library/cpp/protobuf/util/ut/common_ut.proto | 80 | ||||
-rw-r--r-- | library/cpp/protobuf/util/ut/sample_for_simple_reflection.proto | 20 | ||||
-rw-r--r-- | library/cpp/protobuf/util/ut/ya.make | 4 | ||||
-rw-r--r-- | library/cpp/protobuf/util/walk.h | 12 | ||||
-rw-r--r-- | library/cpp/protobuf/util/walk_ut.cpp | 210 | ||||
-rw-r--r-- | library/cpp/protobuf/util/ya.make | 6 |
19 files changed, 504 insertions, 504 deletions
diff --git a/library/cpp/protobuf/util/cast.h b/library/cpp/protobuf/util/cast.h index 40076feac8..83749dfcee 100644 --- a/library/cpp/protobuf/util/cast.h +++ b/library/cpp/protobuf/util/cast.h @@ -1,17 +1,17 @@ -#pragma once +#pragma once #include "traits.h" - + #include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> - + #include <util/generic/cast.h> - -namespace NProtoBuf { + +namespace NProtoBuf { // C++ compatible conversions of FieldDescriptor::CppType's - + using ECppType = FieldDescriptor::CppType; - + namespace NCast { template <ECppType src, ECppType dst> struct TIsCompatibleCppType { @@ -19,67 +19,67 @@ namespace NProtoBuf { Result = src == dst || (TIsNumericCppType<src>::Result && TIsNumericCppType<dst>::Result) }; - }; - + }; + template <ECppType src, ECppType dst> struct TIsEnumToNumericCppType { enum { Result = (src == FieldDescriptor::CPPTYPE_ENUM && TIsNumericCppType<dst>::Result) }; - }; - + }; + template <ECppType src, ECppType dst, bool compatible> // compatible == true struct TCompatCastBase { static const bool IsCompatible = true; - + typedef typename TCppTypeTraits<src>::T TSrc; typedef typename TCppTypeTraits<dst>::T TDst; - + static inline TDst Cast(TSrc value) { return value; } }; - + template <ECppType src, ECppType dst> // compatible == false struct TCompatCastBase<src, dst, false> { static const bool IsCompatible = false; - + typedef typename TCppTypeTraits<src>::T TSrc; typedef typename TCppTypeTraits<dst>::T TDst; - + static inline TDst Cast(TSrc) { ythrow TBadCastException() << "Incompatible FieldDescriptor::CppType conversion: #" << (size_t)src << " to #" << (size_t)dst; } }; - + template <ECppType src, ECppType dst, bool isEnumToNum> // enum -> numeric struct TCompatCastImpl { static const bool IsCompatible = true; - + typedef typename TCppTypeTraits<dst>::T TDst; - + static inline TDst Cast(const EnumValueDescriptor* value) { Y_ASSERT(value != nullptr); return value->number(); } }; - + template <ECppType src, ECppType dst> struct TCompatCastImpl<src, dst, false>: public TCompatCastBase<src, dst, TIsCompatibleCppType<src, dst>::Result> { using TCompatCastBase<src, dst, TIsCompatibleCppType<src, dst>::Result>::IsCompatible; }; - + template <ECppType src, ECppType dst> struct TCompatCast: public TCompatCastImpl<src, dst, TIsEnumToNumericCppType<src, dst>::Result> { typedef TCompatCastImpl<src, dst, TIsEnumToNumericCppType<src, dst>::Result> TBase; - + typedef typename TCppTypeTraits<src>::T TSrc; typedef typename TCppTypeTraits<dst>::T TDst; - + using TBase::Cast; using TBase::IsCompatible; - + inline bool Try(TSrc value, TDst& res) { if (IsCompatible) { res = Cast(value); @@ -88,69 +88,69 @@ namespace NProtoBuf { return false; } }; - + } - template <ECppType src, ECppType dst> + template <ECppType src, ECppType dst> inline typename TCppTypeTraits<dst>::T CompatCast(typename TCppTypeTraits<src>::T value) { return NCast::TCompatCast<src, dst>::Cast(value); } - - template <ECppType src, ECppType dst> + + template <ECppType src, ECppType dst> inline bool TryCompatCast(typename TCppTypeTraits<src>::T value, typename TCppTypeTraits<dst>::T& res) { return NCast::TCompatCast<src, dst>::Try(value, res); } - + // Message static/dynamic checked casts - + template <typename TpMessage> inline const TpMessage* TryCast(const Message* msg) { if (!msg || TpMessage::descriptor() != msg->GetDescriptor()) return NULL; return CheckedCast<const TpMessage*>(msg); } - + template <typename TpMessage> inline const TpMessage* TryCast(const Message* msg, const TpMessage*& ret) { ret = TryCast<TpMessage>(msg); return ret; } - + template <typename TpMessage> inline TpMessage* TryCast(Message* msg) { if (!msg || TpMessage::descriptor() != msg->GetDescriptor()) return nullptr; return CheckedCast<TpMessage*>(msg); } - + template <typename TpMessage> inline TpMessage* TryCast(Message* msg, TpMessage*& ret) { ret = TryCast<TpMessage>(msg); return ret; } - + // specialize for Message itself - + template <> inline const Message* TryCast<Message>(const Message* msg) { return msg; } - + template <> inline Message* TryCast<Message>(Message* msg) { return msg; } - + // Binary serialization compatible conversion inline bool TryBinaryCast(const Message* from, Message* to, TString* buffer = nullptr) { TString tmpbuf; if (!buffer) buffer = &tmpbuf; - + if (!from->SerializeToString(buffer)) return false; - + return to->ParseFromString(*buffer); } - -} + +} diff --git a/library/cpp/protobuf/util/is_equal.cpp b/library/cpp/protobuf/util/is_equal.cpp index f191e8bfad..227408006e 100644 --- a/library/cpp/protobuf/util/is_equal.cpp +++ b/library/cpp/protobuf/util/is_equal.cpp @@ -1,16 +1,16 @@ -#include "is_equal.h" -#include "traits.h" - +#include "is_equal.h" +#include "traits.h" + #include <google/protobuf/descriptor.h> - -#include <util/generic/yexception.h> + +#include <util/generic/yexception.h> #include <util/string/cast.h> #include <util/string/vector.h> - -namespace NProtoBuf { + +namespace NProtoBuf { template <bool useDefault> static bool IsEqualImpl(const Message& m1, const Message& m2, TVector<TString>* differentPath); - + namespace { template <FieldDescriptor::CppType CppType, bool useDefault> struct TCompareValue { @@ -26,12 +26,12 @@ namespace NProtoBuf { return NProtoBuf::IsEqualImpl<useDefault>(*value1, *value2, differentPath); } }; - + template <FieldDescriptor::CppType CppType, bool useDefault> class TCompareField { typedef TCppTypeTraits<CppType> TTraits; typedef TCompareValue<CppType, useDefault> TCompare; - + public: static inline bool IsEqual(const Message& m1, const Message& m2, const FieldDescriptor& field, TVector<TString>* differentPath) { if (field.is_repeated()) @@ -39,12 +39,12 @@ namespace NProtoBuf { else return IsEqualSingle(m1, m2, &field, differentPath); } - + private: static bool IsEqualSingle(const Message& m1, const Message& m2, const FieldDescriptor* field, TVector<TString>* differentPath) { bool has1 = m1.GetReflection()->HasField(m1, field); bool has2 = m2.GetReflection()->HasField(m2, field); - + if (has1 != has2) { if (!useDefault || field->is_required()) { return false; @@ -60,7 +60,7 @@ namespace NProtoBuf { static bool IsEqualRepeated(const Message& m1, const Message& m2, const FieldDescriptor* field, TVector<TString>* differentPath) { int fieldSize = m1.GetReflection()->FieldSize(m1, field); if (fieldSize != m2.GetReflection()->FieldSize(m2, field)) - return false; + return false; for (int i = 0; i < fieldSize; ++i) if (!IsEqualRepeatedValue(m1, m2, field, i, differentPath)) { if (!!differentPath) { @@ -68,16 +68,16 @@ namespace NProtoBuf { } return false; } - return true; + return true; } - + static inline bool IsEqualRepeatedValue(const Message& m1, const Message& m2, const FieldDescriptor* field, int index, TVector<TString>* differentPath) { return TCompare::IsEqual(TTraits::GetRepeated(m1, field, index), TTraits::GetRepeated(m2, field, index), differentPath); } }; - + template <bool useDefault> bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field, TVector<TString>* differentPath) { #define CASE_CPPTYPE(cpptype) \ @@ -88,7 +88,7 @@ namespace NProtoBuf { } \ return r; \ } - + switch (field.cpp_type()) { CASE_CPPTYPE(INT32) CASE_CPPTYPE(INT64) @@ -105,10 +105,10 @@ namespace NProtoBuf { } #undef CASE_CPPTYPE - } + } } - - template <bool useDefault> + + template <bool useDefault> bool IsEqualImpl(const Message& m1, const Message& m2, TVector<TString>* differentPath) { const Descriptor* descr = m1.GetDescriptor(); if (descr != m2.GetDescriptor()) { @@ -120,7 +120,7 @@ namespace NProtoBuf { } return true; } - + bool IsEqual(const Message& m1, const Message& m2) { return IsEqualImpl<false>(m1, m2, nullptr); } @@ -131,14 +131,14 @@ namespace NProtoBuf { bool r = IsEqualImpl<false>(m1, m2, differentPathVectorPtr); if (!r && differentPath) { *differentPath = JoinStrings(differentPathVector.rbegin(), differentPathVector.rend(), "/"); - } + } return r; } - + bool IsEqualDefault(const Message& m1, const Message& m2) { return IsEqualImpl<true>(m1, m2, nullptr); - } - + } + template <bool useDefault> static bool IsEqualFieldImpl( const Message& m1, @@ -147,11 +147,11 @@ namespace NProtoBuf { TVector<TString>* differentPath) { const Descriptor* descr = m1.GetDescriptor(); if (descr != m2.GetDescriptor()) { - return false; + return false; } return IsEqualField<useDefault>(m1, m2, field, differentPath); } - + bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field) { return IsEqualFieldImpl<false>(m1, m2, field, nullptr); } diff --git a/library/cpp/protobuf/util/is_equal.h b/library/cpp/protobuf/util/is_equal.h index 35515639d0..13c0aae63d 100644 --- a/library/cpp/protobuf/util/is_equal.h +++ b/library/cpp/protobuf/util/is_equal.h @@ -1,7 +1,7 @@ -#pragma once - +#pragma once + #include <util/generic/fwd.h> - + namespace google { namespace protobuf { class Message; @@ -9,11 +9,11 @@ namespace google { } } -namespace NProtoBuf { +namespace NProtoBuf { using ::google::protobuf::FieldDescriptor; using ::google::protobuf::Message; } - + namespace NProtoBuf { // Reflection-based equality check for arbitrary protobuf messages @@ -21,7 +21,7 @@ namespace NProtoBuf { // a field with explicitly set default value. bool IsEqual(const Message& m1, const Message& m2); bool IsEqual(const Message& m1, const Message& m2, TString* differentPath); - + bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field); // Non-strict version: optional field without explicit value is compared @@ -29,5 +29,5 @@ namespace NProtoBuf { bool IsEqualDefault(const Message& m1, const Message& m2); bool IsEqualFieldDefault(const Message& m1, const Message& m2, const FieldDescriptor& field); - -} + +} diff --git a/library/cpp/protobuf/util/is_equal_ut.cpp b/library/cpp/protobuf/util/is_equal_ut.cpp index b10be7bb18..3ca4c90dd5 100644 --- a/library/cpp/protobuf/util/is_equal_ut.cpp +++ b/library/cpp/protobuf/util/is_equal_ut.cpp @@ -49,7 +49,7 @@ Y_UNIT_TEST_SUITE(ProtobufIsEqual) { bool equalField = NProtoBuf::IsEqualField(a, b, *InnerDescr); UNIT_ASSERT(!equalField); } - + Y_UNIT_TEST(IsEqual3) { TSampleForIsEqual a; TSampleForIsEqual b; @@ -75,14 +75,14 @@ Y_UNIT_TEST_SUITE(ProtobufIsEqual) { } Y_UNIT_TEST(IsEqualDefault) { - TSampleForIsEqual a; - TSampleForIsEqual b; - - a.SetName(""); - UNIT_ASSERT(NProtoBuf::IsEqualDefault(a, b)); - UNIT_ASSERT(!NProtoBuf::IsEqual(a, b)); + TSampleForIsEqual a; + TSampleForIsEqual b; + + a.SetName(""); + UNIT_ASSERT(NProtoBuf::IsEqualDefault(a, b)); + UNIT_ASSERT(!NProtoBuf::IsEqual(a, b)); UNIT_ASSERT(!NProtoBuf::IsEqualField(a, b, *NameDescr)); UNIT_ASSERT(NProtoBuf::IsEqualFieldDefault(a, b, *NameDescr)); - } + } } diff --git a/library/cpp/protobuf/util/merge.cpp b/library/cpp/protobuf/util/merge.cpp index 4af4431d46..dc2b9cc806 100644 --- a/library/cpp/protobuf/util/merge.cpp +++ b/library/cpp/protobuf/util/merge.cpp @@ -1,30 +1,30 @@ -#include "merge.h" +#include "merge.h" #include "simple_reflection.h" #include <google/protobuf/message.h> #include <library/cpp/protobuf/util/proto/merge.pb.h> - -namespace NProtoBuf { + +namespace NProtoBuf { void RewriteMerge(const Message& src, Message& dst) { const Descriptor* d = src.GetDescriptor(); Y_ASSERT(d == dst.GetDescriptor()); - + for (int i = 0; i < d->field_count(); ++i) { if (TConstField(src, d->field(i)).Has()) TMutableField(dst, d->field(i)).Clear(); } - + dst.MergeFrom(src); - } - + } + static void ClearNonMergeable(const Message& src, Message& dst) { const Descriptor* d = src.GetDescriptor(); if (d->options().GetExtension(DontMerge)) { dst.Clear(); return; } - + for (int i = 0; i < d->field_count(); ++i) { const FieldDescriptor* fd = d->field(i); TConstField srcField(src, fd); @@ -36,11 +36,11 @@ namespace NProtoBuf { ClearNonMergeable(*srcField.Get<const Message*>(), *dstField.MutableMessage()); } } - } - + } + void CustomMerge(const Message& src, Message& dst) { ClearNonMergeable(src, dst); dst.MergeFrom(src); - } - -} + } + +} diff --git a/library/cpp/protobuf/util/merge.h b/library/cpp/protobuf/util/merge.h index 847b65dd0e..924975f141 100644 --- a/library/cpp/protobuf/util/merge.h +++ b/library/cpp/protobuf/util/merge.h @@ -1,22 +1,22 @@ -#pragma once - +#pragma once + namespace google { namespace protobuf { class Message; } } - + namespace NProtoBuf { using Message = ::google::protobuf::Message; } - -namespace NProtoBuf { + +namespace NProtoBuf { // Similiar to Message::MergeFrom, overwrites existing repeated fields // and embedded messages completely instead of recursive merging. void RewriteMerge(const Message& src, Message& dst); - + // Does standard MergeFrom() by default, except messages/fields marked with DontMerge or DontMergeField option. // Such fields are merged using RewriteMerge() (i.e. destination is cleared before merging anything from source) void CustomMerge(const Message& src, Message& dst); - + } diff --git a/library/cpp/protobuf/util/merge_ut.cpp b/library/cpp/protobuf/util/merge_ut.cpp index 44f4db69b7..22217db183 100644 --- a/library/cpp/protobuf/util/merge_ut.cpp +++ b/library/cpp/protobuf/util/merge_ut.cpp @@ -1,83 +1,83 @@ -#include "merge.h" +#include "merge.h" #include <library/cpp/protobuf/util/ut/common_ut.pb.h> - + #include <library/cpp/testing/unittest/registar.h> - -using namespace NProtoBuf; - + +using namespace NProtoBuf; + Y_UNIT_TEST_SUITE(ProtobufMerge) { static void InitProto(NProtobufUtilUt::TMergeTest & p, bool isSrc) { - size_t start = isSrc ? 0 : 100; - - p.AddMergeInt(start + 1); - p.AddMergeInt(start + 2); - - p.AddNoMergeInt(start + 3); - p.AddNoMergeInt(start + 4); - - NProtobufUtilUt::TMergeTestMerge* m = p.MutableMergeSub(); - m->SetA(start + 5); - m->AddB(start + 6); - m->AddB(start + 7); - m->AddC(start + 14); - - if (!isSrc) { - // only for dst - NProtobufUtilUt::TMergeTestMerge* mm1 = p.AddNoMergeRepSub(); - mm1->SetA(start + 8); - mm1->AddB(start + 9); - mm1->AddB(start + 10); - } - - NProtobufUtilUt::TMergeTestNoMerge* mm3 = p.MutableNoMergeOptSub(); - mm3->SetA(start + 11); - mm3->AddB(start + 12); - mm3->AddB(start + 13); - } - + size_t start = isSrc ? 0 : 100; + + p.AddMergeInt(start + 1); + p.AddMergeInt(start + 2); + + p.AddNoMergeInt(start + 3); + p.AddNoMergeInt(start + 4); + + NProtobufUtilUt::TMergeTestMerge* m = p.MutableMergeSub(); + m->SetA(start + 5); + m->AddB(start + 6); + m->AddB(start + 7); + m->AddC(start + 14); + + if (!isSrc) { + // only for dst + NProtobufUtilUt::TMergeTestMerge* mm1 = p.AddNoMergeRepSub(); + mm1->SetA(start + 8); + mm1->AddB(start + 9); + mm1->AddB(start + 10); + } + + NProtobufUtilUt::TMergeTestNoMerge* mm3 = p.MutableNoMergeOptSub(); + mm3->SetA(start + 11); + mm3->AddB(start + 12); + mm3->AddB(start + 13); + } + Y_UNIT_TEST(CustomMerge) { - NProtobufUtilUt::TMergeTest src, dst; - InitProto(src, true); - InitProto(dst, false); - + NProtobufUtilUt::TMergeTest src, dst; + InitProto(src, true); + InitProto(dst, false); + // Cerr << "\nsrc: " << src.ShortDebugString() << Endl; // Cerr << "dst: " << dst.ShortDebugString() << Endl; - NProtoBuf::CustomMerge(src, dst); + NProtoBuf::CustomMerge(src, dst); // Cerr << "dst2:" << dst.ShortDebugString() << Endl; - - // repeated uint32 MergeInt = 1; - UNIT_ASSERT_EQUAL(dst.MergeIntSize(), 4); - UNIT_ASSERT_EQUAL(dst.GetMergeInt(0), 101); - UNIT_ASSERT_EQUAL(dst.GetMergeInt(1), 102); - UNIT_ASSERT_EQUAL(dst.GetMergeInt(2), 1); - UNIT_ASSERT_EQUAL(dst.GetMergeInt(3), 2); - - // repeated uint32 NoMergeInt = 2 [(DontMergeField)=true]; - UNIT_ASSERT_EQUAL(dst.NoMergeIntSize(), 2); - UNIT_ASSERT_EQUAL(dst.GetNoMergeInt(0), 3); - UNIT_ASSERT_EQUAL(dst.GetNoMergeInt(1), 4); - - // optional TMergeTestMerge MergeSub = 3; - UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetA(), 5); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().BSize(), 4); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(0), 106); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(1), 107); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(2), 6); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(3), 7); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().CSize(), 1); - UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetC(0), 14); - - // repeated TMergeTestMerge NoMergeRepSub = 4 [(DontMergeField)=true]; - UNIT_ASSERT_EQUAL(dst.NoMergeRepSubSize(), 1); - UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).GetA(), 108); - UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).BSize(), 2); - UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).GetB(0), 109); - UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).GetB(1), 110); - - // optional TMergeTestNoMerge NoMergeOptSub = 5; - UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().GetA(), 11); - UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().BSize(), 2); - UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().GetB(0), 12); - UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().GetB(1), 13); - } -} + + // repeated uint32 MergeInt = 1; + UNIT_ASSERT_EQUAL(dst.MergeIntSize(), 4); + UNIT_ASSERT_EQUAL(dst.GetMergeInt(0), 101); + UNIT_ASSERT_EQUAL(dst.GetMergeInt(1), 102); + UNIT_ASSERT_EQUAL(dst.GetMergeInt(2), 1); + UNIT_ASSERT_EQUAL(dst.GetMergeInt(3), 2); + + // repeated uint32 NoMergeInt = 2 [(DontMergeField)=true]; + UNIT_ASSERT_EQUAL(dst.NoMergeIntSize(), 2); + UNIT_ASSERT_EQUAL(dst.GetNoMergeInt(0), 3); + UNIT_ASSERT_EQUAL(dst.GetNoMergeInt(1), 4); + + // optional TMergeTestMerge MergeSub = 3; + UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetA(), 5); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().BSize(), 4); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(0), 106); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(1), 107); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(2), 6); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetB(3), 7); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().CSize(), 1); + UNIT_ASSERT_EQUAL(dst.GetMergeSub().GetC(0), 14); + + // repeated TMergeTestMerge NoMergeRepSub = 4 [(DontMergeField)=true]; + UNIT_ASSERT_EQUAL(dst.NoMergeRepSubSize(), 1); + UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).GetA(), 108); + UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).BSize(), 2); + UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).GetB(0), 109); + UNIT_ASSERT_EQUAL(dst.GetNoMergeRepSub(0).GetB(1), 110); + + // optional TMergeTestNoMerge NoMergeOptSub = 5; + UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().GetA(), 11); + UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().BSize(), 2); + UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().GetB(0), 12); + UNIT_ASSERT_EQUAL(dst.GetNoMergeOptSub().GetB(1), 13); + } +} diff --git a/library/cpp/protobuf/util/proto/merge.proto b/library/cpp/protobuf/util/proto/merge.proto index 1adfa8db1e..a937041c07 100644 --- a/library/cpp/protobuf/util/proto/merge.proto +++ b/library/cpp/protobuf/util/proto/merge.proto @@ -1,11 +1,11 @@ import "google/protobuf/descriptor.proto"; - -// These meta-options are used for selecting proper merging method, see merge.h - -extend google.protobuf.MessageOptions { - optional bool DontMerge = 54287; -} - -extend google.protobuf.FieldOptions { - optional bool DontMergeField = 54288; -} + +// These meta-options are used for selecting proper merging method, see merge.h + +extend google.protobuf.MessageOptions { + optional bool DontMerge = 54287; +} + +extend google.protobuf.FieldOptions { + optional bool DontMergeField = 54288; +} diff --git a/library/cpp/protobuf/util/repeated_field_utils.h b/library/cpp/protobuf/util/repeated_field_utils.h index 8971b8f3d2..c07bd84647 100644 --- a/library/cpp/protobuf/util/repeated_field_utils.h +++ b/library/cpp/protobuf/util/repeated_field_utils.h @@ -1,7 +1,7 @@ #pragma once #include <google/protobuf/repeated_field.h> -#include <util/generic/vector.h> +#include <util/generic/vector.h> template <typename T> void RemoveRepeatedPtrFieldElement(google::protobuf::RepeatedPtrField<T>* repeated, unsigned index) { @@ -15,8 +15,8 @@ void RemoveRepeatedPtrFieldElement(google::protobuf::RepeatedPtrField<T>* repeat } r.Swap(repeated); } - -namespace NProtoBuf { + +namespace NProtoBuf { /// Move item to specified position template <typename TRepeated> static void MoveRepeatedFieldItem(TRepeated* field, size_t indexFrom, size_t indexTo) { @@ -32,7 +32,7 @@ namespace NProtoBuf { field->SwapElements(i, i + 1); } } - + template <typename T> static T* InsertRepeatedFieldItem(NProtoBuf::RepeatedPtrField<T>* field, size_t index) { T* ret = field->Add(); @@ -44,13 +44,13 @@ namespace NProtoBuf { static void RemoveRepeatedFieldItem(TRepeated* field, size_t index) { if ((int)index >= field->size()) return; - + for (int i = index + 1; i < field->size(); ++i) field->SwapElements(i - 1, i); - + field->RemoveLast(); } - + template <typename TRepeated, typename TPred> // suitable both for RepeatedField and RepeatedPtrField static void RemoveRepeatedFieldItemIf(TRepeated* repeated, TPred p) { auto last = std::remove_if(repeated->begin(), repeated->end(), p); @@ -60,7 +60,7 @@ namespace NProtoBuf { repeated->RemoveLast(); } } - + namespace NImpl { template <typename TRepeated> static void ShiftLeft(TRepeated* field, int begIndex, int endIndex, size_t shiftSize) { @@ -73,24 +73,24 @@ namespace NProtoBuf { } // Remove several items at once, could be more efficient compared to calling RemoveRepeatedFieldItem several times - template <typename TRepeated> + template <typename TRepeated> static void RemoveRepeatedFieldItems(TRepeated* field, const TVector<size_t>& sortedIndices) { if (sortedIndices.empty()) return; - + size_t shift = 1; for (size_t i = 1; i < sortedIndices.size(); ++i, ++shift) NImpl::ShiftLeft(field, sortedIndices[i - 1] + 1, sortedIndices[i], shift); NImpl::ShiftLeft(field, sortedIndices.back() + 1, field->size(), shift); - + for (; shift > 0; --shift) field->RemoveLast(); } - + template <typename TRepeated> static void ReverseRepeatedFieldItems(TRepeated* field) { for (int i1 = 0, i2 = field->size() - 1; i1 < i2; ++i1, --i2) field->SwapElements(i1, i2); } - -} + +} diff --git a/library/cpp/protobuf/util/simple_reflection.h b/library/cpp/protobuf/util/simple_reflection.h index baee5e4a53..61e877a787 100644 --- a/library/cpp/protobuf/util/simple_reflection.h +++ b/library/cpp/protobuf/util/simple_reflection.h @@ -1,18 +1,18 @@ -#pragma once - +#pragma once + #include "cast.h" #include "path.h" -#include "traits.h" - +#include "traits.h" + #include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> - + #include <util/generic/maybe.h> #include <util/generic/typetraits.h> #include <util/generic/vector.h> #include <util/system/defaults.h> -namespace NProtoBuf { +namespace NProtoBuf { class TConstField { public: TConstField(const Message& msg, const FieldDescriptor* fd) @@ -21,11 +21,11 @@ namespace NProtoBuf { { Y_ASSERT(Fd && Fd->containing_type() == Msg.GetDescriptor()); } - + static TMaybe<TConstField> ByPath(const Message& msg, const TStringBuf& path); static TMaybe<TConstField> ByPath(const Message& msg, const TVector<const FieldDescriptor*>& fieldsPath); static TMaybe<TConstField> ByPath(const Message& msg, const TFieldPath& fieldsPath); - + const Message& Parent() const { return Msg; } @@ -33,50 +33,50 @@ namespace NProtoBuf { const FieldDescriptor* Field() const { return Fd; } - + bool HasValue() const { return IsRepeated() ? Refl().FieldSize(Msg, Fd) > 0 : Refl().HasField(Msg, Fd); } - + // deprecated, use HasValue() instead bool Has() const { return HasValue(); } - + size_t Size() const { return IsRepeated() ? Refl().FieldSize(Msg, Fd) : (Refl().HasField(Msg, Fd) ? 1 : 0); } - + template <typename T> inline typename TSelectCppType<T>::T Get(size_t index = 0) const; - + template <typename TMsg> inline const TMsg* GetAs(size_t index = 0) const { // casting version of Get return IsMessageInstance<TMsg>() ? CheckedCast<const TMsg*>(Get<const Message*>(index)) : nullptr; } - + template <typename T> bool IsInstance() const { return CppType() == TSelectCppType<T>::Result; } - + template <typename TMsg> bool IsMessageInstance() const { return IsMessage() && Fd->message_type() == TMsg::descriptor(); } - + template <typename TMsg> bool IsInstance(std::enable_if_t<std::is_base_of<Message, TMsg>::value && !std::is_same<Message, TMsg>::value, void>* = NULL) const { // template will be selected when specifying Message children types return IsMessage() && Fd->message_type() == TMsg::descriptor(); } - + bool IsString() const { return CppType() == FieldDescriptor::CPPTYPE_STRING; } - + bool IsMessage() const { return CppType() == FieldDescriptor::CPPTYPE_MESSAGE; } @@ -95,11 +95,11 @@ namespace NProtoBuf { bool IsRepeated() const { return Fd->is_repeated(); } - + FieldDescriptor::CppType CppType() const { return Fd->cpp_type(); } - + const Reflection& Refl() const { return *Msg.GetReflection(); } @@ -107,23 +107,23 @@ namespace NProtoBuf { [[noreturn]] void RaiseUnknown() const { ythrow yexception() << "Unknown field cpp-type: " << (size_t)CppType(); } - + bool IsSameField(const TConstField& other) const { return &Parent() == &other.Parent() && Field() == other.Field(); } - + protected: const Message& Msg; const FieldDescriptor* Fd; }; - + class TMutableField: public TConstField { public: TMutableField(Message& msg, const FieldDescriptor* fd) : TConstField(msg, fd) { } - + static TMaybe<TMutableField> ByPath(Message& msg, const TStringBuf& path, bool createPath = false); static TMaybe<TMutableField> ByPath(Message& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath = false); static TMaybe<TMutableField> ByPath(Message& msg, const TFieldPath& fieldsPath, bool createPath = false); @@ -131,26 +131,26 @@ namespace NProtoBuf { Message* MutableParent() { return Mut(); } - + template <typename T> inline void Set(T value, size_t index = 0); - + template <typename T> inline void Add(T value); inline void MergeFrom(const TConstField& src); - + inline void Clear() { Refl().ClearField(Mut(), Fd); } /* - void Swap(TMutableField& f) { + void Swap(TMutableField& f) { Y_ASSERT(Field() == f.Field()); - - // not implemented yet, TODO: implement when Reflection::Mutable(Ptr)RepeatedField - // is ported into arcadia protobuf library from up-stream. - } -*/ + + // not implemented yet, TODO: implement when Reflection::Mutable(Ptr)RepeatedField + // is ported into arcadia protobuf library from up-stream. + } +*/ inline void RemoveLast() { Y_ASSERT(HasValue()); if (IsRepeated()) @@ -158,7 +158,7 @@ namespace NProtoBuf { else Clear(); } - + inline void SwapElements(size_t index1, size_t index2) { Y_ASSERT(IsRepeated()); Y_ASSERT(index1 < Size()); @@ -188,7 +188,7 @@ namespace NProtoBuf { return Refl().MutableMessage(Mut(), Fd); } } - + template <typename TMsg> inline TMsg* AddMessage() { return CheckedCast<TMsg*>(AddMessage()); @@ -207,9 +207,9 @@ namespace NProtoBuf { template <typename T> inline void MergeValue(T srcValue); }; - + // template implementations - + template <typename T> inline typename TSelectCppType<T>::T TConstField::Get(size_t index) const { Y_ASSERT(index < Size() || !Fd->is_repeated() && index == 0); // Get for single fields is always allowed because of default values @@ -222,8 +222,8 @@ namespace NProtoBuf { RaiseUnknown(); } #undef TMP_MACRO_FOR_CPPTYPE - } - + } + template <typename T> inline void TMutableField::Set(T value, size_t index) { Y_ASSERT(!IsRepeated() && index == 0 || index < Size()); @@ -237,8 +237,8 @@ namespace NProtoBuf { RaiseUnknown(); } #undef TMP_MACRO_FOR_CPPTYPE - } - + } + template <typename T> inline void TMutableField::Add(T value) { #define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ @@ -251,13 +251,13 @@ namespace NProtoBuf { RaiseUnknown(); } #undef TMP_MACRO_FOR_CPPTYPE - } - + } + template <typename T> inline void TMutableField::MergeValue(T srcValue) { Add(srcValue); } - + template <> inline void TMutableField::MergeValue<const Message*>(const Message* srcValue) { if (IsRepeated()) { diff --git a/library/cpp/protobuf/util/simple_reflection_ut.cpp b/library/cpp/protobuf/util/simple_reflection_ut.cpp index 347fd8d980..169d4703c9 100644 --- a/library/cpp/protobuf/util/simple_reflection_ut.cpp +++ b/library/cpp/protobuf/util/simple_reflection_ut.cpp @@ -156,21 +156,21 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { { TMaybe<TConstField> field = TConstField::ByPath(msg, "OneStr"); UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); UNIT_ASSERT_VALUES_EQUAL("1", (field->Get<TString>())); } { TMaybe<TConstField> field = TConstField::ByPath(msg, "OneMsg"); UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); UNIT_ASSERT(field->IsMessageInstance<TInnerSample>()); } { TMaybe<TConstField> field = TConstField::ByPath(msg, "/OneMsg/RepInt"); UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); UNIT_ASSERT_VALUES_EQUAL(2, field->Size()); UNIT_ASSERT_VALUES_EQUAL(2, field->Get<int>(0)); UNIT_ASSERT_VALUES_EQUAL(3, field->Get<int>(1)); @@ -179,7 +179,7 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { { TMaybe<TConstField> field = TConstField::ByPath(msg, "RepMsg/RepInt"); UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); UNIT_ASSERT_VALUES_EQUAL(2, field->Size()); UNIT_ASSERT_VALUES_EQUAL(4, field->Get<int>(0)); UNIT_ASSERT_VALUES_EQUAL(5, field->Get<int>(1)); @@ -194,13 +194,13 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { { TMaybe<TConstField> field = TConstField::ByPath(msg, "OneStr"); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); } { TMaybe<TConstField> field = TConstField::ByPath(msg, "OneMsg/RepInt"); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); } { @@ -217,25 +217,25 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { { TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneStr"); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); field->Set(TString("zz")); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); UNIT_ASSERT_VALUES_EQUAL("zz", msg.GetOneStr()); } { TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneStr"); UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); field->Set(TString("dd")); - UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT(field->HasValue()); UNIT_ASSERT_VALUES_EQUAL("dd", msg.GetOneStr()); } { TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneMsg/RepInt"); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); field->Add(10); UNIT_ASSERT_VALUES_EQUAL(10, msg.GetOneMsg().GetRepInt(0)); } @@ -253,13 +253,13 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { { TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneStr", true); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); } { TMaybe<TMutableField> field = TMutableField::ByPath(msg, "OneMsg/RepInt", true); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); UNIT_ASSERT(msg.HasOneMsg()); field->Add(10); UNIT_ASSERT_VALUES_EQUAL(10, msg.GetOneMsg().GetRepInt(0)); @@ -270,7 +270,7 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { TMaybe<TMutableField> fieldCopy = TMutableField::ByPath(msg, "RepMsg/RepInt", true); Y_UNUSED(fieldCopy); UNIT_ASSERT(field); - UNIT_ASSERT(!field->HasValue()); + UNIT_ASSERT(!field->HasValue()); UNIT_ASSERT_VALUES_EQUAL(1, msg.RepMsgSize()); field->Add(12); UNIT_ASSERT_VALUES_EQUAL(12, field->Get<int>()); diff --git a/library/cpp/protobuf/util/sort.h b/library/cpp/protobuf/util/sort.h index bd851b4e5a..985ba6f689 100644 --- a/library/cpp/protobuf/util/sort.h +++ b/library/cpp/protobuf/util/sort.h @@ -1,15 +1,15 @@ -#pragma once - +#pragma once + #include <google/protobuf/message.h> - -#include <util/generic/vector.h> -#include <util/generic/algorithm.h> - -namespace NProtoBuf { + +#include <util/generic/vector.h> +#include <util/generic/algorithm.h> + +namespace NProtoBuf { // TComparePtr is something like: // typedef bool (*TComparePtr)(const Message* msg1, const Message* msg2); // typedef bool (*TComparePtr)(const TProto* msg1, const TProto* msg2); - + template <typename TProto, typename TComparePtr> void SortMessages(RepeatedPtrField<TProto>& msgs, TComparePtr cmp) { TVector<TProto*> ptrs; @@ -17,12 +17,12 @@ namespace NProtoBuf { while (msgs.size()) { ptrs.push_back(msgs.ReleaseLast()); } - + ::StableSort(ptrs.begin(), ptrs.end(), cmp); for (size_t i = 0; i < ptrs.size(); ++i) { msgs.AddAllocated(ptrs[i]); } - } - -} + } + +} diff --git a/library/cpp/protobuf/util/traits.h b/library/cpp/protobuf/util/traits.h index 4be520f22a..50f036d0ea 100644 --- a/library/cpp/protobuf/util/traits.h +++ b/library/cpp/protobuf/util/traits.h @@ -1,16 +1,16 @@ -#pragma once - -#include <util/generic/typetraits.h> - +#pragma once + +#include <util/generic/typetraits.h> + #include <google/protobuf/descriptor.h> #include <google/protobuf/message.h> - -namespace NProtoBuf { -// this nasty windows.h macro interfers with protobuf::Reflection::GetMessage() -#if defined(GetMessage) -#undef GetMessage -#endif - + +namespace NProtoBuf { +// this nasty windows.h macro interfers with protobuf::Reflection::GetMessage() +#if defined(GetMessage) +#undef GetMessage +#endif + struct TCppTypeTraitsBase { static inline bool Has(const Message& msg, const FieldDescriptor* field) { // non-repeated return msg.GetReflection()->HasField(msg, field); @@ -18,24 +18,24 @@ namespace NProtoBuf { static inline size_t Size(const Message& msg, const FieldDescriptor* field) { // repeated return msg.GetReflection()->FieldSize(msg, field); } - + static inline void Clear(Message& msg, const FieldDescriptor* field) { msg.GetReflection()->ClearField(&msg, field); } - + static inline void RemoveLast(Message& msg, const FieldDescriptor* field) { msg.GetReflection()->RemoveLast(&msg, field); } - + static inline void SwapElements(Message& msg, const FieldDescriptor* field, int index1, int index2) { msg.GetReflection()->SwapElements(&msg, field, index1, index2); } }; - + // default value accessor template <FieldDescriptor::CppType cpptype> struct TCppTypeTraitsDefault; - + #define DECLARE_CPPTYPE_DEFAULT(cpptype, method) \ template <> \ struct TCppTypeTraitsDefault<cpptype> { \ @@ -62,23 +62,23 @@ namespace NProtoBuf { template <FieldDescriptor::CppType cpptype> struct TCppTypeTraits : TCppTypeTraitsBase { static const FieldDescriptor::CppType CppType = cpptype; - + struct T {}; static T Get(const Message& msg, const FieldDescriptor* field); static T GetRepeated(const Message& msg, const FieldDescriptor* field, int index); static T GetDefault(const FieldDescriptor* field); - + static void Set(Message& msg, const FieldDescriptor* field, T value); static void AddRepeated(Message& msg, const FieldDescriptor* field, T value); static void SetRepeated(Message& msg, const FieldDescriptor* field, int index, T value); }; - + // any type T -> CppType template <typename T> struct TSelectCppType { //static const FieldDescriptor::CppType Result = FieldDescriptor::MAX_CPPTYPE; }; - + #define DECLARE_CPPTYPE_TRAITS(cpptype, type, method) \ template <> \ struct TCppTypeTraits<cpptype>: public TCppTypeTraitsBase { \ @@ -108,8 +108,8 @@ namespace NProtoBuf { struct TSelectCppType<type> { \ static const FieldDescriptor::CppType Result = cpptype; \ typedef type T; \ - }; - + }; + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_INT32, i32, Int32); DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_INT64, i64, Int64); DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_UINT32, ui32, UInt32); @@ -120,15 +120,15 @@ namespace NProtoBuf { DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_ENUM, const EnumValueDescriptor*, Enum); DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_STRING, TString, String); //DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_MESSAGE, const Message&, Message); - -#undef DECLARE_CPPTYPE_TRAITS - + +#undef DECLARE_CPPTYPE_TRAITS + // specialization for message pointer template <> struct TCppTypeTraits<FieldDescriptor::CPPTYPE_MESSAGE>: public TCppTypeTraitsBase { typedef const Message* T; static const FieldDescriptor::CppType CppType = FieldDescriptor::CPPTYPE_MESSAGE; - + static inline T Get(const Message& msg, const FieldDescriptor* field) { return &(msg.GetReflection()->GetMessage(msg, field)); } @@ -151,29 +151,29 @@ namespace NProtoBuf { return ret; } }; - + template <> struct TSelectCppType<const Message*> { static const FieldDescriptor::CppType Result = FieldDescriptor::CPPTYPE_MESSAGE; typedef const Message* T; }; - + template <> struct TSelectCppType<Message> { static const FieldDescriptor::CppType Result = FieldDescriptor::CPPTYPE_MESSAGE; typedef const Message* T; }; - + template <FieldDescriptor::CppType CppType, bool Repeated> struct TFieldTraits { typedef TCppTypeTraits<CppType> TBaseTraits; typedef typename TBaseTraits::T T; - + static inline T Get(const Message& msg, const FieldDescriptor* field, size_t index = 0) { Y_ASSERT(index == 0); return TBaseTraits::Get(msg, field); } - + static inline T GetDefault(const FieldDescriptor* field) { return TBaseTraits::GetDefault(field); } @@ -181,11 +181,11 @@ namespace NProtoBuf { static inline bool Has(const Message& msg, const FieldDescriptor* field) { return TBaseTraits::Has(msg, field); } - + static inline size_t Size(const Message& msg, const FieldDescriptor* field) { return Has(msg, field); } - + static inline void Set(Message& msg, const FieldDescriptor* field, T value, size_t index = 0) { Y_ASSERT(index == 0); TBaseTraits::Set(msg, field, value); @@ -195,28 +195,28 @@ namespace NProtoBuf { TBaseTraits::Set(msg, field, value); } }; - + template <FieldDescriptor::CppType CppType> struct TFieldTraits<CppType, true> { typedef TCppTypeTraits<CppType> TBaseTraits; typedef typename TBaseTraits::T T; - + static inline T Get(const Message& msg, const FieldDescriptor* field, size_t index = 0) { return TBaseTraits::GetRepeated(msg, field, index); } - + static inline T GetDefault(const FieldDescriptor* field) { return TBaseTraits::GetDefault(field); } - + static inline size_t Size(const Message& msg, const FieldDescriptor* field) { return TBaseTraits::Size(msg, field); } - + static inline bool Has(const Message& msg, const FieldDescriptor* field) { return Size(msg, field) > 0; } - + static inline void Set(Message& msg, const FieldDescriptor* field, T value, size_t index = 0) { TBaseTraits::SetRepeated(msg, field, index, value); } @@ -225,28 +225,28 @@ namespace NProtoBuf { TBaseTraits::AddRepeated(msg, field, value); } }; - + // Simpler interface at the cost of checking is_repeated() on each call template <FieldDescriptor::CppType CppType> struct TSimpleFieldTraits { typedef TFieldTraits<CppType, true> TRepeated; typedef TFieldTraits<CppType, false> TSingle; typedef typename TRepeated::T T; - + static inline size_t Size(const Message& msg, const FieldDescriptor* field) { if (field->is_repeated()) return TRepeated::Size(msg, field); else return TSingle::Size(msg, field); } - + static inline bool Has(const Message& msg, const FieldDescriptor* field) { if (field->is_repeated()) return TRepeated::Has(msg, field); else return TSingle::Has(msg, field); } - + static inline T Get(const Message& msg, const FieldDescriptor* field, size_t index = 0) { Y_ASSERT(index < Size(msg, field) || !field->is_repeated() && index == 0); // Get for single fields is always allowed because of default values if (field->is_repeated()) @@ -254,11 +254,11 @@ namespace NProtoBuf { else return TSingle::Get(msg, field, index); } - + static inline T GetDefault(const FieldDescriptor* field) { return TSingle::GetDefault(field); } - + static inline void Set(Message& msg, const FieldDescriptor* field, T value, size_t index = 0) { Y_ASSERT(!field->is_repeated() && index == 0 || index < Size(msg, field)); if (field->is_repeated()) @@ -266,7 +266,7 @@ namespace NProtoBuf { else TSingle::Set(msg, field, value, index); } - + static inline void Add(Message& msg, const FieldDescriptor* field, T value) { if (field->is_repeated()) TRepeated::Add(msg, field, value); @@ -274,9 +274,9 @@ namespace NProtoBuf { TSingle::Add(msg, field, value); } }; - + // some cpp-type groups - + template <FieldDescriptor::CppType CppType> struct TIsIntegerCppType { enum { @@ -285,16 +285,16 @@ namespace NProtoBuf { CppType == FieldDescriptor::CPPTYPE_UINT32 || CppType == FieldDescriptor::CPPTYPE_UINT64 }; - }; - + }; + template <FieldDescriptor::CppType CppType> struct TIsFloatCppType { enum { Result = CppType == FieldDescriptor::CPPTYPE_FLOAT || CppType == FieldDescriptor::CPPTYPE_DOUBLE }; - }; - + }; + template <FieldDescriptor::CppType CppType> struct TIsNumericCppType { enum { @@ -302,19 +302,19 @@ namespace NProtoBuf { TIsIntegerCppType<CppType>::Result || TIsFloatCppType<CppType>::Result }; - }; - + }; + // a helper macro for splitting flow by cpp-type (e.g. in a switch) - + #define APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_INT32) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_INT64) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_UINT32) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_UINT64) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_DOUBLE) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_FLOAT) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_BOOL) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_ENUM) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_STRING) \ - TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_MESSAGE) + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_INT32) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_INT64) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_UINT32) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_UINT64) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_DOUBLE) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_FLOAT) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_BOOL) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_ENUM) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_STRING) \ + TMP_MACRO_FOR_CPPTYPE(NProtoBuf::FieldDescriptor::CPPTYPE_MESSAGE) } diff --git a/library/cpp/protobuf/util/ut/common_ut.proto b/library/cpp/protobuf/util/ut/common_ut.proto index 871b1b9832..9cf803ffbf 100644 --- a/library/cpp/protobuf/util/ut/common_ut.proto +++ b/library/cpp/protobuf/util/ut/common_ut.proto @@ -1,29 +1,29 @@ import "google/protobuf/descriptor.proto"; import "library/cpp/protobuf/util/proto/merge.proto"; - -package NProtobufUtilUt; - -extend google.protobuf.FieldOptions { - optional bool XXX = 53772; -} - -message TWalkTest { - optional uint32 OptInt = 1 [(XXX)=true]; - repeated uint32 RepInt = 2; - - optional string OptStr = 3; - repeated string RepStr = 4 [(XXX)=true]; - - optional TWalkTest OptSub = 5 [(XXX)=true]; - repeated TWalkTest RepSub = 6; -} - + +package NProtobufUtilUt; + +extend google.protobuf.FieldOptions { + optional bool XXX = 53772; +} + +message TWalkTest { + optional uint32 OptInt = 1 [(XXX)=true]; + repeated uint32 RepInt = 2; + + optional string OptStr = 3; + repeated string RepStr = 4 [(XXX)=true]; + + optional TWalkTest OptSub = 5 [(XXX)=true]; + repeated TWalkTest RepSub = 6; +} + message TWalkTestCyclic { optional TNested OptNested = 1; repeated uint64 OptInt64 = 2; optional TWalkTestCyclic OptSub = 3; optional TEnum OptEnum = 4; - + message TNested { optional uint32 OptInt32 = 1; optional TWalkTestCyclic OptSubNested = 2; @@ -37,27 +37,27 @@ message TWalkTestCyclic { } } -message TMergeTestNoMerge { - option (DontMerge) = true; - - optional uint32 A = 1; - repeated uint32 B = 2; -} - -message TMergeTestMerge { - optional uint32 A = 1; - repeated uint32 B = 2; - repeated uint32 C = 3 [(DontMergeField)=true]; -} - -message TMergeTest { - repeated uint32 MergeInt = 1; - repeated uint32 NoMergeInt = 2 [(DontMergeField)=true]; - - optional TMergeTestMerge MergeSub = 3; - repeated TMergeTestMerge NoMergeRepSub = 4 [(DontMergeField)=true]; - optional TMergeTestNoMerge NoMergeOptSub = 5; -} +message TMergeTestNoMerge { + option (DontMerge) = true; + + optional uint32 A = 1; + repeated uint32 B = 2; +} + +message TMergeTestMerge { + optional uint32 A = 1; + repeated uint32 B = 2; + repeated uint32 C = 3 [(DontMergeField)=true]; +} + +message TMergeTest { + repeated uint32 MergeInt = 1; + repeated uint32 NoMergeInt = 2 [(DontMergeField)=true]; + + optional TMergeTestMerge MergeSub = 3; + repeated TMergeTestMerge NoMergeRepSub = 4 [(DontMergeField)=true]; + optional TMergeTestNoMerge NoMergeOptSub = 5; +} message TTextTest { optional uint32 Foo = 1; diff --git a/library/cpp/protobuf/util/ut/sample_for_simple_reflection.proto b/library/cpp/protobuf/util/ut/sample_for_simple_reflection.proto index e9c5c569af..cca1dd869a 100644 --- a/library/cpp/protobuf/util/ut/sample_for_simple_reflection.proto +++ b/library/cpp/protobuf/util/ut/sample_for_simple_reflection.proto @@ -11,15 +11,15 @@ message TSample { repeated string RepStr = 4; optional string AnotherOneStr = 5; - optional int32 OneInt = 6; - repeated int32 RepInt = 7; - - enum EEnum { - V1 = 1; - V2 = 2; - } - optional EEnum OneEnum = 8; - repeated EEnum RepEnum = 9; - + optional int32 OneInt = 6; + repeated int32 RepInt = 7; + + enum EEnum { + V1 = 1; + V2 = 2; + } + optional EEnum OneEnum = 8; + repeated EEnum RepEnum = 9; + extensions 100 to 199; } diff --git a/library/cpp/protobuf/util/ut/ya.make b/library/cpp/protobuf/util/ut/ya.make index 182871179b..701ba9a8c8 100644 --- a/library/cpp/protobuf/util/ut/ya.make +++ b/library/cpp/protobuf/util/ut/ya.make @@ -6,14 +6,14 @@ SRCS( extensions.proto sample_for_is_equal.proto sample_for_simple_reflection.proto - common_ut.proto + common_ut.proto pb_io_ut.cpp is_equal_ut.cpp iterators_ut.cpp simple_reflection_ut.cpp repeated_field_utils_ut.cpp walk_ut.cpp - merge_ut.cpp + merge_ut.cpp ) END() diff --git a/library/cpp/protobuf/util/walk.h b/library/cpp/protobuf/util/walk.h index 944a80dc95..d15d76562d 100644 --- a/library/cpp/protobuf/util/walk.h +++ b/library/cpp/protobuf/util/walk.h @@ -1,13 +1,13 @@ -#pragma once - -#include "simple_reflection.h" - +#pragma once + +#include "simple_reflection.h" + #include <google/protobuf/message.h> #include <google/protobuf/descriptor.h> - + #include <functional> -namespace NProtoBuf { +namespace NProtoBuf { // Apply @onField processor to each field in @msg (even empty) // Do not walk deeper the field if the field is an empty message // Returned bool defines if we should walk down deeper to current node children (true), or not (false) diff --git a/library/cpp/protobuf/util/walk_ut.cpp b/library/cpp/protobuf/util/walk_ut.cpp index 0597867b32..2ea6071b17 100644 --- a/library/cpp/protobuf/util/walk_ut.cpp +++ b/library/cpp/protobuf/util/walk_ut.cpp @@ -1,56 +1,56 @@ -#include "walk.h" -#include "simple_reflection.h" +#include "walk.h" +#include "simple_reflection.h" #include <library/cpp/protobuf/util/ut/common_ut.pb.h> - + #include <library/cpp/testing/unittest/registar.h> - -using namespace NProtoBuf; - + +using namespace NProtoBuf; + Y_UNIT_TEST_SUITE(ProtobufWalk) { static void InitProto(NProtobufUtilUt::TWalkTest & p, int level = 0) { - p.SetOptInt(1); - p.AddRepInt(2); - p.AddRepInt(3); - - p.SetOptStr("123"); - p.AddRepStr("*"); - p.AddRepStr("abcdef"); - p.AddRepStr("1234"); - - if (level == 0) { - InitProto(*p.MutableOptSub(), 1); - InitProto(*p.AddRepSub(), 1); - InitProto(*p.AddRepSub(), 1); - } - } - + p.SetOptInt(1); + p.AddRepInt(2); + p.AddRepInt(3); + + p.SetOptStr("123"); + p.AddRepStr("*"); + p.AddRepStr("abcdef"); + p.AddRepStr("1234"); + + if (level == 0) { + InitProto(*p.MutableOptSub(), 1); + InitProto(*p.AddRepSub(), 1); + InitProto(*p.AddRepSub(), 1); + } + } + static bool IncreaseInts(Message & msg, const FieldDescriptor* fd) { - TMutableField f(msg, fd); - if (f.IsInstance<ui32>()) { - for (size_t i = 0; i < f.Size(); ++i) + TMutableField f(msg, fd); + if (f.IsInstance<ui32>()) { + for (size_t i = 0; i < f.Size(); ++i) f.Set(f.Get<ui64>(i) + 1, i); // ui64 should be ok! - } - return true; - } - + } + return true; + } + static bool RepeatString1(Message & msg, const FieldDescriptor* fd) { - TMutableField f(msg, fd); - if (f.IsString()) { - for (size_t i = 0; i < f.Size(); ++i) + TMutableField f(msg, fd); + if (f.IsString()) { + for (size_t i = 0; i < f.Size(); ++i) if (f.Get<TString>(i).StartsWith('1')) f.Set(f.Get<TString>(i) + f.Get<TString>(i), i); - } - return true; - } - + } + return true; + } + static bool ClearXXX(Message & msg, const FieldDescriptor* fd) { - const FieldOptions& opt = fd->options(); - if (opt.HasExtension(NProtobufUtilUt::XXX) && opt.GetExtension(NProtobufUtilUt::XXX)) - TMutableField(msg, fd).Clear(); - - return true; - } - + const FieldOptions& opt = fd->options(); + if (opt.HasExtension(NProtobufUtilUt::XXX) && opt.GetExtension(NProtobufUtilUt::XXX)) + TMutableField(msg, fd).Clear(); + + return true; + } + struct TestStruct { bool Ok = false; @@ -62,67 +62,67 @@ Y_UNIT_TEST_SUITE(ProtobufWalk) { }; Y_UNIT_TEST(TestWalkRefl) { - NProtobufUtilUt::TWalkTest p; - InitProto(p); - - { - UNIT_ASSERT_EQUAL(p.GetOptInt(), 1); - UNIT_ASSERT_EQUAL(p.RepIntSize(), 2); - UNIT_ASSERT_EQUAL(p.GetRepInt(0), 2); - UNIT_ASSERT_EQUAL(p.GetRepInt(1), 3); - - WalkReflection(p, IncreaseInts); - - UNIT_ASSERT_EQUAL(p.GetOptInt(), 2); - UNIT_ASSERT_EQUAL(p.RepIntSize(), 2); - UNIT_ASSERT_EQUAL(p.GetRepInt(0), 3); - UNIT_ASSERT_EQUAL(p.GetRepInt(1), 4); - - UNIT_ASSERT_EQUAL(p.GetOptSub().GetOptInt(), 2); - UNIT_ASSERT_EQUAL(p.GetOptSub().RepIntSize(), 2); - UNIT_ASSERT_EQUAL(p.GetOptSub().GetRepInt(0), 3); - UNIT_ASSERT_EQUAL(p.GetOptSub().GetRepInt(1), 4); - - UNIT_ASSERT_EQUAL(p.RepSubSize(), 2); - UNIT_ASSERT_EQUAL(p.GetRepSub(1).GetOptInt(), 2); - UNIT_ASSERT_EQUAL(p.GetRepSub(1).RepIntSize(), 2); - UNIT_ASSERT_EQUAL(p.GetRepSub(1).GetRepInt(0), 3); - UNIT_ASSERT_EQUAL(p.GetRepSub(1).GetRepInt(1), 4); - } - { - UNIT_ASSERT_EQUAL(p.GetOptStr(), "123"); - UNIT_ASSERT_EQUAL(p.GetRepStr(2), "1234"); - - WalkReflection(p, RepeatString1); - - UNIT_ASSERT_EQUAL(p.GetOptStr(), "123123"); - UNIT_ASSERT_EQUAL(p.RepStrSize(), 3); - UNIT_ASSERT_EQUAL(p.GetRepStr(0), "*"); - UNIT_ASSERT_EQUAL(p.GetRepStr(1), "abcdef"); - UNIT_ASSERT_EQUAL(p.GetRepStr(2), "12341234"); - - UNIT_ASSERT_EQUAL(p.RepSubSize(), 2); - UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetOptStr(), "123123"); - UNIT_ASSERT_EQUAL(p.GetRepSub(0).RepStrSize(), 3); - UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetRepStr(0), "*"); - UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetRepStr(1), "abcdef"); - UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetRepStr(2), "12341234"); - } - { - UNIT_ASSERT(p.HasOptInt()); - UNIT_ASSERT(p.RepStrSize() == 3); - UNIT_ASSERT(p.HasOptSub()); - - WalkReflection(p, ClearXXX); - - UNIT_ASSERT(!p.HasOptInt()); - UNIT_ASSERT(p.RepIntSize() == 2); - UNIT_ASSERT(p.HasOptStr()); - UNIT_ASSERT(p.RepStrSize() == 0); - UNIT_ASSERT(!p.HasOptSub()); - UNIT_ASSERT(p.RepSubSize() == 2); - } - } + NProtobufUtilUt::TWalkTest p; + InitProto(p); + + { + UNIT_ASSERT_EQUAL(p.GetOptInt(), 1); + UNIT_ASSERT_EQUAL(p.RepIntSize(), 2); + UNIT_ASSERT_EQUAL(p.GetRepInt(0), 2); + UNIT_ASSERT_EQUAL(p.GetRepInt(1), 3); + + WalkReflection(p, IncreaseInts); + + UNIT_ASSERT_EQUAL(p.GetOptInt(), 2); + UNIT_ASSERT_EQUAL(p.RepIntSize(), 2); + UNIT_ASSERT_EQUAL(p.GetRepInt(0), 3); + UNIT_ASSERT_EQUAL(p.GetRepInt(1), 4); + + UNIT_ASSERT_EQUAL(p.GetOptSub().GetOptInt(), 2); + UNIT_ASSERT_EQUAL(p.GetOptSub().RepIntSize(), 2); + UNIT_ASSERT_EQUAL(p.GetOptSub().GetRepInt(0), 3); + UNIT_ASSERT_EQUAL(p.GetOptSub().GetRepInt(1), 4); + + UNIT_ASSERT_EQUAL(p.RepSubSize(), 2); + UNIT_ASSERT_EQUAL(p.GetRepSub(1).GetOptInt(), 2); + UNIT_ASSERT_EQUAL(p.GetRepSub(1).RepIntSize(), 2); + UNIT_ASSERT_EQUAL(p.GetRepSub(1).GetRepInt(0), 3); + UNIT_ASSERT_EQUAL(p.GetRepSub(1).GetRepInt(1), 4); + } + { + UNIT_ASSERT_EQUAL(p.GetOptStr(), "123"); + UNIT_ASSERT_EQUAL(p.GetRepStr(2), "1234"); + + WalkReflection(p, RepeatString1); + + UNIT_ASSERT_EQUAL(p.GetOptStr(), "123123"); + UNIT_ASSERT_EQUAL(p.RepStrSize(), 3); + UNIT_ASSERT_EQUAL(p.GetRepStr(0), "*"); + UNIT_ASSERT_EQUAL(p.GetRepStr(1), "abcdef"); + UNIT_ASSERT_EQUAL(p.GetRepStr(2), "12341234"); + + UNIT_ASSERT_EQUAL(p.RepSubSize(), 2); + UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetOptStr(), "123123"); + UNIT_ASSERT_EQUAL(p.GetRepSub(0).RepStrSize(), 3); + UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetRepStr(0), "*"); + UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetRepStr(1), "abcdef"); + UNIT_ASSERT_EQUAL(p.GetRepSub(0).GetRepStr(2), "12341234"); + } + { + UNIT_ASSERT(p.HasOptInt()); + UNIT_ASSERT(p.RepStrSize() == 3); + UNIT_ASSERT(p.HasOptSub()); + + WalkReflection(p, ClearXXX); + + UNIT_ASSERT(!p.HasOptInt()); + UNIT_ASSERT(p.RepIntSize() == 2); + UNIT_ASSERT(p.HasOptStr()); + UNIT_ASSERT(p.RepStrSize() == 0); + UNIT_ASSERT(!p.HasOptSub()); + UNIT_ASSERT(p.RepSubSize() == 2); + } + } Y_UNIT_TEST(TestMutableCallable) { TestStruct testStruct; @@ -155,4 +155,4 @@ Y_UNIT_TEST_SUITE(ProtobufWalk) { UNIT_ASSERT_STRINGS_EQUAL(printedSchema, schema); } -} +} diff --git a/library/cpp/protobuf/util/ya.make b/library/cpp/protobuf/util/ya.make index 6908416823..b62028af58 100644 --- a/library/cpp/protobuf/util/ya.make +++ b/library/cpp/protobuf/util/ya.make @@ -1,7 +1,7 @@ LIBRARY() -OWNER(mowgli) - +OWNER(mowgli) + PEERDIR( contrib/libs/protobuf library/cpp/binsaver @@ -12,7 +12,7 @@ PEERDIR( SRCS( is_equal.cpp iterators.h - merge.cpp + merge.cpp path.cpp pb_io.cpp pb_utils.h |