Project import generated by Copybara.
GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/proto/ast_pb2.py b/proto/ast_pb2.py
new file mode 100644
index 0000000..2b77ca9
--- /dev/null
+++ b/proto/ast_pb2.py
@@ -0,0 +1,111 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Protocol buffers for user queries parsed into abstract syntax trees.
+
+A user issue query can look like [Type=Defect owner:jrobbins "memory leak"].
+In that simple form, all the individual search conditions are simply ANDed
+together. In the code, a list of conditions to be ANDed is called a
+conjunction.
+
+Monorail also supports a quick-or feature: [Type=Defect,Enhancement]. That
+will match any issue that has labels Type-Defect or Type-Enhancement, or both.
+
+Monorail supports a top-level "OR" keyword that can
+be used to logically OR a series of conjunctions. For example:
+[Type=Defect stars>10 OR Type=Enhancement stars>50].
+
+Parentheses groups and "OR" statements are preprocessed before the final
+QueryAST is constructed.
+
+So, QueryAST is always exactly two levels: the overall tree
+consists of a list of conjunctions, and each conjunction consists of a list
+of conditions.
+
+A condition can look like [stars>10] or [summary:memory] or
+[Type=Defect,Enhancement]. Each condition has a single comparison operator.
+Most conditions refer to a single field definition, but in the case of
+cross-project search a single condition can have a list of field definitions
+from the different projects being searched. Each condition can have a list
+of constant values to compare against. The values may be all strings or all
+integers.
+
+Some conditions are procesed by the SQL database and others by the GAE
+search API. All conditions are passed to each module and it is up to
+the module to decide which conditions to handle and which to ignore.
+"""
+
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+from protorpc import messages
+
+from proto import tracker_pb2
+
+
+# This is a special field_name for a FieldDef that means to do a fulltext
+# search for words that occur in any part of the issue.
+ANY_FIELD = 'any_field'
+
+
+class QueryOp(messages.Enum):
+ """Enumeration of possible query condition operators."""
+ EQ = 1
+ NE = 2
+ LT = 3
+ GT = 4
+ LE = 5
+ GE = 6
+ TEXT_HAS = 7
+ NOT_TEXT_HAS = 8
+ IS_DEFINED = 11
+ IS_NOT_DEFINED = 12
+ KEY_HAS = 13
+
+
+class TokenType(messages.Enum):
+ """Enumeration of query tokens used for parentheses parsing."""
+ SUBQUERY = 1
+ LEFT_PAREN = 2
+ RIGHT_PAREN = 3
+ OR = 4
+
+
+class QueryToken(messages.Message):
+ """Data structure to represent a single token for parentheses parsing."""
+ token_type = messages.EnumField(TokenType, 1, required=True)
+ value = messages.StringField(2)
+
+
+class Condition(messages.Message):
+ """Representation of one query condition. E.g., [Type=Defect,Task]."""
+ op = messages.EnumField(QueryOp, 1, required=True)
+ field_defs = messages.MessageField(tracker_pb2.FieldDef, 2, repeated=True)
+ str_values = messages.StringField(3, repeated=True)
+ int_values = messages.IntegerField(4, repeated=True)
+ # The suffix of a search field
+ # eg. the 'approver' in 'UXReview-approver:user@mail.com'
+ key_suffix = messages.StringField(5)
+ # The name of the phase this field value should belong to.
+ phase_name = messages.StringField(6)
+
+
+class Conjunction(messages.Message):
+ """A list of conditions that are implicitly ANDed together."""
+ conds = messages.MessageField(Condition, 1, repeated=True)
+
+
+class QueryAST(messages.Message):
+ """Abstract syntax tree for the user's query."""
+ conjunctions = messages.MessageField(Conjunction, 1, repeated=True)
+
+
+def MakeCond(op, field_defs, str_values, int_values,
+ key_suffix=None, phase_name=None):
+ """Shorthand function to construct a Condition PB."""
+ return Condition(
+ op=op, field_defs=field_defs, str_values=str_values,
+ int_values=int_values, key_suffix=key_suffix, phase_name=phase_name)