simple_reflection.cpp 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "simple_reflection.h"
  2. namespace NProtoBuf {
  3. const Message* GetMessageHelper(const TConstField& curField, bool) {
  4. return curField.HasValue() && curField.IsMessage() ? curField.Get<Message>() : nullptr;
  5. }
  6. Message* GetMessageHelper(TMutableField& curField, bool createPath) {
  7. if (curField.IsMessage()) {
  8. if (!curField.HasValue()) {
  9. if (createPath)
  10. return curField.Field()->is_repeated() ? curField.AddMessage() : curField.MutableMessage();
  11. } else {
  12. return curField.MutableMessage();
  13. }
  14. }
  15. return nullptr;
  16. }
  17. template <class TField, class TMsg>
  18. TMaybe<TField> ByPathImpl(TMsg& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath) {
  19. if (fieldsPath.empty())
  20. return TMaybe<TField>();
  21. TMsg* curParent = &msg;
  22. for (size_t i = 0, size = fieldsPath.size(); i < size; ++i) {
  23. const FieldDescriptor* field = fieldsPath[i];
  24. if (!curParent)
  25. return TMaybe<TField>();
  26. TField curField(*curParent, field);
  27. if (size - i == 1) // last element in path
  28. return curField;
  29. curParent = GetMessageHelper(curField, createPath);
  30. }
  31. if (curParent)
  32. return TField(*curParent, fieldsPath.back());
  33. else
  34. return TMaybe<TField>();
  35. }
  36. TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TVector<const FieldDescriptor*>& fieldsPath) {
  37. return ByPathImpl<TConstField, const Message>(msg, fieldsPath, false);
  38. }
  39. TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TStringBuf& path) {
  40. TFieldPath fieldPath;
  41. if (!fieldPath.InitUnsafe(msg.GetDescriptor(), path))
  42. return TMaybe<TConstField>();
  43. return ByPathImpl<TConstField, const Message>(msg, fieldPath.Fields(), false);
  44. }
  45. TMaybe<TConstField> TConstField::ByPath(const Message& msg, const TFieldPath& path) {
  46. return ByPathImpl<TConstField, const Message>(msg, path.Fields(), false);
  47. }
  48. TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TVector<const FieldDescriptor*>& fieldsPath, bool createPath) {
  49. return ByPathImpl<TMutableField, Message>(msg, fieldsPath, createPath);
  50. }
  51. TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TStringBuf& path, bool createPath) {
  52. TFieldPath fieldPath;
  53. if (!fieldPath.InitUnsafe(msg.GetDescriptor(), path))
  54. return TMaybe<TMutableField>();
  55. return ByPathImpl<TMutableField, Message>(msg, fieldPath.Fields(), createPath);
  56. }
  57. TMaybe<TMutableField> TMutableField::ByPath(Message& msg, const TFieldPath& path, bool createPath) {
  58. return ByPathImpl<TMutableField, Message>(msg, path.Fields(), createPath);
  59. }
  60. }