o
    6d3H                     @   s$  d dl mZmZmZmZ d dlmZ d dlmZ d dl	Z	ddl
mZmZmZmZmZ dZer`d dlZddl
mZmZmZmZmZmZmZmZ d d	lmZ e	jrXejejd
f Z nejejdf Z G dd de!Z"G dd de!Z#G dd
 d
e!Z$G dd de!Z%G dd de!Z&G dd de!Z'dS )    )absolute_importdivisionprint_functionunicode_literals)OrderedDict)StrictVersionN   )
doc_unwrapis_aliasis_composite_typeis_list_typeis_nullable_typeF)Alias
AnnotationAnnotationTypeDataTypeListNullableStructUserDefined)AstRouteDefApiNamespaces   ApiNamespacec                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )ApizL
    A full description of an API's namespaces, data types, and routes.
    c                 C   s   t || _t | _d | _d S N)r   versionr   
namespacesroute_schema)selfr    r   cC:\Users\jesus\OneDrive\Desktop\erpjis_fastapi\backend\jisbackend\Lib\site-packages\stone/ir/api.py__init__.   s   

zApi.__init__c                 C   s"   || j vrt|| j |< | j | S )z
        Only creates a namespace if it hasn't yet been defined.

        :param str name: Name of the namespace.

        :return ApiNamespace:
        )r   r   r   namer   r   r   ensure_namespace4   s   
	
zApi.ensure_namespacec                 C   sJ   t  }t| j D ]	}| j| ||< q
|| _| j D ]}|  qdS )zj
        Alphabetizes namespaces and routes to make spec parsing order mostly
        irrelevant.
        N)r   sortedr   keysvalues	normalize)r   Zordered_namespacesZnamespace_name	namespacer   r   r   r'   A   s   
zApi.normalizec                 C   s   | j d u sJ || _ d S r   )r   )r   r   r   r   r   add_route_schemaP   s   
zApi.add_route_schemaN)__name__
__module____qualname____doc__r    r#   r'   r)   r   r   r   r   r   *   s    r   c                   @      e Zd ZdZdd ZdS )_ImportReasonz5
    Tracks the reason a namespace was imported.
    c                 C   s   d| _ d| _d| _d| _d S )NF)alias	data_type
annotationannotation_typer   r   r   r   r    [   s   
z_ImportReason.__init__Nr*   r+   r,   r-   r    r   r   r   r   r/   V       r/   c                   @   s   e 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d Zdd Zdd Zdd Z			d%ddZdd Zdd  Zd!d" Zd#S )&r   zQ
    Represents a category of API endpoints and their associated data types.
    c                 C   sX   || _ d | _g | _i | _i | _g | _i | _g | _i | _g | _	i | _
g | _i | _i | _d S r   )r"   docroutesroute_by_nameroutes_by_name
data_typesdata_type_by_namealiasesalias_by_nameannotationsannotation_by_nameannotation_typesannotation_type_by_name_imported_namespacesr!   r   r   r   r    h   s   
zApiNamespace.__init__c                 C   sJ   t |tjsJ t|t|d }| jdu r|| _dS |  j|7  _dS )aU  Adds a docstring for this namespace.

        The input docstring is normalized to have no leading whitespace and
        no trailing whitespace except for a newline at the end.

        If a docstring already exists, the new normalized docstring is appended
        to the end of the existing one with two newlines separating them.
        
N)
isinstancesix	text_typetyper	   r7   )r   	docstringZnormalized_docstringr   r   r   add_docz   s
   


zApiNamespace.add_docc                 C   sT   | j | |jdkr|| j|j< |j| jvrt | j|j< || j|j j|j< d S )Nr   )r8   appendr   r9   r"   r:   ApiRoutesByVersion
at_version)r   router   r   r   	add_route   s   
zApiNamespace.add_routec                 C      | j | || j|j< d S r   )r;   rK   r<   r"   r   r1   r   r   r   add_data_type      zApiNamespace.add_data_typec                 C   rP   r   )r=   rK   r>   r"   r   r0   r   r   r   	add_alias   rS   zApiNamespace.add_aliasc                 C   rP   r   )r?   rK   r@   r"   )r   r2   r   r   r   add_annotation   rS   zApiNamespace.add_annotationc                 C   rP   r   )rA   rK   rB   r"   )r   r3   r   r   r   add_annotation_type   rS   z ApiNamespace.add_annotation_typeFc                 C   sT   | j |j ks
J d| j|t }|rd|_|rd|_|r!d|_|r(d|_dS dS )a  
        Keeps track of namespaces that this namespace imports.

        Args:
            namespace (Namespace): The imported namespace.
            imported_alias (bool): Set if this namespace references an alias
                in the imported namespace.
            imported_data_type (bool): Set if this namespace references a
                data type in the imported namespace.
            imported_annotation (bool): Set if this namespace references a
                annotation in the imported namespace.
            imported_annotation_type (bool): Set if this namespace references an
                annotation in the imported namespace, possibly indirectly (by
                referencing an annotation elsewhere that has this type).
        zNamespace cannot import itself.TN)r"   rC   
setdefaultr/   r0   r1   r2   r3   )r   r(   Zimported_aliasZimported_data_typeZimported_annotationZimported_annotation_typereasonr   r   r   add_imported_namespace   s   
z#ApiNamespace.add_imported_namespacec                    4   g t   fdd jD ]} | qS )ad  
        Returns a list of all data types used in the namespace. Because the
        inheritance of data types can be modeled as a DAG, the list will be a
        linearization of the DAG. It's ideal to generate data types in this
        order so that composite types that reference other composite types are
        defined in the correct order.
        c                    sJ   | v rd S | j krd S t| r| jr | j |  |  d S r   )r(   r   Zparent_typerK   addr1   rR   Zlinearized_data_typesZseen_data_typesr   r   r   rR      s   


z8ApiNamespace.linearize_data_types.<locals>.add_data_type)setr;   rQ   r   r^   r   linearize_data_types   s   	

z!ApiNamespace.linearize_data_typesc                    r[   )z
        Returns a list of all aliases used in the namespace. The aliases are
        ordered to ensure that if they reference other aliases those aliases
        come earlier in the list.
        c                    sF   | v rd S | j krd S t| jr | j |  |  d S r   )r(   r
   r1   rK   r\   r0   rU   Zlinearized_aliasesZseen_aliasesr   r   r   rU      s   



z1ApiNamespace.linearize_aliases.<locals>.add_alias)r_   r=   rT   r   rb   r   linearize_aliases   s   

zApiNamespace.linearize_aliasesc                 C   s0   t  }| jD ]	}|| |O }qt|dd dS )a  
        Returns a list of all user-defined data types that are referenced as
        either an argument, result, or error of a route. If a List or Nullable
        data type is referenced, then the contained data type is returned
        assuming it's a user-defined type.
        c                 S      | j S r   r"   dtr   r   r   <lambda>      z6ApiNamespace.get_route_io_data_types.<locals>.<lambda>key)r_   r8   !get_route_io_data_types_for_router$   )r   r;   rN   r   r   r   get_route_io_data_types  s   
z$ApiNamespace.get_route_io_data_typesc                 C   sh   t  }|j|j|jfD ]&}t|st|r"|}|j}t|st|st|s*t|r1|}|	| q|S )zV
        Given a route, returns a set of its argument/result/error datatypes.
        )
r_   arg_data_typeresult_data_typeerror_data_typer   r   r1   r   r
   r\   )r   rN   r;   ZdtypeZdata_list_typeZdata_user_typer   r   r   rl     s   
z.ApiNamespace.get_route_io_data_types_for_routec                 C   sr   g }| j  D ]'\}}|r|jsq|s|js|js|jsq|s)|js)|js)|js)q|| q|jdd d |S )a  
        Returns a list of Namespace objects. A namespace is a member of this
        list if it is imported by the current namespace and a data type is
        referenced from it. Namespaces are in ASCII order by name.

        Args:
            must_have_imported_data_type (bool): If true, result does not
                include namespaces that were not imported for data types.
            consider_annotations (bool): If false, result does not include
                namespaces that were only imported for annotations
            consider_annotation_types (bool): If false, result does not
                include namespaces that were only imported for annotation types.

        Returns:
            List[Namespace]: A list of imported namespaces.
        c                 S   rd   r   re   nr   r   r   rh   @  ri   z6ApiNamespace.get_imported_namespaces.<locals>.<lambda>rj   )rC   itemsr1   r0   r3   r2   rK   sort)r   Zmust_have_imported_data_typeZconsider_annotationsZconsider_annotation_typesZimported_namespacesZimported_namespacerY   r   r   r   get_imported_namespaces  s.   
z$ApiNamespace.get_imported_namespacesc                 C   sJ   t |  dd d}t }|D ]}|j| kr||j qt |dd dS )a  
        Returns a list of Namespace objects. A namespace is a member of this
        list if it is imported by the current namespace and has a data type
        from it referenced as an argument, result, or error of a route.
        Namespaces are in ASCII order by name.
        c                 S   rd   r   re   rf   r   r   r   rh   L  ri   zBApiNamespace.get_namespaces_imported_by_route_io.<locals>.<lambda>rj   c                 S   rd   r   re   rq   r   r   r   rh   Q  ri   )r$   rm   r_   r(   r\   )r   Znamespace_data_typesZreferenced_namespacesr1   r   r   r   #get_namespaces_imported_by_route_ioC  s   
z0ApiNamespace.get_namespaces_imported_by_route_ioc                 C   sL   | j jdd d | jjdd d | jjdd d | jjdd d dS )zQ
        Alphabetizes routes to make route declaration order irrelevant.
        c                 S   rd   r   re   )rN   r   r   r   rh   X  ri   z(ApiNamespace.normalize.<locals>.<lambda>rj   c                 S   rd   r   re   r]   r   r   r   rh   Y  ri   c                 S   rd   r   re   ra   r   r   r   rh   Z  ri   c                 S   rd   r   re   )r2   r   r   r   rh   [  ri   N)r8   rt   r;   r=   r?   r4   r   r   r   r'   S  s   zApiNamespace.normalizec                 C   s   t d| jS )NzApiNamespace({!r}))strformatr"   r4   r   r   r   __repr__]  s   zApiNamespace.__repr__N)FFFF)FFF)r*   r+   r,   r-   r    rJ   rO   rR   rU   rV   rW   rZ   r`   rc   rm   rl   ru   rv   r'   ry   r   r   r   r   r   c   s2    	
"
&
c                   @   sp   e 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 Zdd Zdd Zdd Zdd ZdS )ApiRoutez%
    Represents an API endpoint.
    c                 C   s@   || _ || _|| _d| _d| _d| _d| _d| _d| _d| _	dS )z
        :param str name: Designated name of the endpoint.
        :param int version: Designated version of the endpoint.
        :param ast_node: Raw route definition from the parser.
        N)
r"   r   	_ast_node
deprecatedraw_docr7   rn   ro   rp   attrs)r   r"   r   Zast_noder   r   r   r    g  s   

zApiRoute.__init__c                 C   s2   || _ || _t|| _|| _|| _|| _|| _dS )a]  
        Converts a forward reference definition of a route into a full
        definition.

        :param DeprecationInfo deprecated: Set if this route is deprecated.
        :param str doc: Description of the endpoint.
        :type arg_data_type: :class:`stone.data_type.DataType`
        :type result_data_type: :class:`stone.data_type.DataType`
        :type error_data_type: :class:`stone.data_type.DataType`
        :param dict attrs: Map of string keys to values that are either int,
            float, bool, str, or None. These are the route attributes assigned
            in the spec.
        N)r|   r}   r	   r7   rn   ro   rp   r~   )r   r|   r7   rn   ro   rp   r~   r   r   r   set_attributes~  s   

zApiRoute.set_attributesc                 C   s    | j dkr| jS d| j| j S )z
        Get user-friendly representation of the route.

        :return: Route name with version suffix. The version suffix is omitted for version 1.
        r   z{}:{})r   r"   rx   r4   r   r   r   name_with_version  s   
zApiRoute.name_with_versionc                 C   s   d |  S )NzApiRoute({}))rx   r   r4   r   r   r   ry     s   zApiRoute.__repr__c                 C   sl   t |tstd|t |tstd||j|jk s$|j|jk r&dS |j|jks2|j|jkr4dS dS )Nz Expected ApiRoute for object: {}r   r   )rE   rz   	TypeErrorrx   r"   r   )r   lhsrhsr   r   r   _compare  s   

zApiRoute._comparec                 C   s   |  | |dk S Nr   r   r   otherr   r   r   __lt__     zApiRoute.__lt__c                 C   s   |  | |dkS r   r   r   r   r   r   __gt__  r   zApiRoute.__gt__c                 C   s   |  | |dkS r   r   r   r   r   r   __eq__  r   zApiRoute.__eq__c                 C   s   |  | |dkS r   r   r   r   r   r   __le__  r   zApiRoute.__le__c                 C   s   |  | |dkS r   r   r   r   r   r   __ge__  r   zApiRoute.__ge__c                 C   s   |  | |dkS r   r   r   r   r   r   __ne__  r   zApiRoute.__ne__c                 C   s4   t | j| j| j| j| j| j| j| j| j	t
| jf
S r   )hashr"   r   r{   r|   r}   r7   rn   ro   rp   idr~   r4   r   r   r   __hash__  s   zApiRoute.__hash__N)r*   r+   r,   r-   r    r   r   ry   r   r   r   r   r   r   r   r   r   r   r   r   rz   b  s    rz   c                   @   s   e Zd ZdddZdS )DeprecationInfoNc                 C   s(   |du st |tsJ t||| _dS )zR
        :param ApiRoute by: The route that replaces this deprecated one.
        N)rE   rz   reprby)r   r   r   r   r   r      s   
zDeprecationInfo.__init__r   )r*   r+   r,   r    r   r   r   r   r     s    r   c                   @   r.   )rL   zD
    Represents routes of different versions for a common name.
    c                 C   s
   i | _ dS )zR
        :param at_version: The dict mapping a version number to a route.
        N)rM   r4   r   r   r   r      s   
zApiRoutesByVersion.__init__Nr5   r   r   r   r   rL     r6   rL   )(
__future__r   r   r   r   collectionsr   Zdistutils.versionr   rF   r;   r	   r
   r   r   r   Z_MYPYtypingr   r   r   r   r   ZDataTypeListr   r   r   Zstone.frontend.astr   PY3DictTextZNamespaceDictobjectr   r/   r   rz   r   rL   r   r   r   r   <module>   s*    (,  i
