diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/protobuf/util/simple_reflection.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/protobuf/util/simple_reflection.cpp')
-rw-r--r-- | library/cpp/protobuf/util/simple_reflection.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/library/cpp/protobuf/util/simple_reflection.cpp b/library/cpp/protobuf/util/simple_reflection.cpp new file mode 100644 index 0000000000..d842e9ee44 --- /dev/null +++ b/library/cpp/protobuf/util/simple_reflection.cpp @@ -0,0 +1,70 @@ +#include "simple_reflection.h" + +namespace NProtoBuf { + 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(); + } + } + 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 + 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 TFieldPath& path) { + return ByPathImpl<TConstField, const Message>(msg, path.Fields(), false); + } + + 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 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); + } + +} |