
    O                         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Jr  SSKr " S S\5      r  SS jrg)z5A class for parsing a resource projection expression.    )absolute_import)division)unicode_literalsN)resource_exceptions)resource_filter)resource_lex)resource_projection_spec)resource_transformc                       \ rS rSrSrSS/rS/rSS jr " S S	\5      r	 " S
 S\5      r
S rS rS rS rS rS rS rSS jrSrg)Parser"   a[  Resource projection expression parser.

A projection is an expression string that contains a list of resource keys
with optional attributes. This class parses a projection expression into
resource key attributes and a tree data structure that is used by a projector.

A projector is a method that takes a JSON-serializable object and a
projection as input and produces a new JSON-serializable object containing
only the values corresponding to the keys in the projection. Optional
projection key attributes may transform the values in the resulting
JSON-serializable object.

In the Cloud SDK projection attributes are used for output formatting.

A default or empty projection expression still produces a projector that
converts a resource to a JSON-serializable object.

Attributes:
  __key_attributes_only: Parse projection key list for attributes only.
  _projection: The resource_projection_spec.ProjectionSpec to parse into.
  _root: The projection _Tree tree root node.
  _snake_headings: Dict used to disambiguate key attribute labels.
  _snake_re: Compiled re for converting key names to angry snake case.
optionalreversewrapNc                 b    SU l         [        R                  " XX4S9U l        0 U l        SU l        g)a	  Constructor.

Args:
  defaults: resource_projection_spec.ProjectionSpec defaults.
  symbols: Transform function symbol table dict indexed by function name.
  aliases: Resource key alias dictionary.
  compiler: The projection compiler method for nested projections.
FdefaultssymbolsaliasescompilerN)_Parser__key_attributes_onlyr	   ProjectionSpec_projection_snake_headings	_snake_re)selfr   r   r   r   s        >lib/googlecloudsdk/core/resource/resource_projection_parser.py__init__Parser.__init__?   s4     "'D/>>GPDDDN    c                       \ rS rSrSrS rSrg)Parser._TreeN   z}Defines a Projection tree node.

Attributes:
  tree: Projection _Tree node indexed by key path.
  attribute: Key _Attribute.
c                     0 U l         Xl        g N)tree	attribute)r   r'   s     r   r   Parser._Tree.__init__V   s    di nr    )r'   r&   N)__name__
__module____qualname____firstlineno____doc__r   __static_attributes__ r    r   _Treer"   N   s    !r    r0   c                   $    \ rS rSrSrS rS rSrg)Parser._AttributeZ   aY  Defines a projection key attribute.

Attribute semantics, except transform, are caller defined.  e.g., the table
formatter uses the label attribute for the column heading for the key.

Attributes:
  align: The column alignment name: left, center, or right.
  flag: The projection algorithm flag, one of DEFAULT, INNER, PROJECT.
  hidden: Attribute is projected but not displayed.
  label: A string associated with each projection key.
  optional: Column data is optional if True.
  order: The column sort order, None if not ordered. Lower values have
    higher sort precedence.
  reverse: Reverse column sort if True.
  skip_reorder: Don't reorder this attribute in the next _Reorder().
  subformat: Sub-format string.
  transform: obj = func(obj,...) function applied during projection.
  width: Fixed column width.
  wrap: Column can be wrapped if True.
c                     [         R                  U l        Xl        SU l        S U l        S U l        S U l        S U l        SU l	        S U l
        S U l        S U l        S U l        g )NF)r	   ALIGN_DEFAULTalignflaghiddenlabelr   orderr   skip_reorder	subformat	transformwidthr   )r   r7   s     r   r   Parser._Attribute.__init__p   s[    +99djidkdjdmdjdlddndndjdir    c                    / nU R                   (       a  UR                  S5        U R                  (       a  UR                  S5        U R                  (       a  UR                  S5        U R                  (       a  UR                  S5        U(       a!  SR                  SR                  U5      5      nOSnSR                  U R                  U R                  c  S	O[        R                  " U R                  5      U R                  c  U R                  OS
U R                  -   S
-   U R                  U R                  (       a  U R                  R                  OS U R                  U R                  US9$ )Nr8   r   r   r<   z, [{0}]| zK({flag}, {order}, {label}, {align}, {active}, {wrap}, {transform}{options})	UNORDERED')r7   r:   r9   r6   activer   r=   options)r8   appendr   r   r<   formatjoinr7   r:   six	text_typer9   r6   r=   rE   r   )r   optionrF   s      r   __str__Parser._Attribute.__str__~   s   f	h	j!	i 	k"	""388F#34''-vyy JJ. %47MM$**4M'+zz'9s@$&)@*

26....dyy NN! (. 
(#$r    )r6   r7   r8   r9   r   r:   r   r;   r<   r=   r>   r   N)r)   r*   r+   r,   r-   r   rM   r.   r/   r    r   
_Attributer2   Z   s    *$r    rO   c                 z   U R                   c  [        R                  " S5      U l         Sn[        U5       H  n[	        U[
        R                  5      (       d  M$  U R                   R                  SU5      R                  5       nU(       a	  US-   U-   nOUnX R                  ;  d  Mq  SU R                  U'     U$    U$ )a  Returns an ANGRY_SNAKE_CASE string representation of a parsed key.

For key input [A, B, C] the headings [C, C_B, C_B_A] are generated. The
first heading not in self._snake_headings is added to self._snake_headings
and returned.

Args:
    key: A parsed resource key and/or list of strings.

Returns:
  The ANGRY_SNAKE_CASE string representation of key, adding components
    from right to left to disambiguate from previous ANGRY_SNAKE_CASE
    strings.
z)((?<=[a-z0-9])[A-Z]+|(?!^)[A-Z](?=[a-z]))rB   z_\1_   )
r   recompilereversed
isinstancerJ   string_typessubupperr   )r   keyr9   index	key_snakes        r   _AngrySnakeCaseParser._AngrySnakeCase   s     ~~zz"MNdnE#	E3++	,	,NN&&vu5;;=	c/E)%%,,,()$

u
%
L  Lr    c                 2	   U R                   nUSS  H  nUR                  nXE;   aN  XT   R                  nUR                  U R                  R
                  :w  a  U R                  R                  Ul        O6U R                  U R                  U R                  R                  5      5      XT'   XT   nM     UR                  nU(       a  US   OSnXE;   nU(       a  XT   R                  nU R                  (       d`  [        U R                  R                  5        Vs/ s H  oR                  U:X  d  M  UPM     sn5      (       a  [        R                  " U5      nU R                  (       a  UR                  (       d  SUl        O[!        U["        R$                  5      (       a0  SU;   a*  [        R&                  " US   5      XT'   XT   R                  nOVUnU R                  (       a  UR                  (       a  SUl        U(       d  UR(                  (       a  U R                  U5      XT'   UR                  b>  UR                  Ul        U R                  (       a  U =R*                  S-  sl        SUl        UR.                  b  UR.                  Ul        O#UR.                  c  U R1                  U5      Ul        UR2                  [4        R6                  :w  a  UR2                  Ul        UR8                  b  UR8                  Ul        OUR8                  c  SUl        UR:                  b  UR:                  Ul        OUR:                  c  SUl        UR(                  (       a  UR(                  Ul        UR<                  (       a  UR<                  Ul        UR>                  b  UR>                  Ul        OUR>                  c  SUl        UR@                  b  UR@                  Ul         OUR@                  c  SUl         U R                  RC                  UR.                  X5        U R                  (       a  UR                  (       a7  U R                  R
                  Ul        U R                  RE                  X5        gU(       d  U R                  RF                  Ul        ggs  snf )zPropagates default attribute values and adds key to the projection.

Args:
  key: The parsed key to add.
  attribute_add: Parsed _Attribute to add.
NrB   FTrR   )$_rootr&   r'   r7   r   PROJECTINNERr0   rO   r   anyColumnsrZ   copyr:   r8   rV   rJ   integer_typesdeepcopyr=   _Parser__key_order_offsetr;   r9   r]   r6   r	   r5   r   r   r<   r>   r   AddAliasAddKeyDEFAULT)	r   rZ   attribute_add
projectionnamer&   r'   name_in_treecols	            r   _AddKeyParser._AddKey   s~    J CR__d	J((	>>T--555++11).ZZ0@0@0F0F GH
:j  ??D3r7rD<L*&&i((
d..668K8sGGsNs8K
L
L IIi(	''y 		D#++	,	,==d,dj*&&i  i		#	#				##ZZ	*
 &%++io		#	#1$!%	&%++io		 ,,S1io6DDD%++io)(11i				# i('//i				"i)33i)33i&%++io		 io%$))in		inioos>%%)9)9''//in
c-''//in { Ls   R.Rc                    ^ ^ UU 4S jmT R                   (       a$  T" T R                  R                  5        ST l         gg)zRecursively adds self.__key_order_offset to non-zero attribute order.

This slides established attribute.order out of the way so new
attribute.order in projection composition take precedence.
c                 :  > U R                  5        H  nUR                  R                  (       aV  UR                  R                  (       a  SUR                  l        O)UR                  =R                  TR                  -  sl        T" UR
                  5        M     g)a  Adds self.__key_order_offset to unmarked attribute.order.

A DFS search that visits each attribute once. The search clears
skip_reorder attributes marked skip_reorder, otherwise it adds
self.__key_order_offset to attribute.order.

Args:
  tree: The attribute subtree to reorder.
FN)valuesr'   r:   r;   ri   r&   )r&   node_AddOffsetToOrderr   s     r   rx   *Parser._Reorder.<locals>._AddOffsetToOrder  sb     ++-$>>^^((*/DNN'NN  D$;$;; $))$  r    r   N)ri   ra   r&   )r   rx   s   `@r   _ReorderParser._Reorder  s0    %$ 

( !d r    c                     U R                   R                  SSS9nU R                   R                  5       nU R                   R                  SSS9(       a  SnU R                   R                  SSSS9nO"SnUR	                  S	5      (       a  US
S nSnOSnX0R
                  ;   aF  U(       d>  [        R                  " SR                  U R                   R                  U5      5      5      eOTU(       aM  X0R                  ;  a>  [        R                  " SR                  U R                   R                  U5      5      5      eUS:X  ac  U(       d>  [        R                  " SR                  U R                   R                  U5      5      5      eU R                  R                  XaU5        GOUS:X  aY  U[        R                  ;  a>  [        R                  " SR                  U R                   R                  U5      5      5      eXbl        OUS:X  a  U=(       d    SUl        OUS:X  a  U=(       d    SUl        OUS:X  a  Xbl        OrUS:X  a  Xbl        OeUS:X  a  Xbl        OXUS:X  a  Xbl        OKUS:X  a  Xbl        O>[        R                  " SR                  U R                   R                  U5      5      5      eU R                   R                  S5      (       d  gGM  )a7  Parses one or more key attributes and adds them to attribute.

The initial ':' has been consumed by the caller.

Args:
  key: The parsed key name of the attributes.
  attribute: Add the parsed transform to this resource_projector._Attribute.

Raises:
  ExpressionSyntaxError: The expression has a syntax error.
Tz=:,)Fspace=eoi_okz:,)r~   convertno-   Nzvalue not expected [{0}].zvalue expected [{0}].aliaszCannot unset alias [{0}].r6   zUnknown alignment [{0}].rH   rB   r9   r   r   sortr>   r   zUnknown key attribute [{0}].:)_lexTokenGetPositionIsCharacter
startswith_BOOLEAN_ATTRIBUTESr   ExpressionSyntaxErrorrH   Annotate_OPTIONAL_BOOLEAN_ATTRIBUTESr   rj   r	   
ALIGNMENTSr6   r<   r9   r   r   r:   r>   r   )r   rZ   r'   ro   hereboolean_valuevalues          r   _ParseKeyAttributesParser._ParseKeyAttributes2  si    YY__V5_1dYY""$d			s4		0		UDA??5!!ab$%%	))	)#99)001C1CD1IJL L  T)J)JJ!77#**499+=+=d+CDF 	F	#99)001C1CD1IJL L!!%i87?0;;;#99(//		0B0B40HIK K8#kr	7?+2	:"9!6>7?6>!77*11$))2D2DT2JKM 	MYY""3''e r    c                   ^ U R                   R                  5       u  pU R                   R                  SSS9(       a?  U R                   R                  UR	                  5       U R
                  R                  5      nOSnU R                  (       d  U(       d  U R                  (       a%  U(       a  U(       d  [        R                  " U5      nO%U R                  U R
                  R                  5      nUR                  (       d  X2l        O6U(       a/  UR                  R                  R                  UR                  5        U R                   R                  5         U R                   R                  S5      (       a  U R                  X5        UR                  (       a  UR                  R                   (       a  U R
                  R"                  R%                  [&        R(                  " S5      5      mU4S jn[*        R,                  " [*        R.                  U0S9n[0        R2                  " UR                  R                   US	9R5                  T5      (       d  gUR6                  cg  U(       d`  UR                  (       aO  U R9                  UR                  R:                  /UR                  R                  S
   R<                  -   5      Ul        U R?                  X5        g)a  Parses a key and optional attributes from the expression.

The parsed key is appended to the ordered list of keys via _AddKey().
Transform functions and key attributes are also handled here.

Raises:
  ExpressionSyntaxError: The expression has a syntax error.
(Tr   Nr   conditionalsc                    > [        TUS 5      $ r%   )getattr)
unused_objrestrictionunused_patternr   s      r   EvalGlobalRestriction/Parser._ParseKey.<locals>.EvalGlobalRestriction  s    |[$77r    )r   )r   r   ) r   KeyWithAttributer   	Transformpopr   rE   r   rf   rO   rb   r=   _transformsextend	SkipSpacer   conditionalr   getr
   GetTypeDataNamer	   r   GLOBAL_RESTRICTION_NAMEr   CompileEvaluater9   r]   ro   argsrr   )r   rZ   r'   add_transformr   r   r   s         @r   	_ParseKeyParser._ParseKeyr  s    YY//1NCyyS.ii))#'')T5E5E5L5LMmm&&t11i ))I&i//$"2"2":":;i)	%%,,]-F-FGIIyyS!!
s.y22>>%%--11

,
,^
<>l8 *88+CC(*+h $$



)
)%Xl34 	sy/B/B,,##
$



)
)!
,
1
123io 	LL r    c                    U R                   R                  S5      (       a  g U R                  5         U R                   R                  5         U R                   R                  S5      (       a  gU R                   R                  S5      (       d=  [        R
                  " SR                  U R                   R                  5       5      5      eM  )zParses a comma separated list of keys.

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

Raises:
  ExpressionSyntaxError: The expression has a syntax error.
)N,z*Expected ) in projection expression [{0}].)r   r   r   r   r   r   rH   r   )r   s    r   
_ParseKeysParser._ParseKeys  s     yyS!!

nn
ii			s	#	#YY""3''!778??		""$&' 	' r    c                 "    U R                   R                  SSS9nU(       a  U R                   R                  S5      (       a  U R                   R                  SSSS9nOSn[        U[        R
                  5      (       a"  UR                  S	S
5      R                  SS5      nU R                  R                  X5        UR                  S5      (       a  U R                  R                  USS 5        OU R                  R                  SU-   5        U R                   R                  S5      (       a  gU R                   R                  S5      (       d=  [        R                  " SR                  U R                   R                  5       5      5      eGM  )zParses a comma separated [no-]name[=value] projection attribute list.

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

Raises:
  ExpressionSyntaxError: The expression has a syntax error.
Tz=,])Fr}   r   z,])r   rR   z\n
z\t	r   r   N]r   z#Expected ] in attribute list [{0}].)r   r   r   rV   rJ   rW   replacer   AddAttributer   DelAttributer   r   rH   r   )r   ro   r   s      r   _ParseAttributesParser._ParseAttributes  s9    YY__V5_1d	99  %%))//%ud/C%%eS--..--t,44UDA%%%d2??5!!



'
'QR
1



'
'
5			s	#	#YY""3''!771889K9K9MNP 	P# r    c                 (   U R                   R                  5       U l        U R                  (       d^  U R                  U R	                  U R                   R
                  5      5      U l        U R                   R                  U R                  5        U R                   R                  U R                  U R	                  U R                   R                  5      5      5        U(       Ga$  [        R                  " XR                   5      U l        SnSU l        U R                  R                  5       (       Ga  U R                  R                  S5      (       ag  U R                  (       d  SnU R                   R                  5         U R!                  5         U R                  (       a  SU l        U R#                  5         GOU R                  R                  S5      (       a  U R%                  5         OU R                  R                  S5      (       a  SU l        SU l        OU R                  R)                  5       nU R                  R+                  S5      nUR-                  5       (       d>  [.        R0                  " SR3                  U R                  R5                  U5      5      5      eU R                   R7                  U5        SnU R                  R                  5       (       a  GM  S	U l        U(       a  U R                   R                  5         U R                   $ )
zParse a projection expression.

An empty projection is OK.

Args:
  expression: The resource projection expression string.

Raises:
  ExpressionSyntaxError: The expression has a syntax error.

Returns:
  A ProjectionSpec for the expression.
Fr   [r   Tr   z:([zName expected [{0}].N)r   GetRootra   r0   rO   rl   SetRootSetEmptyrb   r   Lexerr   r   r   r   Defaultsr   rz   r   ri   r   r   isalphar   r   rH   r   SetName)r   
expressionr   r   ro   s        r   ParseParser.Parse  s'    !!))+DJ::::dood.>.>.F.FGHdj
tzz*

4??4#3#3#;#;<=?$$Z1A1ABdih#(d II!!99  %%++H%%'
//
'').D&MMOYY""3''



!YY""3'''+$
$$%$
!&&($'$%;;&--dii.@.@.FGI I



"
"4
((+ II!!, di	!!#r    )__key_attributes_only__key_order_offsetr   r   ra   r   r   )NNNNr%   )r)   r*   r+   r,   r-   r   r   r   objectr0   rO   r]   rr   rz   r   r   r   r   r   r.   r/   r    r   r   r   "   sg    2 $Y/"(
!f 
!=$6 =$~<\0|":>@3!j'*P81r    r   c                 6    [        XUUS9R                  U 5      $ )a  Parses a resource projector expression.

Args:
  expression: The resource projection expression string.
  defaults: resource_projection_spec.ProjectionSpec defaults.
  symbols: Transform function symbol table dict indexed by function name.
  aliases: Resource key alias dictionary.
  compiler: The projection compiler method for nested projections.

Returns:
  A ProjectionSpec for the expression.
r   )r   r   )r   r   r   r   r   s        r   r   r     s"     
G!
##(5#45r    )rB   NNNN)r-   
__future__r   r   r   rf   rS   googlecloudsdk.core.resourcer   r   r   r	   r
   rJ   r   r   r   r/   r    r   <module>r      sH     < &  '  	 < 8 5 A ; 
gV gT ?C5r    