
    9                         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Zddlm	Z	  ej                  d      Zd Zdd	Zd
 Zd Zd Zd Zd Zd Zd ZddZd Zd Zd Zy)zResource property Get.    )absolute_import)division)unicode_literalsN)rangez9((?<=[a-z0-9])[A-Z]+(?=[A-Z][a-z]|$)|(?!^)[A-Z](?=[a-z]))c                     	 | D ]  }|j                  |      |k(  s|c S  	 y# t        t        t        t        f$ r Y yw xY w)az  Gets the dict in items that contains key==value.

  A metadict object is a list of dicts of the form:
    [
      {key: value-1, ...},
      {key: value-2, ...},
      ...
    ]

  Args:
    items: A list of dicts.
    key: The dict key name.
    value: The dict key value.

  Returns:
    The dict in items that contains key==value or None if no match or not a
    metadict.
  N)getAttributeError
IndexError	TypeError
ValueError)itemskeyvalueitems       5lib/googlecloudsdk/core/resource/resource_property.py_GetMetaDictr   !   sK    &		#%	 
 
 *i	< 			s   # # # ??c                     t        | d|      }|y|j                  dd      }|r	 t        j                  |      S |S # t        t
        f$ r Y |S w xY w)aY  Gets the metadata value for the item in items with key == name.

  A metadata object is a list of dicts of the form:
    [
      {'key': key-name-1, 'value': field-1-value-string},
      {'key': key-name-2, 'value': field-2-value-string},
      ...
    ]

  Examples:
    x.metadata[windows-keys].email
      Deserializes the 'windows-keys' metadata value and gets the email value.
    x.metadata[windows-keys]
      Gets the 'windows-key' metadata string value.
    x.metadata[windows-keys][]
      Gets the deserialized 'windows-key' metadata value.

  Args:
    items: The metadata items list.
    name: The metadata name (which must match one of the 'key' values).
    deserialize: If True then attempt to deserialize a compact JSON string.

  Returns:
    The metadata value for name or None if not found or if items is not a
    metadata dict list.
  r   Nr   )r   r   jsonloadsr   r   )r   namedeserializer   r   s        r   _GetMetaDataValuer   =   sf    6 
eUD	)$	\
((7D
!%ZZ 
, z" 
	,s   = AAc                 f    | j                  d      }|d   dj                  d |dd D              z   S )z&Converts snake_case name to camelCase._r    c              3   <   K   | ]  }|j                           y wN)title).0xs     r   	<genexpr>z%ConvertToCamelCase.<locals>.<genexpr>g   s     7h1779hs      N)splitjoin)r   parts     r   ConvertToCamelCaser&   d   s3    	C$	a2777d12h77	77    c                 J    t         j                  d|       j                         S )z&Converts camelCase name to snake_case._\1)	_SNAKE_REsublowerr   s    r   ConvertToSnakeCaser.   j       	vt	$	*	*	,,r'   c                 J    t         j                  d|       j                         S )z,Converts camelCase name to ANGRY_SNAKE_CASE.r)   )r*   r+   upperr-   s    r   ConvertToAngrySnakeCaser2   o   r/   r'   c                      ||       r| S t        | t        j                        syt        t        fD ]  } ||       } ||      s|c S  y)z6Returns index converted to a case that satisfies func.N
isinstancesixstring_typesr&   r.   )indexfuncconvertr   s       r   GetMatchingIndexr;   t   sK    	%[L	E3++	,$&89g5>DDzk : 
r'   c                      ||       }|r|S t        | t        j                        syt        t        fD ]  } | ||             }|s|c S  y)z?Returns the first non-None func value for case-converted index.Nr4   )r8   r9   r   r:   s       r   GetMatchingIndexValuer=      sQ    
u+%
L	E3++	,$&89g El : 
r'   c                 t   g }| D ]  }t        |t        j                        sd t        t        fD ]'  } ||      }	 |j                  |      j                  } n t        dj                  |            |j                  |        |t        j                  k(  rt        }||fS # t        t        f$ r Y w xY w)a  Returns the messages module type for key in message and the actual key.

  Handles camelCase/snake_case key name variants for OnePlatform compatibility.
  Indices and slices in resource_key are ignored -- they are not needed for
  repeated field queries.

  Args:
    resource_key: Ordered list of key names/indices, applied left to right. Each
      element in the list may be one of:
        str - A resource property name. This could be a class attribute name or
          a dict index.
        int - A list index. Selects one member is the list. Negative indices
          count from the end of the list, starting with -1 for the last element
          in the list. An out of bounds index is not an error; it produces the
          value None.
        None - A list slice. Selects all members of a list or dict like object.
          A slice of an empty dict or list is an empty dict or list.
    message: The known proto message type if not None.

  Raises:
    KeyError: If key is not in message.

  Returns:
    (type, actual_key), the messages module type for key in message and the
      actual key (names in the proper case, indices omitted).
  c                     | S r    r    s    r   <lambda>z%GetMessageFieldType.<locals>.<lambda>   s    ar'   zField {} not in message.)r5   r6   r7   r&   r.   field_by_nametyper	   KeyErrorformatappendinteger_typesint)resource_keymessage
actual_keyr   r:   actual_names         r   GetMessageFieldTyperN      s    6 *ddC,,-!35GHDMk''499 	 I /66t<==k"  !!! G	*	 h' s   B%%B76B7c           
      "   d t         t        fD ]t  }| D cg c]&  }t        |t        j                        r ||      n|( }}dj                  |D cg c]  }t        |t        j                        r|  c}      }||v sr|c S  yc c}w c c}w )al  Returns the actual_key match of resource_key in fields.

  Handles camelCase/snake_case key name variants for OnePlatform compatibility.
  Indices and slices in resource_key are ignored to normalize the lookup. This
  means that the lookup can determine the existence of an attribute name, but
  not a specific value among all repeated values.

  Args:
    resource_key: Ordered list of key names/indices, applied left to right. Each
      element in the list may be one of:
        str - A resource property name. This could be a class attribute name or
          a dict index.
        int - A list index. Selects one member is the list. Negative indices
          count from the end of the list, starting with -1 for the last element
          in the list. An out of bounds index is not an error; it produces the
          value None.
        None - A list slice. Selects all members of a list or dict like object.
          A slice of an empty dict or list is an empty dict or list.
    fields: The set of dotted field names to match against.

  Returns:
    The actual_key match of resource_key in fields or None if no match.
  c                     | S r   r@   rA   s    r   rB   zLookupField.<locals>.<lambda>   s    Ar'   .N)r&   r.   r5   r6   r7   r$   )rJ   fieldsr:   r   rL   
lookup_keys         r   LookupFieldrT      s    0 13EFg*,*d $.dC4D4D#E'$-4O*  ,J BJD(s/?/?@  J B CJV G 
,Bs   +B#B
c                 d  
 t        |      
| 
ri
j                  d      }t        t              rt	              |S t        d      rU|#
rD cg c]  }t        |g
z   |       c}S S t        |fd      }|r|   {dv r
fd}t        ||      |S t        |t        j                        r,t        |fd      }|rt        ||      }t        |      s|t        d      st        t        j                        ri|5
r1t        t                    D cg c]  }t        |g
z   |       c}S S t        |t        j                        st        |t        j                        rt        t               rt              rt        d   t               r
r't#        |
d         }|%|
j                  d      }t%        |      }||S |d   v r2t        t                    D cg c]  }t        ||g
z   |       c}S D cg c]  }|j'                  |       c}D 	cg c]  }	|	s|		 c}	xs |S |S |t        t               t                    v r|   j|S t        t              rt	              S c c}w c c}w c c}w c c}w c c}	w )a  Gets the value referenced by key in the object resource.

  Since it is common for resource instances to be sparse it is not an error if
  a key is not present in a particular resource instance, or if an index does
  not match the resource type.

  Args:
    resource_obj: The resource object possibly containing a value for key.
    resource_key: Ordered list of key names/indices, applied left to right. Each
      element in the list may be one of:
        str - A resource property name. This could be a class attribute name or
          a dict index.
        int - A list index. Selects one member is the list. Negative indices
          count from the end of the list, starting with -1 for the last element
          in the list. An out of bounds index is not an error; it produces the
          value None.
        None - A list slice. Selects all members of a list or dict like object.
          A slice of an empty dict or list is an empty dict or list.
    default: Get() returns this value if key is not in resource.

  Returns:
    The value, None if any of the given keys are not found. This is
      intentionally not an error. In this context a value can be any data
      object: dict, list, tuple, class, str, int, float, ...
  r   r   c                     | v S r   r@   r    resources    r   rB   zGet.<locals>.<lambda>  s	    qH}r'   c                 8    t        d   | t                    S )Nr   )r   )r   bool)r8   r   rX   s    r   	_GetValuezGet.<locals>._GetValue$  s     "wDI? ?r'   c                     t        |       S r   )hasattrrW   s    r   rB   zGet.<locals>.<lambda>0  s    wx/Cr'   __iter__)listpopr5   setsortedr]   Getr;   r=   r6   r7   getattrcallabler   lenrH   dictr   r   r   )resource_objrJ   defaultr8   kr   r[   rdfr   rX   s             @@r   rc   rc      s   4 	\#( GGAJE (C !h nx!	=EFX#hc	73XF
Fe%<=d	D>	H		?
 )	:n%))*e%CDd	HdG,{(
x$
8S=M=M(N	 !X/1/a hc	73/1 1 s001eS--.:h3M]z(1+t<xA7a
 $He4a#  %S]353! (QJ$4g>35 5 8@ @x!ux @F @1AQ @F   	%XH6	6E? N #hH	/y GN165 !AFs$   J+J J# J(=J-J-c                      t        | |d      duS )z*True if resource contains key, else False.N)rc   )rX   r   s     r   ResourceContainsKeyro   t  s    	XsD	!	--r'   c                    | syt        | t        j                        r	 t        |j	                  |             S t        | t        t        f      r$	 t        |j	                  t        |                   S 	 t        j                  |       D ]&  \  }}|j                  d      rt        |||      s& y 	 	 t        j                  | j                        D ]&  \  }}|j                  d      rt        |||      s& y 	 y# t
        $ r Y w xY w# t
        $ r Y w xY w# t        $ r, 	 | D ]  }t        |||      s Y y Y y# t
        $ r Y nw xY wY w xY w# t        $ r Y yw xY w)ao  Returns True if any attribute value in resource matches the RE pattern.

  This function is called to evaluate a global restriction on a resource. For
  example, --filter="Foo.Bar" results in a call like this on each resource item:

    resource_property.EvaluateGlobalRestriction(
      resource,
      'Foo.Bar',
      re.compile(re.escape('Foo.Bar'), re.IGNORECASE),
    )

  Args:
    resource: The object to check.
    restriction: The global restriction string.
    pattern: The global restriction pattern for matcing resource values.

  Returns:
    True if any attribute value in resource matches the RE pattern.
  Fr   T)r5   r6   r7   rZ   searchr   floatrI   str	iteritems
startswithEvaluateGlobalRestrictionr	   __dict__)rX   restrictionpatternr   r   s        r   rv   rv   y  sd   ( 
#**+'..*++ 5#,''..X/00mmH-
U^^C %>
g&' .	mmH$5$56
U^^C %>
g&' 7 
7  

  
 
 %$UKA   

 
 			s   C> "D 4,D !D /D 1D 46E +E 9E ;E >	D
	D
	DD	E&D?9D?<D??	EE
EEE	E E c                 v    t        | t              xs( t        | d      xr t        | d      xs t        | d      S )zChecks if resource is a list-like iterable object.

  Args:
    resource: The object to check.

  Returns:
    True if resource is a list-like iterable object.
  r^   next__next__)r5   r_   r]   )rX   s    r   
IsListLiker}     s@     Xt
$ I8Z( HHf%F:)FJr'   )Fr   )__doc__
__future__r   r   r   r   rer6   	six.movesr   compiler*   r   r   r&   r.   r2   r;   r=   rN   rT   rc   ro   rv   r}   r@   r'   r   <module>r      s}      &  '  	 
  BJJ?A	8$N8-
-

/dDNb.
4nJr'   