o
    4                     @   s   d Z ddlZddlZddlZddlZddlmZ ddlmZ ddlmZ g dZ	dd Z
e
 ZG d	d
 d
ejZG dd deZejZejZe jZe jZdS )zJSON support for message types.

Public classes:
  MessageJSONEncoder: JSON encoder for message objects.

Public functions:
  encode_message: Encodes a message in to a JSON string.
  decode_message: Merge from a JSON string in to a message.
    N)message_types)messages)util)ALTERNATIVE_CONTENT_TYPESCONTENT_TYPEMessageJSONEncoderencode_messagedecode_message	ProtoJsonc                  C   s   d} dD ]6}zt |i i d}t|ds d| }t| t||W   S  ty: } z
| s0|} W Y d}~qd}~ww td | )a  Try to load a valid json module.

    There are more than one json modules that might be installed.  They are
    mostly compatible with one another but some versions may be different.
    This function attempts to load various json modules in a preferred order.
    It does a basic check to guess if a loaded version of json is compatible.

    Returns:
      Compatible json module.

    Raises:
      ImportError if there are no json modules or the loaded json module is
        not compatible with ProtoRPC.
    N)json
simplejsonr   JSONEncoderz1json library "%s" is not compatible with ProtoRPCz0Must use valid json library (json or simplejson))
__import__hasattrloggingwarningImportErrorerror)first_import_errormodule_namemodulemessageerr r   M/tmp/google-cloud-sdk/lib/third_party/apitools/base/protorpclite/protojson.py_load_json_module/   s&   



r   c                       s.   e Zd ZdZd fdd	Z fddZ  ZS )r   ziMessage JSON encoder class.

    Extension of JSONEncoder that can build JSON from a message object.
    Nc                    s(   t t| jdi | |pt | _dS )zVConstructor.

        Args:
          protojson_protocol: ProtoJson instance.
        Nr   )superr   __init__r
   get_default'_MessageJSONEncoder__protojson_protocol)selfprotojson_protocolkwargs	__class__r   r   r   ]   s   
zMessageJSONEncoder.__init__c                    s   t |tjr
t|S tjrt |tr|dS t |tjrQi }|	 D ]}|
|j}|dg dfvr<| j||||j< q#| D ]}||\}}|||< qA|S tt| |S )zReturn dictionary instance from a message object.

        Args:
        value: Value to get dictionary for.  If not encodable, will
          call superclasses default method.
        utf8Nr   )
isinstancer   EnumstrsixPY3bytesdecodeMessage
all_fieldsget_assigned_valuenamer   encode_fieldall_unrecognized_fieldsget_unrecognized_field_infor   r   default)r    valueresultfielditemunknown_keyunrecognized_field_r#   r   r   r4   g   s&   

zMessageJSONEncoder.default)N)__name__
__module____qualname____doc__r   r4   __classcell__r   r   r#   r   r   W   s    
r   c                   @   sd   e Zd ZdZdZg dZdd Zdd Zdd	 Zd
d Z	dd Z
dd Zedd Zedd ZdS )r
   a  ProtoRPC JSON implementation class.

    Implementation of JSON based protocol used for serializing and
    deserializing message objects. Instances of remote.ProtocolConfig
    constructor or used with remote.Protocols.add_protocol. See the
    remote.py module for more details.

    zapplication/json)zapplication/x-javascriptztext/javascriptztext/x-javascriptztext/x-jsonz	text/jsonc                 C   sb   t |tjr|jrdd |D }|S t|}|S t |tjr/|jr+dd |D }|S | }|S )zEncode a python field value to a JSON value.

        Args:
          field: A ProtoRPC field instance.
          value: A python value supported by field.

        Returns:
          A JSON serializable value appropriate for field.
        c                 S   s   g | ]}t |qS r   )base64	b64encode).0byter   r   r   
<listcomp>   s    z*ProtoJson.encode_field.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   )	isoformat)rC   ir   r   r   rE      s    )	r&   r   
BytesFieldrepeatedrA   rB   r   DateTimeFieldrF   )r    r7   r5   r   r   r   r1      s   
	
zProtoJson.encode_fieldc                 C   s   |   tj|t| dS )a#  Encode Message instance to JSON string.

        Args:
          Message instance to encode in to JSON string.

        Returns:
          String encoding of Message instance in protocol JSON format.

        Raises:
          messages.ValidationError if message is not initialized.
        )clsr!   )check_initializedr   dumpsr   )r    r   r   r   r   r      s   zProtoJson.encode_messagec                 C   s:   t |}| s| S t|}| ||}|  |S )a  Merge JSON structure to Message instance.

        Args:
          message_type: Message to decode data to.
          encoded_message: JSON encoded version of message.

        Returns:
          Decoded instance of message_type.

        Raises:
          ValueError: If encoded_message is not valid JSON.
          messages.ValidationError if merged message is not initialized.
        )r)   
ensure_strstripr   loads_ProtoJson__decode_dictionaryrL   )r    message_typeencoded_message
dictionaryr   r   r   r   r	      s   

zProtoJson.decode_messagec              	   C   s   t |tr	tjjS t |tjrtjjS t |trtjj	S t |tj
r&tjjS t |ttfrbdtjjtjj	tjjg}d}|D ] }| |}z||}W n tyV   d}Y nw ||kr]|}q=|| S dS )a,  Find the messages.Variant type that describes this value.

        Args:
          value: The value whose variant type is being determined.

        Returns:
          The messages.Variant value that best describes value's type,
          or None if it's a type we don't know how to handle.

        Nr   )r&   boolr   VariantBOOLr)   integer_typesINT64floatDOUBLEstring_typesSTRINGlisttuple_ProtoJson__find_variantindex
IndexError)r    r5   variant_prioritychosen_priorityvvariantpriorityr   r   r   __find_variant   s6   


zProtoJson.__find_variantc              
   C   s  | }t |D ]\}}|du r"z|| W n	 ty    Y nw qz||}W n ty@   | |}|r>|||| Y qw t|t	j
}d}	|jrt|tsT|g}g }
|D ]'}z| ||}|ri|du riW qXW n t	jyy   |su d}	Y qXw |
| qXt||j|
 |	r| |}|r|||| q|g krqzt||j| || W q t	jy   |s | |}|r|||| Y qw |S )a  Merge dictionary in to message.

        Args:
          message: Message to merge dictionary in to.
          dictionary: Dictionary to extract information from.  Dictionary
            is as parsed from JSON.  Nested objects will also be dictionaries.
        NFT)r)   	iteritemsresetAttributeErrorfield_by_nameKeyErrorra   set_unrecognized_fieldr&   r   	EnumFieldrI   r_   decode_fieldDecodeErrorappendsetattrr0   )r    rR   rT   r   keyr5   r7   rg   is_enum_fieldis_unrecognized_fieldvalid_valuer8   rf   r   r   r   __decode_dictionary   sn   



zProtoJson.__decode_dictionaryc              
   C   sR  t |tjrz||W S  ty   td|pd w t |tjr@zt|W S  t	j
tfy? } ztd| d}~ww t |tjr`ztj|ddW S  ty_ } zt|d}~ww t |tjrtt|jtjrt| |j|S t |tjrt |tjtjfrzt|W S    Y |S t |tjrt |tjrzt|W S    Y |S |S )zDecode a JSON value to a python value.

        Args:
          field: A ProtoRPC field instance.
          value: A serialized JSON value.

        Return:
          A Python value compatible with field.
        zInvalid enum value "%s" zBase64 decoding error: %sNT)truncate_time)r&   r   rp   type	TypeErrorrr   rH   rA   	b64decodebinasciiErrorr   rJ   r   decode_datetime
ValueErrorMessageField
issubclassr-   rQ   
FloatFieldr)   rY   r]   r[   IntegerFieldint)r    r7   r5   r   r   r   r   rq   D  sT   



	

zProtoJson.decode_fieldc                   C   s*   zt jW S  ty   t  t _t j Y S w )z!Get default instanceof ProtoJson.)r
   _ProtoJson__defaultrl   r   r   r   r   r   u  s   
zProtoJson.get_defaultc                 C   s   t | ts	td| t_dS )zhSet the default instance of ProtoJson.

        Args:
          protocol: A ProtoJson instance.
        z#Expected protocol of type ProtoJsonN)r&   r
   r}   r   )protocolr   r   r   set_default~  s   

zProtoJson.set_defaultN)r<   r=   r>   r?   r   r   r1   r   r	   ra   rQ   rq   staticmethodr   r   r   r   r   r   r
      s    	&D1
r
   )r?   rA   r   r   r)   apitools.base.protorpcliter   r   r   __all__r   r   r   r   objectr
   r   r   r   r   r	   r   r   r   r   <module>   s&   	
$1  
