o
    lh3                     @   sr   d dl mZ d dlmZ d dlZddlmZmZ ddlmZ ddl	m
Z
 dd	 ZG d
d dZdd Zdd ZdS )    )OrderedDict)DecimalN   )JsonSchemaValueExceptionJsonSchemaDefinitionException)indent)RefResolverc                 C   s   t | tr| S | gS N)
isinstancelist)variable r   l/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/fastjsonschema/generator.pyenforce_list
   s   
r   c                   @   s   e Zd ZdZdZd-ddZedd Zed	d
 Ze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edd Zdd Zddd d!d"Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, ZdS )/CodeGeneratora7  
    This class is not supposed to be used directly. Anything
    inside of this class can be changed without noticing.

    This class generates code of validation function from JSON
    schema object as string. Example:

    .. code-block:: python

        CodeGenerator(json_schema_definition).func_code
       NTc                 C   s   g | _ i | _i | _|| _dg| _dti| _t | _d| _	d | _
d | _d | _|| _d | _i | _t | _|d u r=tj|i d}|| _| j | j| j < t | _d S )Nzfrom decimal import Decimalr   r   )store)_code_compile_regexps_custom_formats_detailed_exceptions_extra_imports_linesr   _extra_imports_objectsset
_variables_indent_indent_last_line	_variable_variable_name_root_definition_definition_needed_validation_functions_validation_functions_doner   from_schema	_resolverget_scope_nameget_urir   _json_keywords_to_function)self
definitionresolverdetailed_exceptionsr   r   r   __init__    s,   zCodeGenerator.__init__c                 C   s   |    d| jS )zP
        Returns generated code of whole validation function as string.
        
)_generate_func_codejoinr   r(   r   r   r   	func_codeG   s   zCodeGenerator.func_codec                 C   s&   |    tdi | j| jttdS )z
        Returns global variables for generating function from ``func_code``. Includes
        compiled regular expressions and imports, so it does not have to do it every
        time when validation function is called.
        )REGEX_PATTERNSrer   Nr   )r.   dictr   r   r3   r   r0   r   r   r   global_stateP   s   
zCodeGenerator.global_statec              
   C   sH   |    | jsd| jg d S d| jdddddt| j dg S )z
        Returns global variables for generating function from ``func_code`` as code.
        Includes compiled regular expressions and imports.
        r-   )3from fastjsonschema import JsonSchemaValueException r7   z	import rer6   r7   zREGEX_PATTERNS = )r.   r   r/   r   serialize_regexesr0   r   r   r   global_state_code`   s   zCodeGenerator.global_state_codec                 C   s   | j s	|   d S d S r	   )r   generate_func_coder0   r   r   r   r.   x   s   z!CodeGenerator._generate_func_codec                 C   s8   |  d | jr| j \}}| || | jsdS dS )zt
        Creates base code of validation function and calls helper
        for creating code by definition.
        zNoneType = type(None)N)lr!   popitemgenerate_validation_function)r(   urinamer   r   r   r:   |   s
   
z CodeGenerator.generate_func_codec              	   C   s   | j | | d | j|5}| d| | j|dddd | d W d   n1 s1w   Y  W d   dS W d   dS 1 sIw   Y  dS )zL
        Generate validation function for given uri with given name
        r7   z4def {}(data, custom_formats={{}}, name_prefix=None):dataT)clear_variableszreturn dataN)r"   addr;   r$   	resolvinggenerate_func_code_block)r(   r>   r?   r)   r   r   r   r=      s   
"z*CodeGenerator.generate_validation_functionFc                 C   s`   | j | j| jf}|||| _ | _| _|r| j}t | _| |}|\| _ | _| _|r.|| _|S )z
        Creates validation rules for current definition.

        Returns the number of validation rules generated as code.
        )r    r   r   r   r   _generate_func_code_block)r(   r)   r   variable_namerA   backupbackup_variablescountr   r   r   rD      s   
z&CodeGenerator.generate_func_code_blockc                 C   s,   t |ts	tdd|v r|  S | |S )Nzdefinition must be an object$ref)r
   r4   r   generate_refrun_generate_functions)r(   r)   r   r   r   rE      s
   

z'CodeGenerator._generate_func_code_blockc                 C   s2   d}| j  D ]\}}||v r|  |d7 }q|S )z<Returns the number of generate functions that were executed.r   r   )r'   items)r(   r)   rI   keyfuncr   r   r   rL      s   z$CodeGenerator.run_generate_functionsc                 C   s   | j | jd A | j  }| j  }|| jvr|| j|< | jds&J | jdd }d	|}d|v r:|d }| j
d||d	 W d   dS 1 sMw   Y  dS )
aW  
        Ref can be link to remote or local definition.

        .. code-block:: python

            {'$ref': 'http://json-schema.org/draft-04/schema#'}
            {
                'properties': {
                    'foo': {'type': 'integer'},
                    'bar': {'$ref': '#/properties/foo'}
                }
            }
        rJ   r@   r   Nz(name_prefix or "data") + "{}"{z.format(**locals())z*{}({variable}, custom_formats, {name_arg}))name_arg)r$   in_scoper    r%   r&   r"   r!   r   
startswithformatr;   )r(   r?   r>   pathrQ   r   r   r   rK      s   




"zCodeGenerator.generate_refc                 O   s   d| j  | j }| j}|r$|dsJ d|dd  }d|v r$|d }t| jr0| jdur0| jni f| j|d	|}|j|i |}|d
ddd}| j	
||  |S )a  
        Short-cut of line. Used for inserting line. It's formated with parameters
        ``variable``, ``variable_name`` (as ``name`` for short-cut), all keys from
        current JSON schema ``definition`` and also passed arguments in ``args``
        and named ``kwds``.

        .. code-block:: python

            self.l('if {variable} not in {enum}: raise JsonSchemaValueException("Wrong!")')

        When you want to indent block, use it as context manager. For example:

        .. code-block:: python

            with self.l('if {variable} not in {enum}:'):
                self.l('raise JsonSchemaValueException("Wrong!")')
         r@   z" + (name_prefix or "data") + "r   NrP   z".format(**locals()) + "T)r   r?   r-   z\nz\r)INDENTr   r   rS   r4   r    r   rT   replacer   append)r(   lineargskwdsspacesr?   contextr   r   r   r;      s&   zCodeGenerator.lc                 C   s   t |ddS )z
        Short-cut of escape. Used for inserting user values into a string message.

        .. code-block:: python

            self.l('raise JsonSchemaValueException("Variable: {}")', self.e(variable))
        "z\")strrY   )r(   stringr   r   r   e   s   zCodeGenerator.e)append_to_msgrulec                G   s   | j s| jd| d g|R   dS d| d }|r"|d| d 7 }d| d }| | j}| t|tr:||nd}| j|g|R t|t||d	 dS )
zG
        Short-cut for creating raising exception in the code.
        z raise JsonSchemaValueException("z")Nr`   z + ()zraise JsonSchemaValueException(zH, value={variable}, name="{name}", definition={definition}, rule={rule}))r)   re   definition_rule)	r   r;   _expand_refsr    rc   r
   r4   getrepr)r(   msgrd   re   r\   argr)   rg   r   r   r   exc
  s   (zCodeGenerator.excc                    s   t |tr fdd|D S t |ts|S d|v r:t |d tr: j|d 
}|W  d    S 1 s5w   Y   fdd| D S )Nc                    s   g | ]}  |qS r   rh   ).0vr0   r   r   
<listcomp>  s    z.CodeGenerator._expand_refs.<locals>.<listcomp>rJ   c                    s   i | ]
\}}|  |qS r   rn   ro   krp   r0   r   r   
<dictcomp>"  s    z.CodeGenerator._expand_refs.<locals>.<dictcomp>)r
   r   r4   ra   r$   rC   rM   )r(   r)   schemar   r0   r   rh     s   

 zCodeGenerator._expand_refsc                 C   4   d | j}|| jv rdS | j| | d dS )a  
        Append code for creating variable with length of that variable
        (for example length of list or dictionary) with name ``{variable}_len``.
        It can be called several times and always it's done only when that variable
        still does not exists.
        z{}_lenNz {variable}_len = len({variable})rT   r   r   rB   r;   r(   rF   r   r   r   create_variable_with_length$  s
   
z)CodeGenerator.create_variable_with_lengthc                 C   rv   )z
        Append code for creating variable with keys of that variable (dictionary)
        with a name ``{variable}_keys``. Similar to `create_variable_with_length`.
        z{}_keysNz({variable}_keys = set({variable}.keys())rw   rx   r   r   r   create_variable_keys1  
   
z"CodeGenerator.create_variable_keysc                 C   rv   )z
        Append code for creating variable with bool if it's instance of list
        with a name ``{variable}_is_list``. Similar to `create_variable_with_length`.
        z
{}_is_listNz:{variable}_is_list = isinstance({variable}, (list, tuple))rw   rx   r   r   r   create_variable_is_list<  r{   z%CodeGenerator.create_variable_is_listc                 C   rv   )z
        Append code for creating variable with bool if it's instance of list
        with a name ``{variable}_is_dict``. Similar to `create_variable_with_length`.
        z
{}_is_dictNz1{variable}_is_dict = isinstance({variable}, dict)rw   rx   r   r   r   create_variable_is_dictG  r{   z%CodeGenerator.create_variable_is_dict)NT)F)__name__
__module____qualname____doc__rX   r,   propertyr1   r5   r9   r.   r:   r=   rD   rE   rL   rK   r   r;   rc   rm   rh   ry   rz   r|   r}   r   r   r   r   r      s4    
'



		
'

r   c                 C   s$   dd |   D }dd| d S )Nc                 s   s(    | ]\}}t |d  t| V  qdS )z: N)rj   
repr_regexrr   r   r   r   	<genexpr>V  s
    
z$serialize_regexes.<locals>.<genexpr>z{
    z,
    z
})rM   r/   )patterns_dictregex_patternsr   r   r   r8   S  s   r8   c                    s:   d}d  fdd|D }|rd| nd}d j|S )N)AIDEBUGLMSXz | c                 3   s*    | ]} j tt|@ rd | V  qdS )zre.N)flagsgetattrr3   )ro   fregexr   r   r   _  s   ( zrepr_regex.<locals>.<genexpr>z, r7   zre.compile({!r}{}))r/   rT   pattern)r   	all_flagsr   r   r   r   r   ]  s   r   )collectionsr   decimalr   r3   
exceptionsr   r   r   ref_resolverr   r   r   r8   r   r   r   r   r   <module>   s      D
