
    F                        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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j&                        Z G d de
j*                        Z G d d ej.                  ej0                  e            Z G d de      Z G d de      Z G d de      Z G d de      Zy)z6Utilities for creating/parsing update argument groups.    )absolute_import)division)unicode_literalsN)arg_parsers)arg_parsers_usage_text)base)util)	arg_utils)yaml_command_schema_utilc                       e Zd ZdZdZdZdZy)PrefixaddupdateremoveclearN)__name__
__module____qualname__ADDUPDATEREMOVECLEAR     7lib/googlecloudsdk/command_lib/util/apis/update_args.pyr   r   (   s    #&&
%r   r   c                   (     e Zd ZdZ fdZd Z xZS )_ConvertValueTypezWraps flag types in arg_utils.ConvertValue while maintaining help text.

  Attributes:
    arg_gen: UpdateBasicArgumentGenerator, update argument generator
  c                     t         t        |   |j                         |j                  | _        |j
                  | _        |j                  | _        |j                  | _        y N)superr   __init__	flag_typefieldrepeated	processorchoices)selfarg_gen	__class__s     r   r!   z_ConvertValueType.__init__6   sI    	
T+G,=,=>DJ$$DM&&DN??DLr   c           	          | j                  |      }t        j                  | j                  || j                  | j
                  t        j                  j                  | j                              S )z&Converts arg_value into type arg_type.)r$   r%   r&   )
arg_typer
   ConvertValuer#   r$   r%   r	   ChoiceToChoiceMapr&   )r'   	arg_valuevalues      r   __call__z_ConvertValueType.__call__=   sQ    MM)$E!!

..''5 r   )r   r   r   __doc__r!   r1   __classcell__r)   s   @r   r   r   /   s    #	r   r   c                       e Zd ZdZd Z	 	 ddZed        Zed        Zed        Z	ed        Z
dd	Zej                  d
        Zej                  d        Zd Zd Zd Zd Zd Zy)UpdateArgumentGeneratoraH  Update flag generator.

  To use this base class, provide required methods for parsing
  (GetArgFromNamespace and GetFieldValueFromNamespace) and override
  the flags that are needed to update the value. For example, if argument
  group requires a set flag, we would override the `set_arg` property and
  ApplySetFlag method.
  c                 X    |r|S t        |t              ryt        |t              ry|y|S )Nz	empty mapz
empty listnull)
isinstancedictlist)r'   r0   s     r   _GetTextFormatOfEmptyValuez2UpdateArgumentGenerator._GetTextFormatOfEmptyValueS   s1    l%%}Lr   Nc                     t        j                  ||xr |j                        }t        j                  |||      }|dk(  r|S ||j
                  d<   t        j                  |||      x}	r|	|j
                  d<   |S )av  Creates a flag.

    Args:
      arg_name: str, root name of the arg
      flag_prefix: Prefix | None, prefix for the flag name
      flag_type: func, type that flag is used to convert user input
      action: str, flag action
      metavar: str, user specified metavar for flag
      help_text: str, flag help text

    Returns:
      base.Argument with correct params
    )actionhelp
store_truetypemetavar)r
   GetFlagNamer0   r   Argumentkwargs
GetMetavar)
r'   arg_nameflag_prefixr"   r>   rB   	help_text	flag_nameargflag_metavars
             r   _CreateFlagz#UpdateArgumentGenerator._CreateFlag`   s~    " %%+3+"3"35I
--	&y
ACj"CJJv ++GY	JJ|J*cjjJr   c                      y)z'Flag that sets field to specifed value.Nr   r'   s    r   set_argzUpdateArgumentGenerator.set_arg~        r   c                      y)zFlag that clears field.Nr   rO   s    r   	clear_argz!UpdateArgumentGenerator.clear_arg   rQ   r   c                      y)z2Flag that updates value if part of existing field.Nr   rO   s    r   
update_argz"UpdateArgumentGenerator.update_arg   rQ   r   c                      y)z2Flag that removes value if part of existing field.Nr   rO   s    r   
remove_argz"UpdateArgumentGenerator.remove_arg   rQ   r   c                 T   t        j                  dd| j                  dj                  | j                              }| j
                  r|j                  | j
                         t        j                  d      }| j                  r|j                  | j                         t        j                  dd      }| j                  r|j                  | j                         | j                  r|j                  | j                         |j                  r|j                  |       |j                  r|j                  |       |s|S t        j                  d| j                  dj                  | j                              }|j                  |       |D ]  }|j                  |        |S )	ap  Returns ArgumentGroup with all flags specified in generator.

    ArgumentGroup is returned where the set flag is mutually exclusive with
    the rest of the update flags. In addition, remove and clear flags are
    mutually exclusive. The following combinations are allowed

    # sets the foo value to value1,value2
    {command} --foo=value1,value2

    # adds values value3
    {command} --add-foo=value3

    # clears values and sets foo to value4,value5
    {command} --add-foo=value4,value5 --clear

    # removes value4 and adds value6
    {command} --add-foo=value6 --remove-foo=value4

    # removes value6 and then re-adds it
    {command} --add-foo=value6 --remove-foo=value6

    Args:
      additional_flags: [base.Argument], list of additional arguments needed
        to udpate the value

    Returns:
      base.ArgumentGroup, argument group containing flags
    TFz
Update {}.)mutexrequiredhiddenr?   )rZ   )rY   rZ   z"All arguments needed to update {}.)rZ   r[   r?   )r   ArgumentGroup	is_hiddenformatrG   rP   AddArgumentrU   rS   rW   	arguments)r'   additional_flags
base_groupupdate_groupclear_groupwrapper_grouprK   s          r   Generatez UpdateArgumentGenerator.Generate   sL   : ##~~  /	J ||T\\*%%u5Lt/$$4%@K~~dnn-doo.{+\*&&~~188GM
 j)$  r   c                      y)zRetrieves namespace value associated with flag.

    Args:
      namespace: The parsed command line argument namespace.
      arg: base.Argument, used to get namespace value

    Returns:
      value parsed from namespace
    Nr   r'   	namespacerK   s      r   GetArgFromNamespacez+UpdateArgumentGenerator.GetArgFromNamespace   s     	r   c                      y)zRetrieves existing field from message.

    Args:
      existing_message: apitools message we need to get field value from

    Returns:
      field value from apitools message
    Nr   )r'   existing_messages     r   GetFieldValueFromMessagez0UpdateArgumentGenerator.GetFieldValueFromMessage   s     	r   c                     |S )z@Updates result to new value (No-op: implementation in subclass).r   )r'   existing_valunused_set_vals      r   ApplySetFlagz$UpdateArgumentGenerator.ApplySetFlag       r   c                     |S )z:Clears existing value (No-op: implementation in subclass).r   )r'   ro   unused_clear_flags      r   ApplyClearFlagz&UpdateArgumentGenerator.ApplyClearFlag   rr   r   c                     |S )z;Removes existing value (No-op: implementation in subclass).r   )r'   ro   unused_remove_vals      r   ApplyRemoveFlagz'UpdateArgumentGenerator.ApplyRemoveFlag   rr   r   c                     |S )z;Updates existing value (No-op: implementation in subclass).r   )r'   ro   unused_update_vals      r   ApplyUpdateFlagz'UpdateArgumentGenerator.ApplyUpdateFlag   rr   r   c                    | j                  |      }| j                  || j                        | j                  || j                        | j                  || j                        | j                  || j
                        f\  }}}}| j                  ||      }| j                  ||      }| j                  ||      }| j                  ||      }|S )a  Parses update flags from namespace and returns updated message field.

    Args:
      namespace: The parsed command line argument namespace.
      existing_message: Apitools message that exists for given resource.

    Returns:
      Modified existing apitools message field.
    )
rm   rj   rP   rS   rW   rU   ru   rx   rq   r{   )r'   ri   rl   result	set_valueclear_valueremove_valueupdate_values           r   ParsezUpdateArgumentGenerator.Parse   s     **+;<F  DLL9  DNN;  DOO<  DOO<	:6I{L,   5F!!&,7F vy1F!!&,7FMr   )NNNNNr   )r   r   r   r2   r<   rM   propertyrP   rS   rU   rW   rf   abcabstractmethodrj   rm   rq   ru   rx   r{   r   r   r   r   r6   r6   I   s     @D"<        @F 
	 
	 		 		r   r6   c                   Z     e Zd ZdZed        Z	 	 	 	 	 	 	 	 	 	 d fd	Zd Zd Zd Z	 xZ
S )UpdateBasicArgumentGeneratorz'Update flag generator for simple flags.c                    t        j                  ||      \  }}|j                  |j                  n|j                  }t        j                  |      }|t         j                  j
                  k(  rt        }n|rt        }nt        } ||j                  ||||j                  |j                  |j                  |j                  |j                  |j                  |j                        S )a#  Creates a flag generator from yaml arg data and request message.

    Args:
      arg_data: yaml_arg_schema.Argument, data about flag being generated
      field: messages.Field, apitools field instance.

    Returns:
      UpdateArgumentGenerator, the correct version of flag generator
    )rG   r"   r#   r>   r]   rI   	api_fieldr$   r%   r&   rB   )r
   GenerateFlagTyper$   GetFieldType	FieldTypeMAPUpdateMapArgumentGeneratorUpdateListArgumentGeneratorUpdateDefaultArgumentGeneratorrG   r[   rI   r   r%   r&   rB   )clsarg_datar#   r"   r>   is_repeated
field_typegen_clss           r   FromArgDataz(UpdateBasicArgumentGenerator.FromArgData$  s     "225(CIv #++39J9J  ''.JY((,,,*g	+g.g""//$$$$""$$     r   c                     t         t        |           t        j                  |      | _        || _        || _        || _        || _	        || _
        || _        || _        |	| _        |
| _        || _        y r   )r    r   r!   format_utilNormalizeFormatrG   r#   r"   r>   r]   rI   r   r$   r%   r&   rB   )r'   rG   r"   r#   r>   r]   rI   r   r$   r%   r&   rB   r)   s               r   r!   z%UpdateBasicArgumentGenerator.__init__K  sk     

&68//9DMDJDNDKDNDNDNDMDNDLDLr   c                 H    |y t        j                  ||j                        S r   )r
   GetFromNamespacenamerh   s      r   rj   z0UpdateBasicArgumentGenerator.GetArgFromNamespacef  s!    
{%%i::r   c                     |r!t        j                  || j                        }nd}t        |t              r|j                         }|S )z&Retrieves existing field from message.N)r
   rm   r   r9   r;   copy)r'   rl   existing_values      r   rm   z5UpdateBasicArgumentGenerator.GetFieldValueFromMessagek  sC     99
DNNn n.$'%**,nr   c                 >     | j                   dd| j                  i|S )NrG   r   )rM   rG   )r'   rE   s     r   _CreateBasicFlagz-UpdateBasicArgumentGenerator._CreateBasicFlagx  s!    4=T]]=f==r   )
NNNFNNFNNN)r   r   r   r2   classmethodr   r!   rj   rm   r   r3   r4   s   @r   r   r   !  sM    /$ $R 6;
>r   r   c                   L    e Zd ZdZed        Zed        Zed        Zd Zd Z	y)r   z(Update flag generator for simple values.c                      y r   r   rO   s    r   _empty_valuez+UpdateDefaultArgumentGenerator._empty_value  s    r   c                     | j                  t        |       | j                  | j                  dj	                  | j
                              S NzSet {} to new value.)r"   r>   rB   rI   r   r   r>   rB   r^   rG   rO   s    r   rP   z&UpdateDefaultArgumentGenerator.set_arg  B      #D){{(//>	 !  r   c           
          | j                  t        j                  ddj                  | j                  | j                  | j                                    S Nr@   zClear {} value and set to {}.)rH   r>   rI   r   r   r   r^   rG   r<   r   rO   s    r   rS   z(UpdateDefaultArgumentGenerator.clear_arg  M      LL188MM4::4;L;LMO !  r   c                     ||S |S r   r   r'   ro   set_vals      r   rq   z+UpdateDefaultArgumentGenerator.ApplySetFlag      nr   c                 "    |r| j                   S |S r   r   r'   ro   
clear_flags      r   ru   z-UpdateDefaultArgumentGenerator.ApplyClearFlag      r   N)
r   r   r   r2   r   r   rP   rS   rq   ru   r   r   r   r   r   |  sI    0     
r   r   c                   ~    e Zd ZdZed        Zed        Zed        Zed        Zed        Z	d Z
d Zd	 Zd
 Zd Zy)r   zUpdate flag generator for list.c                     g S r   r   rO   s    r   r   z(UpdateListArgumentGenerator._empty_value      Ir   c                     | j                  t        |       | j                  | j                  dj	                  | j
                              S r   r   rO   s    r   rP   z#UpdateListArgumentGenerator.set_arg  r   r   c           
          | j                  t        j                  ddj                  | j                  | j                  | j                                    S r   r   rO   s    r   rS   z%UpdateListArgumentGenerator.clear_arg  r   r   c                     | j                  t        j                  t        |       | j                  dj                  | j                              S )NzAdd new value to {} list.rH   r"   r>   rI   )r   r   r   r   r>   r^   rG   rO   s    r   rU   z&UpdateListArgumentGenerator.update_arg  sB      JJ#D){{-44T]]C	 !  r   c                     | j                  t        j                  t        |       | j                  dj                  | j                              S )Nz#Remove existing value from {} list.r   )r   r   r   r   r>   r^   rG   rO   s    r   rW   z&UpdateListArgumentGenerator.remove_arg  sB      MM#D){{7>>t}}M	 !  r   c                      t         j                  t        j                        rt	         fd|D              S |v S )Nc              3   V   K   | ]   }j                   j                  |       " y wr   )r"   Matches).0valnew_valr'   s     r   	<genexpr>z;UpdateListArgumentGenerator._ContainsVal.<locals>.<genexpr>  s'      D:B3$..
 
 #
.(s   &))r9   r"   r	   EquitableTypeany)r'   r   all_valss   `` r   _ContainsValz(UpdateListArgumentGenerator._ContainsVal  sB    $..$"4"45 D:BD D D   r   c                     ||S |S r   r   r   s      r   rq   z(UpdateListArgumentGenerator.ApplySetFlag  r   r   c                 "    |r| j                   S |S r   r   r   s      r   ru   z*UpdateListArgumentGenerator.ApplyClearFlag  r   r   c                 Z    |#|D cg c]  }| j                  ||      r| c}S |S c c}w r   r   )r'   ro   
remove_valxs       r   rx   z+UpdateListArgumentGenerator.ApplyRemoveFlag  sB    !K!):):1j)I!\K KKs   ((c                 b    |'|D cg c]  }| j                  ||      r| }}||z   S |S c c}w r   r   )r'   ro   
update_valr   new_valss        r   r{   z+UpdateListArgumentGenerator.ApplyUpdateFlag  sL    Kt'8'8L'I!Z  KH$$Ks   ,,N)r   r   r   r2   r   r   rP   rS   rU   rW   r   rq   ru   rx   r{   r   r   r   r   r     s    '         !

r   r   c                       e Zd ZdZed        Zed        Zd Zd Zed        Z	ed        Z
ed        Zed	        Zd
 Zd Zd Zd Zy)r   z>Update flag generator for key-value pairs ie proto map fields.c                     i S r   r   rO   s    r   r   z'UpdateMapArgumentGenerator._empty_value  r   r   c                 P    | j                   j                  t        j                  k(  S r   )r#   r   r
   ADDITIONAL_PROPSrO   s    r   _is_list_fieldz)UpdateMapArgumentGenerator._is_list_field  s    ::??i8888r   c                     | j                   r|S | j                  j                         }t        j                  |t        j
                  |       |S )zWraps field AdditionalProperties in apitools message if needed.

    Args:
      output_list: list of apitools AdditionalProperties messages.

    Returns:
      apitools message instance.
    )r   r#   rA   r
   SetFieldInMessager   )r'   output_listmessages      r   _WrapOutputz&UpdateMapArgumentGenerator._WrapOutput  sC     jjooG++[:Nr   c                 n    |sg S | j                   r|S t        j                  |t        j                        S )zRetrieves AdditionalProperties field value.

    Args:
      field: apitools instance that contains AdditionalProperties field

    Returns:
      list of apitools AdditionalProperties messages.
    )r   r
   rm   r   )r'   r#   s     r   _GetPropsFieldValuez.UpdateMapArgumentGenerator._GetPropsFieldValue  s3     il--eY5O5OPPr   c                     | j                  t        |       | j                  | j                  dj	                  | j
                              S r   r   rO   s    r   rP   z"UpdateMapArgumentGenerator.set_arg  r   r   c           
          | j                  t        j                  ddj                  | j                  | j                  | j                                    S r   r   rO   s    r   rS   z$UpdateMapArgumentGenerator.clear_arg  r   r   c                     | j                  t        j                  t        |       | j                  dj                  | j                              S )Nz&Update {} value or add key value pair.r   )r   r   r   r   r>   r^   rG   rO   s    r   rU   z%UpdateMapArgumentGenerator.update_arg&  sE      MM#D){{:AAMM
	 !  r   c                    | j                   r| j                  }n8t        j                  | j                  j                  t        j
                        }t        j                  |j                  d      }|j                  xs) t        j                  j                  |j                        }t        j                  |d      }| j                  t        j                  |ddj                  | j                              S )NkeyT)
value_typer$   storez"Remove existing value from map {}.r   )r   r#   r
   GetFieldFromMessagerA   r   TYPESgetvariantr   	ArgObjectr   r   r   r^   rG   )r'   r#   	key_fieldkey_typekey_lists        r   rW   z%UpdateMapArgumentGenerator.remove_arg1  s    jje++
**//955e --ejj%@I~~G!4!4Y5F5F!GH$$d,H   MM6==dmmL	 !  r   c                     ||S |S r   r   r   s      r   rq   z'UpdateMapArgumentGenerator.ApplySetFlagF  r   r   c                 ,    |r| j                  g       S |S r   )r   r   s      r   ru   z)UpdateMapArgumentGenerator.ApplyClearFlagK  s    b!!r   c                    |w| j                  |      }| j                  |      }t        |D cg c]  }|j                   c}      }|D cg c]  }|j                  |vs| }}| j                  ||z         S |S c c}w c c}w r   )r   setr   r   )r'   ro   r   r   update_val_listr   update_key_setdeduped_lists           r   r{   z*UpdateMapArgumentGenerator.ApplyUpdateFlagP  s    ,,\:k00<o?;?aAEE?;<n!,LA^0KalLl_<== <Ls   A<B Bc                     |J| j                  |      }t        |      }| j                  |D cg c]  }|j                  |vs| c}      S |S c c}w r   )r   r   r   r   )r'   ro   r   r   remove_val_setr   s         r   rx   z*UpdateMapArgumentGenerator.ApplyRemoveFlagY  s_    ,,\:k:n!
AkQUU.%@1k
AC C Bs   AAN)r   r   r   r2   r   r   r   r   r   rP   rS   rU   rW   rq   ru   r{   rx   r   r   r   r   r     s    F  9 9 Q        (

r   r   )r2   
__future__r   r   r   r   enumgooglecloudsdk.callioper   r   
usage_textr    googlecloudsdk.calliope.conceptsr	   r   $googlecloudsdk.command_lib.util.apisr
   r   sixEnumr   DefaultArgTypeWrapperr   with_metaclassABCMetaobjectr6   r   r   r   r   r   r   r   <module>r     s    = &  ' 
  / H ( @ : Q 
TYY 
88 4U0c00fE UpX>#: X>v!%A !HG"> GTu!= ur   