
    |                         S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKJr  SSKJ	r	  SSKJ
r
  SS	KJr  SSKrSS
KJr  SSKJr  Sr\S-   r " S S\5      r " S S\5      rSS jr " S S\5      rS rSS jrg)a  Resource expression lexer.

This class is used to parse resource keys, quoted tokens, and operator strings
and characters from resource filter and projection expression strings. Tokens
are defined by isspace() and caller specified per-token terminator characters.
" or ' quotes are supported, with these literal escapes: \\ => \, \' => ',
\" => ", and \<any-other-character> => \<any-other-character>.

Typical resource usage:

  # Initialize a lexer with the expression string.
  lex = resource_lex.Lexer(expression_string)
  # isspace() separated tokens. lex.SkipSpace() returns False at end of input.
  while lex.SkipSpace():
    # Save the expression string position for syntax error annotation.
    here = lex.GetPosition()
    # The next token must be a key.
    key = lex.Key()
    if not key:
      if lex.EndOfInput():
        # End of input is OK here.
        break
      # There were some characters in the input that did not form a valid key.
      raise resource_exceptions.ExpressionSyntaxError(
          'key expected [{0}].'.format(lex.Annotate(here)))
    # Check if the key is a function call.
    if lex.IsCharacter('('):
      # Collect the actual args and convert numeric args to float or int.
      args = lex.Args(convert=True)
    else:
      args = None
    # Skip an isspace() characters. End of input will fail with an
    # 'Operator expected [...]' resource_exceptions.ExpressionSyntaxError.
    lex.SkipSpace(token='Operator')
    # The next token must be one of these operators ...
    operator = lex.IsCharacter('+-*/&|')
    if not operator:
      # ... one of the operator names.
      if lex.IsString('AND'):
        operator = '&'
      elif lex.IsString('OR'):
        operator = '|'
      else:
        raise resource_exceptions.ExpressionSyntaxError(
            'Operator expected [{0}].'.format(lex.Annotate()))
    # The next token must be an operand. Convert to float or int if possible.
    # lex.Token() by default eats leading isspace().
    operand = lex.Token(convert=True)
    if not operand:
      raise resource_exceptions.ExpressionSyntaxErrorSyntaxError(
          'Operand expected [{0}].'.format(lex.Annotate()))
    # Process the key, args, operator and operand.
    Process(key, args, operator, operand)
    )absolute_import)division)unicode_literalsN)resource_exceptions)resource_projection_spec)resource_property)resource_transform)map)rangez:=!<>~()z[].{},+*/%&|^#;?c                   2    \ rS rSrSr  SS jrS rS rSrg)	_TransformCall`   a	  A key transform function call with actual args.

Attributes:
  name: The transform function name.
  func: The transform function.
  active: The parent projection active level. A transform is active if
    transform.active is None or equal to the caller active level.
  map_transform: If r is a list then apply the transform to each list item
    up to map_transform times. map_transform>1 handles nested lists.
  args: List of function call actual arg strings.
  kwargs: List of function call actual keyword arg strings.
Nc                 t    Xl         X l        X0l        X@l        U=(       d    / U l        U=(       d    0 U l        g N)namefuncactivemap_transformargskwargs)selfr   r   r   r   r   r   s          0lib/googlecloudsdk/core/resource/resource_lex.py__init___TransformCall.__init__n   s-    IIK&
DI,BDK    c                 ^   U R                    Vs/ s H&  n[        U[        R                  5      (       a  SOUPM(     nnU R                  S:  a  SR                  U R                  5      nOU R                  S:X  a  SnOSnSR                  X0R                  SR                  U5      5      $ s  snf )Nz<projecton>   z	map({0}).zmap(). z{0}{1}({2}),)r   
isinstancer   ProjectionSpecr   formatr   join)r   argr   prefixs       r   __str___TransformCall.__str__w   s     yy"  (%446 6M;>?  	 " A!!$"4"45f			q	 ff		388D>BB"s   -B*c                 .    [         R                   " U 5      $ r   )copy)r   memos     r   __deepcopy___TransformCall.__deepcopy__   s    99T?r   )r   r   r   r   r   r   )r   r   NN)	__name__
__module____qualname____firstlineno____doc__r   r&   r+   __static_attributes__ r   r   r   r   `   s!     BF
Cr   r   c                       \ rS rSrSrS rS r\S 5       r\S 5       r	\S 5       r
\S 5       r\S	 5       rS
 rS rS rSS jrSrg)
_Transform   zAn object that contains an ordered list of _TransformCall objects.

Attributes:
  _conditional: The resource_filter expression string for the if() transform.
  _transforms: The list of _TransformCall objects.
c                      S U l         / U l        g r   _conditional_transformsr   s    r   r   _Transform.__init__   s    DDr   c                 r    SR                  SR                  [        [        U R                  5      5      5      $ )Nz[{0}].)r"   r#   r
   strr:   r;   s    r   r&   _Transform.__str__   s'    >>#((3sD,<,<#=>??r   c                 Z    U R                   (       a  U R                   S   R                  $ S$ )z4The transform active level or None if always active.r   Nr:   r   r;   s    r   r   _Transform.active   s(     *.)9)94A%%CtCr   c                     U R                   $ )z1The if() transform conditional expression string.r9   r;   s    r   conditional_Transform.conditional   s     r   c                     [        U R                  5      S:w  d+  U R                  S   R                  [        R                  :w  a  gU R                  S   R
                  S   $ )aW  The global restriction string or None if not a global restriction.

Terms in a fiter expression are sometimes called "restrictions" because
they restrict or constrain values.  A regular restriction is of the form
"attribute<op>operand".  A "global restriction" is a term that has no
attribute or <op>.  It is a bare string that is matched against every
attribute value in the resource object being filtered.  The global
restriction matches if any of those values contains the string using case
insensitive string match.

Returns:
  The global restriction string or None if not a global restriction.
r   r   N)lenr:   r   r   GLOBAL_RESTRICTION_NAMEr   r;   s    r   global_restriction_Transform.global_restriction   sX     	D"			!		!	!	!	9	9
:A##A&&r   c                 Z    U R                   (       a  U R                   S   R                  $ S$ )zThe name of the last transform.r   )r:   r   r;   s    r   r   _Transform.name   s(     )-(8(84B$$@b@r   c                 `    U R                   (       a  U R                   S   R                  S   $ S$ )z"The first global restriction term.r   r   )r:   r   r;   s    r   term_Transform.term   s-     +/*:*:4A##A&BBr   c                 J    U R                   =(       a    U R                  SU4;   $ )z=Returns True if the Transform active level is None or active.NrB   )r   r   s     r   IsActive_Transform.IsActive   s     =f~ ==r   c                 :    U R                   R                  U5        g)zAdds a transform to the list.N)r:   append)r   	transforms     r   Add_Transform.Add   s    I&r   c                     Xl         g)z'Sets the conditional expression string.NrE   )r   exprs     r   SetConditional_Transform.SetConditional   s    r   Nc           	      j   U R                    GH  nUR                  S:X  a  Ub  UnUR                  (       a  [        R                  " U5      (       a  Un[        UR                  S-
  5       H"  n/ n U H  nUR                  U5        M     UnM$     / nU H<  nUR                  UR                  " U/UR                  Q70 UR                  D65        M>     M  U(       d  UR                  (       a  M  UR                  " U/UR                  Q70 UR                  D6nGM     U$ ! [         a       M  f = f)zEApply the list of transforms to obj and return the transformed value.urir   )r:   r   r   r   
IsListLiker   extend	TypeErrorrW   r   r   r   )r   objoriginal_objectrX   items_nesteditems           r   Evaluate_Transform.Evaluate   s   %%	 
5	 _%@		 	 %6%A%A#%F%F
 y..23A&mmD!  % 4 D
**Y^^DN9>>NY=M=MN
O i---nnSF9>>FY5E5EF1 &2 J  s   2D##
D21D2r8   r   )r-   r.   r/   r0   r1   r   r&   propertyr   rF   rK   r   rQ   rT   rY   r]   rj   r2   r3   r   r   r5   r5      s    @ D D   ' '( A A C C>'r   r5   c           	      L    [        5       nUR                  [        XX#S95        U$ )a  Returns a transform call object for func(*args, **kwargs).

Args:
  func_name: The function name.
  func: The function object.
  args: The actual call args.
  kwargs: The actual call kwargs.

Returns:
  A transform call object for func(obj, *args, **kwargs).
)r   r   )r5   rY   r   )	func_namer   r   r   callss        r   MakeTransformrp      s#     ,%))N9EF	,r   c                       \ rS rSrSrSrSrSS jrSS jrS r	S	 r
SS
 jrSS jrSS jrSS jr  SS jrSS jrS rS rS rS rSS jrSS jrSrg)Lexer   aE  Resource expression lexer.

This lexer handles simple and compound tokens. Compound tokens returned by
Key() and Args() below are not strictly lexical items (i.e., they are parsed
against simple grammars), but treating them as tokens here simplifies the
resource expression parsers that use this class and avoids code replication.

Attributes:
  _ESCAPE: The quote escape character.
  _QUOTES: The quote characters.
  _defaults: ProjectionSpec object for aliases and symbols defaults.
  _expr: The expression string.
  _position: The index of the next character in _expr to parse.
\z'"Nc                 x    U=(       d    SU l         SU l        U=(       d    [        R                  " 5       U l        g)zInitializes a resource lexer.

Args:
  expression: The expression string.
  defaults: ProjectionSpec object for aliases and symbols defaults.
r   r   N)_expr	_positionr   r!   	_defaults)r   
expressiondefaultss      r   r   Lexer.__init__  s-     !rDJDNJ!9!H!H!JDNr   c                 P    Uc  U R                   nU[        U R                  5      :  $ )zChecks if the current expression string position is at the end of input.

Args:
  position: Checks position instead of the current expression position.

Returns:
  True if the expression string position is at the end of input.
)rw   rI   rv   r   positions     r   
EndOfInputLexer.EndOfInput  s&     hs4::&&r   c                     U R                   $ )zVReturns the current expression position.

Returns:
  The current expression position.
rw   r;   s    r   GetPositionLexer.GetPosition&  s     >>r   c                     Xl         g)zSets the current expression position.

Args:
  position: Sets the current position to position. Position should be 0 or a
    previous value returned by GetPosition().
Nr   r}   s     r   SetPositionLexer.SetPosition.  s	     Nr   c                 `   Ub  UOU R                   nSnUS:  a*  U R                  US-
     R                  5       (       d  SU-   nU[        U R                  5      :  a'  U R                  U   R                  5       (       d  US-  nSR	                  U R                  SU X0R                  US 5      $ )a  Returns the expression string annotated for syntax error messages.

The current position is marked by '*HERE*' for visual effect.

Args:
  position: Uses position instead of the current expression position.

Returns:
  The expression string with current position annotated.
Nz*HERE*r   r    z	{0}{1}{2})rw   rv   isspacerI   r"   )r   r~   herecursors       r   AnnotateLexer.Annotate7  s      +8DFax

4!8,4466V|fc$**odjj&6&>&>&@&@mfdjj40&**TU:KLLr   c                 b   U R                  5       (       d`  U R                  U R                     nUR                  5       (       a  X2;   a  gU =R                  S-  sl        U R                  5       (       d  M`  U(       a3  [        R
                  " SR                  XR                  5       5      5      eg)a  Skips spaces in the expression string.

Args:
  token: The expected next token description string, None if end of input is
    OK. This string is used in the exception message. It is not used to
    validate the type of the next token.
  terminators: Space characters in this string will not be skipped.

Raises:
  ExpressionSyntaxError: End of input reached after skipping and a token is
    expected.

Returns:
  True if the expression is not at end of input.
Tr   z{0} expected [{1}].F)r   rv   rw   r   r   ExpressionSyntaxErrorr"   r   )r   tokenterminatorscs       r   	SkipSpaceLexer.SkipSpaceJ  s      oo
**T^^
$aYY[[A,
nnn	 oo
 55

&
&ummo
>@ @r   c                 *   U R                  5       (       aB  U(       d  U(       a  g[        R                  " SR                  U R	                  5       5      5      eU R
                  U R                     nXA;  a  gU(       d  U =R                  S-  sl        U$ )a  Checks if the next character is in characters and consumes it if it is.

Args:
  characters: A set of characters to check for. It may be a string, tuple,
    list or set.
  peek: Does not consume a matching character if True.
  eoi_ok: True if end of input is OK. Returns None if at end of input.

Raises:
  ExpressionSyntaxError: End of input reached and peek and eoi_ok are False.

Returns:
  The matching character or None if no match.
NzMore tokens expected [{0}].r   )r   r   r   r"   r   rv   rw   )r   
characterspeekeoi_okr   s        r   IsCharacterLexer.IsCharacterd  ss     	55
'
.
.t}}
?A A

4>>"A
nnnHr   c                 |   U R                  5       (       d  gU R                  5       nU R                  US R                  U5      (       d  gU[	        U5      -  nU R                  U5      (       d5  U R                  U   R                  5       (       d  U R                  U   S:X  a  U(       d  U R                  U5        gg)a  Skips leading space and checks if the next token is name.

One of space, '(', or end of input terminates the next token.

Args:
  name: The token name to check.
  peek: Does not consume the string on match if True.

Returns:
  True if the next space or ( separated token is name.
FN(T)r   r   rv   
startswithrI   r   r   r   )r   r   r   is       r   IsStringLexer.IsString  s     >>A::ab>$$T**TNAqTZZ]2244

18Lr   c                 H   SnSnSnSnU R                  5       n	U R                  U	5      (       Gd  U R                  U	   n
XR                  :X  a  U R                  U	S-   5      (       ds  U R                  U	S-      n
Uc  / nXR                  :w  a6  X:w  a1  U(       d  XR                  ;  a  UR                  U R                  5        UR                  U
5        U	S-  n	OX:X  a  SnOU(       d  XR                  ;   a
  U
nSnUc  / nOU(       d  U
R                  5       (       a  Uc  OU(       dB  U(       a;  U
S;   a5  U
S:X  a  US-  nOX;   a  U(       d  OUS-  nUc  / nUR                  U
5        OUU(       d  U(       d  X;   a  O_U(       d  U
R                  5       (       a
  Ub  U(       a  Uc  / nUR                  U
5        OUb  OU	S-  n	U R                  U	5      (       d  GM  U(       a3  [        R                  " SR                  XPR                  5       5      5      eU R                  U	5        U(       a  U R                  US	9  Ub  S
R                  U5      nU(       a  U(       a  U(       d   [        U5      $ U$ ! [         a!     [!        U5      s $ ! [         a      U$ f = ff = f)af  Parses a possibly quoted token from the current expression position.

The quote characters are in _QUOTES. The _ESCAPE character can prefix
an _ESCAPE or _QUOTE character to treat it as a normal character. If
_ESCAPE is at end of input, or is followed by any other character, then it
is treated as a normal character.

Quotes may be adjacent ("foo"" & ""bar" => "foo & bar") and they may appear
mid token (foo" & "bar => "foo & bar").

Args:
  terminators: A set of characters that terminate the token. isspace()
    characters always terminate the token. It may be a string, tuple, list
    or set. Terminator characters are not consumed.
  balance_parens: True if (...) must be balanced.
  space: True if space characters should be skipped after the token. Space
    characters are always skipped before the token.
  convert: Converts unquoted numeric string tokens to numbers if True.

Raises:
  ExpressionSyntaxError: The expression has a syntax error.

Returns:
  None if there is no token, the token string if convert is False or the
  token is quoted, otherwise the converted float / int / string value of
  the token.
NFr   r   Tz()r   zUnterminated [{0}] quote [{1}].)r   r   )r   r   rv   _ESCAPE_QUOTESrW   r   r   r   r"   r   r   r   r#   int
ValueErrorfloat)r   r   balance_parensspaceconvertquotequotedr   paren_countr   r   s              r   TokenLexer.Token  sL   : EFEKAooa  
**Q-a	
ll	4??1q5#9#9JJq1u=%!*a||+
,,t||
$Q	Q:ll*=%AI8

+k

+=%Q[Q-=		u'8^=%Q1fa[ ooa  \ 55
+
2
25--/
JL LQ
nnn-ggene55z L  	u
 	
L	s0   )
I6 6
J!
JJ!
JJ!JJ!c                 n   Sn/ nUS-   n U R                  5       nU R                  USUS9nU R                  S5      nU(       a  Un	O[U R                  USS9n	U	(       dD  U R                  5       n[        R                  " SR                  U R                  U5      5      5      eUb.  U(       d  U	R                  5       (       d  UR                  U5        OBU(       d  U(       d4  [        R                  " SR                  U R                  U5      5      5      eU(       a   U$ U	R                  5       (       + nGM,  )a  Parses a separators-separated, )-terminated arg list.

The initial '(' has already been consumed by the caller. The arg list may
be empty. Otherwise the first ',' must be preceded by a non-empty argument,
and every ',' must be followed by a non-empty argument.

Args:
  convert: Converts unquoted numeric string args to numbers if True.
  separators: A string of argument separator characters.

Raises:
  ExpressionSyntaxError: The expression has a syntax error.

Returns:
  [...]: The arg list.
F)T)r   r   r   z*Closing ) expected in argument list [{0}].zArgument expected [{0}].)	r   r   r   r   r   r"   r   r   rW   )
r   r   
separatorsrequiredr   r   r   r$   endseps
             r   Args
Lexer.Args  s   " HDs"K
dJJ{4JIcS!c	z$7 !!#$#99:AA--%'( ( 
ckkmm
++c
3!77&--dmmD.ABD 	D	K [[]"h3 r   c                 :   SnU R                  S5      (       a  US-  nU R                  S5      (       a  M  U(       d  gSR                  U R                  SU R                  U-
   UU R                  U R                  S 5      U l        U =R                  U-  sl        g)z-Checks for N '*' chars shorthand for .map(N).r   *r   Nz{}map({}).{})r   r"   rv   rw   )r   	map_levels     r   _CheckMapShorthandLexer._CheckMapShorthand+  s    I


3

1ni 

3

  &&

.DNNY./

4>>?#%DJ
 	NNiNr   c                 r   / nSnU R                  5       (       Gd  U R                  5         U R                  5       nU R                  [        SS9nU(       aw  U R                  SSSS9nU(       dM  U(       dF  X@R                  R                  ;   a-  U R                  R                  U   u  pbUR                  U5        OUR                  U5        OU R                  SSS9(       d  U(       d_  U R                  S	5      (       aI  U R                  S	SSS9(       d3  U R                  5       (       d  U R                  [        SSS9(       a   X4$ [        R                  " S
R                  U R                  U5      5      5      eU R                  5       (       a   X4$ U R                  S5      (       a4  [        R                  " SR                  U R                  U5      5      5      eU R                  SSS9(       aI  U R                  SSS9nU R                  S5        UR                  U5        U R                  SSS9(       a  MI  U R                  S	SS9(       d   X4$ U R                  5       (       a3  [        R                  " S
R                  U R                  5       5      5      eU R                  5       (       d  GM  X4$ )a  Parses a resource key from the expression.

A resource key is a '.' separated list of names with optional [] slice or
[NUMBER] array indices. Names containing _RESERVED_OPERATOR_CHARS must be
quoted. For example, "k.e.y".value has two name components, 'k.e.y' and
'value'.

A parsed key is encoded as an ordered list of tokens, where each token may
be:

  KEY VALUE   PARSED VALUE  DESCRIPTION
  ---------   ------------  -----------
  name        string        A dotted name list element.
  [NUMBER]    NUMBER        An array index.
  []          None          An array slice.

For example, the key 'abc.def[123].ghi[].jkl' parses to this encoded list:
  ['abc', 'def', 123, 'ghi', None, 'jkl']

Raises:
  ExpressionKeyError: The expression has a key syntax error.

Returns:
  (key, attribute) The parsed key and attribute. attribute is the alias
    attribute if there was an alias expansion, None otherwise.
NF)r   r   T)r   r   [)r   r>   z"Non-empty key name expected [{0}].]zUnmatched ] in key [{0}].r   )r   )r   r   r   r   _RESERVED_OPERATOR_CHARSr   rx   aliasesrb   rW   r   r   r"   r   )r   key	attributer   r   is_functionkindexs           r   KeyWithAttributeLexer.KeyWithAttribute;  sf   6 CIoo
dZZ0Z>d	&&sd&C;4>>3I3I+I//5,!
**Q-
**T
$/S!!  4 =!!T%5%5,4 &6 &F
& >% "77077d8KLN 	N			 > 
		#		!77'..t}}T/BCE 	ES.

3
-

5	 S..
 c$/
 >	 
		!77077HJ 	JG ooJ >r   c                 *    U R                  5       u  pU$ )zEParses a resource key from the expression and returns the parsed key.)r   )r   r   rg   s      r   Key	Lexer.Key  s    ""$FCJr   c                   ^ / mU H  n[        U5      nUR                  S5      (       d  [        R                  " S5      e/ nUR	                  5        H  nSU;   a  UR                  SS5      u  pgSnOSSU;   a0  UR                  SS5      u  pi[        U	5      R                  5       nSnO[        U5      R                  5       nSnSnUR                  XhU45        M     TR                  U5        M     U4S jn
U
$ )a  Parses the synthesize() transform args and returns a new transform.

The args are a list of tuples. Each tuple is a schema that defines the
synthesis of one resource list item. Each schema item is an attribute
that defines the synthesis of one synthesized_resource attribute from
an original_resource attribute.

There are three kinds of attributes:

  name:literal
    The value for the name attribute in the synthesized resource is the
    literal value.
  name=key
    The value for the name attribute in the synthesized_resource is the
    value of key in the original_resource.
  key:
    All the attributes of the value of key in the original_resource are
    added to the attributes in the synthesized_resource.

Args:
  args: The original synthesize transform args.

Returns:
  A synthesize transform function that uses the schema from the parsed
  args.

Example:
  This returns a list of two resource items:
    synthesize((name:up, upInfo), (name:down, downInfo))
  If upInfo and downInfo serialize to
    {"foo": 1, "bar": "yes"}
  and
    {"foo": 0, "bar": "no"}
  then the synthesized resource list is
    [{"name": "up", "foo": 1, "bar": "yes"},
    {"name": "down", "foo": 0, "bar": "no"}]
  which could be displayed by a nested table using
    synthesize(...):format="table(name, foo, bar)"
r   z-(...) args expected in synthesize() transform:r   N=c                 
  > / nT	 Hy  n0 nU H]  nUu  pVnU(       a  [         R                  " XS5      OUnU(       a  XU'   M5  [        U[        5      (       d  ML  UR	                  U5        M_     UR                  U5        M{     U$ )zSynthesize a new resource list from the original resource r.

Args:
  r: The original resource.

Returns:
  The synthesized resource list.
N)r   Getr    dictupdaterW   )
rsynthesized_resource_listschemasynthesized_resourceattrr   r   literalvalueschemass
            r   _Synthesize+Lexer._ParseSynthesize.<locals>._Synthesize  s     #%&!D#
$W9<#''5'%).&%&& ''.  	"(()=>  '&r   )rr   r   r   r   r   splitr   rW   )r   r   r$   lexr   r   r   r   r   r   r   r   s              @r   _ParseSynthesizeLexer._ParseSynthesize  s    P G#Jc__S!!!77;= 	=f((*$$;**S!,-$#D[

3*+$e  "#'d!#$'t'*+  nnV' *', r   c           	      d   U R                  5       nU R                  R                  R                  U5      nU(       d4  [        R
                  " SR                  XR                  U5      5      5      e/ n0 n[        USS5      nU(       a/  [        R                  U;   a  UR                  U R                  5        [        USS5      (       aJ  U R                  5        H5  n	U	R                  S5      u  pnU(       a  XU
'   M$  UR                  U	5        M7     OX`R                  5       -  n[        XUX6US9$ )a  Parses a transform function call.

The initial '(' has already been consumed by the caller.

Args:
  func_name: The transform function name.
  active: The transform active level or None if always active.
  map_transform: Apply the transform to each resource list item this many
    times.

Returns:
  A _TransformCall object. The caller appends these to a list that is used
  to apply the transform functions.

Raises:
  ExpressionSyntaxError: The expression has a syntax error.
%Unknown transform function {0} [{1}].r1   N__defaults__r   )r   r   r   r   )r   rx   symbolsgetr   UnknownTransformErrorr"   r   getattrr   PROJECTION_ARG_DOCrW   r   	partitionr   )r   rn   r   r   r   r   r   r   docr$   r   r   vals                r   _ParseTransformLexer._ParseTransform  s   $ D>>!!%%i0D55
1
8
8t,./ / DF
$	4
(C
'::cA
kk$..!t^T**#s+3,
++c
  iikd)&(5Q Qr   c                    U R                  5       n[        5       nSn U R                  XUS9nUR                  [        R
                  :X  a  SnSnGOGUR                  [        R                  :X  a.  UR                  (       a  [        UR                  S   5      OSnSnOUR                  [        R                  :X  al  [        UR                  5      S:w  a4  [        R                  " SR                  U R                  U5      5      5      eUR                  UR                  S   5        OqUR                  [        R                   :X  a@  U R#                  UR                  5      Ul        / Ul        0 Ul        UR'                  U5        OSnUR'                  U5        U R)                  SSS9(       d   U$ U R+                  5       nU R                  5       nU R)                  S	5      (       d4  [        R                  " S
R                  U R                  U5      5      5      e[        U5      S:w  aD  [        R,                  " SR                  SR/                  U5      U R                  U5      5      5      eUR1                  5       nGMc  )aQ  Parses one or more transform calls and returns a _Transform call object.

The initial '(' has already been consumed by the caller.

Args:
  func_name: The name of the first transform function.
  active: The transform active level, None for always active.

Returns:
  The _Transform object containing the ordered list of transform calls.
r   T)r   r   Nr   z-Conditional filter expression expected [{0}].r>   r   r   z"Transform function expected [{0}].r   )r   r5   r   r   r	   TransformAlwaysTransformMapr   r   TransformIfrI   r   r   r"   r   r]   TransformSynthesizer   r   rY   r   r   r   r#   pop)r   rn   r   r   ro   r   rX   calls           r   	TransformLexer.Transform  s    DLEM
&&y5B ' Di	-==	=	>>/<<<2;..INN1-.a	>>/;;;y~~!##99=DD--%'( ( 	Y^^A./>>/CCC..y~~>					) 		)c$/ L XXZddc""!77077d#%& 	& 
Ta!773::d 356 	6 ((*iK r   )rx   rv   rw   r   )Nr   )FF)F)r   FTF)Fr   )r   N)r   )r-   r.   r/   r0   r1   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r2   r3   r   r   rr   rr      sw     ''	K'M&460 ?CbH.`  BH
Tl*QX5r   rr   c                     [        U 5      nUR                  5       nUR                  5       (       d3  [        R                  " SR                  UR                  5       5      5      eU$ )a  Returns a parsed key for the dotted resource name string.

This is an encapsulation of Lexer.Key(). That docstring has the input/output
details for this function.

Args:
  name: A resource name string that may contain dotted components and
    multi-value indices.

Raises:
  ExpressionSyntaxError: If there are unexpected tokens after the key name.

Returns:
  A parsed key for he dotted resource name string.
zUnexpected tokens [{0}] in key.)rr   r   r   r   r   r"   r   )r   r   r   s      r   ParseKeyr   >  sS      	d#	#			

3
3)00@B B	*r   c                     / nU  H  nUc"  U(       a  M  SnU(       a  US==   U-  ss'   M'  O[        U[        R                  5      (       a/  U(       a  MP  SR                  US9nU(       a  US==   U-  ss'   Mu  OVU(       aO  [        R
                  " SU5      (       a3  UR                  SS5      nUR                  SS	5      nS
R                  US9nUR                  U5        M     U(       a  SR                  U5      $ S$ )a  Returns the string representation for a parsed key.

This is the inverse of Lexer.Key(). That docstring has the input/output
details for this function.

Args:
  key: A parsed key, which is an ordered list of key names/indices. Each
    element in the list may be one of:
      str - A resource property name. This could be a class attribute name or
        a dict index.
      int - A list index. Selects one member is the list. Negative indices
        count from the end of the list, starting with -1 for the last element
        in the list. An out of bounds index is not an error; it produces the
        value None.
      None - A list slice. Selects all members of a list or dict like object.
        A slice of an empty dict or list is an empty dict or list.
  quote: "..." the key name if it contains non-alphanum characters.
  omit_indices: Omit [...] indices if True.

Returns:
  The string representation of the parsed key.
z[]rN   z[{part}])partz[^-@\w]rt   z\\"z\"z"{part}"r>   )	r    sixinteger_typesr"   researchreplacerW   r#   )r   r   omit_indicespartsr   s        r   
GetKeyNamer  V  s    . %d|	d	b	T	 
 
D#++	,	,	D)d	b	T	 
 
299Z..\\$'d\\#u%dD)d	LL' ( "%*s*r   )NN)TF)r1   
__future__r   r   r   r)   r   googlecloudsdk.core.resourcer   r   r   r	   r   	six.movesr
   r   OPERATOR_CHARSr   objectr   r5   rp   rr   r   r  r3   r   r   <module>r
     s    5n '  '  	 < A : ; 
    *,>> %V %P` `F"F D0,+r   