o
    /i-                     @   s   d Z ddlmZ ddlmZ ddlZddlZddlZedej	Z
dZdZdd	 Zd
d Zdd Zdd Zdd Zdd Zdd ZdddZdS )a  Expand and validate URL path templates.

This module provides the :func:`expand` and :func:`validate` functions for
interacting with Google-style URL `path templates`_ which are commonly used
in Google APIs for `resource names`_.

.. _path templates: https://github.com/googleapis/googleapis/blob
    /57e2d376ac7ef48681554204a3ba78a414f2c533/google/api/http.proto#L212
.. _resource names: https://cloud.google.com/apis/design/resource_names
    )unicode_literals)dequeNae  
    (  # Capture the entire variable expression
        (?P<positional>\*\*?)  # Match & capture * and ** positional variables.
        |
        # Match & capture named variables {name}
        {
            (?P<name>[^/]+?)
            # Optionally match and capture the named variable's template.
            (?:=(?P<template>.+?))?
        }
    )
    z([^/]+)z(.+)c              
   C   s   | d}| d}|dur)zt|| W S  ty(   td||j| w |durHzt| dW S  tyG   td|j| w td| d)a  Expand a matched variable with its value.

    Args:
        positional_vars (list): A list of positional variables. This list will
            be modified.
        named_vars (dict): A dictionary of named variables.
        match (re.Match): A regular expression match.

    Returns:
        str: The expanded variable to replace the match.

    Raises:
        ValueError: If a positional or named variable is required by the
            template but not specified or if an unexpected template expression
            is encountered.
    
positionalnameNzLNamed variable '{}' not specified and needed by template `{}` at position {}r   zLPositional variable not specified and needed by template `{}` at position {}Unknown template expression {})	groupstrKeyError
ValueErrorformatstringstartpop
IndexError)positional_vars
named_varsmatchr   r    r   Q/var/www/passon-env/lib/python3.10/site-packages/google/api_core/path_template.py_expand_variable_matchA   s*   

r   c                 O   s   t tt||}t|| S )a  Expand a path template with the given variables.

    .. code-block:: python

        >>> expand('users/*/messages/*', 'me', '123')
        users/me/messages/123
        >>> expand('/v1/{name=shelves/*/books/*}', name='shelves/1/books/3')
        /v1/shelves/1/books/3

    Args:
        tmpl (str): The path template.
        args: The positional variables for the path.
        kwargs: The named variables for the path.

    Returns:
        str: The expanded path

    Raises:
        ValueError: If a positional or named variable is required by the
            template but not specified or if an unexpected template expression
            is encountered.
    )	functoolspartialr   list_VARIABLE_REsub)tmplargskwargsreplacerr   r   r   expandh   s   r   c                 C   sz   |  d}|  d}|  d}|dur'|st|S |dkr#t|S t|S |dkr-tS |dkr3tS td|  d)	af  Replace a variable match with a pattern that can be used to validate it.

    Args:
        match (re.Match): A regular expression match

    Returns:
        str: A regular expression pattern that can be used to validate the
            variable in an expanded path.

    Raises:
        ValueError: If an unexpected template expression is encountered.
    r   r   templateNz***r   r   )r   _SINGLE_SEGMENT_PATTERNr   _MULTI_SEGMENT_PATTERN_generate_pattern_for_templater
   )r   r   r   r    r   r   r   _replace_variable_with_pattern   s   




r%   c                 C   s   t t| S )zGenerate a pattern that can validate a path template.

    Args:
        tmpl (str): The path template

    Returns:
        str: A regular expression pattern that can be used to validate an
            expanded path template.
    )r   r   r%   )r   r   r   r   r$      s   
r$   c                 C   sL   | d}| }|D ]}t|tst||d}q	||}q	t|tr$dS |S )zGet the value of a field from a given dictionary.

    Args:
        request (dict | Message): A dictionary or a Message object.
        field (str): The key to the request in dot notation.

    Returns:
        The value of the field.
    .N)split
isinstancedictgetattrget)requestfieldpartsvaluepartr   r   r   	get_field   s   



r1   c                 C   s   t |d}t|dkr/| }t| ts$t| |r"t| |d} ndS | |} t|dks| }t| tsFt| |rD| 	| dS dS | 
|d dS )zDelete the value of a field from a given dictionary.

    Args:
        request (dict | Message): A dictionary object or a Message.
        field (str): The key to the request in dot notation.
    r&      N)r   r'   lenpopleftr(   r)   hasattrr*   r+   
ClearFieldr   )r,   r-   r.   r0   r   r   r   delete_field   s   


	

r7   c                 C   s$   t | d }t||durdS dS )a/  Validate a path against the path template.

    .. code-block:: python

        >>> validate('users/*/messages/*', 'users/me/messages/123')
        True
        >>> validate('users/*/messages/*', 'users/me/drafts/123')
        False
        >>> validate('/v1/{name=shelves/*/books/*}', /v1/shelves/1/books/3)
        True
        >>> validate('/v1/{name=shelves/*/books/*}', /v1/shelves/1/tapes/3)
        False

    Args:
        tmpl (str): The path template.
        path (str): The expanded path.

    Returns:
        bool: True if the path matches.
    $NTF)r$   rer   )r   pathpatternr   r   r   validate   s   r<   c              
      sp  |p| g }| D ]}i }|d }dd t |D }|||f  fdd|D }t|fi ||d< t||d rAt| sBqt }	|D ]	\}
}t	|	|
 qI|
d}|r|dkrp|	|d< |rk| |d< n2i |d< n-z|rt|	||d< t	|	| n|	||d< W n ttfy   Y qw |	|d< n|	|d< |d	 |d	< |  S d
d |D }tdd|)au  Transcodes a grpc request pattern into a proper HTTP request following the rules outlined here,
    https://github.com/googleapis/googleapis/blob/master/google/api/http.proto#L44-L312

     Args:
         http_options (list(dict)): A list of dicts which consist of these keys,
             'method'    (str): The http method
             'uri'       (str): The path template
             'body'      (str): The body field name (optional)
             (This is a simplified representation of the proto option `google.api.http`)

         message (Message) : A request object (optional)
         request_kwargs (dict) : A dict representing the request object

     Returns:
         dict: The transcoded request with these keys,
             'method'        (str)   : The http method
             'uri'           (str)   : The expanded uri
             'body'          (dict | Message)  : A dict or a Message representing the body (optional)
             'query_params'  (dict | Message)  : A dict or Message mapping query parameter variables and values

     Raises:
         ValueError: If the request does not match the given template.
    uric                 S   s    g | ]}| d | dfqS )r   r    )r   ).0mr   r   r   
<listcomp>  s    ztranscode.<locals>.<listcomp>c                    s   i | ]
\}}|t  |qS r   )r1   )r>   r-   _transcoded_valuer   r   
<dictcomp>  s    ztranscode.<locals>.<dictcomp>bodyr!   query_paramsmethodc              	   S   s,   g | ]\}}d  |ddd |D qS )z*
	URI: "{}"
	Required request fields:
		{}z
		c                 S   s$   g | ]\}}d  ||r|ndqS )zfield: "{}", pattern: "{}"r!   )r   )r>   npr   r   r   r@   H  s    z(transcode.<locals>.<listcomp>.<listcomp>)r   join)r>   r=   fieldsr   r   r   r@   C  s    aQ  Invalid request.
Some of the fields of the request message are either not initialized or initialized with an invalid value.
Please make sure your request matches at least one accepted HTTP binding.
To match a binding the request message must have all the required fields initialized with values matching their patterns as listed below:{}
)r   finditerappendr   r<   allvaluescopydeepcopyr7   r+   	__class__r*   r   r	   AttributeErrorr
   r   rJ   )http_optionsmessagerequest_kwargsbindingshttp_optionr,   uri_templaterK   	path_args	leftovers
path_fieldrA   rE   bindings_descriptionr   rB   r   	transcode   sZ   



r_   )N)__doc__
__future__r   collectionsr   rQ   r   r9   compileVERBOSEr   r"   r#   r   r   r%   r$   r1   r7   r<   r_   r   r   r   r   <module>   s(   '