node_visitor.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "node_visitor.h"
  2. #include <util/generic/algorithm.h>
  3. #include <util/string/printf.h>
  4. namespace NYT {
  5. ////////////////////////////////////////////////////////////////////////////////
  6. namespace {
  7. template <typename Fun>
  8. void Iterate(const TNode::TMapType& nodeMap, bool sortByKey, Fun action)
  9. {
  10. if (sortByKey) {
  11. TVector<TNode::TMapType::const_iterator> iterators;
  12. for (auto it = nodeMap.begin(); it != nodeMap.end(); ++it) {
  13. iterators.push_back(it);
  14. }
  15. SortBy(iterators, [](TNode::TMapType::const_iterator it) { return it->first; });
  16. for (const auto& it : iterators) {
  17. action(*it);
  18. }
  19. } else {
  20. ForEach(nodeMap.begin(), nodeMap.end(), action);
  21. }
  22. }
  23. } // namespace
  24. ////////////////////////////////////////////////////////////////////////////////
  25. TNodeVisitor::TNodeVisitor(NYson::IYsonConsumer* consumer, bool sortMapKeys)
  26. : Consumer_(consumer)
  27. , SortMapKeys_(sortMapKeys)
  28. { }
  29. void TNodeVisitor::Visit(const TNode& node)
  30. {
  31. VisitAny(node);
  32. }
  33. void TNodeVisitor::VisitAny(const TNode& node)
  34. {
  35. if (node.HasAttributes()) {
  36. Consumer_->OnBeginAttributes();
  37. Iterate(node.GetAttributes().AsMap(), SortMapKeys_, [&](const auto& item) {
  38. Consumer_->OnKeyedItem(item.first);
  39. if (item.second.IsUndefined()) {
  40. ythrow TNode::TTypeError() << "unable to visit attribute value of type "
  41. << TNode::EType::Undefined << "; attribute name: `" << item.first << '\'' ;
  42. }
  43. VisitAny(item.second);
  44. });
  45. Consumer_->OnEndAttributes();
  46. }
  47. switch (node.GetType()) {
  48. case TNode::String:
  49. VisitString(node);
  50. break;
  51. case TNode::Int64:
  52. VisitInt64(node);
  53. break;
  54. case TNode::Uint64:
  55. VisitUint64(node);
  56. break;
  57. case TNode::Double:
  58. VisitDouble(node);
  59. break;
  60. case TNode::Bool:
  61. VisitBool(node);
  62. break;
  63. case TNode::List:
  64. VisitList(node.AsList());
  65. break;
  66. case TNode::Map:
  67. VisitMap(node.AsMap());
  68. break;
  69. case TNode::Null:
  70. VisitEntity();
  71. break;
  72. case TNode::Undefined:
  73. ythrow TNode::TTypeError() << "unable to visit TNode of type " << node.GetType();
  74. default:
  75. Y_FAIL("Unexpected type: %d", node.GetType());
  76. }
  77. }
  78. void TNodeVisitor::VisitString(const TNode& node)
  79. {
  80. Consumer_->OnStringScalar(node.AsString());
  81. }
  82. void TNodeVisitor::VisitInt64(const TNode& node)
  83. {
  84. Consumer_->OnInt64Scalar(node.AsInt64());
  85. }
  86. void TNodeVisitor::VisitUint64(const TNode& node)
  87. {
  88. Consumer_->OnUint64Scalar(node.AsUint64());
  89. }
  90. void TNodeVisitor::VisitDouble(const TNode& node)
  91. {
  92. Consumer_->OnDoubleScalar(node.AsDouble());
  93. }
  94. void TNodeVisitor::VisitBool(const TNode& node)
  95. {
  96. Consumer_->OnBooleanScalar(node.AsBool());
  97. }
  98. void TNodeVisitor::VisitList(const TNode::TListType& nodeList)
  99. {
  100. Consumer_->OnBeginList();
  101. size_t index = 0;
  102. for (const auto& item : nodeList) {
  103. Consumer_->OnListItem();
  104. if (item.IsUndefined()) {
  105. ythrow TNode::TTypeError() << "unable to visit list node child of type "
  106. << TNode::EType::Undefined << "; list index: " << index;
  107. }
  108. VisitAny(item);
  109. ++index;
  110. }
  111. Consumer_->OnEndList();
  112. }
  113. void TNodeVisitor::VisitMap(const TNode::TMapType& nodeMap)
  114. {
  115. Consumer_->OnBeginMap();
  116. Iterate(nodeMap, SortMapKeys_, [&](const auto& item) {
  117. Consumer_->OnKeyedItem(item.first);
  118. if (item.second.IsUndefined()) {
  119. ythrow TNode::TTypeError() << "unable to visit map node child of type "
  120. << TNode::EType::Undefined << "; map key: `" << item.first << '\'' ;
  121. }
  122. VisitAny(item.second);
  123. });
  124. Consumer_->OnEndMap();
  125. }
  126. void TNodeVisitor::VisitEntity()
  127. {
  128. Consumer_->OnEntity();
  129. }
  130. ////////////////////////////////////////////////////////////////////////////////
  131. } // namespace NYT