• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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