1 // Copyright (C) 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef ICING_QUERY_ADVANCED_QUERY_PARSER_ABSTRACT_SYNTAX_TREE_H_ 16 #define ICING_QUERY_ADVANCED_QUERY_PARSER_ABSTRACT_SYNTAX_TREE_H_ 17 18 #include <memory> 19 #include <string> 20 #include <string_view> 21 #include <utility> 22 #include <vector> 23 24 namespace icing { 25 namespace lib { 26 27 class FunctionNameNode; 28 class StringNode; 29 class TextNode; 30 class MemberNode; 31 class FunctionNode; 32 class UnaryOperatorNode; 33 class NaryOperatorNode; 34 35 class AbstractSyntaxTreeVisitor { 36 public: 37 virtual ~AbstractSyntaxTreeVisitor() = default; 38 39 virtual void VisitFunctionName(const FunctionNameNode* node) = 0; 40 virtual void VisitString(const StringNode* node) = 0; 41 virtual void VisitText(const TextNode* node) = 0; 42 virtual void VisitMember(const MemberNode* node) = 0; 43 virtual void VisitFunction(const FunctionNode* node) = 0; 44 virtual void VisitUnaryOperator(const UnaryOperatorNode* node) = 0; 45 virtual void VisitNaryOperator(const NaryOperatorNode* node) = 0; 46 }; 47 48 class Node { 49 public: 50 virtual ~Node() = default; 51 virtual void Accept(AbstractSyntaxTreeVisitor* visitor) const = 0; 52 }; 53 54 class TerminalNode : public Node { 55 public: TerminalNode(std::string value,std::string_view raw_value,bool is_prefix)56 explicit TerminalNode(std::string value, std::string_view raw_value, 57 bool is_prefix) 58 : value_(std::move(value)), 59 raw_value_(raw_value), 60 is_prefix_(is_prefix) {} 61 value()62 const std::string& value() const& { return value_; } value()63 std::string value() && { return std::move(value_); } 64 is_prefix()65 bool is_prefix() const { return is_prefix_; } 66 raw_value()67 std::string_view raw_value() const { return raw_value_; } 68 69 private: 70 std::string value_; 71 std::string_view raw_value_; 72 bool is_prefix_; 73 }; 74 75 class FunctionNameNode : public TerminalNode { 76 public: FunctionNameNode(std::string value)77 explicit FunctionNameNode(std::string value) 78 : TerminalNode(std::move(value), /*raw_value=*/"", /*is_prefix=*/false) {} Accept(AbstractSyntaxTreeVisitor * visitor)79 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 80 visitor->VisitFunctionName(this); 81 } 82 }; 83 84 class StringNode : public TerminalNode { 85 public: 86 explicit StringNode(std::string value, std::string_view raw_value, 87 bool is_prefix = false) TerminalNode(std::move (value),raw_value,is_prefix)88 : TerminalNode(std::move(value), raw_value, is_prefix) {} Accept(AbstractSyntaxTreeVisitor * visitor)89 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 90 visitor->VisitString(this); 91 } 92 }; 93 94 class TextNode : public TerminalNode { 95 public: 96 explicit TextNode(std::string value, std::string_view raw_value, 97 bool is_prefix = false) TerminalNode(std::move (value),raw_value,is_prefix)98 : TerminalNode(std::move(value), raw_value, is_prefix) {} Accept(AbstractSyntaxTreeVisitor * visitor)99 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 100 visitor->VisitText(this); 101 } 102 }; 103 104 class MemberNode : public Node { 105 public: MemberNode(std::vector<std::unique_ptr<TextNode>> children,std::unique_ptr<FunctionNode> function)106 explicit MemberNode(std::vector<std::unique_ptr<TextNode>> children, 107 std::unique_ptr<FunctionNode> function) 108 : children_(std::move(children)), function_(std::move(function)) {} 109 Accept(AbstractSyntaxTreeVisitor * visitor)110 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 111 visitor->VisitMember(this); 112 } children()113 const std::vector<std::unique_ptr<TextNode>>& children() const { 114 return children_; 115 } function()116 const FunctionNode* function() const { return function_.get(); } 117 118 private: 119 std::vector<std::unique_ptr<TextNode>> children_; 120 // This is nullable. When it is not nullptr, this class will represent a 121 // function call. 122 std::unique_ptr<FunctionNode> function_; 123 }; 124 125 class FunctionNode : public Node { 126 public: FunctionNode(std::unique_ptr<FunctionNameNode> function_name)127 explicit FunctionNode(std::unique_ptr<FunctionNameNode> function_name) 128 : FunctionNode(std::move(function_name), {}) {} FunctionNode(std::unique_ptr<FunctionNameNode> function_name,std::vector<std::unique_ptr<Node>> args)129 explicit FunctionNode(std::unique_ptr<FunctionNameNode> function_name, 130 std::vector<std::unique_ptr<Node>> args) 131 : function_name_(std::move(function_name)), args_(std::move(args)) {} 132 Accept(AbstractSyntaxTreeVisitor * visitor)133 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 134 visitor->VisitFunction(this); 135 } function_name()136 const FunctionNameNode* function_name() const { return function_name_.get(); } args()137 const std::vector<std::unique_ptr<Node>>& args() const { return args_; } 138 139 private: 140 std::unique_ptr<FunctionNameNode> function_name_; 141 std::vector<std::unique_ptr<Node>> args_; 142 }; 143 144 class UnaryOperatorNode : public Node { 145 public: UnaryOperatorNode(std::string operator_text,std::unique_ptr<Node> child)146 explicit UnaryOperatorNode(std::string operator_text, 147 std::unique_ptr<Node> child) 148 : operator_text_(std::move(operator_text)), child_(std::move(child)) {} 149 Accept(AbstractSyntaxTreeVisitor * visitor)150 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 151 visitor->VisitUnaryOperator(this); 152 } operator_text()153 const std::string& operator_text() const { return operator_text_; } child()154 const Node* child() const { return child_.get(); } 155 156 private: 157 std::string operator_text_; 158 std::unique_ptr<Node> child_; 159 }; 160 161 class NaryOperatorNode : public Node { 162 public: NaryOperatorNode(std::string operator_text,std::vector<std::unique_ptr<Node>> children)163 explicit NaryOperatorNode(std::string operator_text, 164 std::vector<std::unique_ptr<Node>> children) 165 : operator_text_(std::move(operator_text)), 166 children_(std::move(children)) {} 167 Accept(AbstractSyntaxTreeVisitor * visitor)168 void Accept(AbstractSyntaxTreeVisitor* visitor) const override { 169 visitor->VisitNaryOperator(this); 170 } operator_text()171 const std::string& operator_text() const { return operator_text_; } children()172 const std::vector<std::unique_ptr<Node>>& children() const { 173 return children_; 174 } 175 176 private: 177 std::string operator_text_; 178 std::vector<std::unique_ptr<Node>> children_; 179 }; 180 181 } // namespace lib 182 } // namespace icing 183 184 #endif // ICING_QUERY_ADVANCED_QUERY_PARSER_ABSTRACT_SYNTAX_TREE_H_ 185