diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/protobuf/util | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/protobuf/util')
21 files changed, 1203 insertions, 1203 deletions
diff --git a/library/cpp/protobuf/util/cast.h b/library/cpp/protobuf/util/cast.h index 83749dfcee..e99d4f200a 100644 --- a/library/cpp/protobuf/util/cast.h +++ b/library/cpp/protobuf/util/cast.h @@ -1,5 +1,5 @@ #pragma once - + #include "traits.h" #include <google/protobuf/descriptor.h> @@ -8,149 +8,149 @@ #include <util/generic/cast.h> namespace NProtoBuf { - // C++ compatible conversions of FieldDescriptor::CppType's - - using ECppType = FieldDescriptor::CppType; + // C++ compatible conversions of FieldDescriptor::CppType's - namespace NCast { - template <ECppType src, ECppType dst> - struct TIsCompatibleCppType { - enum { - Result = src == dst || - (TIsNumericCppType<src>::Result && TIsNumericCppType<dst>::Result) - }; - }; + using ECppType = FieldDescriptor::CppType; - template <ECppType src, ECppType dst> - struct TIsEnumToNumericCppType { - enum { - Result = (src == FieldDescriptor::CPPTYPE_ENUM && TIsNumericCppType<dst>::Result) - }; + namespace NCast { + template <ECppType src, ECppType dst> + struct TIsCompatibleCppType { + enum { + Result = src == dst || + (TIsNumericCppType<src>::Result && 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> + struct TIsEnumToNumericCppType { + enum { + Result = (src == FieldDescriptor::CPPTYPE_ENUM && TIsNumericCppType<dst>::Result) + }; }; - 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); - return true; - } - return false; - } - }; - - } - + 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); + return true; + } + return false; + } + }; + + } + template <ECppType src, ECppType dst> - inline typename TCppTypeTraits<dst>::T CompatCast(typename TCppTypeTraits<src>::T value) { - return NCast::TCompatCast<src, dst>::Cast(value); - } + inline typename TCppTypeTraits<dst>::T CompatCast(typename TCppTypeTraits<src>::T value) { + return NCast::TCompatCast<src, dst>::Cast(value); + } 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); - } + 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 227408006e..f9711c9565 100644 --- a/library/cpp/protobuf/util/is_equal.cpp +++ b/library/cpp/protobuf/util/is_equal.cpp @@ -8,156 +8,156 @@ #include <util/string/vector.h> 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 { - typedef typename TCppTypeTraits<CppType>::T T; - static inline bool IsEqual(T value1, T value2, TVector<TString>*) { - return value1 == value2; - } - }; - - template <bool useDefault> - struct TCompareValue<FieldDescriptor::CPPTYPE_MESSAGE, useDefault> { - static inline bool IsEqual(const Message* value1, const Message* value2, TVector<TString>* differentPath) { - 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()) - return IsEqualRepeated(m1, m2, &field, differentPath); - 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; - } - } else if (!has1) - return true; - - return TCompare::IsEqual(TTraits::Get(m1, field), - TTraits::Get(m2, field), - differentPath); - } - - 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)) + template <bool useDefault> + static bool IsEqualImpl(const Message& m1, const Message& m2, TVector<TString>* differentPath); + + namespace { + template <FieldDescriptor::CppType CppType, bool useDefault> + struct TCompareValue { + typedef typename TCppTypeTraits<CppType>::T T; + static inline bool IsEqual(T value1, T value2, TVector<TString>*) { + return value1 == value2; + } + }; + + template <bool useDefault> + struct TCompareValue<FieldDescriptor::CPPTYPE_MESSAGE, useDefault> { + static inline bool IsEqual(const Message* value1, const Message* value2, TVector<TString>* differentPath) { + 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()) + return IsEqualRepeated(m1, m2, &field, differentPath); + 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; + } + } else if (!has1) + return true; + + return TCompare::IsEqual(TTraits::Get(m1, field), + TTraits::Get(m2, field), + differentPath); + } + + 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; - for (int i = 0; i < fieldSize; ++i) - if (!IsEqualRepeatedValue(m1, m2, field, i, differentPath)) { - if (!!differentPath) { - differentPath->push_back(ToString(i)); - } - return false; - } + for (int i = 0; i < fieldSize; ++i) + if (!IsEqualRepeatedValue(m1, m2, field, i, differentPath)) { + if (!!differentPath) { + differentPath->push_back(ToString(i)); + } + return false; + } 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) \ - case FieldDescriptor::CPPTYPE_##cpptype: { \ - bool r = TCompareField<FieldDescriptor::CPPTYPE_##cpptype, useDefault>::IsEqual(m1, m2, field, differentPath); \ - if (!r && !!differentPath) { \ - differentPath->push_back(field.name()); \ - } \ - return r; \ - } - - switch (field.cpp_type()) { - CASE_CPPTYPE(INT32) - CASE_CPPTYPE(INT64) - CASE_CPPTYPE(UINT32) - CASE_CPPTYPE(UINT64) - CASE_CPPTYPE(DOUBLE) - CASE_CPPTYPE(FLOAT) - CASE_CPPTYPE(BOOL) - CASE_CPPTYPE(ENUM) - CASE_CPPTYPE(STRING) - CASE_CPPTYPE(MESSAGE) - default: - ythrow yexception() << "Unsupported cpp-type field comparison"; - } - -#undef CASE_CPPTYPE + } + + 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) \ + case FieldDescriptor::CPPTYPE_##cpptype: { \ + bool r = TCompareField<FieldDescriptor::CPPTYPE_##cpptype, useDefault>::IsEqual(m1, m2, field, differentPath); \ + if (!r && !!differentPath) { \ + differentPath->push_back(field.name()); \ + } \ + return r; \ + } + + switch (field.cpp_type()) { + CASE_CPPTYPE(INT32) + CASE_CPPTYPE(INT64) + CASE_CPPTYPE(UINT32) + CASE_CPPTYPE(UINT64) + CASE_CPPTYPE(DOUBLE) + CASE_CPPTYPE(FLOAT) + CASE_CPPTYPE(BOOL) + CASE_CPPTYPE(ENUM) + CASE_CPPTYPE(STRING) + CASE_CPPTYPE(MESSAGE) + default: + ythrow yexception() << "Unsupported cpp-type field comparison"; + } + +#undef CASE_CPPTYPE } - } + } template <bool useDefault> - bool IsEqualImpl(const Message& m1, const Message& m2, TVector<TString>* differentPath) { - const Descriptor* descr = m1.GetDescriptor(); - if (descr != m2.GetDescriptor()) { - return false; + bool IsEqualImpl(const Message& m1, const Message& m2, TVector<TString>* differentPath) { + const Descriptor* descr = m1.GetDescriptor(); + if (descr != m2.GetDescriptor()) { + return false; } - for (int i = 0; i < descr->field_count(); ++i) - if (!IsEqualField<useDefault>(m1, m2, *descr->field(i), differentPath)) { - return false; - } - return true; - } - - bool IsEqual(const Message& m1, const Message& m2) { - return IsEqualImpl<false>(m1, m2, nullptr); - } - - bool IsEqual(const Message& m1, const Message& m2, TString* differentPath) { - TVector<TString> differentPathVector; - TVector<TString>* differentPathVectorPtr = !!differentPath ? &differentPathVector : nullptr; - bool r = IsEqualImpl<false>(m1, m2, differentPathVectorPtr); - if (!r && differentPath) { - *differentPath = JoinStrings(differentPathVector.rbegin(), differentPathVector.rend(), "/"); + for (int i = 0; i < descr->field_count(); ++i) + if (!IsEqualField<useDefault>(m1, m2, *descr->field(i), differentPath)) { + return false; + } + return true; + } + + bool IsEqual(const Message& m1, const Message& m2) { + return IsEqualImpl<false>(m1, m2, nullptr); + } + + bool IsEqual(const Message& m1, const Message& m2, TString* differentPath) { + TVector<TString> differentPathVector; + TVector<TString>* differentPathVectorPtr = !!differentPath ? &differentPathVector : nullptr; + bool r = IsEqualImpl<false>(m1, m2, differentPathVectorPtr); + if (!r && differentPath) { + *differentPath = JoinStrings(differentPathVector.rbegin(), differentPathVector.rend(), "/"); } - return r; - } + return r; + } - bool IsEqualDefault(const Message& m1, const Message& m2) { - return IsEqualImpl<true>(m1, m2, nullptr); + bool IsEqualDefault(const Message& m1, const Message& m2) { + return IsEqualImpl<true>(m1, m2, nullptr); } - template <bool useDefault> - static bool IsEqualFieldImpl( - const Message& m1, - const Message& m2, - const FieldDescriptor& field, - TVector<TString>* differentPath) { - const Descriptor* descr = m1.GetDescriptor(); - if (descr != m2.GetDescriptor()) { + template <bool useDefault> + static bool IsEqualFieldImpl( + const Message& m1, + const Message& m2, + const FieldDescriptor& field, + TVector<TString>* differentPath) { + const Descriptor* descr = m1.GetDescriptor(); + if (descr != m2.GetDescriptor()) { return false; } - return IsEqualField<useDefault>(m1, m2, field, differentPath); - } + 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); + bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field) { + return IsEqualFieldImpl<false>(m1, m2, field, nullptr); } - bool IsEqualFieldDefault(const Message& m1, const Message& m2, const FieldDescriptor& field) { - return IsEqualFieldImpl<true>(m1, m2, field, nullptr); + bool IsEqualFieldDefault(const Message& m1, const Message& m2, const FieldDescriptor& field) { + return IsEqualFieldImpl<true>(m1, m2, field, nullptr); } } diff --git a/library/cpp/protobuf/util/is_equal.h b/library/cpp/protobuf/util/is_equal.h index 13c0aae63d..46d38591ae 100644 --- a/library/cpp/protobuf/util/is_equal.h +++ b/library/cpp/protobuf/util/is_equal.h @@ -10,24 +10,24 @@ namespace google { } namespace NProtoBuf { - using ::google::protobuf::FieldDescriptor; + using ::google::protobuf::FieldDescriptor; using ::google::protobuf::Message; } namespace NProtoBuf { - // Reflection-based equality check for arbitrary protobuf messages + // Reflection-based equality check for arbitrary protobuf messages - // Strict comparison: optional field without value is NOT equal to - // 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); + // Strict comparison: optional field without value is NOT equal to + // 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); + bool IsEqualField(const Message& m1, const Message& m2, const FieldDescriptor& field); - // Non-strict version: optional field without explicit value is compared - // using its default value. - bool IsEqualDefault(const Message& m1, const Message& m2); + // Non-strict version: optional field without explicit value is compared + // using its default value. + bool IsEqualDefault(const Message& m1, const Message& m2); - bool IsEqualFieldDefault(const Message& m1, const Message& m2, const FieldDescriptor& field); + bool IsEqualFieldDefault(const Message& m1, const Message& m2, const FieldDescriptor& field); } diff --git a/library/cpp/protobuf/util/merge.cpp b/library/cpp/protobuf/util/merge.cpp index dc2b9cc806..258cbb737f 100644 --- a/library/cpp/protobuf/util/merge.cpp +++ b/library/cpp/protobuf/util/merge.cpp @@ -6,41 +6,41 @@ #include <library/cpp/protobuf/util/proto/merge.pb.h> namespace NProtoBuf { - void RewriteMerge(const Message& src, Message& dst) { - const Descriptor* d = src.GetDescriptor(); - Y_ASSERT(d == dst.GetDescriptor()); + 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(); - } + 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); + 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); - if (srcField.Has()) { - TMutableField dstField(dst, fd); - if (fd->options().GetExtension(DontMergeField)) - dstField.Clear(); - else if (!fd->is_repeated() && dstField.IsMessage() && dstField.Has()) - ClearNonMergeable(*srcField.Get<const Message*>(), *dstField.MutableMessage()); - } - } + 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); + if (srcField.Has()) { + TMutableField dstField(dst, fd); + if (fd->options().GetExtension(DontMergeField)) + dstField.Clear(); + else if (!fd->is_repeated() && dstField.IsMessage() && dstField.Has()) + ClearNonMergeable(*srcField.Get<const Message*>(), *dstField.MutableMessage()); + } + } } - void CustomMerge(const Message& src, Message& dst) { - ClearNonMergeable(src, dst); - dst.MergeFrom(src); + 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 924975f141..b354331788 100644 --- a/library/cpp/protobuf/util/merge.h +++ b/library/cpp/protobuf/util/merge.h @@ -11,12 +11,12 @@ 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); + // 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); + // 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 22217db183..84b40c24b8 100644 --- a/library/cpp/protobuf/util/merge_ut.cpp +++ b/library/cpp/protobuf/util/merge_ut.cpp @@ -6,7 +6,7 @@ using namespace NProtoBuf; Y_UNIT_TEST_SUITE(ProtobufMerge) { - static void InitProto(NProtobufUtilUt::TMergeTest & p, bool isSrc) { + static void InitProto(NProtobufUtilUt::TMergeTest & p, bool isSrc) { size_t start = isSrc ? 0 : 100; p.AddMergeInt(start + 1); @@ -40,10 +40,10 @@ Y_UNIT_TEST_SUITE(ProtobufMerge) { InitProto(src, true); InitProto(dst, false); - // Cerr << "\nsrc: " << src.ShortDebugString() << Endl; - // Cerr << "dst: " << dst.ShortDebugString() << Endl; + // Cerr << "\nsrc: " << src.ShortDebugString() << Endl; + // Cerr << "dst: " << dst.ShortDebugString() << Endl; NProtoBuf::CustomMerge(src, dst); - // Cerr << "dst2:" << dst.ShortDebugString() << Endl; + // Cerr << "dst2:" << dst.ShortDebugString() << Endl; // repeated uint32 MergeInt = 1; UNIT_ASSERT_EQUAL(dst.MergeIntSize(), 4); diff --git a/library/cpp/protobuf/util/path.cpp b/library/cpp/protobuf/util/path.cpp index efa2a42c8a..aeb9b52b71 100644 --- a/library/cpp/protobuf/util/path.cpp +++ b/library/cpp/protobuf/util/path.cpp @@ -3,59 +3,59 @@ #include <util/generic/yexception.h> namespace NProtoBuf { - TFieldPath::TFieldPath() { - } - - TFieldPath::TFieldPath(const Descriptor* msgType, const TStringBuf& path) { - Init(msgType, path); - } - - TFieldPath::TFieldPath(const TVector<const FieldDescriptor*>& path) - : Path(path) - { - } - - bool TFieldPath::InitUnsafe(const Descriptor* msgType, TStringBuf path) { - Path.clear(); - while (path) { - TStringBuf next; - while (!next && path) - next = path.NextTok('/'); - if (!next) - return true; - - if (!msgType) // need field but no message type - return false; - - TString nextStr(next); - const FieldDescriptor* field = msgType->FindFieldByName(nextStr); - if (!field) { - // Try to find extension field by FindAllExtensions() - const DescriptorPool* pool = msgType->file()->pool(); - Y_ASSERT(pool); // never NULL by protobuf docs - TVector<const FieldDescriptor*> extensions; - pool->FindAllExtensions(msgType, &extensions); // find all extensions of this extendee - for (const FieldDescriptor* ext : extensions) { - if (ext->full_name() == nextStr || ext->name() == nextStr) { - if (field) - return false; // ambiguity - field = ext; - } + TFieldPath::TFieldPath() { + } + + TFieldPath::TFieldPath(const Descriptor* msgType, const TStringBuf& path) { + Init(msgType, path); + } + + TFieldPath::TFieldPath(const TVector<const FieldDescriptor*>& path) + : Path(path) + { + } + + bool TFieldPath::InitUnsafe(const Descriptor* msgType, TStringBuf path) { + Path.clear(); + while (path) { + TStringBuf next; + while (!next && path) + next = path.NextTok('/'); + if (!next) + return true; + + if (!msgType) // need field but no message type + return false; + + TString nextStr(next); + const FieldDescriptor* field = msgType->FindFieldByName(nextStr); + if (!field) { + // Try to find extension field by FindAllExtensions() + const DescriptorPool* pool = msgType->file()->pool(); + Y_ASSERT(pool); // never NULL by protobuf docs + TVector<const FieldDescriptor*> extensions; + pool->FindAllExtensions(msgType, &extensions); // find all extensions of this extendee + for (const FieldDescriptor* ext : extensions) { + if (ext->full_name() == nextStr || ext->name() == nextStr) { + if (field) + return false; // ambiguity + field = ext; + } } } - if (!field) - return false; - - Path.push_back(field); - msgType = field->type() == FieldDescriptor::TYPE_MESSAGE ? field->message_type() : nullptr; - } - return true; - } + if (!field) + return false; - void TFieldPath::Init(const Descriptor* msgType, const TStringBuf& path) { - if (!InitUnsafe(msgType, path)) - ythrow yexception() << "Failed to resolve path \"" << path << "\" relative to " << msgType->full_name(); + Path.push_back(field); + msgType = field->type() == FieldDescriptor::TYPE_MESSAGE ? field->message_type() : nullptr; + } + return true; } + void TFieldPath::Init(const Descriptor* msgType, const TStringBuf& path) { + if (!InitUnsafe(msgType, path)) + ythrow yexception() << "Failed to resolve path \"" << path << "\" relative to " << msgType->full_name(); + } + } diff --git a/library/cpp/protobuf/util/path.h b/library/cpp/protobuf/util/path.h index 487f643a2d..99cf198415 100644 --- a/library/cpp/protobuf/util/path.h +++ b/library/cpp/protobuf/util/path.h @@ -6,47 +6,47 @@ #include <util/generic/vector.h> namespace NProtoBuf { - class TFieldPath { - public: - TFieldPath(); - TFieldPath(const Descriptor* msgType, const TStringBuf& path); // throws exception if path doesn't exist - TFieldPath(const TVector<const FieldDescriptor*>& path); + class TFieldPath { + public: + TFieldPath(); + TFieldPath(const Descriptor* msgType, const TStringBuf& path); // throws exception if path doesn't exist + TFieldPath(const TVector<const FieldDescriptor*>& path); TFieldPath(const TFieldPath&) = default; TFieldPath& operator=(const TFieldPath&) = default; - bool InitUnsafe(const Descriptor* msgType, const TStringBuf path); // noexcept - void Init(const Descriptor* msgType, const TStringBuf& path); // throws + bool InitUnsafe(const Descriptor* msgType, const TStringBuf path); // noexcept + void Init(const Descriptor* msgType, const TStringBuf& path); // throws - const TVector<const FieldDescriptor*>& Fields() const { - return Path; - } + const TVector<const FieldDescriptor*>& Fields() const { + return Path; + } - void AddField(const FieldDescriptor* field) { - Path.push_back(field); - } + void AddField(const FieldDescriptor* field) { + Path.push_back(field); + } - const Descriptor* ParentType() const { - return Empty() ? nullptr : Path.front()->containing_type(); - } + const Descriptor* ParentType() const { + return Empty() ? nullptr : Path.front()->containing_type(); + } - const FieldDescriptor* FieldDescr() const { - return Empty() ? nullptr : Path.back(); - } + const FieldDescriptor* FieldDescr() const { + return Empty() ? nullptr : Path.back(); + } - bool Empty() const { - return Path.empty(); - } + bool Empty() const { + return Path.empty(); + } - explicit operator bool() const { - return !Empty(); - } + explicit operator bool() const { + return !Empty(); + } - bool operator!() const { - return Empty(); - } + bool operator!() const { + return Empty(); + } - private: - TVector<const FieldDescriptor*> Path; - }; + private: + TVector<const FieldDescriptor*> Path; + }; -} +} diff --git a/library/cpp/protobuf/util/pb_io.cpp b/library/cpp/protobuf/util/pb_io.cpp index 6270ee0624..f26b5322c9 100644 --- a/library/cpp/protobuf/util/pb_io.cpp +++ b/library/cpp/protobuf/util/pb_io.cpp @@ -23,50 +23,50 @@ namespace NProtoBuf { void ParseFromBase64String(const TStringBuf dataBase64, Message& m, bool allowUneven) { if (!m.ParseFromString(allowUneven ? Base64DecodeUneven(dataBase64) : Base64StrictDecode(dataBase64))) { - ythrow yexception() << "can't parse " << m.GetTypeName() << " from base64-encoded string"; - } - } + ythrow yexception() << "can't parse " << m.GetTypeName() << " from base64-encoded string"; + } + } bool TryParseFromBase64String(const TStringBuf dataBase64, Message& m, bool allowUneven) { - try { + try { ParseFromBase64String(dataBase64, m, allowUneven); - return true; - } catch (const std::exception&) { - return false; - } + return true; + } catch (const std::exception&) { + return false; + } } - void SerializeToBase64String(const Message& m, TString& dataBase64) { - TString rawData; - if (!m.SerializeToString(&rawData)) { - ythrow yexception() << "can't serialize " << m.GetTypeName(); - } - - Base64EncodeUrl(rawData, dataBase64); + void SerializeToBase64String(const Message& m, TString& dataBase64) { + TString rawData; + if (!m.SerializeToString(&rawData)) { + ythrow yexception() << "can't serialize " << m.GetTypeName(); + } + + Base64EncodeUrl(rawData, dataBase64); } - - TString SerializeToBase64String(const Message& m) { - TString s; - SerializeToBase64String(m, s); - return s; + + TString SerializeToBase64String(const Message& m) { + TString s; + SerializeToBase64String(m, s); + return s; } - bool TrySerializeToBase64String(const Message& m, TString& dataBase64) { - try { - SerializeToBase64String(m, dataBase64); - return true; - } catch (const std::exception&) { - return false; - } + bool TrySerializeToBase64String(const Message& m, TString& dataBase64) { + try { + SerializeToBase64String(m, dataBase64); + return true; + } catch (const std::exception&) { + return false; + } } - const TString ShortUtf8DebugString(const Message& message) { - TextFormat::Printer printer; - printer.SetSingleLineMode(true); - printer.SetUseUtf8StringEscaping(true); - TString result; - printer.PrintToString(message, &result); - return result; + const TString ShortUtf8DebugString(const Message& message) { + TextFormat::Printer printer; + printer.SetSingleLineMode(true); + printer.SetUseUtf8StringEscaping(true); + TString result; + printer.PrintToString(message, &result); + return result; } bool MergePartialFromString(NProtoBuf::Message& m, const TStringBuf serializedProtoMessage) { @@ -81,7 +81,7 @@ namespace NProtoBuf { } } -int operator&(NProtoBuf::Message& m, IBinSaver& f) { +int operator&(NProtoBuf::Message& m, IBinSaver& f) { TStringStream ss; if (f.IsReading()) { f.Add(0, &ss.Str()); diff --git a/library/cpp/protobuf/util/pb_io.h b/library/cpp/protobuf/util/pb_io.h index 493c84cb5f..261adf2b0e 100644 --- a/library/cpp/protobuf/util/pb_io.h +++ b/library/cpp/protobuf/util/pb_io.h @@ -40,9 +40,9 @@ namespace NProtoBuf { bool MergePartialFromString(NProtoBuf::Message& m, const TStringBuf serializedProtoMessage); bool MergeFromString(NProtoBuf::Message& m, const TStringBuf serializedProtoMessage); -} +} -int operator&(NProtoBuf::Message& m, IBinSaver& f); +int operator&(NProtoBuf::Message& m, IBinSaver& f); // Write a textual representation of the given message to the given file. void SerializeToTextFormat(const NProtoBuf::Message& m, const TString& fileName); diff --git a/library/cpp/protobuf/util/pb_io_ut.cpp b/library/cpp/protobuf/util/pb_io_ut.cpp index 875d6dc602..b81274b5ec 100644 --- a/library/cpp/protobuf/util/pb_io_ut.cpp +++ b/library/cpp/protobuf/util/pb_io_ut.cpp @@ -24,7 +24,7 @@ static NProtobufUtilUt::TTextEnumTest GetCorrectEnumMessage() { } static const TString CORRECT_MESSAGE = - R"(Foo: 42 + R"(Foo: 42 )"; static const TString CORRECT_ENUM_NAME_MESSAGE = R"(Slot: EET_SLOT_1 @@ -34,7 +34,7 @@ static const TString CORRECT_ENUM_ID_MESSAGE = )"; static const TString INCORRECT_MESSAGE = - R"(Bar: 1 + R"(Bar: 1 )"; static const TString INCORRECT_ENUM_NAME_MESSAGE = R"(Slot: EET_SLOT_3 @@ -177,8 +177,8 @@ Y_UNIT_TEST_SUITE(TTestProtoBufIO) { NProtobufUtilUt::TTextTest m; const auto f = [&correctFileName](NProtobufUtilUt::TTextTest& mm) { mm = ParseFromTextFormat<NProtobufUtilUt::TTextTest>( - correctFileName, - EParseFromTextFormatOption::AllowUnknownField); + correctFileName, + EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); @@ -188,8 +188,8 @@ Y_UNIT_TEST_SUITE(TTestProtoBufIO) { NProtobufUtilUt::TTextTest m; const auto f = [&incorrectFileName](NProtobufUtilUt::TTextTest& mm) { mm = ParseFromTextFormat<NProtobufUtilUt::TTextTest>( - incorrectFileName, - EParseFromTextFormatOption::AllowUnknownField); + incorrectFileName, + EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(empty, m)); @@ -354,8 +354,8 @@ Y_UNIT_TEST_SUITE(TTestProtoBufIO) { NProtobufUtilUt::TTextTest m; const auto f = [&correctFileName](NProtobufUtilUt::TTextTest& mm) { mm = MergeFromTextFormat<NProtobufUtilUt::TTextTest>( - correctFileName, - EParseFromTextFormatOption::AllowUnknownField); + correctFileName, + EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(GetCorrectMessage(), m)); @@ -365,8 +365,8 @@ Y_UNIT_TEST_SUITE(TTestProtoBufIO) { NProtobufUtilUt::TTextTest m; const auto f = [&incorrectFileName](NProtobufUtilUt::TTextTest& mm) { mm = MergeFromTextFormat<NProtobufUtilUt::TTextTest>( - incorrectFileName, - EParseFromTextFormatOption::AllowUnknownField); + incorrectFileName, + EParseFromTextFormatOption::AllowUnknownField); }; UNIT_ASSERT_NO_EXCEPTION(f(m)); UNIT_ASSERT(NProtoBuf::IsEqual(empty, m)); diff --git a/library/cpp/protobuf/util/pb_utils.h b/library/cpp/protobuf/util/pb_utils.h index 9e9a110b48..71a76ff4c2 100644 --- a/library/cpp/protobuf/util/pb_utils.h +++ b/library/cpp/protobuf/util/pb_utils.h @@ -1,11 +1,11 @@ #pragma once #define UPDATE_PB_FIELD_MAX(PBMESS, FIELD, VAL) \ - if ((VAL) > (PBMESS).Get##FIELD()) { \ - (PBMESS).Set##FIELD(VAL); \ - } + if ((VAL) > (PBMESS).Get##FIELD()) { \ + (PBMESS).Set##FIELD(VAL); \ + } -#define UPDATE_OPT_PB_FIELD_MAX(PBMESS, FIELD, VAL) \ - if (!(PBMESS).Has##FIELD() || ((VAL) > (PBMESS).Get##FIELD())) { \ - (PBMESS).Set##FIELD(VAL); \ - } +#define UPDATE_OPT_PB_FIELD_MAX(PBMESS, FIELD, VAL) \ + if (!(PBMESS).Has##FIELD() || ((VAL) > (PBMESS).Get##FIELD())) { \ + (PBMESS).Set##FIELD(VAL); \ + } diff --git a/library/cpp/protobuf/util/repeated_field_utils.h b/library/cpp/protobuf/util/repeated_field_utils.h index c07bd84647..74767eaafe 100644 --- a/library/cpp/protobuf/util/repeated_field_utils.h +++ b/library/cpp/protobuf/util/repeated_field_utils.h @@ -6,8 +6,8 @@ template <typename T> void RemoveRepeatedPtrFieldElement(google::protobuf::RepeatedPtrField<T>* repeated, unsigned index) { google::protobuf::RepeatedPtrField<T> r; - Y_ASSERT(index < (unsigned)repeated->size()); - for (unsigned i = 0; i < (unsigned)repeated->size(); ++i) { + Y_ASSERT(index < (unsigned)repeated->size()); + for (unsigned i = 0; i < (unsigned)repeated->size(); ++i) { if (i == index) { continue; } @@ -17,80 +17,80 @@ void RemoveRepeatedPtrFieldElement(google::protobuf::RepeatedPtrField<T>* repeat } namespace NProtoBuf { - /// Move item to specified position - template <typename TRepeated> - static void MoveRepeatedFieldItem(TRepeated* field, size_t indexFrom, size_t indexTo) { - if (!field->size() || indexFrom >= static_cast<size_t>(field->size()) || indexFrom == indexTo) - return; - if (indexTo >= static_cast<size_t>(field->size())) - indexTo = field->size() - 1; - if (indexFrom > indexTo) { - for (size_t i = indexFrom; i > indexTo; --i) - field->SwapElements(i, i - 1); - } else { - for (size_t i = indexFrom; i < indexTo; ++i) - field->SwapElements(i, i + 1); - } - } + /// Move item to specified position + template <typename TRepeated> + static void MoveRepeatedFieldItem(TRepeated* field, size_t indexFrom, size_t indexTo) { + if (!field->size() || indexFrom >= static_cast<size_t>(field->size()) || indexFrom == indexTo) + return; + if (indexTo >= static_cast<size_t>(field->size())) + indexTo = field->size() - 1; + if (indexFrom > indexTo) { + for (size_t i = indexFrom; i > indexTo; --i) + field->SwapElements(i, i - 1); + } else { + for (size_t i = indexFrom; i < indexTo; ++i) + field->SwapElements(i, i + 1); + } + } - template <typename T> - static T* InsertRepeatedFieldItem(NProtoBuf::RepeatedPtrField<T>* field, size_t index) { - T* ret = field->Add(); - MoveRepeatedFieldItem(field, field->size() - 1, index); - return ret; + template <typename T> + static T* InsertRepeatedFieldItem(NProtoBuf::RepeatedPtrField<T>* field, size_t index) { + T* ret = field->Add(); + MoveRepeatedFieldItem(field, field->size() - 1, index); + return ret; } - template <typename TRepeated> // suitable both for RepeatedField and RepeatedPtrField - static void RemoveRepeatedFieldItem(TRepeated* field, size_t index) { - if ((int)index >= field->size()) - return; + template <typename TRepeated> // suitable both for RepeatedField and RepeatedPtrField + 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); + for (int i = index + 1; i < field->size(); ++i) + field->SwapElements(i - 1, i); - field->RemoveLast(); - } + 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); - if (last != repeated->end()) { - size_t countToRemove = repeated->end() - last; - while (countToRemove--) - repeated->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); + if (last != repeated->end()) { + size_t countToRemove = repeated->end() - last; + while (countToRemove--) + repeated->RemoveLast(); + } + } - namespace NImpl { - template <typename TRepeated> - static void ShiftLeft(TRepeated* field, int begIndex, int endIndex, size_t shiftSize) { - Y_ASSERT(begIndex <= field->size()); - Y_ASSERT(endIndex <= field->size()); - size_t shiftIndex = (int)shiftSize < begIndex ? begIndex - shiftSize : 0; - for (int i = begIndex; i < endIndex; ++i, ++shiftIndex) - field->SwapElements(shiftIndex, i); - } + namespace NImpl { + template <typename TRepeated> + static void ShiftLeft(TRepeated* field, int begIndex, int endIndex, size_t shiftSize) { + Y_ASSERT(begIndex <= field->size()); + Y_ASSERT(endIndex <= field->size()); + size_t shiftIndex = (int)shiftSize < begIndex ? begIndex - shiftSize : 0; + for (int i = begIndex; i < endIndex; ++i, ++shiftIndex) + field->SwapElements(shiftIndex, i); + } } - // Remove several items at once, could be more efficient compared to calling RemoveRepeatedFieldItem several times + // Remove several items at once, could be more efficient compared to calling RemoveRepeatedFieldItem several times template <typename TRepeated> - static void RemoveRepeatedFieldItems(TRepeated* field, const TVector<size_t>& sortedIndices) { - if (sortedIndices.empty()) - return; + 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); + 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(); - } + 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); - } + 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.cpp b/library/cpp/protobuf/util/simple_reflection.cpp index d842e9ee44..913a011028 100644 --- a/library/cpp/protobuf/util/simple_reflection.cpp +++ b/library/cpp/protobuf/util/simple_reflection.cpp @@ -1,70 +1,70 @@ #include "simple_reflection.h" namespace NProtoBuf { - const Message* GetMessageHelper(const TConstField& curField, bool) { - return curField.HasValue() && curField.IsMessage() ? curField.Get<Message>() : nullptr; - } + const Message* GetMessageHelper(const TConstField& curField, bool) { + return curField.HasValue() && curField.IsMessage() ? curField.Get<Message>() : nullptr; + } - Message* GetMessageHelper(TMutableField& curField, bool createPath) { - if (curField.IsMessage()) { - if (!curField.HasValue()) { - if (createPath) - return curField.Field()->is_repeated() ? curField.AddMessage() : curField.MutableMessage(); - } else { - return curField.MutableMessage(); - } + Message* GetMessageHelper(TMutableField& curField, bool createPath) { + if (curField.IsMessage()) { + if (!curField.HasValue()) { + if (createPath) + return curField.Field()->is_repeated() ? curField.AddMessage() : curField.MutableMessage(); + } else { + return curField.MutableMessage(); + } } - return nullptr; + return nullptr; } - template <class TField, class TMsg> - TMaybe<TField> ByPathImpl(TMsg& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath) { - if (fieldsPath.empty()) - return TMaybe<TField>(); - TMsg* curParent = &msg; - for (size_t i = 0, size = fieldsPath.size(); i < size; ++i) { - const FieldDescriptor* field = fieldsPath[i]; - if (!curParent) - return TMaybe<TField>(); - TField curField(*curParent, field); - if (size - i == 1) // last element in path - return curField; - curParent = GetMessageHelper(curField, createPath); - } - if (curParent) - return TField(*curParent, fieldsPath.back()); - else + template <class TField, class TMsg> + TMaybe<TField> ByPathImpl(TMsg& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath) { + if (fieldsPath.empty()) return TMaybe<TField>(); + TMsg* curParent = &msg; + for (size_t i = 0, size = fieldsPath.size(); i < size; ++i) { + const FieldDescriptor* field = fieldsPath[i]; + if (!curParent) + return TMaybe<TField>(); + TField curField(*curParent, field); + if (size - i == 1) // last element in path + return curField; + curParent = GetMessageHelper(curField, createPath); + } + if (curParent) + return TField(*curParent, fieldsPath.back()); + else + return TMaybe<TField>(); } - TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TVector<const FieldDescriptor*>& fieldsPath) { - return ByPathImpl<TConstField, const Message>(msg, fieldsPath, false); - } - - TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TStringBuf& path) { - TFieldPath fieldPath; - if (!fieldPath.InitUnsafe(msg.GetDescriptor(), path)) - return TMaybe<TConstField>(); - return ByPathImpl<TConstField, const Message>(msg, fieldPath.Fields(), false); - } + TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TVector<const FieldDescriptor*>& fieldsPath) { + return ByPathImpl<TConstField, const Message>(msg, fieldsPath, false); + } - TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TFieldPath& path) { - return ByPathImpl<TConstField, const Message>(msg, path.Fields(), false); - } + TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TStringBuf& path) { + TFieldPath fieldPath; + if (!fieldPath.InitUnsafe(msg.GetDescriptor(), path)) + return TMaybe<TConstField>(); + return ByPathImpl<TConstField, const Message>(msg, fieldPath.Fields(), false); + } - TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath) { - return ByPathImpl<TMutableField, Message>(msg, fieldsPath, createPath); - } + TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TFieldPath& path) { + return ByPathImpl<TConstField, const Message>(msg, path.Fields(), false); + } - TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TStringBuf& path, bool createPath) { - TFieldPath fieldPath; - if (!fieldPath.InitUnsafe(msg.GetDescriptor(), path)) - return TMaybe<TMutableField>(); - return ByPathImpl<TMutableField, Message>(msg, fieldPath.Fields(), createPath); - } + TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath) { + return ByPathImpl<TMutableField, Message>(msg, fieldsPath, createPath); + } - TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TFieldPath& path, bool createPath) { - return ByPathImpl<TMutableField, Message>(msg, path.Fields(), createPath); - } + TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TStringBuf& path, bool createPath) { + TFieldPath fieldPath; + if (!fieldPath.InitUnsafe(msg.GetDescriptor(), path)) + return TMaybe<TMutableField>(); + return ByPathImpl<TMutableField, Message>(msg, fieldPath.Fields(), createPath); + } + TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TFieldPath& path, bool createPath) { + return ByPathImpl<TMutableField, Message>(msg, path.Fields(), createPath); + } + } diff --git a/library/cpp/protobuf/util/simple_reflection.h b/library/cpp/protobuf/util/simple_reflection.h index 61e877a787..172de02f78 100644 --- a/library/cpp/protobuf/util/simple_reflection.h +++ b/library/cpp/protobuf/util/simple_reflection.h @@ -13,137 +13,137 @@ #include <util/system/defaults.h> namespace NProtoBuf { - class TConstField { - public: - TConstField(const Message& msg, const FieldDescriptor* fd) - : Msg(msg) - , Fd(fd) - { - 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; - } - - 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; - } - - bool HasSameType(const TConstField& other) const { - if (CppType() != other.CppType()) - return false; - if (IsMessage() && Field()->message_type() != other.Field()->message_type()) - return false; - if (CppType() == FieldDescriptor::CPPTYPE_ENUM && Field()->enum_type() != other.Field()->enum_type()) - return false; - return true; - } - - protected: - bool IsRepeated() const { - return Fd->is_repeated(); - } - - FieldDescriptor::CppType CppType() const { - return Fd->cpp_type(); - } - - const Reflection& Refl() const { - return *Msg.GetReflection(); - } + class TConstField { + public: + TConstField(const Message& msg, const FieldDescriptor* fd) + : Msg(msg) + , Fd(fd) + { + 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; + } + + 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; + } + + bool HasSameType(const TConstField& other) const { + if (CppType() != other.CppType()) + return false; + if (IsMessage() && Field()->message_type() != other.Field()->message_type()) + return false; + if (CppType() == FieldDescriptor::CPPTYPE_ENUM && Field()->enum_type() != other.Field()->enum_type()) + return false; + return true; + } + + protected: + bool IsRepeated() const { + return Fd->is_repeated(); + } + + FieldDescriptor::CppType CppType() const { + return Fd->cpp_type(); + } + + const Reflection& Refl() const { + return *Msg.GetReflection(); + } [[noreturn]] void RaiseUnknown() const { - ythrow yexception() << "Unknown field cpp-type: " << (size_t)CppType(); - } + ythrow yexception() << "Unknown field cpp-type: " << (size_t)CppType(); + } - bool IsSameField(const TConstField& other) const { - return &Parent() == &other.Parent() && Field() == other.Field(); - } + bool IsSameField(const TConstField& other) const { + return &Parent() == &other.Parent() && Field() == other.Field(); + } - protected: - const Message& Msg; - const FieldDescriptor* Fd; - }; + protected: + const Message& Msg; + const FieldDescriptor* Fd; + }; - class TMutableField: public TConstField { - public: - TMutableField(Message& msg, const FieldDescriptor* fd) - : TConstField(msg, 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); + 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); - Message* MutableParent() { - return Mut(); - } + Message* MutableParent() { + return Mut(); + } - template <typename T> - inline void Set(T value, size_t index = 0); + template <typename T> + inline void Set(T value, size_t index = 0); - template <typename T> - inline void Add(T value); + template <typename T> + inline void Add(T value); - inline void MergeFrom(const TConstField& src); + inline void MergeFrom(const TConstField& src); - inline void Clear() { - Refl().ClearField(Mut(), Fd); - } - /* + inline void Clear() { + Refl().ClearField(Mut(), Fd); + } + /* void Swap(TMutableField& f) { Y_ASSERT(Field() == f.Field()); @@ -151,139 +151,139 @@ namespace NProtoBuf { // is ported into arcadia protobuf library from up-stream. } */ - inline void RemoveLast() { - Y_ASSERT(HasValue()); - if (IsRepeated()) - Refl().RemoveLast(Mut(), Fd); - else - Clear(); - } - - inline void SwapElements(size_t index1, size_t index2) { - Y_ASSERT(IsRepeated()); - Y_ASSERT(index1 < Size()); - Y_ASSERT(index2 < Size()); - if (index1 == index2) - return; - Refl().SwapElements(Mut(), Fd, index1, index2); - } - - inline void Remove(size_t index) { - if (index >= Size()) - return; - - // Move to the end - for (size_t i = index, size = Size(); i < size - 1; ++i) - SwapElements(i, i + 1); - RemoveLast(); - } - - Message* MutableMessage(size_t index = 0) { - Y_ASSERT(IsMessage()); - if (IsRepeated()) { - Y_ASSERT(index < Size()); - return Refl().MutableRepeatedMessage(Mut(), Fd, index); - } else { - Y_ASSERT(index == 0); - return Refl().MutableMessage(Mut(), Fd); - } - } - - template <typename TMsg> - inline TMsg* AddMessage() { - return CheckedCast<TMsg*>(AddMessage()); - } - - inline Message* AddMessage() { - Y_ASSERT(IsMessage() && IsRepeated()); - return Refl().AddMessage(Mut(), Fd); - } - - private: - Message* Mut() { - return const_cast<Message*>(&Msg); - } - - 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 -#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ - case CPPTYPE: \ - return CompatCast<CPPTYPE, TSelectCppType<T>::Result>(TSimpleFieldTraits<CPPTYPE>::Get(Msg, Fd, index)); - switch (CppType()) { - APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() - default: - RaiseUnknown(); - } -#undef TMP_MACRO_FOR_CPPTYPE + inline void RemoveLast() { + Y_ASSERT(HasValue()); + if (IsRepeated()) + Refl().RemoveLast(Mut(), Fd); + else + Clear(); + } + + inline void SwapElements(size_t index1, size_t index2) { + Y_ASSERT(IsRepeated()); + Y_ASSERT(index1 < Size()); + Y_ASSERT(index2 < Size()); + if (index1 == index2) + return; + Refl().SwapElements(Mut(), Fd, index1, index2); + } + + inline void Remove(size_t index) { + if (index >= Size()) + return; + + // Move to the end + for (size_t i = index, size = Size(); i < size - 1; ++i) + SwapElements(i, i + 1); + RemoveLast(); + } + + Message* MutableMessage(size_t index = 0) { + Y_ASSERT(IsMessage()); + if (IsRepeated()) { + Y_ASSERT(index < Size()); + return Refl().MutableRepeatedMessage(Mut(), Fd, index); + } else { + Y_ASSERT(index == 0); + return Refl().MutableMessage(Mut(), Fd); + } + } + + template <typename TMsg> + inline TMsg* AddMessage() { + return CheckedCast<TMsg*>(AddMessage()); + } + + inline Message* AddMessage() { + Y_ASSERT(IsMessage() && IsRepeated()); + return Refl().AddMessage(Mut(), Fd); + } + + private: + Message* Mut() { + return const_cast<Message*>(&Msg); + } + + 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 +#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ + case CPPTYPE: \ + return CompatCast<CPPTYPE, TSelectCppType<T>::Result>(TSimpleFieldTraits<CPPTYPE>::Get(Msg, Fd, index)); + switch (CppType()) { + APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() + default: + 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()); -#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ - case CPPTYPE: \ - TSimpleFieldTraits<CPPTYPE>::Set(*Mut(), Fd, CompatCast<TSelectCppType<T>::Result, CPPTYPE>(value), index); \ - break; - switch (CppType()) { - APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() - default: - 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()); +#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ + case CPPTYPE: \ + TSimpleFieldTraits<CPPTYPE>::Set(*Mut(), Fd, CompatCast<TSelectCppType<T>::Result, CPPTYPE>(value), index); \ + break; + switch (CppType()) { + APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() + default: + RaiseUnknown(); + } +#undef TMP_MACRO_FOR_CPPTYPE } - template <typename T> - inline void TMutableField::Add(T value) { -#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ - case CPPTYPE: \ - TSimpleFieldTraits<CPPTYPE>::Add(*Mut(), Fd, CompatCast<TSelectCppType<T>::Result, CPPTYPE>(value)); \ - break; - switch (CppType()) { - APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() - default: - RaiseUnknown(); - } -#undef TMP_MACRO_FOR_CPPTYPE + template <typename T> + inline void TMutableField::Add(T value) { +#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ + case CPPTYPE: \ + TSimpleFieldTraits<CPPTYPE>::Add(*Mut(), Fd, CompatCast<TSelectCppType<T>::Result, CPPTYPE>(value)); \ + break; + switch (CppType()) { + APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() + default: + RaiseUnknown(); + } +#undef TMP_MACRO_FOR_CPPTYPE } - template <typename T> - inline void TMutableField::MergeValue(T srcValue) { + template <typename T> + inline void TMutableField::MergeValue(T srcValue) { Add(srcValue); } - template <> - inline void TMutableField::MergeValue<const Message*>(const Message* srcValue) { - if (IsRepeated()) { - Add(srcValue); - } else { - MutableMessage()->MergeFrom(*srcValue); + template <> + inline void TMutableField::MergeValue<const Message*>(const Message* srcValue) { + if (IsRepeated()) { + Add(srcValue); + } else { + MutableMessage()->MergeFrom(*srcValue); } } - - inline void TMutableField::MergeFrom(const TConstField& src) { - Y_ASSERT(HasSameType(src)); - if (IsSameField(src)) - return; -#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ - case CPPTYPE: { \ - for (size_t itemIdx = 0; itemIdx < src.Size(); ++itemIdx) { \ - MergeValue(TSimpleFieldTraits<CPPTYPE>::Get(src.Parent(), src.Field(), itemIdx)); \ - } \ - break; \ - } - switch (CppType()) { - APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() - default: - RaiseUnknown(); - } -#undef TMP_MACRO_FOR_CPPTYPE - } - + + inline void TMutableField::MergeFrom(const TConstField& src) { + Y_ASSERT(HasSameType(src)); + if (IsSameField(src)) + return; +#define TMP_MACRO_FOR_CPPTYPE(CPPTYPE) \ + case CPPTYPE: { \ + for (size_t itemIdx = 0; itemIdx < src.Size(); ++itemIdx) { \ + MergeValue(TSimpleFieldTraits<CPPTYPE>::Get(src.Parent(), src.Field(), itemIdx)); \ + } \ + break; \ + } + switch (CppType()) { + APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() + default: + RaiseUnknown(); + } +#undef TMP_MACRO_FOR_CPPTYPE + } + } diff --git a/library/cpp/protobuf/util/simple_reflection_ut.cpp b/library/cpp/protobuf/util/simple_reflection_ut.cpp index 169d4703c9..4b6d6e715d 100644 --- a/library/cpp/protobuf/util/simple_reflection_ut.cpp +++ b/library/cpp/protobuf/util/simple_reflection_ut.cpp @@ -36,7 +36,7 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { dstOneMsg.MergeFrom(TConstField(src, descr->FindFieldByName("OneMsg"))); UNIT_ASSERT_VALUES_EQUAL(dst.GetOneMsg().RepIntSize(), src.GetOneMsg().RepIntSize()); dstOneMsg.MergeFrom(TConstField(src, descr->FindFieldByName("OneMsg"))); - UNIT_ASSERT_VALUES_EQUAL(dst.GetOneMsg().RepIntSize(), src.GetOneMsg().RepIntSize() * 2); + UNIT_ASSERT_VALUES_EQUAL(dst.GetOneMsg().RepIntSize(), src.GetOneMsg().RepIntSize() * 2); } { // MergeFrom for repeated fields acts like append @@ -44,7 +44,7 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { dstRepMsg.MergeFrom(TConstField(src, descr->FindFieldByName("RepMsg"))); UNIT_ASSERT_VALUES_EQUAL(dst.RepMsgSize(), src.RepMsgSize()); dstRepMsg.MergeFrom(TConstField(src, descr->FindFieldByName("RepMsg"))); - UNIT_ASSERT_VALUES_EQUAL(dst.RepMsgSize(), src.RepMsgSize() * 2); + UNIT_ASSERT_VALUES_EQUAL(dst.RepMsgSize(), src.RepMsgSize() * 2); for (size_t repMsgIndex = 0; repMsgIndex < dst.RepMsgSize(); ++repMsgIndex) { UNIT_ASSERT_VALUES_EQUAL(dst.GetRepMsg(repMsgIndex).RepIntSize(), src.GetRepMsg(0).RepIntSize()); } @@ -107,14 +107,14 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { msg.AddRepMsg()->AddRepInt(3); UNIT_ASSERT_VALUES_EQUAL(3, msg.RepMsgSize()); // 1, 2, 3 - fld.Remove(1); // from middle + fld.Remove(1); // from middle UNIT_ASSERT_VALUES_EQUAL(2, msg.RepMsgSize()); UNIT_ASSERT_VALUES_EQUAL(1, msg.GetRepMsg(0).GetRepInt(0)); UNIT_ASSERT_VALUES_EQUAL(3, msg.GetRepMsg(1).GetRepInt(0)); msg.AddRepMsg()->AddRepInt(5); UNIT_ASSERT_VALUES_EQUAL(3, msg.RepMsgSize()); // 1, 3, 5 - fld.Remove(2); // from end + fld.Remove(2); // from end UNIT_ASSERT_VALUES_EQUAL(2, msg.RepMsgSize()); UNIT_ASSERT_VALUES_EQUAL(1, msg.GetRepMsg(0).GetRepInt(0)); UNIT_ASSERT_VALUES_EQUAL(3, msg.GetRepMsg(1).GetRepInt(0)); @@ -127,7 +127,7 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { msg.AddRepStr("2"); msg.AddRepStr("3"); UNIT_ASSERT_VALUES_EQUAL(3, msg.RepStrSize()); // "1", "2", "3" - fld.Remove(0); // from begin + fld.Remove(0); // from begin UNIT_ASSERT_VALUES_EQUAL(2, msg.RepStrSize()); UNIT_ASSERT_VALUES_EQUAL("2", msg.GetRepStr(0)); UNIT_ASSERT_VALUES_EQUAL("3", msg.GetRepStr(1)); @@ -279,81 +279,81 @@ Y_UNIT_TEST_SUITE(ProtobufSimpleReflection) { // error { - {TSample msg; - UNIT_ASSERT(!TConstField::ByPath(msg, "SomeField")); + {TSample msg; + UNIT_ASSERT(!TConstField::ByPath(msg, "SomeField")); + } + + { + TSample msg; + UNIT_ASSERT(!TMutableField::ByPath(msg, "SomeField/FieldSome")); + } + + { + TSample msg; + UNIT_ASSERT(!TMutableField::ByPath(msg, "SomeField/FieldSome", true)); + } +} + +// extension +{ + TSample msg; + msg.SetExtension(NExt::TTestExt::ExtField, "ext"); + msg.SetExtension(NExt::ExtField, 2); + msg.AddExtension(NExt::Ext2Field, 33); + TInnerSample* subMsg = msg.MutableExtension(NExt::SubMsgExt); + subMsg->AddRepInt(20); + subMsg->SetExtension(NExt::Ext3Field, 54); + + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.TTestExt.ExtField"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT_VALUES_EQUAL("ext", field->Get<TString>()); } - - { - TSample msg; - UNIT_ASSERT(!TMutableField::ByPath(msg, "SomeField/FieldSome")); - } - - { - TSample msg; - UNIT_ASSERT(!TMutableField::ByPath(msg, "SomeField/FieldSome", true)); - } -} - -// extension -{ - TSample msg; - msg.SetExtension(NExt::TTestExt::ExtField, "ext"); - msg.SetExtension(NExt::ExtField, 2); - msg.AddExtension(NExt::Ext2Field, 33); - TInnerSample* subMsg = msg.MutableExtension(NExt::SubMsgExt); - subMsg->AddRepInt(20); - subMsg->SetExtension(NExt::Ext3Field, 54); - - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.TTestExt.ExtField"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - UNIT_ASSERT_VALUES_EQUAL("ext", field->Get<TString>()); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.ExtField"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - UNIT_ASSERT_VALUES_EQUAL(2, field->Get<int>()); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "ExtField"); // ambiguity - UNIT_ASSERT(!field); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.Ext2Field"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - UNIT_ASSERT_VALUES_EQUAL(33, field->Get<int>()); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "Ext2Field"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - UNIT_ASSERT_VALUES_EQUAL(33, field->Get<int>()); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - const TInnerSample* subMsg2 = field->GetAs<TInnerSample>(); - UNIT_ASSERT(subMsg2); - UNIT_ASSERT_VALUES_EQUAL(1, subMsg2->RepIntSize()); - UNIT_ASSERT_VALUES_EQUAL(20, subMsg2->GetRepInt(0)); - UNIT_ASSERT_VALUES_EQUAL(54, subMsg2->GetExtension(NExt::Ext3Field)); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt/Ext3Field"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - UNIT_ASSERT_VALUES_EQUAL(54, field->Get<int>()); - } - { - TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt/RepInt"); - UNIT_ASSERT(field); - UNIT_ASSERT(field->HasValue()); - UNIT_ASSERT_VALUES_EQUAL(20, field->Get<int>()); - } -} -} + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.ExtField"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT_VALUES_EQUAL(2, field->Get<int>()); + } + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "ExtField"); // ambiguity + UNIT_ASSERT(!field); + } + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "NExt.Ext2Field"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT_VALUES_EQUAL(33, field->Get<int>()); + } + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "Ext2Field"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT_VALUES_EQUAL(33, field->Get<int>()); + } + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + const TInnerSample* subMsg2 = field->GetAs<TInnerSample>(); + UNIT_ASSERT(subMsg2); + UNIT_ASSERT_VALUES_EQUAL(1, subMsg2->RepIntSize()); + UNIT_ASSERT_VALUES_EQUAL(20, subMsg2->GetRepInt(0)); + UNIT_ASSERT_VALUES_EQUAL(54, subMsg2->GetExtension(NExt::Ext3Field)); + } + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt/Ext3Field"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT_VALUES_EQUAL(54, field->Get<int>()); + } + { + TMaybe<TConstField> field = TConstField::ByPath(msg, "SubMsgExt/RepInt"); + UNIT_ASSERT(field); + UNIT_ASSERT(field->HasValue()); + UNIT_ASSERT_VALUES_EQUAL(20, field->Get<int>()); + } } +} +} diff --git a/library/cpp/protobuf/util/sort.h b/library/cpp/protobuf/util/sort.h index 985ba6f689..5c9ed37161 100644 --- a/library/cpp/protobuf/util/sort.h +++ b/library/cpp/protobuf/util/sort.h @@ -6,23 +6,23 @@ #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); + // 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; - ptrs.reserve(msgs.size()); - while (msgs.size()) { - ptrs.push_back(msgs.ReleaseLast()); - } + template <typename TProto, typename TComparePtr> + void SortMessages(RepeatedPtrField<TProto>& msgs, TComparePtr cmp) { + TVector<TProto*> ptrs; + ptrs.reserve(msgs.size()); + 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]); - } + ::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 50f036d0ea..8f00b6d6e1 100644 --- a/library/cpp/protobuf/util/traits.h +++ b/library/cpp/protobuf/util/traits.h @@ -11,302 +11,302 @@ namespace NProtoBuf { #undef GetMessage #endif - struct TCppTypeTraitsBase { - static inline bool Has(const Message& msg, const FieldDescriptor* field) { // non-repeated - return msg.GetReflection()->HasField(msg, field); - } - 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); - } + struct TCppTypeTraitsBase { + static inline bool Has(const Message& msg, const FieldDescriptor* field) { // non-repeated + return msg.GetReflection()->HasField(msg, field); + } + 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> { \ + static auto GetDefault(const FieldDescriptor* fd) \ + -> decltype(fd->default_value_##method()) { \ + Y_ASSERT(fd); \ + return fd->default_value_##method(); \ + } \ }; - // default value accessor - template <FieldDescriptor::CppType cpptype> - struct TCppTypeTraitsDefault; - -#define DECLARE_CPPTYPE_DEFAULT(cpptype, method) \ - template <> \ - struct TCppTypeTraitsDefault<cpptype> { \ - static auto GetDefault(const FieldDescriptor* fd) \ - -> decltype(fd->default_value_##method()) { \ - Y_ASSERT(fd); \ - return fd->default_value_##method(); \ - } \ - }; - - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_INT32, int32); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_INT64, int64); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_UINT32, uint32); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_UINT64, uint64); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_FLOAT, float); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_DOUBLE, double); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_BOOL, bool); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_ENUM, enum); - DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_STRING, string); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_INT32, int32); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_INT64, int64); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_UINT32, uint32); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_UINT64, uint64); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_FLOAT, float); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_DOUBLE, double); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_BOOL, bool); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_ENUM, enum); + DECLARE_CPPTYPE_DEFAULT(FieldDescriptor::CppType::CPPTYPE_STRING, string); #undef DECLARE_CPPTYPE_DEFAULT - // getters/setters of field with specified CppType - 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); + // getters/setters of field with specified CppType + 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 { \ + typedef type T; \ + static const FieldDescriptor::CppType CppType = cpptype; \ + \ + static inline T Get(const Message& msg, const FieldDescriptor* field) { \ + return msg.GetReflection()->Get##method(msg, field); \ + } \ + static inline T GetRepeated(const Message& msg, const FieldDescriptor* field, int index) { \ + return msg.GetReflection()->GetRepeated##method(msg, field, index); \ + } \ + static inline T GetDefault(const FieldDescriptor* field) { \ + return TCppTypeTraitsDefault<cpptype>::GetDefault(field); \ + } \ + static inline void Set(Message& msg, const FieldDescriptor* field, T value) { \ + msg.GetReflection()->Set##method(&msg, field, value); \ + } \ + static inline void AddRepeated(Message& msg, const FieldDescriptor* field, T value) { \ + msg.GetReflection()->Add##method(&msg, field, value); \ + } \ + static inline void SetRepeated(Message& msg, const FieldDescriptor* field, int index, T value) { \ + msg.GetReflection()->SetRepeated##method(&msg, field, index, value); \ + } \ + }; \ + template <> \ + struct TSelectCppType<type> { \ + static const FieldDescriptor::CppType Result = cpptype; \ + typedef type T; \ }; - // 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 { \ - typedef type T; \ - static const FieldDescriptor::CppType CppType = cpptype; \ - \ - static inline T Get(const Message& msg, const FieldDescriptor* field) { \ - return msg.GetReflection()->Get##method(msg, field); \ - } \ - static inline T GetRepeated(const Message& msg, const FieldDescriptor* field, int index) { \ - return msg.GetReflection()->GetRepeated##method(msg, field, index); \ - } \ - static inline T GetDefault(const FieldDescriptor* field) { \ - return TCppTypeTraitsDefault<cpptype>::GetDefault(field); \ - } \ - static inline void Set(Message& msg, const FieldDescriptor* field, T value) { \ - msg.GetReflection()->Set##method(&msg, field, value); \ - } \ - static inline void AddRepeated(Message& msg, const FieldDescriptor* field, T value) { \ - msg.GetReflection()->Add##method(&msg, field, value); \ - } \ - static inline void SetRepeated(Message& msg, const FieldDescriptor* field, int index, T value) { \ - msg.GetReflection()->SetRepeated##method(&msg, field, index, value); \ - } \ - }; \ - template <> \ - 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); - DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_UINT64, ui64, UInt64); - DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_DOUBLE, double, Double); - DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_FLOAT, float, Float); - DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_BOOL, bool, Bool); - 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); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_INT32, i32, Int32); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_INT64, i64, Int64); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_UINT32, ui32, UInt32); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_UINT64, ui64, UInt64); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_DOUBLE, double, Double); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_FLOAT, float, Float); + DECLARE_CPPTYPE_TRAITS(FieldDescriptor::CPPTYPE_BOOL, bool, Bool); + 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 - // 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)); - } - static inline T GetRepeated(const Message& msg, const FieldDescriptor* field, int index) { - return &(msg.GetReflection()->GetRepeatedMessage(msg, field, index)); - } - static inline Message* Set(Message& msg, const FieldDescriptor* field, const Message* value) { - Message* ret = msg.GetReflection()->MutableMessage(&msg, field); - ret->CopyFrom(*value); - return ret; - } - static inline Message* AddRepeated(Message& msg, const FieldDescriptor* field, const Message* value) { - Message* ret = msg.GetReflection()->AddMessage(&msg, field); - ret->CopyFrom(*value); - return ret; - } - static inline Message* SetRepeated(Message& msg, const FieldDescriptor* field, int index, const Message* value) { - Message* ret = msg.GetReflection()->MutableRepeatedMessage(&msg, field, index); - ret->CopyFrom(*value); - 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); - } - - 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); - } - - static inline void Add(Message& msg, const FieldDescriptor* field, T value) { - 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); - } - - static inline void Add(Message& msg, const FieldDescriptor* field, T value) { - 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()) - return TRepeated::Get(msg, field, index); - 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()) - TRepeated::Set(msg, field, value, index); - 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); - else - TSingle::Add(msg, field, value); - } - }; - - // some cpp-type groups - - template <FieldDescriptor::CppType CppType> - struct TIsIntegerCppType { - enum { - Result = CppType == FieldDescriptor::CPPTYPE_INT32 || - CppType == FieldDescriptor::CPPTYPE_INT64 || - CppType == FieldDescriptor::CPPTYPE_UINT32 || - CppType == FieldDescriptor::CPPTYPE_UINT64 - }; + // 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)); + } + static inline T GetRepeated(const Message& msg, const FieldDescriptor* field, int index) { + return &(msg.GetReflection()->GetRepeatedMessage(msg, field, index)); + } + static inline Message* Set(Message& msg, const FieldDescriptor* field, const Message* value) { + Message* ret = msg.GetReflection()->MutableMessage(&msg, field); + ret->CopyFrom(*value); + return ret; + } + static inline Message* AddRepeated(Message& msg, const FieldDescriptor* field, const Message* value) { + Message* ret = msg.GetReflection()->AddMessage(&msg, field); + ret->CopyFrom(*value); + return ret; + } + static inline Message* SetRepeated(Message& msg, const FieldDescriptor* field, int index, const Message* value) { + Message* ret = msg.GetReflection()->MutableRepeatedMessage(&msg, field, index); + ret->CopyFrom(*value); + 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); + } + + 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); + } + + static inline void Add(Message& msg, const FieldDescriptor* field, T value) { + 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); + } + + static inline void Add(Message& msg, const FieldDescriptor* field, T value) { + 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()) + return TRepeated::Get(msg, field, index); + 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()) + TRepeated::Set(msg, field, value, index); + 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); + else + TSingle::Add(msg, field, value); + } + }; + + // some cpp-type groups + + template <FieldDescriptor::CppType CppType> + struct TIsIntegerCppType { + enum { + Result = CppType == FieldDescriptor::CPPTYPE_INT32 || + CppType == FieldDescriptor::CPPTYPE_INT64 || + 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 TIsFloatCppType { + enum { + Result = CppType == FieldDescriptor::CPPTYPE_FLOAT || + CppType == FieldDescriptor::CPPTYPE_DOUBLE + }; }; - template <FieldDescriptor::CppType CppType> - struct TIsNumericCppType { - enum { - Result = CppType == FieldDescriptor::CPPTYPE_BOOL || - TIsIntegerCppType<CppType>::Result || - TIsFloatCppType<CppType>::Result - }; + template <FieldDescriptor::CppType CppType> + struct TIsNumericCppType { + enum { + Result = CppType == FieldDescriptor::CPPTYPE_BOOL || + TIsIntegerCppType<CppType>::Result || + TIsFloatCppType<CppType>::Result + }; }; - // a helper macro for splitting flow by cpp-type (e.g. in a switch) + // a helper macro for splitting flow by cpp-type (e.g. in a switch) -#define APPLY_TMP_MACRO_FOR_ALL_CPPTYPES() \ +#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) \ @@ -317,4 +317,4 @@ namespace NProtoBuf { 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/walk.h b/library/cpp/protobuf/util/walk.h index d15d76562d..d5d40eee69 100644 --- a/library/cpp/protobuf/util/walk.h +++ b/library/cpp/protobuf/util/walk.h @@ -8,9 +8,9 @@ #include <functional> namespace NProtoBuf { - // Apply @onField processor to each field in @msg (even empty) + // 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) + // Returned bool defines if we should walk down deeper to current node children (true), or not (false) void WalkReflection(Message& msg, std::function<bool(Message&, const FieldDescriptor*)> onField); void WalkReflection(const Message& msg, diff --git a/library/cpp/protobuf/util/walk_ut.cpp b/library/cpp/protobuf/util/walk_ut.cpp index 2ea6071b17..2b101e79c5 100644 --- a/library/cpp/protobuf/util/walk_ut.cpp +++ b/library/cpp/protobuf/util/walk_ut.cpp @@ -7,7 +7,7 @@ using namespace NProtoBuf; Y_UNIT_TEST_SUITE(ProtobufWalk) { - static void InitProto(NProtobufUtilUt::TWalkTest & p, int level = 0) { + static void InitProto(NProtobufUtilUt::TWalkTest & p, int level = 0) { p.SetOptInt(1); p.AddRepInt(2); p.AddRepInt(3); @@ -24,16 +24,16 @@ Y_UNIT_TEST_SUITE(ProtobufWalk) { } } - static bool IncreaseInts(Message & msg, const FieldDescriptor* fd) { + 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) - f.Set(f.Get<ui64>(i) + 1, i); // ui64 should be ok! + f.Set(f.Get<ui64>(i) + 1, i); // ui64 should be ok! } return true; } - static bool RepeatString1(Message & msg, const FieldDescriptor* fd) { + static bool RepeatString1(Message & msg, const FieldDescriptor* fd) { TMutableField f(msg, fd); if (f.IsString()) { for (size_t i = 0; i < f.Size(); ++i) @@ -43,7 +43,7 @@ Y_UNIT_TEST_SUITE(ProtobufWalk) { return true; } - static bool ClearXXX(Message & msg, const FieldDescriptor* fd) { + 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(); diff --git a/library/cpp/protobuf/util/ya.make b/library/cpp/protobuf/util/ya.make index b62028af58..6c9410ee77 100644 --- a/library/cpp/protobuf/util/ya.make +++ b/library/cpp/protobuf/util/ya.make @@ -1,4 +1,4 @@ -LIBRARY() +LIBRARY() OWNER(mowgli) |