o
    tf                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 dd	l
mZ d
d Zdd Zdd ZG dd deZG dd deZdS )zCalliope argparse argument intercepts and extensions.

Refer to the calliope.parser_extensions module for a detailed overview.
    )absolute_import)division)unicode_literalsN)base)display_info)parser_errors)completion_cachec                 C   *   | dkpt | tjpt | tot| tjS )N
store_true)
isinstanceargparse_StoreTrueActiontype
issubclassaction r   E/tmp/google-cloud-sdk/lib/googlecloudsdk/calliope/parser_arguments.py_IsStoreTrueAction"      


r   c                 C   r	   )Nstore_false)r   r   _StoreFalseActionr   r   r   r   r   r   _IsStoreFalseAction*   r   r   c                 C   s   t | pt| S N)r   r   r   r   r   r   _IsStoreBoolAction1      r   c                   @   s:   e Zd ZdZ				dddZedd Zed	d
 ZdS )Argumenta  Parsed argument base class with help generation attributess.

  Attributes:
    arguments: [ArgumentInterceptor], The group argument list if is_group is
      true.
    category: str, The argument help category name.
    help: str, The argument help text.
    is_global: bool, The argument is global to all commands.
    is_hidden: bool, The argument help text is hidden.
    is_group: bool, The argument is a group with arguments in self.arguments.
    is_mutex: bool, This is a mutex argument group; at most one argument in
      arguments may be specified.
    is_positional: bool, The argument is a positional argument.
    is_required: bool, The argument is required.
    sort_args: bool, Whether to sort the arguments in this group when displaying
      help/usage text. Applies only to this arg group (does not propagate to
      nested groups).
    disable_default_heading: bool, The default help heading text is hidden.
  NFTc                 C   sN   |pg | _ |p|| _|| _|| _|| _d| _|| _|| _|| _|	| _	|
| _
d S )NF)	argumentsis_group	is_global
_is_hiddenis_mutexis_positionalis_requiredhelpcategory
_sort_argsdisable_default_heading)selfr   hiddenr   r   mutexrequiredr$   r%   	sort_argsr'   r   r   r   __init__K   s   


zArgument.__init__c                 C      | j S r   )r    r(   r   r   r   	is_hidden[      zArgument.is_hiddenc                 C   r.   r   r&   r/   r   r   r   r,   _   r1   zArgument.sort_args)
NFFFFFNNTF)__name__
__module____qualname____doc__r-   propertyr0   r,   r   r   r   r   r   5   s    

r   c                       sn  e Zd ZdZG dd deZ		dE fdd	Zedd	 Zed
d Z	edd Z
edd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zedd Zed d! Zed"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- ZdFd.d/Z	0	dG fd1d2	ZdHd3d4ZdHd5d6Zd7d8 Zd9d: Z d;d< Z!d=d> Z"d?d@ Z#dAdB Z$dCdD Z%  Z&S )IArgumentInterceptorad  ArgumentInterceptor intercepts calls to argparse parsers.

  The argparse module provides no public way to access the arguments that were
  specified on the command line. Argparse itself does the validation when it is
  run from the command line.

  Attributes:
    allow_positional: bool, Whether or not to allow positional arguments.
    defaults: {str:obj}, A dict of {dest: default} for all the arguments added.
    dests: [str], A list of the dests for all arguments.
    flag_args: [argparse.Action], A list of the flag arguments.
    parser: argparse.Parser, The parser whose methods are being intercepted.
    positional_args: [argparse.Action], A list of the positional arguments.
    required: [str], A list of the dests for all required arguments.

  Raises:
    ArgumentException: if a positional argument is made when allow_positional
        is false.
  c                   @   s   e Zd ZdZdd ZdS )zArgumentInterceptor.ParserDataa  Parser data for the entire command.

    Attributes:
      allow_positional: bool, Allow positional arguments if True.
      ancestor_flag_args: [argparse.Action], The flags for all ancestor groups
        in the cli tree.
      cli_generator: cli.CLILoader, The builder used to generate this CLI.
      command_name: [str], The parts of the command name path.
      concept_handler: calliope.concepts.handlers.RuntimeHandler, a handler
        for concept args.
      defaults: {dest: default}, For all registered arguments.
      dests: [str], A list of the dests for all arguments.
      display_info: [display_info.DisplayInfo], The command display info object.
      flag_args: [ArgumentInterceptor], The flag arguments.
      positional_args: [ArgumentInterceptor], The positional args.
      positional_completers: {Completer}, The set of completers for positionals.
      required: [str], The dests for all required arguments.
    c                 C   sX   || _ || _|| _g | _d | _d | _i | _g | _t	 | _g | _
g | _t | _g | _d S r   )command_namecli_generatorallow_positionalancestor_flag_argsconcept_handlerconceptsdefaultsdestsr   DisplayInfo	flag_argspositional_argssetpositional_completersr+   )r(   r9   r:   r;   r   r   r   r-      s   

z'ArgumentInterceptor.ParserData.__init__N)r3   r4   r5   r6   r-   r   r   r   r   
ParserDatay   s    rF   NTc                    sr   t t| jdddi| |dd| _|dd | _|| _|r#| |_|r*|| _d S tj	| jj
 ||d| _d S )Nr   Tr*   Fr$   )r9   r:   r;   r   )superr8   r-   popr!   r$   parseraidatarF   _calliope_commandGetPath)r(   rI   r:   r;   rK   kwargs	__class__r   r   r-      s   

zArgumentInterceptor.__init__c                 C      | j jS r   )rK   r;   r/   r   r   r   r;         z$ArgumentInterceptor.allow_positionalc                 C   rQ   r   )rK   r:   r/   r   r   r   r:      rR   z!ArgumentInterceptor.cli_generatorc                 C   rQ   r   )rK   r9   r/   r   r   r   r9      rR   z ArgumentInterceptor.command_namec                 C   rQ   r   )rK   r?   r/   r   r   r   r?      rR   zArgumentInterceptor.defaultsc                 C   rQ   r   )rK   r   r/   r   r   r   r      rR   z ArgumentInterceptor.display_infoc                 C   rQ   r   )rK   r+   r/   r   r   r   r+      rR   zArgumentInterceptor.requiredc                 C   rQ   r   )rK   r@   r/   r   r   r   r@      rR   zArgumentInterceptor.destsc                 C   rQ   r   )rK   rC   r/   r   r   r   rC      rR   z#ArgumentInterceptor.positional_argsc                 C   s|   | j rdS ztdd | jD  W dS  ty=   g }| jD ]}t|dr*||j7 }qtdd	| j
| jd	|w )	NTc                 s   s    | ]}|j s|V  qd S r   )r0   ).0ar   r   r   	<genexpr>   s    z0ArgumentInterceptor.is_hidden.<locals>.<genexpr>Foption_stringszvGroups with arguments and subgroups that are all hidden should be marked hidden.
Command: [{}]
Group: [{}]
Flags: [{}].z, )r    nextr   StopIterationhasattrrV   r   ArgumentExceptionformatjoinr9   r$   )r(   flagsargr   r   r   r0      s$   


zArgumentInterceptor.is_hiddenc                 C   rQ   r   )rK   rB   r/   r   r   r   rB      rR   zArgumentInterceptor.flag_argsc                 C   rQ   r   )rK   rE   r/   r   r   r   rE      rR   z)ArgumentInterceptor.positional_completersc                 C   rQ   r   )rK   r<   r/   r   r   r   r<      rR   z&ArgumentInterceptor.ancestor_flag_argsc                 C   rQ   r   )rK   r=   r/   r   r   r   r=      rR   z#ArgumentInterceptor.concept_handlerc                 C   rQ   r   )rK   r>   r/   r   r   r   r>      rR   zArgumentInterceptor.conceptsc                 C   s@   ddl m} t||jr|| j_d S | jjrtd|| j_d S )Nr   )concept_managerszCIt is not permitted to add two runtime handlers to a command class.)#googlecloudsdk.command_lib.conceptsr`   r   RuntimeParserrK   r>   r=   AttributeError)r(   handlerr`   r   r   r   add_concepts   s   z ArgumentInterceptor.add_conceptsc                 O   s  |d }| dd}| dd}|d}|d}|s'|| jjdd}| d	d
}| dd
p5| j}	|d}
|
sEtd||	|
t	j
krQtd|| dd}| dd
}| jpa|}|d}|dd
}| dd}|du ryg }| dd}| jr|tjkrd}|d }|r| jstd|d| jjd|v rtd|d| jj|rtd|d| jj|rtd|d| jj|| j|< |r| j| | j| |rd|vr| |d< |dt	ju r| jj|i |}n	| jj|i |}| ||| ||_||_d
|_|	|_ ||_!||_"|	r3|j#|_$t	j
|_#|rf|rGtd|d| jj|du s\|dks\t%|t&r_|dkr_d|_!| j'| nw|rz|rztd|d| jj|dkrtd |d| jj||_(||_)||_*||_+t%|j,t-rt.|d!|j, t/|j,0 |_,|durt.|d| | j1| | 2||||}|r||_(||_)||_*||_| j1| t3|dd
rt4| jd"kr| j5| |S )#z?add_argument intercepts calls to the parser to track arguments.r   r%   N	completerdefaultdest-_do_not_propagateFr)   r$   z*Argument {} requires help text [hidden={}]z@Argument {} needs hidden=True instead of help=argparse.SUPPRESS.require_coverage_in_testsTis_replicatednargsr+   suggestion_aliaseshidden_choicesGLOBALz3Illegal positional argument [{0}] for command [{1}]rW   zSPositional arguments cannot contain a '-'. Illegal argument [{0}] for command [{1}]zAPositional argument [{0}] cannot have a category in command [{1}]zIPositional argument [{0}] cannot have suggestion aliases in command [{1}]metavar+z;Required flag [{0}] cannot have a category in command [{1}]REQUIREDz;Flag [{0}] cannot have category='REQUIRED' in command [{1}]choices_help   )6rH   getlstriprI   prefix_charsreplacer    
ValueErrorr\   r   SUPPRESSr   r   COMMONLY_USED_FLAGS
startswithr;   r   r[   r]   rK   r9   r?   r+   appendr@   upper	REMAINDERAddRemainderArgumentadd_argument_AttachCompleterrl   r   r0   r#   r"   r$   hidden_helpr   intrC   r%   rk   rm   ro   choicesdictsetattrsortedkeysrB   "_AddInvertedBooleanFlagIfNecessarygetattrlenr   )r(   argsrN   namer%   rf   rg   rh   rk   r)   	help_textrl   rm   r   rn   r+   ro   rp   
positionaladded_argumentinverted_flagr   r   r   r   	  s   











z ArgumentInterceptor.add_argumentc                 C   s   | j |||S r   )rI   register)r(   registry_namevalueobjectr   r   r   r     r   zArgumentInterceptor.registerc                 K   s   | j jdi |S )Nr   )rI   set_defaults)r(   rN   r   r   r   r     s   z ArgumentInterceptor.set_defaultsc                 C   s   | j |S r   )rI   get_default)r(   rh   r   r   r   r     s   zArgumentInterceptor.get_defaultc                 C   s   | j j||dS )z;Hooks ArgumentInterceptor into the argcomplete monkeypatch.)r   	namespace)rI   parse_known_args)r(   r   r   r   r   r   r     s   z$ArgumentInterceptor.parse_known_argsFc           
         st   d|v sd|v rt dtt| j| j }td|| j| j| j	| j
|||||p+| j|d|}	| j|	 |	S )a  Adds an argument group with mutex/required attributes to the parser.

    Args:
      help: str, The group help text description.
      category: str, The group flag category name, None for no category.
      mutex: bool, A mutually exclusive group if True.
      required: bool, A required group if True.
      hidden: bool, A hidden group if True.
      sort_args: bool, Whether to sort the group's arguments in help/usage text.
        NOTE - For ordering consistency across gcloud, generally prefer using
        argument categories to organize information (instead of unsetting the
        argument sorting).
      **kwargs: Passed verbatim to ArgumentInterceptor().

    Returns:
      The added argument object.
    descriptiontitlezVparser.add_group(): description or title kwargs not supported -- use help=... instead.)rI   r   r:   r;   rK   r$   r%   r*   r+   r)   r,   Nr   )r   r[   rG   r   rI   add_argument_groupr8   r   r:   r;   rK   r    r   r   )
r(   r$   r%   r*   r+   r)   r,   rN   
new_parsergrouprO   r   r   	add_group  s*   zArgumentInterceptor.add_groupc                 K   s   | j dd|i|S )Nr$   r   r   r(   r$   rN   r   r   r   r     s   z&ArgumentInterceptor.add_argument_groupc                 K   s   | j d|dd|S )NT)r$   r*   r   r   r   r   r   r   add_mutually_exclusive_group  s   z0ArgumentInterceptor.add_mutually_exclusive_groupc                 K   s~   ||d< d|vr|  |d< | |d< | jjd	d|i|}|j|_d|_|dd|_d|_d|_	| j
| | j| |S )
a  Add a positional argument that adds new args on the fly when called.

    Args:
      name: The name/dest of the positional argument.
      action: The argparse Action to use. It must be a subclass of
        parser_extensions.DynamicPositionalAction.
      **kwargs: Passed verbatim to the argparse.ArgumentParser.add_subparsers
        method.

    Returns:
      argparse.Action, The added action.
    rh   rr   	parent_air   Fr)   TNr   )r   rI   add_subparsersCompletionsrf   r   rw   r0   r"   r#   rC   r   r   )r(   r   r   rN   r   r   r   AddDynamicPositional  s   z(ArgumentInterceptor.AddDynamicPositionalc                 C   s    | j D ]
}||jv r dS qdS )z,If flag with the given option_string exists.TF)rB   rV   )r(   option_stringr   r   r   r   _FlagArgExists  s
   

z"ArgumentInterceptor._FlagArgExistsc                 C   sB   dD ]}|  |r||jv r dS q| j| | jj| dS )zAdd a flag action to this parser, but segregate it from the others.

    Segregating the action allows automatically generated help text to ignore
    this flag.

    Args:
      action: argparse.Action, The action for the flag being added.
    )z	--projectz--billing-projectz--universe-domainz--formatN)r   rV   rI   _add_actionrK   r<   r   )r(   r   flagr   r   r   AddFlagActionFromAncestors  s   z.ArgumentInterceptor.AddFlagActionFromAncestorsc                 C   s  | d}t|dd}|dur|}|}| ||\}}	|sdS | dd}
|	r-t|	j}n|
dvr4d}n	|
r;t|
}nd}t|}t|rHd}nt|rNd}|duraG d	d
 d
|}|| |}||d< | dsn||d< | j	j
|dddfi |}|rt|dd d|_|j|_|S )a  Determines whether to create the --no-* flag and adds it to the parser.

    Args:
      added_argument: The argparse argument that was previously created.
      name: str, The name of the flag.
      dest: str, The dest field of the flag.
      original_kwargs: {str: object}, The original set of kwargs passed to the
        ArgumentInterceptor.

    Returns:
      The new argument that was added to the parser or None, if it was not
      necessary to create a new argument.
    r   wrapped_actionNrg   FTNr   r
   c                   @   s   e Zd ZdS )zIArgumentInterceptor._AddInvertedBooleanFlagIfNecessary.<locals>.NewActionN)r3   r4   r5   r   r   r   r   	NewActionG  s    r   rh   ----no-rv   inverted_synopsisT)rw   r   _ShouldInvertBooleanFlagboolrg   r   r   r   SetWrappedActionrI   r   rz   r   r0   r#   )r(   r   r   rh   original_kwargsr   r   action_wrappershould_invertproprg   r   rN   r   inverted_argumentr   r   r   r     sL   



z6ArgumentInterceptor._AddInvertedBooleanFlagIfNecessaryc                 C   sj   | dsdS | drdS d|dd  | jjv rdS t|r"dS t|dd\}}}|r3|d	k|fS dS )
a  Checks if flag name with action is a Boolean flag to invert.

    Args:
      name: str, The flag name.
      action: argparse.Action, The argparse action.

    Returns:
      (False, None) if flag is not a Boolean flag or should not be inverted,
      (True, property) if flag is a Boolean flag associated with a property,
      (False, property) if flag is a non-Boolean flag associated with a property
      otherwise (True, None) if flag is a pure Boolean flag.
    r   )FNr      Nr   store_property)NNNr   )r~   rI   _option_string_actionsr   r   )r(   r   r   r   kindrj   r   r   r   r   Z  s   

z,ArgumentInterceptor._ShouldInvertBooleanFlagc                 C   sZ   ddl m} |s
dS t|tr(|rt|tjr| jj	| |j
||d|_dS ||_dS )zAttaches a completer to arg if one is specified.

    Args:
      arg: The argument to attach the completer to.
      completer: The completer Completer class or argcomplete function object.
      positional: True if argument is a positional.
    r   )parser_completerN)argument)googlecloudsdk.callioper   r   r   r   r   	CompleterrK   rE   addArgumentCompleterrf   )r(   r_   rf   r   r   r   r   r   r   w  s   	

z$ArgumentInterceptor._AttachCompleterc                 C   s
   || _ dS )aF  Sets whether or not to sort this group's arguments in help/usage text.

    NOTE - For ordering consistency across gcloud, generally prefer using
    argument categories to organize information (instead of unsetting the
    argument sorting).

    Args:
      sort_args: bool, If arguments in this group should be sorted.
    Nr2   )r(   r,   r   r   r   SetSortArgs  s   

zArgumentInterceptor.SetSortArgs)NTN)NN)NNFFFTr   )'r3   r4   r5   r6   r   rF   r-   r7   r;   r:   r9   r?   r   r+   r@   rC   r0   rB   rE   r<   r=   r>   re   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   rO   r   r8   d   sj    %













 

)
Kr8   )r6   
__future__r   r   r   r   r   r   r   r   googlecloudsdk.core.cacher   r   r   r   r   r   r8   r   r   r   r   <module>   s   /