
    ?                     ~    d Z ddlmZ ddlmZ ddlmZ ddlZddlZ G d de      Z G d d	e      Z	 G d
 de      Z
y)zBA module that provides parsing utilities for each command example.    )absolute_import)division)unicode_literalsNc                   L    e Zd ZdZd Zd ZddZddZd Zd Z	d	 Z
dd
Zd Zy)CommandStringParseras  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                 H    || _         | j                   j                  | _        y N)command_node_parsercommand_parser)selfr
   s     5lib/googlecloudsdk/core/util/command_string_parser.py__init__zCommandStringParser.__init__%   s    $D++33D    c                    || _         t               | _        | j                  |      }|sy| j                  j                  |d      }|j                         }|j                         D ]w  \  }}t        ||d      }t        |t              r| j                  |||       7t        |t        j                        r| j                  |||       e| j                  |||       y | j                  S )a  Gets 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   parsezCommandStringParser.parse)   s     1D24D%%&<=K""--kt-LH,,.Hnn&
U(C.i	It	$	3.i!8!89	3. 	)S%0 '    r   Nc                 j   t        |j                               }|d   }|d   }| j                  ||      }	| j                  j	                  t        |d         |	      }
| j                  j                  d|
      }||	k  rt        | j                        }t        |d         }| j                  j                  ||	|      }|t        |      z   dz
  }| j                  |
|dz    }|rdj                  ||      n|}t        ||||
|      }| j                  j                  |       |r|j                  dz   S y)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_stopr0   	dict_list
first_pair	last_pairstart_searchstart_index
next_start
last_valuelast_value_startr:   	arg_valuescopearg_metadatas                     r   r    zCommandStringParser.parse_dictJ   s<   * X^^%&I1J"I((	:L%%++C
1,>MK$$))$<JL s43F3F/G*Yq\"J**00\1;=!C
O3a7J##K
1=I =BO""s%"8sE#CE$/=L**<8$$q(( r   c                    t        |d   t        j                        r| j                  |||       yt        |d   t              r| j                  |||       y| j                  ||      }| j                  j                  t        |d         |      }| j                  j                  d|      }||k  s|dk(  rt        | j                        }t        |d         }	| j                  j                  |	||      }
|
t        |	      z   dz
  }| j                  ||dz    }|rdj                  ||      n|}t        |||||      }| j                  j                  |       |r|j                   dz   S y)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+   r-   r.   r/   N)r   r   r   parse_nested_listr   r1   r   r2   r3   r4   r5   r6   r7   r8   r   r9   r:   )r   list_argr&   r'   r<   r0   r@   rA   rB   rC   rD   r:   rE   rF   rG   s                  r   r   zCommandStringParser.parse_listx   sh   * (1+{667
XsE2	HQK	&
XsE2
 **5)<l''--c(1+.>Mk&&++D+>j	l	"jB&6,,-
x|$j,,22:|3=?#c*o5q8j%%k*Q,?i>Co$$E$:e &c9e[&02l
,,\:	&&** 
r   c           	         | j                   j                  |      }t        |d   t        j                        rt|dk(  r>t        |      dkD  r/t        |d   j                               }t        |d   j                               }|d   d   }|d   d   }| j                  |      }	| j                   j                  t        |      |	      }
| j                   j                  d|
      }||	k  rt        | j                         }| j                   j                  t        |      |	|      t        t        |            z   dz
  }| j                   |
|dz    }t        ||||
|      }| j                  j                  |       yd}t!        |      D ]  }||   }| j#                  |||||dz         }! yd}t!        |      D ]  }||   }| j%                  |||||dz         }! y)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   r-   r+   r,   N)r   r0   r   r   r   r5   r   r   r1   r2   r3   r4   r6   r8   r   r9   ranger    r   )r   rJ   r&   r'   
flag_count
first_dict	last_dictstartstopr@   rA   rB   r:   rE   rG   r<   ivals                     r   rI   z%CommandStringParser.parse_nested_list   s    $$**51J(1+{667 
qS]Q.(1+++-.
"++-.	1a }Q,,U3))//E
LI((--dK@
$3t7J7J3Kj))//D	<0:<#d)n%'()
 ''JqLA	'Y[(24..|<
 	z"A#ooc3y!A#F) # iZ !qkOOCeY!D	 !r   c                    t        |t              s| j                  |      }| j                  j	                  t        |      |      }|dk(  r| j                  ||      }| j                  j                  t        |      |      }t        |||||t        t        |            z   dz
        }| j                  j                  |       yy)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+   r-   N)r   boolr1   r   r4   r3   get_enum_valuer2   r8   r5   r   r9   )r   	other_argr&   r'   r@   rA   rG   s          r   r!   z CommandStringParser.parse_others   s    " i&**51l'',,S^\Jk		''	<@	''--c)nlKk%c9c;&1CI4G&G!&KMl ,,\: 'r   c                    | j                   |d }t        |t              rP|j                         |j	                         |j                  dd      |j                  dd      g}|D ]	  }||v s|} t        |      |vr|j                         }|j                  d      }|dk7  r|d| j                  d      n|j                  d      }t        |      dkD  r"dj                  |d	d       j                         n|d   j                         }|S )
aj  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+   =    r-   )r   r   r3   lowerupperreplacestripr4   splitr5   join)r   
enum_valuer<   unparsed_stringpossible_versionsversionarg_endarg_lists           r   rV   z"CommandStringParser.get_enum_value   s    )))*5O*c"%++-z/?/?/A%--c37%--c379 ''o%* ' :o-'--/o$$U+g:AR-/(7+11#6&,,S1  7:(ma6GCHHXab\*002RL&&(  r   c                 X   |r)| j                   j                  ||      t        |      z   }n'| j                   j                  |      t        |      z   }|dk(  rR| j                  j                  j                  dd      }| j                   j                  |      }|t        |      z   dz   }|S )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+   rZ   rY   r-   )r   r4   r5   r
   namer`   )r   namespace_namer<   r@   command_namecommand_name_starts         r   r1   z$CommandStringParser.get_start_search#  s    " ))..~yI.)*l ))..~>.)*l
 r&&++33C=l..33LA'#l*;;Q>lr   c                     | j                   j                  j                  dd      }|j                  |      }|dk(  ry|t	        |      z   dz   }t        j                  ||d       }|S )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.
    rZ   rY   r+   Nr-   )r
   rk   r`   r4   r5   shlexrb   )r   stringrm   rn   command_name_stop	args_lists         r   r   z"CommandStringParser.get_parse_argsD  sr     $$))11#s;L\2 R +S->>AF#4#567Ir   )r   N)r   )__name__
__module____qualname____doc__r   r)   r    r   rI   r!   rV   r1   r    r   r   r   r      s;    4!B,)\2+h3Ej;<"HBr   r   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	r   zEncapsulates metadata about entire example command string.

  Attributes:
    argument_metadatas: A list containing the metadata for each argument in an
    example command string.
  c                     g | _         y r	   )_argument_metadatasr   s    r   r   zExampleCommandMetadata.__init__e  s
    !Dr   c                 :    | j                   j                  |       y)zAdds an argument's metadata to comprehensive metadata list.

    Args:
      arg_metadata: The argument metadata to be added.
    N)r{   append)r   rG   s     r   r9   z'ExampleCommandMetadata.add_arg_metadatah  s     	##L1r   c                 2    t        | j                  d       S )z:Returns the metadata for an entire example command string.c                     | j                   S r	   r:   xs    r   <lambda>z?ExampleCommandMetadata.get_argument_metadatas.<locals>.<lambda>r  s    !,,r   r&   )sortedr{   r|   s    r   get_argument_metadatasz-ExampleCommandMetadata.get_argument_metadatasp  s    $**0FGGr   c                    t        |t              ryt        | j                  d       }t        |j                  d       }t	        |      t	        |      k7  ryt        t	        | j                              D ]  }||   ||   k7  s y yy)Nc                     | j                   S r	   r   r   s    r   r   z/ExampleCommandMetadata.__eq__.<locals>.<lambda>w  s    r   r   c                     | j                   S r	   r   r   s    r   r   z/ExampleCommandMetadata.__eq__.<locals>.<lambda>x  s    1<<r   FT)r   r   r   r{   r5   rL   )r   otherour_data
other_datarR   s        r   __eq__zExampleCommandMetadata.__eq__t  s{    %/0006LMh%339OPj	X#j/	)S1123!A;*Q-' 4 r   c                 $    | j                  |      S r	   r   r   r   s     r   __ne__zExampleCommandMetadata.__ne__  s    ;;ur   c                     | j                         }|D cg c]  }t        |       }}dj                  dj                  |            S c c}w )Nz
[{result}]z,  )result)r   r3   r7   rc   )r   	metadatasdatar   s       r   __str__zExampleCommandMetadata.__str__  sJ    ++-I$-.IDc$iIF.ejj&899 /s   A
N)
rt   ru   rv   rw   r   r9   r   r   r   r   rx   r   r   r   r   ]  s&    "2H :r   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)r8   aK  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                 J    || _         || _        || _        || _        || _        y r	   )arg_namerE   rF   rA   r:   )r   r   rE   rF   rA   r:   s         r   r   zArgumentMetadata.__init__  s&    DMDNDJ"D DOr   c                     dj                  | j                  | j                  | j                  | j                  | j
                        S )zBReturns a human-readable representation of an argument's metadata.zgArgumentMetadata(name={name},  value={value},  scope={scope},  start_index={start},  stop_index={stop}))rk   rF   r'   rP   rQ   )r7   r   rF   rE   rA   r:   r|   s    r   r   zArgumentMetadata.__str__  s=    v4==

$(NN$:J:J#'??  44r   c                 .   t        |t              r| j                  |j                  k(  xrj | j                  |j                  k(  xrO | j                  |j                  k(  xr4 | j
                  |j
                  k(  xr | j                  |j                  k(  S y)NF)r   r8   r   rE   rF   rA   r:   r   s     r   r   zArgumentMetadata.__eq__  s    %)*mmu~~- 2nn/2jjEKK'2 %"3"332 oo!1!11	3 r   c                 &    | j                  |       S r	   r   r   s     r   r   zArgumentMetadata.__ne__  s    {{5!!!r   N)rt   ru   rv   rw   r   r   r   r   rx   r   r   r8   r8     s    !4"r   r8   )rw   
__future__r   r   r   r   rp   objectr   r   r8   rx   r   r   <module>r      sB     I &  '  @& @F
-:V -:`%"v %"r   