
    Iiz                    	   % S r SSKrSSKrSSKrSSKrSSKrSSKJrJr  SSK	J
r
JrJrJrJrJrJrJrJrJrJrJrJrJrJrJr  SSKrSSKrSSKrSSKJr  \\R@                  RB                  \S\R@                  RD                  4   \\R@                  RF                     4   r$\RJ                  " S5      r& " S S	\'5      r( " S
 S\'5      r) " S S\'5      r*\\R@                  RD                  \*\R@                  RB                  4   r+\S\+4   r,\\+\,4   r-\\\.   \\\.      4   r/\" S\,S9r0S\1S\/S\\0/\04   4S jr2S\S\R@                  RD                  4   S\S\R@                  Rf                  4   4S jr4S\+S\+S\+4S jr5S\+S\+4S jr60 S\R@                  Rn                  _S\Rp                  _S\Rr                  _S\Rt                  _S\Rv                  _S\Rx                  _S \Rz                  _S!\4" \R|                  5      _S"\4" \R~                  5      _S#\4" \R                  5      _S$\4" \R                  5      _S%\4" \R                  5      _S&\4" \R                  5      _S'\5_S(\R@                  R                  _S)\R@                  R                  _S*\R@                  R                  _0 S+\R                  _S,\6_S-S. _S/S0 _S1S2 _S3S4 _S5ShS6 j_S7ShS8 j_S9ShS: j_S;ShS< j_S=ShS> j_S?ShS@ j_SAShSB j_SCShSD j_SEShSF j_SGShSH j_SI\R@                  Rf                  _E\R@                  R                  \R@                  R                  \R@                  R                  \R@                  R                  \R@                  R                  \R@                  R                  \N" S5      \R@                  R                  \R@                  R                  \R@                  R                  \NSJ.ErR\\1\,4   \SSK'    " SL SM5      rT\\1\\+SN4   4   rUSOrV " SP SN\\1\T4   5      rW " SQ SR5      rX " SS ST\R                  R                  5      r[SU\SV\R                  /\
4   S\SV\R                  /\
4   4SW jr] " SX SV\R                  R                  \+   5      r_\R                  " SY5      raSZS[S\S]S^S_S`SaSbScSd.
rbSe\R                  S\R@                  R                  4Sf jrdSe\R                  S\R@                  R                  4Sg jreg)ia  
CEL Interpreter using the AST directly.

The general idea is to map CEL operators to Python operators and push the
real work off to Python objects defined by the :py:mod:`celpy.celtypes` module.

CEL operator "+" is implemented by "_+_" function. We map this to :py:func:`operator.add`.
This will then look for `__add__()` methods in the various :py:class:`celpy.celtypes.CELType`
types.

In order to deal gracefully with missing and incomplete data,
exceptions are turned into first-class :py:class:`Result` objects.
They're not raised directly, but instead saved as part of the evaluation so that
short-circuit operators can ignore the exceptions.

This means that Python exceptions like :exc:`TypeError`, :exc:`IndexError`, and :exc:`KeyError`
are caught and transformed into :exc:`CELEvalError` objects.

The :py:class:`Resut` type hint is a union of the various values that are encountered
during evaluation. It's a union of the :py:class:`celpy.celtypes.CELTypes` type and the
:exc:`CELEvalError` exception.
    N)reducewraps)AnyCallableDictIterableIteratorListMappingMatchOptionalSequenceSizedTupleTypeTypeVarUnioncast)	tree_dump.
evaluationc            	       P   ^  \ rS rSrSrS
S\S\\   S\\   SS4U 4S jjjrS	r	U =r
$ )CELSyntaxErrorB   z@CEL Syntax error -- the AST did not have the expected structure.Narglinecolumnreturnc                 <   > [         TU ]  U5        X l        X0l        g Nsuper__init__r   r   selfr   r   r   	__class__s       6/venv/lib/python3.13/site-packages/celpy/evaluation.pyr"   CELSyntaxError.__init__D       	    r   r   NN)__name__
__module____qualname____firstlineno____doc__r   r   intr"   __static_attributes____classcell__r%   s   @r&   r   r   B   s5    JC x} Xc] ^b  r)   r   c                   @   ^  \ rS rSrSrS\S\S\SS4U 4S jjrS	rU =r	$ )
CELUnsupportedErrorJ   z2Feature unsupported by this implementation of CEL.r   r   r   r   Nc                 <   > [         TU ]  U5        X l        X0l        g r   r    r#   s       r&   r"   CELUnsupportedError.__init__L   r(   r)   r*   )
r,   r-   r.   r/   r0   r   r1   r"   r2   r3   r4   s   @r&   r6   r6   J   s,    <C s C D  r)   r6   c            	         ^  \ rS rSrSrSSS.S\S\\R                     S\\R                     SS4U 4S	 jjjr
S\4S
 jrS\SS 4U 4S jjrS S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\SS 4S jrS\S\4S jrS\SS 4S jrSr U =r!$ )!CELEvalErrorR   a  CEL evaluation problem. This can be saved as a temporary value for later use.
This is politely ignored by logic operators to provide commutative short-circuit.

We provide operator-like special methods so an instance of an error
returns itself when operated on.
N)treetokenargsr=   r>   r   c                  > [         TU ]  " U6   Xl        X l        S U l        S U l        U R                  (       aJ  U R                  R                  R                  U l        U R                  R                  R
                  U l        U R                  (       a7  U R                  R                  U l        U R                  R
                  U l        g g r   )r!   r"   r=   r>   r   r   meta)r$   r=   r>   r?   r%   s       r&   r"   CELEvalError.__init__Y   s    
 	$	
#'	%)99		++DI))..//DK::

DI**++DK r)   c                 x   U R                   R                  nU R                  (       aH  U R                  (       a7  U SU R                   S[        U R                  5      < SU R                  < S3$ U R                  (       a)  U SU R                   S[        U R                  5      < S3$ U SU R                   S3$ )N(*z, tree=z, token=))r%   r,   r=   r>   r?   r   )r$   clss     r&   __repr__CELEvalError.__repr__j   s    nn%%99 %r$))GIdii,@+C8DJJ>YZ[ YYU"TYYKwy/C.FaHH U"TYYKq))r)   tbc                 "   > [         TU ]  U5      $ r   )r!   with_traceback)r$   rI   r%   s     r&   rK   CELEvalError.with_tracebackw   s    w%b))r)   c                     U $ r    r$   s    r&   __neg__CELEvalError.__neg__z       r)   otherc                     U $ r   rN   r$   rS   s     r&   __add__CELEvalError.__add__}   rR   r)   c                     U $ r   rN   rU   s     r&   __sub__CELEvalError.__sub__   rR   r)   c                     U $ r   rN   rU   s     r&   __mul__CELEvalError.__mul__   rR   r)   c                     U $ r   rN   rU   s     r&   __truediv__CELEvalError.__truediv__   rR   r)   c                     U $ r   rN   rU   s     r&   __floordiv__CELEvalError.__floordiv__   rR   r)   c                     U $ r   rN   rU   s     r&   __mod__CELEvalError.__mod__   rR   r)   c                     U $ r   rN   rU   s     r&   __pow__CELEvalError.__pow__   rR   r)   c                     U $ r   rN   rU   s     r&   __radd__CELEvalError.__radd__   rR   r)   c                     U $ r   rN   rU   s     r&   __rsub__CELEvalError.__rsub__   rR   r)   c                     U $ r   rN   rU   s     r&   __rmul__CELEvalError.__rmul__   rR   r)   c                     U $ r   rN   rU   s     r&   __rtruediv__CELEvalError.__rtruediv__   rR   r)   c                     U $ r   rN   rU   s     r&   __rfloordiv__CELEvalError.__rfloordiv__   rR   r)   c                     U $ r   rN   rU   s     r&   __rmod__CELEvalError.__rmod__   rR   r)   c                     U $ r   rN   rU   s     r&   __rpow__CELEvalError.__rpow__   rR   r)   c                 j    [        U[        5      (       a  U R                  UR                  :H  $ [        $ r   )
isinstancer;   r?   NotImplementedrU   s     r&   __eq__CELEvalError.__eq__   s(    e\**99

**r)   c                     U $ r   rN   )r$   r?   s     r&   __call__CELEvalError.__call__   rR   r)   )r   r   r>   r=   )r   r;   )"r,   r-   r.   r/   r0   r   r   larkTreeTokenr"   strrG   rK   rP   rV   rY   r\   r_   rb   re   rh   rk   rn   rq   rt   rw   rz   r}   boolr   r   r2   r3   r4   s   @r&   r;   r;   R   s    )-*.	,, 499%, DJJ'	, 48	, ,"*# ** * *S ^ S ^ S ^   # . S ^ S ^ c n c n c n # . 3 > c n c n C D 
c n  r)   r;   
TargetFunc)boundnew_text	exc_classr   c                 4   ^ ^ S[         S[         4UU 4S jjnU$ )a  
Wrap a function to transform native Python exceptions to CEL CELEvalError values.
Any exception of the given class is replaced with the new CELEvalError object.

:param new_text: Text of the exception, e.g., "divide by zero", "no such overload")
    this is the return value if the :exc:`CELEvalError` becomes the result.
:param exc_class: A Python exception class to match, e.g. ZeroDivisionError,
    or a sequence of exception classes (e.g. (ZeroDivisionError, ValueError))
:return: A decorator that can be applied to a function
    to map Python exceptions to :exc:`CELEvalError` instances.

This is used in the ``all()`` and ``exists()`` macros to silently ignore TypeError exceptions.
functionr   c                    >^  [        T 5      S[        R                  R                  S[        R                  R                  S[        4UU U4S jj5       n[        [        U5      $ )Nr?   kwargsr   c            
        >  T" U 0 UD6$ ! T a  n[         R                  TR                   SU  SU SU 35        [        R                  " 5       u    p4[        TUR                  UR                  5      R                  U5      nX%l	        Us S nA$ S nAf[         a*    [         R                  TR                   SU  SU S35        e f = f)NrD   z, **) --> rE   )loggerdebugr,   sysexc_infor;   r%   r?   rK   	__cause__	Exceptionerror)	r?   r   ex_rI   valuer   r   r   s	         r&   new_function<eval_error.<locals>.concrete_decorator.<locals>.new_function   s    
000  1 12"TF$vhfRDQR<<>1$Xr||RWWETTUWX"$  1 12"TF$vhaHIs    CA9B
C7C)r   celpyceltypesValueResultr   r   )r   r   r   r   s   ` r&   concrete_decorator&eval_error.<locals>.concrete_decorator   sW    	x	 4 4 	@T@T 	Y_ 	 	 
	 J--r)   )r   )r   r   r   s   `` r&   
eval_errorr      s#    .Z .J . . r)   r   c                    ^  [        T 5      S[        R                  R                  S[        R                  R                  S[        R                  R                  4U 4S jj5       nU$ )z
Wraps boolean operators to create CEL BoolType results.

:param function: One of the operator.lt, operator.gt, etc. comparison functions
:return: Decorated function with type coercion.
abr   c                    > T" X5      nU[         :X  a$  [        [        R                  R                  U5      $ [        R                  R	                  [        U5      5      $ r   )r   r   r   r   BoolTyper   )r   r   resultr   s      r&   bool_functionboolean.<locals>.bool_function   sD    !^#//88~~&&tF|44r)   )r   r   r   r   r   )r   r   s   ` r&   booleanr      sV     8_5-- 5%..2F2F 55>>KbKb 5 5
 r)   item	containerc           
         [         R                  R                  S5      n[        [        [
           U5       H*  n X0:X  a!  [         R                  R                  S5      s  $ M,     [        R                  SU < SU< SU< 35        U$ ! [         aJ  n[        R                  SU  SU SU 35        [        SUR                  UR                  5      n SnAM  SnAff = f)	a7  
CEL contains test; ignores type errors.

During evaluation of ``'elem' in [1, 'elem', 2]``,
CEL will raise internal exceptions for ``'elem' == 1`` and ``'elem' == 2``.
The :exc:`TypeError` exceptions are gracefully ignored.

During evaluation of ``'elem' in [1u, 'str', 2, b'bytes']``, however,
CEL will raise internal exceptions every step of the way, and an exception
value is the final result. (Not ``False`` from the one non-exceptional comparison.)

It would be nice to make use of the following::

    eq_test = eval_error("no such overload", TypeError)(lambda x, y: x == y)

It seems like ``next(iter(filter(lambda x: eq_test(c, x) for c in container))))``
would do it. But. It's not quite right for the job.

There need to be three results, something :py:func:`filter` doesn't handle.
These are the chocies:

-   True. There was a item found. Exceptions may or may not have been found.
-   False. No item found AND no expceptions.
-   CELEvalError. No item found AND at least one exception.

To an extent this is a little like the ``exists()`` macro.
We can think of ``container.contains(item)`` as ``container.exists(r, r == item)``.
However, exists() tends to silence exceptions, where this can expost them.

..  todo:: This may be better done as

    ``reduce(logical_or, (item == c for c in container), BoolType(False))``
FTzoperator_in(, r   no such overloadN) = )r   r   r   r   r   r   	TypeErrorr   r   r;   r%   r?   )r   r   r   cr   s        r&   operator_inr      s    D ^^,,U3F(6"I.	My~~..t44  / LL<xr)d6*EFM	  	MLL<vR	{&EF!"4bllBGGLF	Ms   #B
C?CCc                     U c  [         R                  R                  S5      $ [        [        U 5      n[         R                  R                  [        U5      5      n[        R                  SU < SU< 35        U$ )a  
The size() function applied to a Value. Delegate to Python's :py:func:`len`.

(string) -> int     string length
(bytes) -> int      bytes length
(list(A)) -> int    list size
(map(A, B)) -> int  map size

For other types, this will raise a Python :exc:`TypeError`.
(This is captured and becomes an :exc:`CELEvalError` Result.)

..  todo:: check container type for celpy.celtypes.StringType, celpy.celtypes.BytesType,
    celpy.celtypes.ListType and celpy.celtypes.MapType
r   zfunction_size(r   )r   r   IntTyper   r   lenr   r   )r   sized_containerr   s      r&   function_sizer   (  sb     ~~%%a((5),O^^##C$89F
LL>)d6*=>Mr)   !_-__+__-__*__/__%__<__<=__>=__>__==__!=__in__||__&&__?_:__[_]sizeendsWithc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   endswithstexts     r&   <lambda>r   U  s     7 7

48H Ir)   
startsWithc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   
startswithr   s     r&   r   r   V  s    %.."9"9!,,t:L"Mr)   matchesc                 l    [         R                  R                  [        R                  " X5      S L5      $ r   )r   r   r   research)r   patterns     r&   r   r   W  s"    %.."9"9"))G:OW[:["\r)   containsc                 D    [         R                  R                  X;   5      $ r   )r   r   r   r   s     r&   r   r   X  s     7 7	 Br)   getDatec                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   tstz_names     r&   r   r   Z  s    (>(>rzz'?R(Sr)   getDayOfMonthc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   [  s    enn.D.DREUEUV]E^._r)   getDayOfWeekc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   \      U^^-C-CBOOT[D\-]r)   getDayOfYearc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   ]  r   r)   getFullYearc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   ^  s    ENN,B,B2>>RYCZ,[r)   getMonthc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   _      )?)?G@T)Ur)   getHoursc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   a  r   r)   getMillisecondsc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   b  s    0F0FrGYGYZaGb0cr)   
getMinutesc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   c      5>>+A+A"--PWBX+Yr)   
getSecondsc                 ^    [         R                  R                  U R                  U5      5      $ r   )r   r   r   r   r   s     r&   r   r   d  r   r)   r   )bytesdoubledurationr1   listmap	null_typestring	timestampuinttypebase_functionsc                      \ rS rSrSr SS\\   SS4S jjrS\4S jr	\
S\\\R                  R                  \\S4   4S	 j5       r\R$                  S\\\R                  R                  \\S4   SS4S
 j5       rSS jrSrg)Referentiu  a8  
A Name can refer to any of the following things:

-   Annotations -- initially most names are these
    or a CELFunction that may implement a type.
    Must be provided as part of the initialization.

-   NameContainer -- some names are these. This is true
    when the name is *not* provided as part of the initialization because
    we discovered the name during type or environment binding.

-   celpy.celtypes.Value -- many annotations also have values.
    These are provided **after** Annotations, and require them.

-   CELEvalError -- This seems unlikely, but we include it because it's possible.

-   Functions -- All of the type conversion functions are names in a NameContainer.

A name can be ambiguous and refer to both a nested ``NameContainer`` as well
as a ``celpy.celtypes.Value`` (usually a MapType instance.)

Object ``b`` has two possible meanings:

-   ``b.c`` is a NameContainer for ``c``, a string.

-   ``b`` is a mapping, and ``b.c`` is syntax sugar for ``b['c']``.

The "longest name" rule means that the useful value is the "c" object
in the nested ``NameContainer``.
The syntax sugar interpretation is done in the rare case we can't find the ``NameContainer``.

>>> nc = NameContainer("c", celpy.celtypes.StringType)
>>> b = Referent(celpy.celtypes.MapType)
>>> b.value = celpy.celtypes.MapType({"c": "oops"})
>>> b.value == celpy.celtypes.MapType({"c": "oops"})
True
>>> b.container = nc
>>> b.value == nc
True

In effect, this class is
::

    Referent = Union[
        Annotation,
        celpy.celtypes.Value,
        CELEvalError,
        CELFunction,
    ]
Nref_tor   c                 X    S U l         S U l        S U l        SU l        U(       a  Xl         g g )NF)
annotationr   _value
_value_setr$   r  s     r&   r"   Referent.__init__  s4     1548  $ 	  $O r)   c                     U R                   R                   SU R                  < SU R                  < SU R                  < S3$ )Nz(annotation=z, container=z	, _value=rE   )r%   r,   r  r   r  rO   s    r&   rG   Referent.__repr__  sG    ~~&&'|DOO3F G* +kk_A'	
r)   NameContainerc                     U R                   b  U R                   $ U R                  (       a  U R                  $ U R                  $ )z
The longest-path rule means we prefer ``NameContainer`` over any locally defined value.
Otherwise, we'll provide a value if there is one.
Finally, we'll provide the annotation if there's no value.
:return:
)r   r  r  r  rO   s    r&   r   Referent.value  s5     >>%>>!__;; ??"r)   c                     Xl         SU l        g )NT)r  r  r  s     r&   r   r    s     r)   c                     [        U R                  5      nU R                  Ul        U R                  Ul        U R                  Ul        U$ r   )r
  r  r   r  r  )r$   news     r&   cloneReferent.clone  s6    t'[[

r)   )r  r  r  r   r   )r   r
  )r,   r-   r.   r/   r0   r   
Annotationr"   r   rG   propertyr   r   r   r   r;   CELFunctionr   setterr  r2   rN   r)   r&   r
  r
  u  s    1h ,0%Z(% 
%"
# 
 #u,,lKXZ # #  \\ENN00,_\^ 
	 r)   r
  r  z[_a-zA-Z][_a-zA-Z0-9]*c            	         ^  \ rS rSrSr\R                  " \5      r\R                  " S\ S\ S35      r	\
R                  " S 5      r   SS\\   S\\   S	\S    S
S4U 4S jjjrS\\\4   S
S4S jrS\S
S4S jr " S S\5      r\S\\\4   S\\   S
\4S j5       rS\\   S
\S \4   4S jrS
\S    4S jr S\\   S\S
\4S jr!SS jr"S
\4S jr#Sr$U =r%$ )r  i  a  
A namespace that fulfills the CEL name resolution requirement.

::

    Scenario: "qualified_identifier_resolution_unchecked"
      "namespace resolution should try to find the longest prefix for the evaluator."

NameContainer instances can be chained (via parent) to create a sequence of searchable
locations for a name.

-   Local-most is an Activation with local variables within a macro.
    These are part of a nested chain of Activations for each macro. Each local activation
    is a child with a reference to the parent Activation.

-   Parent of any local Activation is the overall Activation for this CEL evaluation.
    The overall Activation contains a number of NameContainers:

    -   The global variable bindings.

    -   Bindings of function definitions. This is the default set of functions for CEL
        plus any add-on functions introduced by C7N.

    -   The run-time annotations from the environment. There are two kinds:

        -   Protobuf message definitions. These are types, really.

        -   Annotations for global variables. The annotations tend to be hidden by the values.
            They're in the lookup chain to simplify access to protobuf messages.

    -   The environment also provides the built-in type names and aliases for the
        :mod:`celtypes` package of built-in types.

This means name resolution marches from local-most to remote-most, searching for a binding.
The global variable bindings have a local-most value and a more remote annotation.
The annotations (i.e. protobuf message types) have only a fairly remote annotation without
a value.

Structure.

A NameContainer is a mapping from names to Referents.

A Referent can be one of three things.

-   A NameContainer further down the path
-   An Annotation
-   An Annotation with a value.

Loading Names.

There are several "phases" to building the chain of ``NameContainer`` instances.

1.  The ``Activation`` creates the initial ``name : annotation`` bindings.
    Generally, the names are type names, like "int", bound to :py:class:`celtypes.IntType`.
    In some cases, the name is a future variable name, "resource",
    bound to :py:class:`celtypes.MapType`.

2.  The ``Activation`` creates a second ``NameContainer`` that has variable names.
    This has a reference back to the parent to resolve names that are types.

This involves decomposing the paths of names to make a tree of nested ``NameContainers``.
Upper-level containers don't (necessarily) have types or values -- they're merely
``NameContainer`` along the path to the target names.

Resolving Names.

See https://github.com/google/cel-spec/blob/master/doc/langdef.md#name-resolution

There are three cases required in the :py:class:`Evaluator` engine.

-   Variables and Functions. These are ``Result_Function`` instances: i.e., ordinary values.

-   ``Name.Name`` can be navigation into a protobuf package, when ``Name`` is protobuf package.
    The idea is to locate the longest possible match.

    If a.b is a name to be resolved in the context of a protobuf declaration with scope A.B,
    then resolution is attempted, in order, as A.B.a.b, A.a.b, and finally a.b.
    To override this behavior, one can use .a.b;
    this name will only be attempted to be resolved in the root scope, i.e. as a.b.

-   ``Name.Name`` can be syntactic sugar for indexing into a mapping when ``Name`` is a value of
    ``MapType`` or a ``MessageType``. It's evaluated as if it was ``Name["Name"]``.
    This is a fall-back plan if the previous resolution failed.

The longest chain of nested packages *should* be resolved first.
This will happen when each name is a ``NameContainer`` object containing
other ``NameContainer`` objects.

The chain of evaluations for ``IDENT . IDENT . IDENT`` is (in effect)
::

    member_dot(member_dot(primary(IDENT), IDENT), IDENT)

This makes the ``member_dot` processing left associative.

The ``primary(IDENT)`` resolves to a CEL object of some kind.
Once the ``primary(IDENT)`` has been resolved, it establishes a context
for subsequent ``member_dot`` methods.

-   If this is a ``MapType`` or a ``MessageType`` with an object,
    then ``member_dot`` will pluck out a field value and return this.

-   If this is a ``NameContainer`` or a ``PackageType`` then the ``member_dot``
    will pluck out a sub-package or ``EnumType`` or ``MessageType``
    and return the type object instead of a value.
    At some point a ``member_object`` production will build an object from the type.

The evaluator's :meth:`ident_value` method resolves the identifier into the ``Referent``.

Acceptance Test Case

We have two names

-   `a.b` -> NameContainer in which c = "yeah". (i.e., a.b.c : "yeah")
-   `a.b` -> Mapping with {"c": "oops"}.

This means any given name can have as many as three meanings:

-   Primarily as a NameContainer. This resolves name.name.name to find the longest
    namespace possible.

-   Secondarily as a Mapping. This will be a fallback when name.name.name is really
    syntactic sugar for name.name['name'].

-   Finally as a type annotation.

z^\.?z(?:\.z)*$Nnamer  parentr   c                 l   > U(       a  U(       a  [         TU ]  X05        O[         TU ]  5         X0l        g r   )r!   r"   r"  )r$   r!  r  r"  r%   s       r&   r"   NameContainer.__init__o  s)     FGd^,G/5r)   namesc                    UR                  5        H  u  p#U R                  R                  SU< SU< 35        U R                  R	                  U5      (       d  [        SU 35      eU nU R                  R                  U5      Gt pVU HN  nUR                  U[        5       5      nUR                  c  [        U R                  S9Ul
        UR                  nMP     UR                  U[        U5      5        M     g)a  
Used by an ``Activation`` to build a container used to resolve
long path names into nested NameContainers.
Sets annotations for all supplied identifiers.

``{"name1.name2": annotation}`` becomes two things:

1. nc2 = NameContainer({"name2" : Referent(annotation)})

2. nc1 = NameContainer({"name1" : Referent(nc2)})

:param names: A dictionary of {"name1.name1....": Referent, ...} items.
zload_annotations  : Invalid name Nr"  )itemsr   infoextended_name_pathmatch
ValueError	ident_patfindall
setdefaultr
  r   r  r"  )r$   r%  r!  	refers_tocontextpathfinalrefs           r&   load_annotationsNameContainer.load_annotations{  s    "  %{{}ODKK0I=IJ**0066 =!788G  >>11$7LT((xz:==($1$ECM--	 
 uhy&9:  -r)   valuesc                    UR                  5        H  u  p#U R                  R                  SU< SU< 35        U R                  R	                  U5      (       d  [        SU 35      eU nU R                  R                  U5      Gt pVU HN  nUR                  U[        5       5      nUR                  c  [        U R                  S9Ul
        UR                  nMP     UR                  U[        5       5        X4U   l        M     g)z&Update annotations with actual values.zload_values r'  r(  Nr)  )r*  r   r+  r,  r-  r.  r/  r0  r1  r
  r   r  r"  r   )r$   r9  r!  r2  r3  r4  r5  r6  s           r&   load_valuesNameContainer.load_values  s    %||~ODKK|D83ymDE**0066 =!788G  >>11$7LT((xz:==($1$ECM--	 
 uhj1#,EN !  .r)   c                       \ rS rSrSrSrg)NameContainer.NotFoundi  z
Raised locally when a name is not found in the middle of package search.
We can't return ``None`` from find_name because that's a valid value.
rN   N)r,   r-   r.   r/   r0   r2   rN   r)   r&   NotFoundr>    s    	 	r)   r?  	some_dictr4  c                 J   U(       a7  Utp# [         R                  [        [        [        [
        4   X   5      U5      $ [        [        U 5      $ ! [         aI    [         R                  R                  U< SU R                  5        35        [         R                  U5      ef = f)z
Extension to navgiate into mappings, messages, and packages.

:param some_dict: An instance of a MapType, MessageType, or PackageType.
:param path: names to follow into the structure.
:returns: Value found down inside the structure.
 not found in )r  dict_find_namer   r   r   r
  KeyErrorr   r   keysr?  r   )r@  r4  headtails       r&   rC  NameContainer.dict_find_name  s     KD3$33c8m,io>  	**	  3$$**dX^INNDTCU+VW#,,T223s   2A AB"c                 p   U(       a  Utp# X   R                   n[        U[
        5      (       a  UR                  U5      $ [        U[        R                  R                  [        R                  R                  [        R                  R                  [        45      (       a3  [
        R                  [!        ["        [$        [&        4   U5      U5      nU$ [!        [
        U5      $ U $ ! [         aE    U R                  R                  U< SU R	                  5        35        [
        R                  U5      ef = f)z
Find the name by searching down through nested packages or raise NotFound.
This is a kind of in-order tree walk of contained packages.
rB  )r   rD  r   r   rE  r  r?  r   	find_namer   r   MessageTypeMapTypePackageTypedictrC  r   r   r   r
  )r$   r4  rF  rG  sub_contextr   s         r&   rJ  NameContainer.find_name  s   
 KD3"j.. +}55",,T22^^//1G1G^^//7  8E7S7Sc8m,k:8  M;77 K-  3!!THN499;-"HI#,,T223s   C& &AD5c              #   x   #    U v   U R                   b#  U R                   R                  5        Sh  vN   gg N7f)zFYield this NameContainer and all of its parents to create a flat list.N)r"  parent_iterrO   s    r&   rR  NameContainer.parent_iter  s2     
;;"{{..000 #0s   /:8:packagec           
         U R                   R                  SU< SU< SU R                  5        SU R                   35        U(       a   U R                  R                  U5      S/-   nOS/n/ nU(       d  U(       az  USS nU R                  5        H,  n X2/-   nUR                  U5      nUR                  Xg45        M.     U R                   R                  SU S	U< S
U 35        U(       d	  U(       a  Mz  U(       d  [        U5      e[        US S9u  p[        [        U	5      $ ! [        R                   a     M  f = f)a  
Search with less and less package prefix until we find the thing.

Resolution works as follows.
If a.b is a name to be resolved in the context of a protobuf declaration with scope A.B,
then resolution is attempted, in order, as

1. A.B.a.b.  (Search for "a" in paackage "A.B"; the ".b" is handled separately.)

2. A.a.b.  (Search for "a" in paackage "A"; the ".b" is handled separately.)

3. (finally) a.b.  (Search for "a" in paackage None; the ".b" is handled separately.)

To override this behavior, one can use .a.b;
this name will only be attempted to be resolved in the root scope, i.e. as a.b.

We Start with the longest package name, a ``List[str]`` assigned to ``target``.

Given a target, search through this ``NameContainer`` and all parents in the
:meth:`parent_iter` iterable.
The first name we find in the parent sequence is the goal.
This is because values are first, type annotations are laast.

If we can't find the identifier with given package target,
truncate the package name from the end to create a new target and try again.
This is a bottom-up look that favors the longest name.

:param package: Prefix string "name.name.name"
:param name: The variable we're looking for
:return: Name resolution as a Rereferent, often a value, but maybe a package or an
    annotation.
zresolve_name(.z) in 	, parent= Nzresolve_name: target=z+[z], matches=c                     [        U S   5      $ Nr   )r   )
path_values    r&   r   ,NameContainer.resolve_name.<locals>.<lambda>2  s    #jm:Lr)   )key)r   r+  rE  r"  r/  r0  rR  rJ  appendr  r?  r   rD  maxr   r
  )
r$   rT  r!  targetr   ppackage_identr-  r4  r   s
             r&   resolve_nameNameContainer.resolve_name  s1   J 	G;axuTYY[M4;;-X	
 ^^++G4t;FTFJLfCR[F%%'/5M<=KK<VENNM#9:	 ( KK 5fXRx{SZR[\] ff 4.  ''LMHe$$ %-- s   (D%%D=<D=c                     [        U R                  S9nU R                  5        H  u  p#UR                  5       X'   M     U$ )Nr)  )r  r"  r*  r  )r$   r  kvs       r&   r  NameContainer.clone5  s4    4;;/JJLDAWWYCF !
r)   c                 f    U R                   R                   S[        U 5       SU R                   S3$ )N(rW  rE   )r%   r,   rN  r"  rO   s    r&   rG   NameContainer.__repr__;  s.    ..))*!DJ<yQOOr)   r)  )NNN)r   r  )&r,   r-   r.   r/   r0   r   compileIDENTr/  r,  logging	getLoggerr   r   r   r
  r"   r   r  r7  Contextr;  r   r?  staticmethodr   r
   r   rC  r   rJ  r	   rR  rd  r  rG   r2   r3   r4   s   @r&   r  r    s}   ~~ 

5!IeE7&s$CD/F #')-04	
63-
6 X&
6 _-	
6
 

6 
6;3
?+; 
;B-' -d -(9  +$sH}"5 +T#Y +6 + +(d3i E/62I,J B1Xo6 1@%c]@% @% 
	@%DP# P Pr)   c                       \ rS rSrSr    SS\\\\4      S\\   S\\	   S\S    SS4
S	 jjr
SS
 jr  SS\\\\4      S\\	   SS 4S jjrS\S\\\4   4S jrS\4S jrSrg)
Activationi?  a	  
Namespace with variable bindings and type name ("annotation") bindings.

..  rubric:: Life and Content

An Activation is created by an Environment and contains the annotations
(and a package name) from that Environment. Variables are loaded into the
activation for evaluation.

A nested Activation is created each time we evaluate a macro.

An Activation contains a ``NameContainer`` instance to resolve identifers.
(This may be a needless distinction and the two classes could, perhaps, be combined.)

..  todo:: The environment's annotations are type names used for protobuf.

..  rubric:: Chaining/Nesting

Activations can form a chain so locals are checked first.
Activations can nest via macro evaluation, creating transient local variables.

::

    ``"[2, 4, 6].map(n, n / 2)"``

means nested activations with ``n`` bound to 2, 4, and 6 respectively.
The resulting objects then form a resulting list.

This is used by an :py:class:`Evaluator` as follows::

    sub_activation: Activation = self.activation.nested_activation()
    sub_eval: Evaluator = self.sub_eval(sub_activation)
    sub_eval_partial: Callable[[Value], Value] = sub_eval.partial(
        tree_for_variable, tree_for_expression)
    push(celtypes.ListType(map(sub_eval_partial, pop()))

The ``localized_eval()`` creates a new :py:class:`Activation`
and an associated :py:class:`Evaluator` for this nested activation context.
It uses the :py:class:`Evaluator.visit` method to evaluate the given expression for
a new object bound to the given variable.

..  rubric:: Namespace Creation

We expand ``{"a.b.c": 42}`` to create nested namespaces: ``{"a": {"b": {"c": 42}}}``.

This depends on two syntax rules to define the valid names::

    member        : primary
                  | member "." IDENT ["(" [exprlist] ")"]

    primary       : ["."] IDENT ["(" [exprlist] ")"]

Ignore the ``["(" [exprlist] ")"]`` options used for member functions.
We have members and primaries, both of which depend on the following lexical rule::

    IDENT         : /[_a-zA-Z][_a-zA-Z0-9]*/

Name expansion is handled in order of length. Here's why::

    Scenario: "qualified_identifier_resolution_unchecked"
          "namespace resolution should try to find the longest prefix for the evaluator."

Most names start with ``IDENT``, but a primary can start with ``.``.
NannotationsrT  varsr"  r   c                 V   [         R                  SU< SU< SU< SU S3	5        [        U(       a  UR                  OSS9U l        Ub  U R                  R	                  U5        X l        Uc  g[        U[        5      (       a  [        S5      eU R                  R                  U5        g)	a/  
Create an Activation.

The annotations are loaded first. The variables are loaded second, and placed
in front of the annotations in the chain of name resolutions. Values come before
annotations.

:param annotations: Variables and type annotations.
    Annotations are loaded first to serve as defaults to create a parent NameContainer.
:param package: The package name to assume as a prefix for name resolution.
:param vars: Variables and their values, loaded to update the NameContainer.
:param parent: A parent activation in the case of macro evaluations.
zActivation(annotations=
, package=, vars=rW  rE   Nr)  zUse Activation.clone())
r   r+  r  identifiersr7  rT  r   rt  NotImplementedErrorr;  )r$   ru  rT  rv  r"  s        r&   r"   Activation.__init__  s    ( 	%k_JwkQUPX YXQ 	

 +8)/6%%T+
 "--k:  <j))%&>?? ((.r)   c                 z    [        5       nU R                  Ul        U R                  R                  5       Ul        U$ )zH
Create a clone of this activation with a deep copy of the identifiers.
)rt  rT  rz  r  )r$   r  s     r&   r  Activation.clone  s2      ,,224r)   c                 2    [        UUU U R                  S9nU$ )a=  
Create a nested sub-Activation that chains to the current activation.
The sub-activations don't have the same implied package context,

:param annotations: Variable type annotations
:param vars: Variables with literals to be converted to the desired types.
:return: An ``Activation`` that chains to this Activation.
)ru  rv  r"  rT  )rt  rT  )r$   ru  rv  r  s       r&   nested_activationActivation.nested_activation  s%     #LL	
 
r)   r!  c                     U R                   R                  U R                  [        U5      5      n[	        [
        [        [        4   U5      $ )a0  Find the object referred to by the name.

An Activation usually has a chain of NameContainers to be searched.

A variable can refer to an annotation and/or a value and/or a nested
container.  Most of the time, we want the `value` attribute of the Referent.
This can be a Result (a Union[Value, CelType])
)rz  rd  rT  r   r   r   r   r  )r$   r!  container_or_values      r&   resolve_variableActivation.resolve_variable  s=     "--::4<<TSE&-/02DEEr)   c           
          U R                   R                   SU R                  R                  < SU R                  < SU R                  < SU R                  R                   S3
$ )Nz(annotations=rx  ry  rW  rE   )r%   r,   rz  r"  rT  rO   s    r&   rG   Activation.__repr__  si    ~~&&'D,,336 7||& '$$' (&&--.a	1	
r)   )rz  rT  )NNNN)r   rt  r+   )r,   r-   r.   r/   r0   r   r   r   r  rq  r"   r  r  r   r   r  r  rG   r2   rN   r)   r&   rt  rt  ?  s    ?F ?C%)&*-1+/!'#z/":;+/ c]+/ 7#	+/
 \*+/ 
+/Z ?C&*!'#z/":; 7# 
	*
FS 
FU6=3H-I 
F
# 
r)   rt  c                       \ rS rSrSrSS jrS\R                  SS4S jr\	S\
S    S\R                  S\\   4S	 j5       rS
rg)	FindIdenti  zLocate the ident token at the bottom of an AST.

This is needed to find the bind variable for macros.

It works by doing a "visit" on the entire tree, but saving
the details of the ``ident`` nodes only.
r   Nc                     S U l         g r   ident_tokenrO   s    r&   r"   FindIdent.__init__  s
    *.r)   r=   c                 t    [        [        R                  UR                  S   5      nUR                  U l        g r[  )r   r   r   childrenr   r  )r$   r=   r  s      r&   identFindIdent.ident  s)    4::t}}Q'78&,,r)   rF   c                 P    [        5       nUR                  U5        UR                  $ r   )r  visitr  )rF   r=   fis      r&   in_treeFindIdent.in_tree  s    [
~~r)   r  )r   N)r,   r-   r.   r/   r0   r"   r   r   r  classmethodr   r   r   r  r2   rN   r)   r&   r  r    sY    /-$)) - - T+& dii HSM  r)   r  method	Evaluatorc                 d   ^  [        T 5      SSS[        R                  S[        4U 4S jj5       nU$ )z
Decorator to create consistent evaluation trace logging.
This only works for a class with a ``level`` attribute.
This is generally applied to the methods matching rule names.
r$   r  r=   r   c                    > U R                   R                  U R                  S-   U< 35        T" X5      nU R                   R                  U R                  S-   UR                   SU< 35        U$ )Nz| z -> )r   r+  leveldata)r$   r=   r   r  s      r&   concrete_methodtrace.<locals>.concrete_method  sd    DJJtO,TH56#DJJtO,TYYKtF:FGr)   )r   r   r   r   )r  r  s   ` r&   tracer    s<     6]k  s  
 r)   c                   N  ^  \ rS rSrSr\R                  " S 5      r S/S\R                  S\
S\\\   \\\4   S4   SS4S jjrS\R                  SS 4S	 jrS
\SS 4S jrS0S\S\S\4S jjrS\R0                  R2                  4S jrS\R                  S\\   4U 4S jjr S/S\R<                  S\\ \      S\4S jjr! S/S\S\R<                  S\\ \      S\4S jjr"S\R                  S\R0                  RF                  4S jr$\%S\R                  S\4S j5       r&\%S\R                  S\4S j5       r'\%S\R                  S\4S j5       r(\%S\R                  S\4S j5       r)\%S\R                  S\4S j5       r*\%S\R                  S\4S j5       r+\%S\R                  S\4S j5       r,S \R                  S\-\R0                  R2                  /\.4   4S! jr/S \R                  S\-\R0                  R2                  /\.4   4S" jr0S \R                  S\1\-\\/\4   \R                  4   4S# jr2\%S\R                  S\4S$ j5       r3\%S\R                  S\4S% j5       r4\%S\R                  S\4S& j5       r5\%S\R                  S\4S' j5       r6\%S\R                  S\4S( j5       r7\%S\R                  S\4S) j5       r8\%S\R                  S\4S* j5       r9\%S\R                  S\4S+ j5       r:\%S\R                  S\4S, j5       r;\%S\R                  S\4S- j5       r<S.r=U =r>$ )1r  i  a  
Evaluate an AST in the context of a specific Activation.

See https://github.com/google/cel-go/blob/master/examples/README.md

General Evaluation.

An AST node must call ``self.visit_children(tree)`` explicitly
to build the values for all the children of this node.

Exceptions.

To handle ``2 / 0 || true``, the ``||``, ``&&``, and ``?:`` operators
do not trivially evaluate and raise exceptions. They bottle up the
exceptions and treat them as a kind of undecided value.

Identifiers.

Identifiers have three meanings:

-   An object. This is either a variable provided in the activation or a function provided
    when building an execution. Objects also have type annotations.

-   A type annotation without an object, This is used to build protobuf messages.

-   A macro name. The ``member_dot_arg`` construct may have a macro.
    Plus the ``ident_arg`` construct may also have a ``dyn()`` or ``has()`` macro.
    See below for more.

Other than macros, a name maps to an ``Referent`` instance. This will have an
annotation and -- perhaps -- an associated object.

Names have nested paths. ``a.b.c`` is a mapping, ``a``, that contains a mapping, ``b``,
that contains ``c``.

**MACROS ARE SPECIAL**.

The macros do not **all** simply visit their children to perform evaluation.
There are three cases:

- ``dyn()`` does effectively nothing.
  It visits it's children, but also provides progressive type resolution
  through annotation of the AST.

- ``has()`` attempts to visit the child and does a boolean transformation
  on the result.
  This is a macro because it doesn't raise an exception for a missing
  member item reference, but instead maps an exception to False.
  It doesn't return the value found, for a member item reference; instead, it maps
  this to True.

- The various ``member.macro()`` constructs do **NOT** visit children.
  They create a nested evaluation environment for the child variable name and expression.

The :py:meth:`member` method implements the macro evaluation behavior.
It does not **always** trivially descend into the children.
In the case of macros, the member evaluates one child tree in the presence
of values from another child tree using specific variable binding in a kind
of stack frame.

Nast
activation	functionsr   c                 6   Xl         X l        U R                  U l        U   [        U[        5      (       aF  U=(       d    /  Vs0 s H  oDR
                  U_M     nn[        R                  " U[        5      U l	        OA[        U[        5      (       a!  [        R                  " U[        5      U l	        O[        U l	        SU l        U R                  R                  SU R                  < 35        U R                  R                  SU R                  < 35        gs  snf )af  
Create an evaluator for an AST with specific variables and functions.

:param ast: The AST to evaluate.
:param activation: The variable bindings to use.
:param functions: The functions to use. If nothing is supplied, the default
    global `base_functions` are used. Otherwise a ChainMap is created so
    these local functions override the base functions.
r   zactivation: functions: N)r  base_activationr  r   r   r,   collectionsChainMapr  r  r   r  r   r+  )r$   r  r  r  flocal_functionss         r&   r"   Evaluator.__init__H  s     )..i**'0B'6!

A   )11/>RDN	7++(11)^LDN+DN
<':;<;t~~&89:s   Dc                 >    [        XR                  U R                  S9$ )z
Build an evaluator for a sub-expression in a macro.
:param ast: The AST for the expression in the macro.
:return: A new `Evaluator` instance.
)r  r  )r  r  r  )r$   r  s     r&   sub_evaluatorEvaluator.sub_evaluatori  s     DNNSSr)   r9  c                     U R                   R                  5       U l        U R                  R                  R	                  U5        U R
                  R                  SU R                  < 35        U $ )z
Chain a new activation using the given Context.
This is used for two things:

1. Bind external variables like command-line arguments or environment variables.

2. Build local variable(s) for macro evaluation.
zActivation: )r  r  r  rz  r;  r   r+  )r$   r9  s     r&   set_activationEvaluator.set_activationq  sU     ..446##//7<':;<r)   r!  
root_scopec                      [        [        U R                  R                  U5      5      $ ! [         a    U R
                  U   s $ f = f)a  Resolve names in the current activation.
This includes variables, functions, the type registry for conversions,
and protobuf packages, as well as protobuf types.

We may be limited to root scope, which prevents searching through alternative
protobuf package definitions.
)r   r   r  r  rD  r  )r$   r!  r  s      r&   ident_valueEvaluator.ident_value  sA    	( @ @ FGG 	(>>$''	(s   (+ AAc                     U R                  U R                  5      n[        U[        5      (       a  Ue[	        [
        R                  R                  U5      $ )a0  
Evaluate this AST and return the value or raise an exception.

There are two variant use cases.

-   External clients want the value or the exception.

-   Internally, we sometimes want to silence CELEvalError exceptions so that
    we can apply short-circuit logic and choose a non-exceptional result.
)r  r  r   r;   r   r   r   r   )r$   r   s     r&   evaluateEvaluator.evaluate  s?     

488$e\**KENN((%00r)   r=   c                 z   > U =R                   S-  sl         [        TU ]	  U5      nU =R                   S-  sl         U$ )zOExtend the superclass to track nesting and current evaluation context.
           )r  r!   visit_children)r$   r=   r   r%   s      r&   r  Evaluator.visit_children  s3     	

a
'-

a
r)   
name_tokenexprlistc           	          U R                   UR                     n[        U[        5      (       a  U$  [        [        [           U=(       d    / 5      nU" U6 $ ! [         aD  nSU SU R                   S3n[	        XTR
                  UR                  US9nXFl        Us SnA$ SnAff = f! [         a2  n[	        SUR
                  UR                  US9nXFl        Us SnA$ SnAf[        [        4 aW  nU R                  R!                  SU< SU S	U 35        [	        S
UR
                  UR                  US9nXFl        Us SnA$ SnAff = f)z|
Function evaluation.

- Object creation and type conversions.
- Other built-in functions like size()
- Extension functions
undeclared reference to '' (in activation '')r>   Nreturn error for overflowzfunction_eval(r   r   r   )r  r   rD  r  r;   r%   r?   r   r   r   r
   r   r.  r   AttributeErrorr   r   )r$   r  r  r   r   errr   list_exprlists           r&   function_evalEvaluator.function_eval  s9   
	~~j&6&67H h--O	 fx~2>M]++  	+J< 8##'??"327  !llBGG:NE OL	  	 +R\\277*VE OL>* 	KKznBxjrdST "BLL"''ME OL	sM   A $B) 
B&"9B!B&!B&)
E
3'C E
 E
3AE?E
E
objectmethod_identc                     U R                   UR                     n[        U[        5      (       a  U$ [        U[        5      (       a  U$  [        [        [           U=(       d    / 5      nU" U/UQ76 $ ! [         a  nU R                  R	                  SU< SU< SU SU< 35        U R                  R	                  SU R                    35        SUR                  < SU R
                   S3n[        XeR                  UR                  US9nXWl	        Us S	nA$ S	nAff = f! [         a2  n[        S
UR                  UR                  US9nXWl	        Us S	nA$ S	nAf[        [         4 a\  nU R                  R	                  SU< SU< SU SU< 35        [        SUR                  UR                  US9nXWl	        Us S	nA$ S	nAff = f)z
Method evaluation. While are (nominally) attached to an object, the only thing
actually special is that the object is the first parameter to a function.
zmethod_eval(r   r   r  zundeclared reference to z (in activation 'r  r  Nr  r   )r  r   rD  r   r   r  r;   r%   r?   r   r   r   r
   r   r.  r   r  )	r$   r  r  r  r   r   r  r   r  s	            r&   method_evalEvaluator.method_eval  s   	~~l&8&89H fl++M,//O	 fx~2>MF3]33%  		KKVJb8H8*TZ[]Z`abKKDNN+;<=*<+=+=*@ A##'??"327  !llBGG<PE OL		&  	 +R\\277,XE OL>* 	KKVJb8H8*TZ[]Z`ab !3R\\277R^_E OL		sO   A3 
(D! 3
D=BDDD!
G+'EGG+AG<GGc                     U R                  U5      n[        R                  R                  [	        US   [
        5      (       + 5      $ )a  
The has(e.f) macro.

https://github.com/google/cel-spec/blob/master/doc/langdef.md#field-selection

1.  If e evaluates to a map, then has(e.f) indicates whether the string f is a
    key in the map (note that f must syntactically be an identifier).

2.  If e evaluates to a message and f is not a declared field for the message,
    has(e.f) raises a no_such_field error.

3.  If e evaluates to a protocol buffers version 2 message and f is a defined field:

    - If f is a repeated field or map field, has(e.f) indicates whether the field is
      non-empty.

    - If f is a singular or oneof field, has(e.f) indicates whether the field is set.

4.  If e evaluates to a protocol buffers version 3 message and f is a defined field:

    - If f is a repeated field or map field, has(e.f) indicates whether the field is
      non-empty.

    - If f is a oneof or singular message field, has(e.f) indicates whether the field
      is set.

    - If f is some other singular field, has(e.f) indicates whether the field's value
      is its default value (zero for numeric fields, false for booleans,
      empty for strings and bytes).

5.  In all other cases, has(e.f) evaluates to an error.

r   )r  r   r   r   r   r;   )r$   r  
has_valuess      r&   macro_has_evalEvaluator.macro_has_eval  s8    D ((2
~~&&:jm\+R'RSSr)   c           
         [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  aM  U R                  S   n[	        [
        [        [        [        4   U R                  U5      5      u  pEn U" XEU5      $ [!        UR"                   SUR                   S3UR$                  R&                  UR$                  R(                  S9e! [         a  nU R                  R                  UR                   SU SU SU 35        S[        U5       S[        U5       S[        U5       S	3n[        XR                  UR                  US
9n	Xyl        U	s SnA$ SnAff = f)z
expr           : conditionalor ["?" conditionalor ":" expr]

The default implementation short-circuits
and can ignore an CELEvalError in a sub-expression.
r  r      r   rk  r   r   z2found no matching overload for _?_:_ applied to '()'r=   N z: bad expr noder   r   r   r  r  r  r   r   r   r   r   r   r,   r  r;   r%   r?   r   r   r  rA   r   r   )
r$   r=   r9  func
cond_valueleftrightr   r  r   s
             r&   exprEvaluator.expr  s[    t}}"((.F!91$>>'*D&*51G+H$J]J]^bJc&d#Je
Je44 !99+Qt}}o_=YY^^yy''   !!T]]O1TF"UG6""NO$$($4#5RT
|2d5k]RTV  %S,,dK"$s   C# #
E5-A=E0*E50E5c           
         [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  aF  U R                  S   n[	        [
        [        [        4   U R                  U5      5      u  pE U" XE5      $ [!        UR"                   SUR                   S3UR$                  R&                  UR$                  R(                  S9e! [         a|  nU R                  R                  UR                   SU SU SU 35        S[        U5       S[        U5       S	3n[        XvR                  UR                  US
9nXhl        Us SnA$ SnAff = f)z
conditionalor  : [conditionalor "||"] conditionaland

The default implementation short-circuits
and can ignore an CELEvalError in a sub-expression.
r  r      r   rk  r   r   z1found no matching overload for _||_ applied to '(r  r  Nr  : bad conditionalor noder  r  	r$   r=   r9  r  r  r  r   r  r   s	            r&   conditionalorEvaluator.conditionalor@  F    t}}"((.F!91$>>&)DuVV^4d6I6I$6OPKD
D(( !99+Qt}}o-EFYY^^yy''   !!T]]O1TF"UG6""NO$$(J<r$u+bB  %S,,dK"$   C 
E"&A1EE"E"c           
         [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  aF  U R                  S   n[	        [
        [        [        4   U R                  U5      5      u  pE U" XE5      $ [!        UR"                   SUR                   S3UR$                  R&                  UR$                  R(                  S9e! [         a|  nU R                  R                  UR                   SU SU SU 35        S[        U5       S[        U5       S	3n[        XvR                  UR                  US
9nXhl        Us SnA$ SnAff = f)z
conditionaland : [conditionaland "&&"] relation

The default implementation short-circuits
and can ignore an CELEvalError in a sub-expression.
r  r   r  r   rk  r   r   z1found no matching overload for _&&_ applied to '(r  r  Nr  r  r  r  r  s	            r&   conditionalandEvaluator.conditionalanda  r  r  c           
         [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  a  [        [        [
        R                  [
        R                  4   UR                  5      u  p4SSSSSS	S
S.UR                     nU R                  U   n[        [        [        [           [        4   U R                  U5      5      u  tpxn	U R                  R                  SU< SU SU	< 35         U" Xy5      $ [)        UR                   SUR                   S3UR*                  R,                  UR*                  R.                  S9e! [         a  n
U R                  R                  UR                   SU SU	 SU
 35        SUR                  < S[        U5       S[        U	5       S3n[!        XR"                  U
R$                  US9nXl        Us Sn
A
$ Sn
A
ff = f)a\  
relation       : [relation_lt | relation_le | relation_ge | relation_gt
               | relation_eq | relation_ne | relation_in] addition

relation_lt    : relation "<"
relation_le    : relation "<="
relation_gt    : relation ">"
relation_ge    : relation ">="
relation_eq    : relation "=="
relation_ne    : relation "!="
relation_in    : relation "in"

This could be refactored into separate methods to skip the lookup.

Ideally::

    values = self.visit_children(tree)
    func = functions[op_name_map[tree.data]]
    result = func(*values)

The AST doesn't provide a flat list of values, however.
r  r   r  r   r   r   r   r   r   r   )relation_ltrelation_lerelation_gerelation_gtrelation_eqrelation_nerelation_inz	relation r  rk  r   r   found no matching overload for  applied to '(r  r  Nz: bad relation noder  )r   r  r  r   r   r   r   r  r  r
   r   r   r   r   r,   r  r;   r%   r?   r   r   rA   r   r   r$   r=   r9  left_op
right_treeop_namer  r  r   r  r   r  r   s                r&   relationEvaluator.relation  s   0 t}}"((.F!91$"&uTYY		-A'BDMM"RG$%%$%%% llG >>'*D $U4<+?%@$BUBUVZB[ \JTKK	$7)1UIFG
D(( !99+Qt}}o-@AYY^^yy''   !!T]]O1TF"UG6""NO5gll5E F$$(J<r$u+bB  %S,,dK"$s   
E 
G3)A?G.(G3.G3c           
         [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  a  [        [        [
        R                  [
        R                  4   UR                  5      u  p4SSS.UR                     nU R                  U   n[        [        [        [           [        4   U R                  U5      5      u  tpxn	U R                  R                  SU< SU SU	< 35         U" Xy5      $ [-        UR                   SUR                   S3UR.                  R0                  UR.                  R2                  S9e! [         a  n
U R                  R                  UR                   S	U S
U	 SU
 35        SUR                  < S[        U5       S
[        U	5       S3n[!        XR"                  U
R$                  US9nXl        Us Sn
A
$ Sn
A
f[(        [*        4 ab  n
U R                  R                  UR                   S	U S
U	 SU
 35        [!        SU
R"                  U
R$                  US9nXl        Us Sn
A
$ Sn
A
ff = f)at  
addition       : [addition_add | addition_sub] multiplication

addition_add   : addition "+"
addition_sub   : addition "-"

This could be refactored into separate methods to skip the lookup.

Ideally::

    values = self.visit_children(tree)
    func = functions[op_name_map[tree.data]]
    result = func(*values)

The AST doesn't provide a flat list of values, however.
r  r   r  r   r   )addition_addaddition_subz	addition r  rk  r   r   r  r  r  r  Nr  z: bad addition noder  )r   r  r  r   r   r   r   r  r  r
   r   r   r   r   r,   r  r;   r%   r?   r   r.  OverflowErrorr   rA   r   r   r  s                r&   additionEvaluator.addition  s'   $ t}}"((.F!91$"&uTYY		-A'BDMM"RG % % llG >>'*D $U4<+?%@$BUBUVZB[ \JTKK	$7)1UIFGD((" !99+Qt}}o-@AYY^^yy'' !  !!T]]O1TF"UG6""NO5gll5E F$$(J<r$u+bB  %S,,dK"$. !!T]]O1TF"UG6""NO$%@",,PRPWPW^bc"$	s2   E 
I$A?G)#I)I<AIIIc           
         [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  a  [        [        [
        R                  [
        R                  4   UR                  5      u  p4SSSS.UR                     nU R                  U   n[        [        [        [           [        4   U R                  U5      5      u  tpxn	U R                  R                  SU< S	U S	U	< 35         U" Xy5      $ [/        UR                   S	UR                   S3UR0                  R2                  UR0                  R4                  S9e! [         a  n
U R                  R                  UR                   S
U SU	 SU
 35        SUR                  < S[        U5       S[        U	5       S3n[!        XR"                  U
R$                  US9nXl        Us Sn
A
$ Sn
A
f[(         ab  n
U R                  R                  UR                   S
U SU	 SU
 35        [!        SU
R"                  U
R$                  US9nXl        Us Sn
A
$ Sn
A
f[*        [,        4 ab  n
U R                  R                  UR                   S
U SU	 SU
 35        [!        SU
R"                  U
R$                  US9nXl        Us Sn
A
$ Sn
A
ff = f)a  
multiplication : [multiplication_mul | multiplication_div | multiplication_mod] unary

multiplication_mul : multiplication "*"
multiplication_div : multiplication "/"
multiplication_mod : multiplication "%"

This could be refactored into separate methods to skip the lookup.

Ideally::

        values = self.visit_children(tree)
        func = functions[op_name_map[tree.data]]
        result = func(*values)

The AST doesn't provide a flat list of values, however.
r  r   r  r   r   r   )multiplication_divmultiplication_mulmultiplication_modzmultiplication r  rk  r   r   r  r  r  r  Nzmodulus or divide by zeror  z: bad multiplication noder  )r   r  r  r   r   r   r   r  r  r
   r   r   r   r   r,   r  r;   r%   r?   r   ZeroDivisionErrorr.  r  r   rA   r   r   r  s                r&   multiplicationEvaluator.multiplication  s   & t}}"((.F!91$"&uTYY		-A'BDMM"RG&+&+&+ ll	G
 >>'*D $U4<+?%@$BUBUVZB[ \JTKKxq	5)LMD((, !99+Qt}}o-FGYY^^yy'' +  !!T]]O1TF"UG6""NO5gll5E F$$(J<r$u+bB  %S,,dK"$$ !!T]]O1TF"UG6""NO$%@",,PRPWPW^bc"$. !!T]]O1TF"UG6""NO$%@",,PRPWPW^bc"$	sE   E 
K	%A?G*$K	*K	7AIK	K	'AK>K	K	c                    [        UR                  5      S:X  a  U R                  U5      nUS   $ [        UR                  5      S:X  a  [        [        [
        R                  [
        R                  4   UR                  5      u  p4SSS.UR                     nU R                  U   n[        [        [        [           [        4   U R                  U5      5      u  pxU R                  R                  SU SU< 35         U" U5      $ [+        UR                   SUR                   S3UR,                  R.                  UR,                  R0                  S9e! [         a{  n	U R                  R                  UR                   S	U S
U	 35        SUR                  < S[        U5       S3n
[!        XR"                  U	R$                  US9nXl        Us Sn	A	$ Sn	A	f[(         a_  n	U R                  R                  UR                   S	U S
U	 35        [!        SU	R"                  U	R$                  US9nXl        Us Sn	A	$ Sn	A	ff = f)aK  
unary          : [unary_not | unary_neg] member

unary_not      : "!"
unary_neg      : "-"

This should be refactored into separate methods to skip the lookup.

ideally::

    values = self.visit_children(tree)
    func = functions[op_name_map[tree.data]]
    result = func(*values)

But, values has the structure ``[[], right]``
r  r   r  r   r   )	unary_not	unary_negzunary r  rk  r   r  r  r  r  Nr  z: bad unary noder  )r   r  r  r   r   r   r   r  r  r
   r   r   r   r   r,   r  r;   r%   r?   r   r.  r   rA   r   r   )r$   r=   r9  op_treer  r  r  r  r  r   r  r   s               r&   unaryEvaluator.unary;  s   $ t}}" ((.F!91$"&uTYY		-A'BDMM"RG!! llG >>'*DuT&\6%9:D<O<OPT<UVKDKKwiq	:;E{"" !99+Qt}}o-=>YY^^yy'' !  !!T]]O1UG6""FG5gll5E F$$(K=4  %S,,dK"$ !!T]]O1UG6""FG$%@",,PRPWPW^bc"$	s2   ?E 
I A0GI I !AH;5I ;I childc                   ^^ [        [        R                  UR                  S   5      n[        [        [        R                  [        R                  4   UR                  5      u  p4[
        R                  U5      mTcM  [        UR                   SUR                   S3UR                  R                  UR                  R                  S9eU R                  US9mS[        R                  R                  S[         4UU4S jjnU$ )	a  
Builds macro function.

For example

    ``[1, 2, 3].map(n, n/2)``

Builds the function = ``lambda n: n/2``.

The function will expose exceptions, disabling short-circuit ``||`` and ``&&``.

The `child` is a `member_dot_arg` construct:

- [0] is the expression to the left of the '.'

- [1] is the function, `map`, to the right of the `.`

- [2] is the arguments in ()'s.
  Within this, there are two children: a variable and an expression.
r  r  : bad macro noder  r  rh  r   c                 b   > TR                  [        [        T5      U 05      R                  5       $ r   r  r   r   r  )rh  
identifiernested_evals    r&   sub_expr,Evaluator.build_macro_eval.<locals>.sub_expr  s)    --tC/Da.HIRRTTr)   r   r   r   r  r   r  r  r   r  rA   r   r   r  r   r   r   r   r$   r  r?   var_tree	expr_treer  r  r  s         @@r&   build_macro_evalEvaluator.build_macro_evalv  s    * DIIu~~a01"5DII)=#>N&&x0
 ::,a//?@ZZ__zz((  ((Y(7	U,, 	U 	U 	U r)   c                   ^^ [        [        R                  UR                  S   5      n[        [        [        R                  [        R                  4   UR                  5      u  p4[
        R                  U5      mTcM  [        UR                   SUR                   S3UR                  R                  UR                  R                  S9eU R                  US9mS[        R                  R                  S[         4UU4S jjnU$ )	a  
Builds macro function for short-circuit logical evaluation ignoring exception values.

For example

    ``[1, 2, 'hello'].exists(n, n >= 2)``

Builds the function = ``lambda n: n >= 2``.

The function will swallow exceptions, enabling short-circuit ``||`` and ``&&``.
r  r  r  r  r  rh  r   c                    >  TR                  [        [        T5      U 05      R                  5       $ ! [         a  nUs S nA$ S nAff = fr   )r  r   r   r  r;   )rh  r   r  r  s     r&   r  /Evaluator.build_ss_macro_eval.<locals>.sub_expr  sC    "114Z3H!2LMVVXX 	s   .2 
AAAAr  r  s         @@r&   build_ss_macro_evalEvaluator.build_ss_macro_eval  s     DIIu~~a01"5DII)=#>N&&x0
 ::,a//?@ZZ__zz((  ((Y(7	,, 	 	 	 r)   c                 d  ^^	^
 [        [        R                  UR                  S   5      n[        [        [        R                  [        R                  [        R                  [        R                  4   UR                  5      u  p4pV[
        R                  U5      m
[
        R                  U5      mT
b  TcM  [        UR                   SUR                   S3UR                  R                  UR                  R                  S9eU R                  US9m	S[        S[        S[        4UU	U
4S	 jjnXu4$ )
a  
Builds macro function and intiial expression for reduce().

For example

    ``[0, 1, 2].reduce(r, i, 0, r + 2*i+1)``

Builds the function = ``lambda r, i: r + 2*i+1`` and initial value = 0.

The `child` is a `member_dot_arg` construct:

- [0] is the expression to the left of the '.'

- [1] is the function, `reduce`, to the right of the `.`

- [2] is the arguments in ()'s.
  Within this, there are four children: two variables and two expressions.
r  r  r  r  r  rir   c                    > TR                  [        [        T5      U [        [        T5      U05      R                  5       $ r   r  )r%  r&  
iter_identr  reduce_idents     r&   r  3Evaluator.build_reduce_macro_eval.<locals>.sub_expr  s9    --c<(!T#z-BAFHHP
Sr)   )r   r   r   r  r   r  r  r   r  rA   r   r   r  r   )r$   r  r?   reduce_var_treeiter_var_treeinit_expr_treer  r  r(  r  r)  s           @@@r&   build_reduce_macro_eval!Evaluator.build_reduce_macro_eval  s   * DIIu~~a01tyy$))TYY		ABDMMR 	B !((9&&}5
:#5 ::,a//?@ZZ__zz((  ((Y(7	S 	S6 	Sf 	S 	S ''r)   c                 .    U R                  U5      nUS   $ )aO  
member         : member_dot | member_dot_arg | member_item | member_object | primary

member_dot     : member "." IDENT
member_dot_arg : member "." IDENT "(" [exprlist] ")"
member_item    : member "[" expr "]"
member_object  : member "{" [fieldinits] "}"

https://github.com/google/cel-spec/blob/master/doc/langdef.md#field-selection
r   )r  )r$   r=   r9  s      r&   memberEvaluator.member  s     $$T*ayr)   c                 X   [        [        [        R                  [        R                  4   UR
                  5      u  p#U R                  U5      nUR                  n[        U[        5      (       a  UnU$ [        U[        5      (       aH  XT;   a  XE   R                  nU$ SU< S[        UR                  5       5       3n[        U[        SUS9n U$ [        U[        R                  R                   5      (       a7  U R"                  R%                  SU< SU< S35        UR'                  U5      nU$ [        U[        R                  R(                  5      (       a   XE   nU$ U< S	[+        U5       S
3n[        U[,        SUS9nU$ ! [         a    SU< 3n[        U[        SUS9n U$ f = f)a  
member         : member_dot | member_dot_arg | member_item | member_object | primary

member_dot     : member "." IDENT
member_dot_arg : member "." IDENT "(" [exprlist] ")"
member_item    : member "[" expr "]"
member_object  : member "{" [fieldinits] "}"

https://github.com/google/cel-spec/blob/master/doc/langdef.md#name-resolution

-   ``primary``: Variables and Functions: some simple names refer to variables in the
    execution context, standard functions, or other name bindings provided by the CEL
    application.

-   ``member_dot``: Field selection: appending a period and identifier to an expression
    could indicate that we're accessing a field within a protocol buffer or map.
    See below for **Field Selection**.

-   ``member_dot``: Protocol buffer package names: a simple or qualified name could
    represent an absolute or relative name in the protocol buffer package namespace.
    Package names must be followed by a message type, enum type, or enum constant.

-   ``member_dot``: Protocol buffer message types, enum types, and enum constants:
    following an optional protocol buffer package name, a simple or qualified name
    could refer to a message type, and enum type, or an enum constant in the package's
    namespace.

Field Selection. There are four cases.

https://github.com/google/cel-spec/blob/master/doc/langdef.md#field-selection

- If e evaluates to a message
  and f is not declared in this message, the runtime error no_such_field is raised.

- If e evaluates to a message
  and f is declared, but the field is not set,
  the default value of the field's type will be produced.

- If e evaluates to a map, then e.f is equivalent to e['f'].

- In all other cases, e.f evaluates to an error.

TODO: implement member "." IDENT for messages.
zNo z in bindings Nr  zmember_dot(r   rE   zno such member in mapping: z with type: 'z"' does not support field selection)r   r   r   r   r   r  r  r   r   r;   r  sortedrE  rD  r   r   rK  r   r+  getrL  r  r   )r$   r=   member_treeproperty_name_tokenr1  property_namer   r  s           r&   
member_dotEvaluator.member_dot  s   \ ,0dii6K0Ldmm+\(K(+11fl++F< ; .. &.442 / M,M&:O9PQ%c8TE, )  : :;;KK{6*B}6GqIJZZ.F$   6 677F.  JmDL>9[\C!#y$TBF  F3M3DE%c8TE Fs   F  F)(F)c                 
  ^ [         [        R                  R                  [        /[        R                  R                  4   n[        [        [        R                  [        R                  4   UR                  SS 5      u  p4UR                  S:X  a  [        [        R                  R                  U R                  U5      5      nU R                  U5      m[        [        [        R                  R                      [#        TU5      5      n[        R                  R                  U5      nU$ UR                  S:X  ao  [        [        R                  R                  U R                  U5      5      nU R                  U5      m[        R                  R                  [%        TU5      5      nU$ UR                  S:X  a  [        [        R                  R                  U R                  U5      5      n[        U['        S[(        5      " [        R                  R*                  5      5      nU R-                  U5      m[/        U[#        TU5      [        R                  R                  S5      5      n	U	$ UR                  S:X  a  [        [        R                  R                  U R                  U5      5      n[        U['        S[(        5      " [        R                  R0                  5      5      n
U R-                  U5      m[/        U
[#        TU5      [        R                  R                  S	5      5      n	U	$ UR                  S
:X  a{  [        [        R                  R                  U R                  U5      5      nU R                  U5      m[3        U4S jU 5       5      n[        R                  R                  US:H  5      $ UR                  S:X  ae  [        [        R                  R                  U R                  U5      5      nU R5                  U5      u  pU R                  U5      n[/        XU5      n	U	$ UR                  S:X  aA  [        [        R                  R                  U R                  U5      5      n [7        U5      n	U	$ [A        UR                  5      S:X  aM  [        [        [        [        R                  4   U RC                  U5      5      u  nnU RE                  UU5      nU$ [        [        [        [        R                  [        [           4   U RC                  U5      5      u  nnnU RE                  UUU5      nU$ ! [8         a-  nSn[;        UUR<                  UR>                  US9n	 SnAU	$ SnAff = f)aq  
member         : member_dot | member_dot_arg | member_item | member_object | primary

member_dot     : member "." IDENT
member_dot_arg : member "." IDENT "(" [exprlist] ")"
member_item    : member "[" expr "]"
member_object  : member "{" [fieldinits] "}"

https://github.com/google/cel-spec/blob/master/doc/langdef.md#field-selection

Method or macro? We Distinguish between these three similar cases.

- Macros: https://github.com/google/cel-spec/blob/master/doc/langdef.md#macros

- member "." IDENT "(" [exprlist] ")" -- used for string operations

- member "." IDENT "(" ")"  -- used for a several timestamp operations.
Nr  r  filterallr   TexistsF
exists_onec              3   X   >#    U  H  n[        T" U5      5      (       d  M  S v   M!     g7f)r  N)r   ).0r   r  s     r&   	<genexpr>+Evaluator.member_dot_arg.<locals>.<genexpr>  s     L{ed8E?6K{s   *	*r  r   minzCAttempt to reduce an empty sequence or a sequence with a None valuer  )#r   r   r   r   r   r   r   r   r   r   r  r   ListTyper  r  r   r   r  r<  r   r   logical_andr"  r   
logical_orsumr.  rD  r.  r;   r%   r?   r   r  r  )r$   r=   CELBoolFunctionr6  method_name_tokenmember_listmappingr   and_oper	reductionor_opercountreduce_exprr-  initial_valuer   r  r1  r  	expr_iterr  s                       @r&   member_dot_argEvaluator.member_dot_argK  sM   . #ENN$;$;V#DennF]F]#]^)-eDIItzz4I.JDMMZ\[\L])^&""e+u~~66

;8OPK,,T2H8ENN$8$893x;UVG^^,,W5FM$$0u~~66

;8OPK,,T2H^^,,VHk-JKFM$$-u~~66

;8OPK-y9NN..0H
 //5HxX{)CU^^E\E\]aEbcI$$0u~~66

;8OPK-y9NN--/G
 //5HwHk(BENND[D[\aDbcI$$4u~~66

;8OPK,,T2HL{LLE>>**5A:66$$0 u~~66

;8OPK*.*F*Ft*L'K JJ~6M{GI$$- u~~66

;8OPKP,	 
 4==!Q& $&$**,-''-! ))&%8 M ,0&$**hv.>>?''-,(y ))&%CM+  P[(bllBGG$O	Ps   4U 
U9"U44U9c           
         U R                   S   nU R                  U5      nUu  pE U" XE5      $ ! [         a|  nU R                  R	                  UR
                   SU SU SU 35        S[        U5       S[        U5       S3n[        XvR                  UR                  US9nXhl
        Us SnA$ SnAf[         ab  nU R                  R	                  UR
                   SU SU SU 35        [        S	UR                  UR                  US9nXhl
        Us SnA$ SnAf[         ab  nU R                  R	                  UR
                   SU SU SU 35        [        S
UR                  UR                  US9nXhl
        Us SnA$ SnAff = f)av  
member         : member_dot | member_dot_arg | member_item | member_object | primary

member_dot     : member "." IDENT
member_dot_arg : member "." IDENT "(" [exprlist] ")"
member_item    : member "[" expr "]"
member_object  : member "{" [fieldinits] "}"

https://github.com/google/cel-spec/blob/master/doc/langdef.md#field-selection

Locating an item in a Mapping or List
r   rk  r   r   z1found no matching overload for _[_] applied to '(r  r  Nzno such keyinvalid_argument)r  r  r   r   r   r,   r  r;   r%   r?   r   rD  
IndexError)	r$   r=   r  r9  r1  indexr   r  r   s	            r&   member_indexEvaluator.member_index  so    ~~f%$$T*	&& 	KKq5'tLM  $V~RU}B@  !llBGG$GE OL 	KKq5'tLM bggDQE OL 	KKq5'tLM !3R\\277QUVE OL		sA   . 
FA1B/)F/F<ADFF&AF=FFc                    U R                  U5      n[        U5      S:X  a  [        [        R                  UR
                  S   5      R                  S:X  a  US   nOO[        [        R                  R                  US   5      nU R                  R                  SU S35         U" S5      nU R                  R                  SU 35        U$ [        U5      S	:X  a  Uu  pg[#        U[        5      (       a  U$ [        [        R                  R                  U5      nU R                  R%                  SU S
U< S35         U" [        [        R                  R&                  U5      5      nU R                  R%                  SU< 35        U$ [)        UR                   SUR
                   S3UR*                  R,                  UR*                  R.                  S9e! [        [        4 a8  n[        UR                  S   UR                   UR                  US9n SnAGNmSnAff = f! [        [        4 a7  n[        UR                  S   UR                   UR                  US9n SnANSnAff = f)a  
member         : member_dot | member_dot_arg | member_item | member_object | primary

member_dot     : member "." IDENT
member_dot_arg : member "." IDENT "(" [exprlist] ")"
member_item    : member "[" expr "]"
member_object  : member "{" [fieldinits] "}"

https://github.com/google/cel-spec/blob/master/doc/langdef.md#field-selection

An object constructor requires a protobyf type, not an object as the "member".
r  r   primaryz	Creating z()Nr  zCreated r  rk  rE   r  z: bad member_object noder  )r  r   r   r   r   r  r  r   r   FunctionTyper   r   r   r.  r;   r?   r%   r   r+  r   r   rA   r   r   )r$   r=   r9  r   protobuf_classr   r1  
fieldinitss           r&   member_objectEvaluator.member_object  s    $$T*v;!DIIt}}Q/055Bq	 "&NN//1I" !!In-=R"@AW*40E KK01L[A!'F&,//!++N KKy(8*qIJS&tENN,@,@*'MN KKxy12L !99+Qt}}o-EFYY^^yy'' 5 ":. W(R\\277QUVEW( z* S$RWWQZrwwTRSs0   #G =*H  H%-HH I'0-I""I'c                 
   [        UR                  5      S:w  aM  [        UR                   SUR                   S3UR                  R
                  UR                  R                  S9e[        [        R                  UR                  S   5      nUR                  S:X  a  U R                  U5      nUS   $ UR                  S:X  a  U R                  U5      nUS   $ UR                  S:X  aQ  [        UR                  5      S:X  a   [        R                  R                  5       nU$ U R                  U5      nUS   nU$ UR                  S	:X  aR  [        UR                  5      S:X  a   [        R                  R                  5       nU$  U R                  U5      nUS   nU$ UR                  S;   aY  U R                  U5      n[        [        R(                  US   5      n [        [*        U R-                  UR.                  SS95      nU$ UR                  S:X  Ga  [        UR                  5      S:X  a=  [        [        R(                  UR                  S   5      n[        R                  " S/ S9nO[        UR                  5      S:X  a>  [        [2        [        R(                  [        R                  4   UR                  5      u  pgOM[        UR                   SUR                   S3UR                  R
                  UR                  R                  S9eUR.                  S:X  a  U R5                  U5      $ UR.                  S:X  a  U R                  U5      nUS   $ U R                  U5      nU R7                  U[        [8        [        R                  R:                     U5      5      $ UR                  S:X  aS  [        [        R(                  UR                  S   5      n [        [*        U R-                  UR.                  5      5      nU$ [        UR                   SUR                   S3UR                  R
                  UR                  R                  S9e! [         a8  n[!        UR"                  S   UR$                  UR"                  US
9n SnAU$ SnAf[&         a8  n[!        UR"                  S   UR$                  UR"                  US
9n SnAU$ SnAff = f! [0         a8  n[!        UR"                  S   UR$                  UR"                  US
9n SnAU$ SnAff = f! [0         a=  nSU SU R<                   S3n	[!        XR$                  UR"                  US
9n SnAU$ SnAff = f)a  
primary        : dot_ident_arg | dot_ident | ident_arg | ident
               | paren_expr | list_lit | map_lit | literal

dot_ident_arg  : "." IDENT "(" [exprlist] ")"
dot_ident      : "." IDENT
ident_arg      : IDENT "(" [exprlist] ")"
ident          : IDENT
paren_expr     : "(" expr ")"
list_lit       : "[" [exprlist] "]"
map_lit        : "{" [mapinits] "}"

TODO: Refactor into separate methods to skip this complex elif chain.
top-level :py:meth:`primary` is similar to :py:meth:`method`.
Each of the individual rules then works with a tree instead of a child of the
primary tree.

This includes function-like macros: has() and dyn().
These are special cases and cannot be overridden.
r  r  z: bad primary noder  r   literal
paren_exprlist_litmap_litr  N)	dot_identdot_ident_argT)r  	ident_argr  )r  r  r  hasdynr  r  r  r  )r   r  r   r  rA   r   r   r   r   r   r  r   r   rE  rL  r.  r;   r?   r%   r   r   r   r  r   rD  r   r  r  r   r   r  )
r$   r=   r  r9  r   r   r  r  
dyn_valuesr  s
             r&   r]  Evaluator.primary  s   0 t}}" 99+Qt}}o-?@YY^^yy''  TYYa 01::"((.F!9ZZ<'((/F!9ZZ:%5>>"a' 002
 M ,,U3MZZ9$5>>"a' //1 MX!007F#AYF
 MZZ99 ((/Fdjj&)4JTfd&6&6z7G7GTX&6&YZ MZZ;& 5>>"a'!$**ennQ.?@
99*rBU^^$)'+E$**dii2G,H%..'Y$
H$yyk4==/1CD99++  5( **844!!U*!00:
!!}$ ,,X6))*d8ENNDXDX;Y[a6bccZZ7"djj%..*;<J
M fd&6&6z7G7G&HI M !99+Qt}}o-?@YY^^yy'' K " X)"''!*bllBGGRVWF M ! X)"''!*bllBGGRVWFMX   T%bggaj",,dSMTT  M/
| <''+&7r;  &c<<tLMMsT   Q (S )T 
S-RS-SS
T#-TT
U%(2U  U%c                 f   [        UR                  5      S:w  aM  [        UR                   SUR                   S3UR                  R
                  UR                  R                  S9e[        [        R                  UR                  S   5      n UR                  S:X  a+  [        R                  R                  UR                  5      nU$ UR                  S:X  a+  [        R                  R                  UR                  5      nU$ UR                  S:X  a  UR                  S	   R!                  5       S
:X  d7  [        SU< 3UR                  R
                  UR                  R                  S9e[        R                  R#                  UR                  SS	 5      nU$ UR                  S;   a  [%        U5      nU$ UR                  S:X  a  ['        U5      nU$ UR                  S:X  a<  [        R                  R)                  UR                  R!                  5       S:H  5      nU$ UR                  S:X  a  SnU$ [+        UR                   SUR                   S3UR
                  UR                  S9e! [,         a8  n[/        UR0                  S   UR2                  UR0                  US9n SnAU$ SnAff = f)z
Create a literal from the token at the top of the parse tree.

..  todo:: Use type provider conversions from string to CEL type objects.
r  r  z: bad literal noder  r   	FLOAT_LITINT_LITUINT_LITrY  uzinvalid unsigned int literal N)MLSTRING_LIT
STRING_LIT	BYTES_LITBOOL_LITtrueNULL_LITz: type not implementedr  )r   r  r   r  rA   r   r   r   r   r   r  r   r   
DoubleTyper   r   lowerUintTypecelstrcelbytesr   r6   r.  r;   r?   r%   )r$   r=   value_tokenr   r   s        r&   rd  Evaluator.literal  sm    t}}" 99+Qt}}o-?@YY^^yy''  4::t}}Q'78	P;.22;3D3DE< ; !!Y.//0A0AB8 7 !!Z/"((,224;(7G!YY^^#yy// 
 001B1B3B1GH( ' !!%CC,$ # !![0!+.   !!Z/NN++K,=,=,C,C,E,OP   !!Z/  *yyk4==/1GH$))&-- 
  	P!"''!*bllBGG$OF	PsD   9I. 
9I. BI. I. 8I. A
I. !I. 59I. .
J08-J++J0c                    U R                  U5      nS U 5       n [        U5      $ ! [         a     Of = f[        R                  R                  [        [        [        R                  R                     U5      5      nU$ )z#
exprlist       : expr ("," expr)*
c              3   T   #    U  H  n[        U[        5      (       d  M  Uv   M      g 7fr   )r   r;   )rA  rh  s     r&   rB  %Evaluator.exprlist.<locals>.<genexpr>  s     CVz!\'B!!Vs   (	()	r  nextStopIterationr   r   rE  r   r
   r   )r$   r=   r9  errorsr   s        r&   r  Evaluator.exprlist  sp    
 $$T*CVC	< 		 ((d5>>3G3G.H&)QRs   
' 
44c           
         0 n[        [        [        [        R                  [        R
                  4      [        UR                  SSS2   UR                  SSS2   5      5      nU H_  u  pEUR                  n[        [        R                  R                  U R                  U5      S   5      nXb;   a  [        SU< 35      eXrU'   Ma     [        R                  R                  " S0 UD6$ )a6  
fieldinits     : IDENT ":" expr ("," IDENT ":" expr)*

The even items, children[0::2] are identifiers, nothing to evaluate.
The odd items, childnre[1::2] are expressions.

This creates a mapping, used by the :meth:`member_object` method to create
and populate a protobuf object. Duplicate names are an error.
r   Nr  r  zDuplicate field label rN   )r   r   r   r   r   r   zipr  r   r   r   r   r  r.  rK  )r$   r=   fieldspairs
ident_node	expr_noder  r  s           r&   r`  Evaluator.fieldinits  s     "$U4::tyy012add#T]]14a4%89
 &+!J$$E,,d.A.A).LQ.OPD #9%!CDD 5M &+ ~~))3F33r)   c                 ,   [         R                  R                  5       n[        [        [         R                  R
                     U R                  U5      5      n[        USSS2   USSS2   5      nU H  u  pVXR;   a  [        SU< 35      eXbU'   M     U$ )a  
mapinits       : expr ":" expr ("," expr ":" expr)*

Extract the key expr's and value expr's to a list of pairs.
This raises an exception on a duplicate key.

TODO: Is ``{'a': 1, 'b': 2/0}['a']`` a meaningful result in CEL?
Or is this an error because the entire member is erroneous?

r   Nr  r  zDuplicate key )	r   r   rL  r   r
   r   r  r  r.  )r$   r=   r   keys_valuesr  r^  r   s          r&   mapinitsEvaluator.mapinits	  s     '') 4 4 45t7J7J47PQK1%{14a4'89JC} >#!9::3K  
 r)   )r  r  r  r  r  r   )F)?r,   r-   r.   r/   r0   ro  rp  r   r   r   rt  r   r   r  r   r   r"   r  rq  r  r   Result_Functionr  r   r   r   r  r
   r   r  r   r   r   r  r  r   r  r  r  r  r  r  r   r  r  r   r   r  r"  r   r.  r1  r9  rT  rZ  ra  r]  rd  r  r`  r  r2   r3   r4   s   @r&   r  r    s   <z {+F X\	;; #; Xk2GC<L4MtST	;
 
;BT T{ TW  ( ( (/ (1%.... 1 499 f  48(

( x/0( =C(\ 48	)) **) x/0	) =C	)V#Ttyy #TU^^5L5L #TJ  v  B $))   @ 499   @ <TYY <6 < <| 6TYY 66 6 6p >499 > > >@ 8$)) 8 8 8t%dii %Henn>R>R=SUX=X4Y %N xAUAU@VX[@[7\ B)()(	x(&01499<	=)(V 499    Ptyy PV P Pd j499 j j jX $ $v $ $L ;$)) ; ; ;z JDII J& J JX /DII /& / /b TYY 6   4tyy 4V 4 4. TYY 6  r)   zO\\[abfnrtv"'\\]|\\\d{3}|\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}|.
	"'\)
z\az\bz\fz\nz\rz\tz\vz\"z\'z\\r>   c                    S[         [        [              S[        [           4S jnU R                  nUSS S;   a  USS S:X  d	  USS S	:X  a  USS
 nO`USS nOZUSS S:X  d	  USS S	:X  a  [
        R                  USS
 5      nO[
        R                  USS 5      nSR                  U" U5      5      n[        R                  R                  U5      $ )a)  
Evaluate a CEL string literal, expanding escapes to create a Python string.

It may be that built-in ``eval()`` might work for some of this, but
the octal escapes aren't really viable.

:param token: CEL token value
:return: str

..  todo:: This can be refactored into celpy.celtypes.StringType.

match_iterr   c              3   l  #    S U  5        H  n[        U5      S:X  a  UnOUS S S:X  a  [        [        USS  S5      5      nOhUS S S;   a  [        [        USS  S5      5      nOFUS S S:X  a(  [        U5      S:X  a  [        [        USS  S	5      5      nO[        R	                  X5      nUv   M     g 7f)
Nc              3   @   #    U  H  oR                  5       v   M     g 7fr   grouprA  ms     r&   rB  )celstr.<locals>.expand.<locals>.<genexpr>6	       4Aggii   r  r  \x   >   \U\ur        )r   chrr1   CEL_ESCAPESr5  )r  r-  expandeds      r&   expandcelstr.<locals>.expand5	  s     44E5zQ re#s59b12rn,s59b12rd"s5zQs59a01&??58N 5s   B2B4Nr  )Rr%  r  """'''r  rY  r   r  rX  )r   r   r   r	   r   CEL_ESCAPES_PATfinditerjoinr   r   
StringTyper>   r  r   r  r  s        r&   r}  r}  )	  s    8E#J/ HSM  ;;DBQx:!9ae!3AbzH AbzH !9ae!3(11$q*=J )11$q*=J776*-.>>$$X..r)   c                    S[         [        [              S[        [           4S jnU R
                  nUSS R                  5       S:X  ai  USS S:X  d	  USS S	:X  a+  [        R                  R                  S
 USS  5       5      nU$ [        R                  R                  S USS  5       5      n U$ USS R                  5       S:X  aj  USS S:X  d	  USS S	:X  a  [        R                  USS 5      nO[        R                  USS 5      n[        R                  R                  U" U5      5      nU$ [        SU R
                  < 35      e)z
Evaluate a CEL bytes literal, expanding escapes to create a Python bytes object.

:param token: CEL token value
:return: bytes

..  todo:: This can be refactored into celpy.celtypes.BytesType.
r  r   c              3     #    S U  5        H  n[        U5      S:X  a  UR                  S5       S h  vN   M-  US S S:X  a  [        USS  S5      v   MI  US S S:X  a  [        USS  S5      v   Me  US S S:X  a"  [        U5      S	:X  a  [        USS  S
5      v   M  [        [        R                  X5      5      v   M     g  N7f)Nc              3   @   #    U  H  oR                  5       v   M     g 7fr   r  r  s     r&   rB  +celbytes.<locals>.expand.<locals>.<genexpr>b	  r  r  r  zutf-8r  r  r  r  r  r  r  )r   encoder1   ordr  r5  )r  r-  s     r&   r  celbytes.<locals>.expanda	  s     44E5zQ <<000re#%)R((re#%)R((rd"s5zQ%)Q''+//%788 50s   0CCBCNr  br   r  r  c              3   8   #    U  H  n[        U5      v   M     g 7fr   r  rA  r   s     r&   rB  celbytes.<locals>.<genexpr>s	       /K
1A
   r  c              3   8   #    U  H  n[        U5      v   M     g 7fr   r  r  s     r&   rB  r  v	  r  r  r  rY  r  r   r  zInvalid bytes literal )r   r   r   r	   r1   r   r{  r   r   	BytesTyper  r  r.  r  s        r&   r~  r~  X	  sF   98E#J/ 9HSM 9 ;;DBQx~~4!9ae!3~~///KQr
/KKH O ~~///KQr
/KKH O 
bq	S	 !9ae!3(11$q*=J )11$q*=J>>++F:,>? O 1%++ABBr)   r   )fr0   r  ro  operatorr   r   	functoolsr   r   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   lark.visitorscelpy.celtypesr   celpy.celparserr   r   CELTyper   r^  r  rp  r   r   r   r6   r;   r   r  r  BaseExceptionException_Filterr   r   r   r   r   r   r   logical_notnegaddsubmultruedivmodltlegegteqnerG  rF  logical_conditiongetitemr  rz  DurationTyper   rE  rL  r  r  TimestampTyper|  r  __annotations__r
  rq  rn  r  rt  visitorsVisitor_Recursiver  r   r  Interpreterr  rm  r  r  r   r}  r~  rN   r)   r&   <module>r     s   ,    	 
 #! ! ! ! !    % 	NNS%..&&&'	$	$%'
 
		<	(Y ) [9 [B 
	NN	NN
 sF{# 

 m,htM7J.KKL \5
 )9 h
|U_G_>` @3 4 445:B3H_H_C_:`"+f + +F +\V  02-%..
$
$2-(,,2- 
8<<2- 
8<<	2-
 
8<<2- 
82- 
8<<2- 
78;;2- GHKK 2- GHKK 2- 
78;;2- GHKK 2- GHKK 2- K2- ENN%%2-  ENN&&!2-" U^^--#2-$ H%2-& M'2-* I+2-, M-2-. \/2-0 B12-4 S52-6 _72-8 ]92-: ];2-< [=2-> U?2-B UC2-D cE2-F YG2-H YI2-L ENN##M2-N ^^%%nn''++>>!!NN##>>!!dnn''--NN##c2-[() 2jj j^ #uV_455
6 	"QPDh' QPh
`
 `
F// ,+tyy1367<DkSWS\S\E]_bEb<c R))&1 Rj( **c T$TsD,/$** ,/!:!: ,/^*DJJ *5>>#;#; *r)   