o
    }l~i0                     @  s   d Z ddlmZ ddlZddlmZ ddlmZmZm	Z	m
Z
 dZdZdZd	Zd
Zed ZdZee ZedZedZg dZddd eD ZeeZd(ddZd)ddZd*ddZd+dd ZeZd,d$d%ZG d&d' d'e Z!dS )-zBUtilities for managing / converting field paths to / from strings.    )annotationsN)abc)AnyIterablecastMutableMappingz!{!r} is not contained in the dataz2{!r} is not contained in the data for the key {!r}zGThe data at {!r} is not a dictionary, so it cannot contain the key {!r}.\   `z^[_a-zA-Z][_a-zA-Z0-9]*$z ^[_a-zA-Z][_a-zA-Z0-9]*[~*/\[\]]))SIMPLEz[_a-zA-Z][_a-zA-Z0-9]*)QUOTEDz`(?:\\`|[^`])*?`)DOTz\.|c                 c  s    | ]}d j | V  qdS )z
(?P<{}>{})N)format).0pair r   k/var/www/newdalilibackend/backend/venv/lib/python3.10/site-packages/google/cloud/firestore_v1/field_path.py	<genexpr>(   s    r   pathstrc                 c  sz    d}t j}|| }|dur)tt|j}||}|V  | }|| |}|dus|t| kr;td	| | |d dS )zLex a field path into tokens (including dots).

    Args:
        path (str): field path to be lexed.
    Returns:
        List(str): tokens
    r   Nz!Path {} not consumed, residue: {})
TOKENS_REGEXmatchr   r   	lastgroupgroupendlen
ValueErrorr   )r   pos	get_tokenr   type_valuer   r   r   _tokenize_field_path,   s   

r#   
str | Nonec                 C  s|   | sg S g }d}t | D ]$}|r|dkrtd| d}q|dkr)td| || d}q|r5|s<td| |S )a  Split a field path into valid elements (without dots).

    Args:
        path (str): field path to be lexed.
    Returns:
        List(str): tokens
    Raises:
        ValueError: if the path does not match the elements-interspersed-
                    with-dots pattern.
    Fr   zInvalid path: {}T)r#   r   r   append)r   elementswant_dotelementr   r   r   split_field_pathA   s    
r)   api_reprc                 C  s\   g }t | D ]%}|d dkr&|d dkr&|dd }|tt}|tt}|| q|S )a;  Parse a **field path** from into a list of nested field names.

    See :func:`field_path` for more on **field paths**.

    Args:
        api_repr (str):
            The unique Firestore api representation which consists of
            either simple or UTF-8 field names. It cannot exceed
            1500 bytes, and cannot be empty. Simple field names match
            ``'^[_a-zA-Z][_a-zA-Z0-9]*$'``. All other field names are
            escaped by surrounding them with backticks.

    Returns:
        List[str, ...]: The list of field names in the field path.
    r   r      )r)   replace_ESCAPED_BACKTICK	_BACKTICK_ESCAPED_BACKSLASH
_BACKSLASHr%   )r*   field_names
field_namer   r   r   parse_field_pathd   s   r4   r2   Iterable[str]c                 C  sf   g }| D ])}t |}|r|d|kr|| q|tttt}|t| t  qt	
|S )aC  Create a **field path** from a list of nested field names.

    A **field path** is a ``.``-delimited concatenation of the field
    names. It is used to represent a nested field. For example,
    in the data

    .. code-block:: python

       data = {
          'aa': {
              'bb': {
                  'cc': 10,
              },
          },
       }

    the field path ``'aa.bb.cc'`` represents that data stored in
    ``data['aa']['bb']['cc']``.

    Args:
        field_names: The list of field names.

    Returns:
        str: The ``.``-delimited field path.
    r   )_SIMPLE_FIELD_NAMEr   r   r%   r-   r1   r0   r/   r.   _FIELD_PATH_DELIMITERjoin)r2   resultr3   r   replacedr   r   r   render_field_path   s   

r;   
field_pathdataMutableMapping[str, Any]c                 C  s   t | }|}t|D ]C\}}t|tjr<||v r|| }q
|dkr*t|}t|t|d| }t	||}t|t|d| }t
||}t||S )a  Get a (potentially nested) value from a dictionary.

    If the data is nested, for example:

    .. code-block:: python

       >>> data
       {
           'top1': {
               'middle2': {
                   'bottom3': 20,
                   'bottom4': 22,
               },
               'middle5': True,
           },
           'top6': b'  foo',
       }

    a **field path** can be used to access the nested data. For
    example:

    .. code-block:: python

       >>> get_nested_value('top1', data)
       {
           'middle2': {
               'bottom3': 20,
               'bottom4': 22,
           },
           'middle5': True,
       }
       >>> get_nested_value('top1.middle2', data)
       {
           'bottom3': 20,
           'bottom4': 22,
       }
       >>> get_nested_value('top1.middle2.bottom3', data)
       20

    See :meth:`~google.cloud.firestore_v1.client.Client.field_path` for
    more information on **field paths**.

    Args:
        field_path (str): A field path (``.``-delimited list of
            field names).
        data (Dict[str, Any]): The (possibly nested) data.

    Returns:
        Any: (A copy of) the value stored for the ``field_path``.

    Raises:
        KeyError: If the ``field_path`` does not match nested data.
    r   N)r4   	enumerate
isinstancer   Mapping_FIELD_PATH_MISSING_TOPr   KeyErrorr;   _FIELD_PATH_MISSING_KEY_FIELD_PATH_WRONG_TYPE)r<   r=   r2   nested_dataindexr3   msgpartialr   r   r   get_nested_value   s    6

rJ   c                   @  s   e Zd ZdZd#ddZed$d	d
Zed%ddZdd Zdd Z	dd Z
dd Zdd Zd&ddZd'ddZd(ddZed&d d!Zd"S ))	FieldPatha  Field Path object for client use.

    A field path is a sequence of element keys, separated by periods.
    Each element key can be either a simple identifier, or a full unicode
    string.

    In the string representation of a field path, non-identifier elements
    must be quoted using backticks, with internal backticks and backslashes
    escaped with a backslash.

    Args:
        parts: (one or more strings)
            Indicating path of the key to be used.
    partsr   c                 G  s2   |D ]}t |tr|sd}t|qt|| _d S )Nz3One or more components is not a string or is empty.)r@   r   r   tuplerL   )selfrL   parterrorr   r   r   __init__
  s   zFieldPath.__init__r*   return'FieldPath'c                 C  s    |  }|s
td| t| S )a  Factory: create a FieldPath from the string formatted per the API.

        Args:
            api_repr (str): a string path, with non-identifier elements quoted
            It cannot exceed 1500 characters, and cannot be empty.
        Returns:
            (:class:`FieldPath`) An instance parsed from ``api_repr``.
        Raises:
            ValueError if the parsing fails
        z.Field path API representation cannot be empty.)stripr   r4   )clsr*   r   r   r   from_api_repr  s   zFieldPath.from_api_reprpath_stringc                 C  s`   z|  |W S  ty/   |d}|D ]}|stdt|r(td|qt|  Y S w )a  Factory: create a FieldPath from a unicode string representation.

        This method splits on the character `.` and disallows the
        characters `~*/[]`. To create a FieldPath whose components have
        those characters, call the constructor.

        Args:
            path_string (str): A unicode string which cannot contain
            `~*/[]` characters, cannot exceed 1500 bytes, and cannot be empty.

        Returns:
            (:class:`FieldPath`) An instance parsed from ``path_string``.
        r   zEmpty elementz.Invalid char in element with leading alpha: {})rV   r   split_LEADING_ALPHA_INVALIDr   r   rK   )rU   rW   r&   r(   r   r   r   from_string"  s   

zFieldPath.from_stringc                 C  s6   d}| j D ]
}|d| d 7 }q|d d }d|S )N 'z',r+   zFieldPath({}))rL   r   )rN   pathsrO   r   r   r   __repr__>  s
   

zFieldPath.__repr__c                 C  s   t |  S N)hashto_api_reprrN   r   r   r   __hash__E  s   zFieldPath.__hash__c                 C  s   t |tr| j|jkS tS r_   r@   rK   rL   NotImplementedrN   otherr   r   r   __eq__H     
zFieldPath.__eq__c                 C  s   t |tr| j|jk S tS r_   rd   rf   r   r   r   __lt__M  ri   zFieldPath.__lt__c                 C  sF   t |tr| j|j }t| S t |tr!| jt|j }t| S tS )zAdds `other` field path to end of this field path.

        Args:
            other (~google.cloud.firestore_v1._helpers.FieldPath, str):
                The field path to add to the end of this `FieldPath`.
        )r@   rK   rL   r   rZ   re   )rN   rg   rL   r   r   r   __add__R  s   

zFieldPath.__add__c                 C  s
   t | jS )zRender a quoted string representation of the FieldPath

        Returns:
            (str) Quoted string representation of the path stored
            within this FieldPath.
        )r;   rL   rb   r   r   r   ra   b  s   
zFieldPath.to_api_reprboolc                 C  s(   | j dt|j  |j dt| j  kS )zCheck whether ``other`` is an ancestor.

        Returns:
            (bool) True IFF ``other`` is an ancestor or equal to ``self``,
            else False.
        N)rL   r   rf   r   r   r   eq_or_parentk  s   (zFieldPath.eq_or_parentset['FieldPath']c                   s"   t dt j} fdd|D S )zVReturn field paths for all parents.

        Returns: Set[:class:`FieldPath`]
        r,   c                   s   h | ]}t  jd |  qS r_   )rK   rL   )r   rG   rb   r   r   	<setcomp>z  s    z$FieldPath.lineage.<locals>.<setcomp>)ranger   rL   )rN   indexesr   rb   r   lineaget  s   zFieldPath.lineagec                   C  s   dS )zA special FieldPath value to refer to the ID of a document. It can be used
           in queries to sort or filter by the document ID.

        Returns: A special sentinel value to refer to the ID of a document.
        __name__r   r   r   r   r   document_id|  s   zFieldPath.document_idN)rL   r   )r*   r   rR   rS   )rW   r   rR   rS   )rR   r   )rR   rl   )rR   rn   )rs   
__module____qualname____doc__rQ   classmethodrV   rZ   r^   rc   rh   rj   rk   ra   rm   rr   staticmethodrt   r   r   r   r   rK      s"    


	
	rK   )r   r   )r   r$   )r*   r   )r2   r5   )r<   r   r=   r>   )"rw   
__future__r   recollectionsr   typingr   r   r   r   rB   rD   rE   r7   r1   r0   r/   r.   compiler6   rY   PATH_ELEMENT_TOKENSr8   TOKENS_PATTERNr   r#   r)   r4   r;   get_field_pathrJ   objectrK   r   r   r   r   <module>   s4   





#
)
M