
    ?                     ~    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\5      r " S S	\5      r	 " S
 S\5      r
g)zBA module that provides parsing utilities for each command example.    )absolute_import)division)unicode_literalsNc                   Z    \ rS rSrSrS rS rSS jrSS jrS r	S	 r
S
 rSS jrS rSrg)CommandStringParser   ae  Object which builds and returns all metadata about string and flags.

Attributes:
  command_node: calliope._CommandCommon, The command object that has access
  to argparse.
  command_parser: The argparse object for command_node.
  example_string: The most recently parsed example command string.
  example_metadata: The metadata gotten from example_string.
c                 F    Xl         U R                   R                  U l        g N)command_node_parsercommand_parser)selfr   s     5lib/googlecloudsdk/core/util/command_string_parser.py__init__CommandStringParser.__init__%   s    $++33D    c                    Xl         [        5       U l        U R                  U5      nU(       d  gU R                  R                  USS9nUR                  5       nUR                  5        H  u  pV[        X5S5      n[        U[        5      (       a  U R                  XuU5        M:  [        U[        R                  5      (       a  U R                  XuU5        Mm  U R                  XuU5        M     U R                  $ )zGets relevant metadata from an example command string.

Args:
  example_command_string: The example command string to be parsed.

Returns:
  An ExampleCommandMetadata object containing the relevant metadata or None
  if there was a parsing error.
NT)raise_error)example_stringExampleCommandMetadataexample_metadataget_parse_argsr   
parse_argsGetSpecifiedArgsDictitemsgetattr
isinstancelist
parse_listcollectionsOrderedDict
parse_dictparse_others)r   example_command_stringparse_inputmetadatafilteredkeyvalue	tmp_values           r   parseCommandStringParser.parse)   s     124D%%&<=K""--kt-LH,,.Hnn&
(.i	It	$	$	.i!8!899	. 	)%0 '    r   Nc                 l   [        UR                  5       5      nUS   nUS   nU R                  X45      n	U R                  R	                  [        US   5      U	5      n
U R                  R                  SU
5      nX:  a  [        U R                  5      n[        US   5      nU R                  R                  XU5      nU[        U5      -   S-
  nU R                  XS-    nU(       a  SR                  X%S9OUn[        X/UX5      nU R                  R                  U5        U(       a  UR                  S-   $ g)a  Gets metadata from an example command string for a simple dict-type arg.

It updates the already existing ExampleCommandMetadata object of the example
string with the metadata.

Args:
  dict_arg: The dictionary-type argument to collect metadata about.
  key: The name of the argument's attribute in the example string's
  namespace.
  value: The actual input representing the flag/argument in the example
  string (e.g --zone, --shielded-secure-boot).
  prev_stop: Optional. The index in the example string the flag was last
  seen.
  count: Optional. The number of times the flag has been seen in the example
  string.

Returns:
  The index in the example string where parsing stopped if the argument is
  specified multiple times.
r   --   {key}_{count}r(   countN)r   r   get_start_searchr   indexstrfindlenrfindformatArgumentMetadatar   add_arg_metadata
stop_index)r   dict_argr(   r)   	prev_stopr3   	dict_list
first_pair	last_pairstart_searchstart_index
next_start
last_valuelast_value_startr=   	arg_valuescopearg_metadatas                     r   r"   CommandStringParser.parse_dictJ   s.   * X^^%&I1J"I((:L%%++C
1,>MK$$))$<J s43F3F/G*Yq\"J**001;=!C
O3a7J##K1=I =BO""s"8sE#CE$/=L**<8$$q(( r   c                    [        US   [        R                  5      (       a  U R                  XU5        g[        US   [        5      (       a  U R                  XU5        gU R                  X45      nU R                  R                  [        US   5      U5      nU R                  R                  SU5      nX:  d  US:X  a  [        U R                  5      n[        US   5      n	U R                  R                  XU5      n
U
[        U	5      -   S-
  nU R                  X{S-    nU(       a  SR                  X%S9OUn[        X,XU5      nU R                  R                  U5        U(       a  UR                   S-   $ g)a  Gets metadata from an example command string for a list-type argument.

It updates the already existing ExampleCommandMetadata object of the example
string with the metadata.

Args:
  list_arg: The list-type argument to collect metadata about.
  key: The name of the argument's attribute in the example string's
  namespace.
  value: The actual input representing the flag/argument in the example
  string (e.g --zone, --shielded-secure-boot).
  prev_stop: Optional. The index in the example string the flag was last
  seen.
  count: Optional. The number of times the flag has been seen in the example
  string.

Returns:
  The index in the example string where parsing stopped if the argument is
  specified multiple times.
r   r/   r.   r0   r1   r2   N)r   r    r!   parse_nested_listr   r4   r   r5   r6   r7   r8   r9   r:   r;   r   r<   r=   )r   list_argr(   r)   r?   r3   rC   rD   rE   rF   rG   r=   rH   rI   rJ   s                  r   r   CommandStringParser.parse_listx   s\   * (1+{6677
XE2	HQK	&	&
XE2
 **5<l''--c(1+.>Mk&&++D+>j		"jB&6,,-
x|$j,,22:3=?#c*o5q8j%%kQ,?i>Co$$$:e &ce&02l
,,\:	&&** 
r   c           	         U R                   R                  U5      n[        US   [        R                  5      (       Gat  US:X  Ga<  [        U5      S:  Ga,  [        US   R                  5       5      n[        US   R                  5       5      nUS   S   nUS   S   nU R                  U5      n	U R                   R                  [        U5      U	5      n
U R                   R                  SU
5      nX:  a  [        U R                   5      nU R                   R                  [        U5      U	U5      [        [        U5      5      -   S-
  nU R                   XS-    n[        X-X*U5      nU R                  R                  U5        gSn[!        U5       H  nUU   nU R#                  UX#UUS-   5      nM!     gSn[!        U5       H  nUU   nU R%                  UX#UUS-   5      nM!     g)a  Gets metadata from an example command string for nested list arguments.

This is a helper function for parse_list().

It updates the already existing ExampleCommandMetadata object of the example
string with the metadata.

Args:
  list_arg: The list-type argument to collect metadata about.
  key: The name of the argument's attribute in the example string's
  namespace.
  value: The actual input representing the flag/argument in the example
  string (e.g --zone, --shielded-secure-boot).
r   r0   r.   r/   N)r   r3   r   r    r!   r8   r   r   r4   r5   r6   r7   r9   r;   r   r<   ranger"   r   )r   rN   r(   r)   
flag_count
first_dict	last_dictstartstoprC   rD   rE   r=   rH   rJ   r?   ivals                     r   rM   %CommandStringParser.parse_nested_list   s    $$**51J(1+{6677 
qS]Q.(1+++-.
"++-.	1a }Q,,U3))//E
LI((--dK@
$3t7J7J3Kj))//D	<0:<#d)n%'()
 ''qLA	'(24..|<
 	z"A#ooc3y!A#F) # iZ !qkOOCY!D	 !r   c                    [        U[        5      (       d  U R                  U5      nU R                  R	                  [        U5      U5      nUS:X  a  U R                  X5      nU R                  R                  [        U5      U5      n[        X!X%U[        [        U5      5      -   S-
  5      nU R                  R                  U5        gg)a  Gets metadata from an example string for non list-type/dict-type args.

It updates the already existing ExampleCommandMetadata object of the example
string with the metadata.

Args:
  other_arg: The non list-type and non dict-type argument to collect
  metadata about.
  key: The name of the argument's attribute in the example string's
  namespace.
  value: The actual input representing the flag/argument in the example
  string (e.g --zone, --shielded-secure-boot).

r.   r0   N)r   boolr4   r   r7   r6   get_enum_valuer5   r;   r8   r   r<   )r   	other_argr(   r)   rC   rD   rJ   s          r   r#    CommandStringParser.parse_others   s    " i&&**51l'',,S^\Jk		''	@	''--c)nlKk%cc&1CI4G&G!&KMl ,,\: 'r   c                 4   U R                   US n[        U[        5      (       aT  UR                  5       UR	                  5       UR                  SS5      UR                  SS5      /nU H  nXS;   d  M
  UnM     [        U5      U;  a  UR                  5       nUR                  S5      nUS:w  a  USU R                  S5      OUR                  S5      n[        U5      S:  a"  SR                  US	S 5      R                  5       OUS   R                  5       nU$ )
aN  Gets the input value of an enum argument in the example string.

This is a helper function for parse_others().

Args:
  enum_value: The namespace value of the argument in question.
  prev_stop: The index in the example string where parsing stopped.

Returns:
 The actual input in the example string representing the argument's value.
N-_z --r.   =    r0   )r   r   r6   lowerupperreplacestripr7   splitr8   join)r   
enum_valuer?   unparsed_stringpossible_versionsversionarg_endarg_lists           r   r\   "CommandStringParser.get_enum_value   s    )))*5O*c""%++-z/?/?/A%--c37%--c379 ''%* ' :o-'--/o$$U+g:AR-/(7+11#6&,,S1  7:(ma6GCHHXab\*002RL&&(  r   c                 b   U(       a(  U R                   R                  X5      [        U5      -   nO'U R                   R                  U5      [        U5      -   nUS:X  aR  U R                  R                  R                  SS5      nU R                   R                  U5      nU[        U5      -   S-   nU$ )a  Gets the position to begin searching for an argument's value.

This is a helper function for all the parse functions aside from parse().

Args:
  namespace_name: The value of the argument in namespace's specified_args
  dictionary. ('INSTANCE_NAMES:1', '--zone', etc)
  prev_stop: Optional. For recurring flags, where the flag was last
  seen.

Returns:
  The index in the example string to begin searching.
r.   ra   r`   r0   )r   r7   r8   r   namerg   )r   namespace_namer?   rC   command_namecommand_name_starts         r   r4   $CommandStringParser.get_start_search#  s    " ))..~I.)*l ))..~>.)*l
 r&&++33C=l..33LA'#l*;;Q>lr   c                     U R                   R                  R                  SS5      nUR                  U5      nUS:X  a  gU[	        U5      -   S-   n[
        R                  " XS 5      nU$ )zGets a list of arguments in a string.

(Note: It assumes '$' is not included in the string)

Args:
  string: The string in question.

Returns:
  A list of the arguments from the string.
ra   r`   r.   Nr0   )r   rs   rg   r7   r8   shlexri   )r   stringru   rv   command_name_stop	args_lists         r   r   "CommandStringParser.get_parse_argsD  so     $$))11#s;L\2 R +S->>AF#567Ir   )r   r   r   r   )r   N)r   )__name__
__module____qualname____firstlineno____doc__r   r+   r"   r   rM   r#   r\   r4   r   __static_attributes__ r   r   r   r      s;    4!B,)\2+h3Ej;<"HBr   r   c                   <    \ rS rSrSrS rS rS rS rS r	S r
S	rg
)r   i]  zEncapsulates metadata about entire example command string.

Attributes:
  argument_metadatas: A list containing the metadata for each argument in an
  example command string.
c                     / U l         g r
   _argument_metadatasr   s    r   r   ExampleCommandMetadata.__init__e  s
    !Dr   c                 :    U R                   R                  U5        g)zvAdds an argument's metadata to comprehensive metadata list.

Args:
  arg_metadata: The argument metadata to be added.
N)r   append)r   rJ   s     r   r<   'ExampleCommandMetadata.add_arg_metadatah  s     	##L1r   c                 ,    [        U R                  S S9$ )z:Returns the metadata for an entire example command string.c                     U R                   $ r
   r=   xs    r   <lambda>?ExampleCommandMetadata.get_argument_metadatas.<locals>.<lambda>r  s    !,,r   r(   )sortedr   r   s    r   get_argument_metadatas-ExampleCommandMetadata.get_argument_metadatasp  s    $**0FGGr   c                    [        U[        5      (       au  [        U R                  S S9n[        UR                  S S9n[	        U5      [	        U5      :w  a  g[        [	        U R                  5      5       H  nX$   X4   :w  d  M    g   gg)Nc                     U R                   $ r
   r   r   s    r   r   /ExampleCommandMetadata.__eq__.<locals>.<lambda>w  s    r   r   c                     U R                   $ r
   r   r   s    r   r   r   x  s    1<<r   FT)r   r   r   r   r8   rQ   )r   otherour_data
other_datarW   s        r   __eq__ExampleCommandMetadata.__eq__t  sz    %/00006LMh%339OPj	X#j/	)S1123!;*-' 4 r   c                 $    U R                  U5      $ r
   r   r   r   s     r   __ne__ExampleCommandMetadata.__ne__  s    ;;ur   c                     U R                  5       nU Vs/ s H  n[        U5      PM     nnSR                  SR                  U5      S9$ s  snf )Nz
[{result}]z,  )result)r   r6   r:   rj   )r   	metadatasdatar   s       r   __str__ExampleCommandMetadata.__str__  sJ    ++-I$-.IDc$iIF.ejj&899 /s   A
r   N)r~   r   r   r   r   r   r<   r   r   r   r   r   r   r   r   r   r   ]  s&    "2H :r   r   c                   0    \ rS rSrSrS rS rS rS rSr	g)	r;   i  a=  Encapsulates metadata about a single argument.

Attributes:
  arg_name: The name of the argument.
  arg_value: Value of the argument.
  scope: The scope of the argument.
  start_index: The  index where the argument starts in the command string.
  stop_index: The index where the argument stops in the command string.
c                 @    Xl         X l        X0l        X@l        XPl        g r
   arg_namerH   rI   rD   r=   )r   r   rH   rI   rD   r=   s         r   r   ArgumentMetadata.__init__  s    MNJ" Or   c                     SR                  U R                  U R                  U R                  U R                  U R
                  S9$ )zBReturns a human-readable representation of an argument's metadata.zgArgumentMetadata(name={name},  value={value},  scope={scope},  start_index={start},  stop_index={stop}))rs   rI   r)   rU   rV   )r:   r   rI   rH   rD   r=   r   s    r   r   ArgumentMetadata.__str__  s=    v4==

$(NN$:J:J#'??  44r   c                 `   [        U[        5      (       a  U R                  UR                  :H  =(       ay    U R                  UR                  :H  =(       aY    U R                  UR                  :H  =(       a9    U R
                  UR
                  :H  =(       a    U R                  UR                  :H  $ g)NF)r   r;   r   rH   rI   rD   r=   r   s     r   r   ArgumentMetadata.__eq__  s    %)**mmu~~- 2nn/2jjEKK'2 %"3"332 oo!1!11	3 r   c                 .    U R                  U5      (       + $ r
   r   r   s     r   r   ArgumentMetadata.__ne__  s    {{5!!!r   r   N)
r~   r   r   r   r   r   r   r   r   r   r   r   r   r;   r;     s    !4"r   r;   )r   
__future__r   r   r   r    ry   objectr   r   r;   r   r   r   <module>r      sB     I &  '  @& @F
-:V -:`%"v %"r   