
    K0                         d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 dd	lZ G d
 de      Zd Zy	)zConceptParsers manage the adding of all concept arguments to argparse parser.

The ConceptParser is created with a list of all resources needed for the
command, and they should be added all at once during calliope's Args method.
    )absolute_import)division)unicode_literals)deps)handlers)util)presentation_specsNc                   r    e Zd ZdZddZe	 	 	 	 dd       Zd Zd Zd Z	d Z
ed	        Zd
 Zd Zd Zd Zy)ConceptParserz4Class that handles adding concept specs to argparse.Nc                     i | _         g | _        |D ]  }| j                  |        | j                  |xs i       | _        y)aU  Initializes a concept holder.

    Args:
      specs: [presentation_specs.PresentationSpec], a list of the
        specs for concepts to be added to the parser.
      command_level_fallthroughs: {str: str}, a map of attributes to argument
        fallthroughs for those attributes. The format of the key should be FOO.a
        (the resource presentation name is "FOO" and the attribute name is "a").
        The format of the value should either be "BAR.b" (where the argument
        depended upon is the main argument generated for attribute "b" of
        the resource presentation spec that is named "BAR"), or "--baz", where
        "--baz" is a non-resource argument that is added separately to the
        parser.

    Raises:
      ValueError: if two presentation specs have the same name or two specs
        contain positional arguments.
    N)_specs	_all_args_AddSpec!_ValidateAndFormatFallthroughsMap_command_level_fallthroughs)selfspecscommand_level_fallthroughsspecs       ?lib/googlecloudsdk/command_lib/util/concepts/concept_parsers.py__init__zConceptParser.__init__$   sC    & DKDN
mmD '+'M'M"(b(*D$    c                     t        j                  |||||xs i |||	|	      }i }t        |||
       t        j                  |
xs i       D ]&  \  }}dj                  |j                  |      }|||<   (  | |g|      S )ax  Constructs a ConceptParser for a single resource argument.

    Automatically sets prefixes to False.

    Args:
      name: str, the name of the main arg for the resource.
      resource_spec: googlecloudsdk.calliope.concepts.ResourceSpec, The spec
        that specifies the resource.
      group_help: str, the help text for the entire arg group.
      required: bool, whether the main argument should be required for the
        command.
      hidden: bool, whether or not the resource is hidden.
      flag_name_overrides: {str: str}, dict of attribute names to the desired
        flag name. To remove a flag altogether, use '' as its rename value.
      plural: bool, True if the resource will be parsed as a list, False
        otherwise.
      prefixes: bool, True if flag names will be prefixed with the resource
        name, False otherwise. Should be False for all typical use cases.
      group: the parser or subparser for a Calliope command that the resource
        arguments should be added to. If not provided, will be added to the main
        parser.
      command_level_fallthroughs: a map of attribute names to lists of command-
        specific fallthroughs. These will be prioritized over the default
        fallthroughs for the attribute.

    Returns:
      (googlecloudsdk.calliope.concepts.concept_parsers.ConceptParser) The fully
        initialized ConceptParser.
    )requiredflag_name_overridespluralprefixesgrouphidden{}.{})r	   ResourcePresentationSpecUpdateFallthroughsMapsix	iteritemsformatname)clsr&   resource_spec
group_helpr   r   r   r   r   r   r   presentation_specfallthroughs_mapattribute_namefallthroughskeys                   r   ForResourcezConceptParser.ForResource>   s    D +CC/52	 *D2LM(+"(b)*$NN,11>Bc*s)* !"$455r   c                 \    t        j                  |      t        j                  |      k(  ryy)a(  Checks if two argument names match in the namespace.

    RESOURCE_ARG and --resource-arg will match with each other, as well as exact
    matches.

    Args:
      name: the first argument name.
      other_name: the second argument name.

    Returns:
      (bool) True if the names match.
    TF)r   NormalizeFormat)r   r&   
other_names      r   _ArgNameMatcheszConceptParser._ArgNameMatchesr   s(     D!T%9%9*%EEr   c                    | j                   D ]  }| j                  ||j                        r%t        dj	                  ||j                              t        j                  |      sZt        j                  |j                        szt        dj	                  ||j                               t        j                  |j                        D ]^  \  }}~t        j                  |      }|| j                  v rt        dj	                  |            | j                  j                  |       ` || j                   |j                  <   y)aG  Adds a given presentation spec to the concept holder's spec registry.

    Args:
      presentation_spec: PresentationSpec, the spec to be added.

    Raises:
      ValueError: if two presentation specs have the same name, if two
        presentation specs are both positional, or if two args are going to
        overlap.
    z:Attempted to add two concepts with the same name: [{}, {}]zFAttempted to add multiple concepts with positional arguments: [{}, {}]z0Attempted to add a duplicate argument name: [{}]N)r   r3   r&   
ValueErrorr%   r   IsPositionalr#   r$   attribute_to_args_mapr1   r   append)r   r*   	spec_nameaarg_namer&   s         r   r   zConceptParser._AddSpec   s     [[				i):)?)?	@ $$*F96G6L6L$MO 	O


I
&


-22
3 //5vi6G6L6L0NO 	O ! }}%6%L%LM8
!!(+d		K &*, 	,
nnD! N +<DKK!&&'r   c                    i }t        j                  |      D ]  \  }}|j                  d      }t        |      dk7  rt	        dj                  |            |\  }}| j                  d||       |D ]a  }|j                  d      }	t        |	      dvrt	        dj                  |            t        |	      dk(  sJ|	\  }
}| j                  d|
|       c ||j                  |i       |<    |S )zEValidate formatting of fallthroughs and build map keyed to spec name..   z}invalid fallthrough key: [{}]. Must be in format "FOO.a" where FOO is the presentation spec name and a is the attribute name.r.   )   r>   zCinvalid fallthrough value: [{}]. Must be in the form BAR.b or --bazvalue)r#   r$   splitlenr5   r%   _ValidateSpecAndAttributeExist
setdefault)r   r   spec_mapr.   fallthroughs_listkeysr9   r,   fallthrough_stringvaluesvalue_spec_namevalue_attribute_names               r   r   z/ConceptParser._ValidateAndFormatFallthroughsMap   s
   H"%--0J"KYYs^d	Ta 44:F3KA 	A #'i
))%NK 1
#))#.v;f$ 1178J1KM Mv;!28
///

-
-g.=.BD !2 <Mh)R(8% #L& Or   c                    || j                   vret        dj                  |dj                  ||      dj                  t	        t        | j                   j                                                       | j                   j                  |      }||j                  j                  D cg c]  }|j                   c}vr-t        dj                  |dj                  ||      ||            yc c}w )zFRaises if a formatted string refers to non-existent spec or attribute.zginvalid fallthrough {}: [{}]. Spec name is not present in the presentation specs. Available names: [{}]r    z, zIinvalid fallthrough {}: [{}]. spec named [{}] has no attribute named [{}]N)r   r5   r%   joinsortedlistrG   getconcept_spec
attributesr&   )r   locationr9   r,   r   	attributes         r   rC   z,ConceptParser._ValidateSpecAndAttributeExist   s    

" $f#">>)^D99VD1B,C%DEGH H ::>>)$D(,(9(9(D(DF(D9	(DF F ..4f#">>)^D$)	/+, ,F Fs   (C-c                     | j                   S N)r   )r   s    r   r   zConceptParser.specs   s    ;;r   c                 r   |j                   j                  }|s%t        j                         }|j	                  |       t        j                  | j                        D ]X  \  }}| j                  |      }|j                  |       |j                  t        j                  |      ||j                         Z y)z|Adds attribute args for all presentation specs to argparse.

    Args:
      parser: the parser for a Calliope command.
    )r   N)dataconcept_handlerr   RuntimeHandleradd_conceptsr#   r$   r   GetInfoAddToParser
AddConceptr   r1   r   )r   parserruntime_handlerr9   r   concept_infos         r   r]   zConceptParser.AddToParser   s     kk11O //1o/*==5	4\\),lv&  


y
)
== ! " 6r   c                     g }| j                   D ]7  }| j                  |      }|j                         }|s'|j                  |       9 d }dj	                  t        ||            S )z:Returns a command line example arg string for the concept.c                 6    | j                  d      rdnd}|| z   S )Nz--ZA)
startswith)argprefixs     r   _PositionalsFirstz<ConceptParser.GetExampleArgString.<locals>._PositionalsFirst   s    nnT*sfc\r    )r.   )r   r\   GetExampleArgListextendrM   rN   )r   examplesr9   infoargsri   s         r   GetExampleArgStringz!ConceptParser.GetExampleArgString   s^    H[[	\\)$d##%d		 ! 88F8):;<<r   c                    |j                  d      }t        |      dk(  r|}t        j                  |d         S t        |      dk(  ro|\  }}| j                  j                  |      }|j                  j                  |d      }|st        dj                  |||            t        j                  |      S t        dj                  |            )z/Make an ArgFallthrough from a formatted string.r=   r?   r   r>   NziInvalid fallthrough value [{}]: No argument associated with attribute [{}] in concept argument named [{}]zbad fallthrough string [{}])	rA   rB   r   ArgFallthroughr   rP   r7   r5   r%   )r   rH   rI   r;   r9   r,   r   s          r   _MakeFallthroughzConceptParser._MakeFallthrough   s    %%c*F
6{ah  ++	V	"(iZZ^^I&d++//Eh<<BF"= 	   ** 4;;<NOPPr   c                    || j                   vrt        dj                  |            | j                   |   }i }|j                  j                  D ]|  }| j
                  j                  |j                  i       j                  |j                  g       }|D cg c]  }| j                  |       }}||j                  z   ||j                  <   ~ |j                  |      S c c}w )z:Build ConceptInfo object for the spec with the given name.z`Presentation spec with name [{}] has not been added to the concept parser, cannot generate info.)r   r5   r%   rQ   rR   r   rP   r&   rs   r-   _GenerateInfo)r   presentation_spec_namer*   r+   rT   fallthrough_stringsrH   r-   s           r   r\   zConceptParser.GetInfo
  s    TZZ/ FFLf1G34 4 

#9:&33>>	 <<@@

 
 "&&)c).."&=  1DE0C, ++,>?0C  E)5	8N8N)Ny~~& ? **+;<<	Es   C rV   )FFNFFNN)__name__
__module____qualname____doc__r   classmethodr/   r3   r   r   rC   propertyr   r]   rp   rs   r\    r   r   r   r   !   si    <*4 AF48).9=16 16f"<B0,&  "$=Q,=r   r   c                 t    t        j                  |xs i       D ]  \  }}dj                  ||      }|| |<    y)z=Helper to add a single resource's command level fallthroughs.r    N)r#   r$   r%   )r+   resource_arg_namer   r,   r-   r.   s         r   r"   r"     s@     '*mm &B'("nl
..*N
;C(S'(r   )r{   
__future__r   r   r    googlecloudsdk.calliope.conceptsr   r   r   (googlecloudsdk.command_lib.util.conceptsr	   r#   objectr   r"   r~   r   r   <module>r      s8    '  ' 1 5 1 G 
x=F x=v)r   