# Filter, possibly empty filter : [expression] ; # Expressions may either be a conjunction (AND) of sequences or a simple # sequence. # # Note, the AND is case-sensitive. # # Example: `a b AND c AND d` # # The expression `(a b) AND c AND d` is equivalent to the example. expression : sequence {WS AND WS sequence} ; # Sequence is composed of one or more whitespace (WS) separated factors. # # A sequence expresses a logical relationship between 'factors' where # the ranking of a filter result may be scored according to the number # factors that match and other such criteria as the proximity of factors # to each other within a document. # # When filters are used with exact match semantics rather than fuzzy # match semantics, a sequence is equivalent to AND. # # Example: `New York Giants OR Yankees` # # The expression `New York (Giants OR Yankees)` is equivalent to the # example. sequence : factor {WS factor} ; # Factors may either be a disjunction (OR) of terms or a simple term. # # Note, the OR is case-sensitive. # # Example: `a < 10 OR a >= 100` factor : term {WS OR WS term} ; # Terms may either be unary or simple expressions. # # Unary expressions negate the simple expression, either mathematically `-` # or logically `NOT`. The negation styles may be used interchangeably. # # Note, the `NOT` is case-sensitive and must be followed by at least one # whitespace (WS). # # Examples: # * logical not : `NOT (a OR b)` # * alternative not : `-file:".java"` # * negation : `-30` term : [(NOT WS | MINUS)] simple ; # Simple expressions may either be a restriction or a nested (composite) # expression. simple : restriction | composite ; # Restrictions express a relationship between a comparable value and a # single argument. When the restriction only specifies a comparable # without an operator, this is a global restriction. # # Note, restrictions are not whitespace sensitive. # # Examples: # * equality : `package=com.google` # * inequality : `msg != 'hello'` # * greater than : `1 > 0` # * greater or equal : `2.5 >= 2.4` # * less than : `yesterday < request.time` # * less or equal : `experiment.rollout <= cohort(request.user)` # * has : `map:key` # * global : `prod` # # In addition to the global, equality, and ordering operators, filters # also support the has (`:`) operator. The has operator is unique in # that it can test for presence or value based on the proto3 type of # the `comparable` value. The has operator is useful for validating the # structure and contents of complex values. restriction : comparable [comparator arg] ; # Comparable may either be a member or function. comparable : member | function ; # Member expressions are either value or DOT qualified field references. # # Example: `expr.type_map.1.type` member : value {DOT field} ; # Function calls may use simple or qualified names with zero or more # arguments. # # All functions declared within the list filter, apart from the special # `arguments` function must be provided by the host service. # # Examples: # * `regex(m.key, '^.*prod.*$')` # * `math.mem('30mb')` # # Antipattern: simple and qualified function names may include keywords: # NOT, AND, OR. It is not recommended that any of these names be used # within functions exposed by a service that supports list filters. function : name {DOT name} LPAREN [argList] RPAREN ; # Comparators supported by list filters. comparator : LESS_EQUALS # <= | LESS_THAN # < | GREATER_EQUALS # >= | GREATER_THAN # > | NOT_EQUALS # != | EQUALS # = | HAS # : ; # Composite is a parenthesized expression, commonly used to group # terms or clarify operator precedence. # # Example: `(msg.endsWith('world') AND retries < 10)` composite : LPAREN expression RPAREN ; # Value may either be a TEXT or STRING. # # TEXT is a free-form set of characters without whitespace (WS) # or . (DOT) within it. The text may represent a variable, string, # number, boolean, or alternative literal value and must be handled # in a manner consistent with the service's intention. # # STRING is a quoted string which may or may not contain a special # wildcard `*` character at the beginning or end of the string to # indicate a prefix or suffix-based search within a restriction. value : TEXT | STRING ; # Fields may be either a value or a keyword. field : value | keyword ; # Names may either be TEXT or a keyword. name : TEXT | keyword ; argList : arg { COMMA arg} ; arg : comparable | composite ; keyword : NOT | AND | OR ;