a
    Lg8                     @   s  d 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mZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZ eZe	e e!df Z"e	ee ef ee f Z#e	e"e#f Z$e	e$d	f Z%ee e&f Z'ee e&f Z(ee e&f Z)ee e&f Z*ee e&f Z+ee e&f Z,ed
e$dZ-G dd dee- Z.de%e/e!e dddZ0e e dddZ1G dd deZ2ee e e!ddddZ3dS )a  
QAPI introspection generator

Copyright (C) 2015-2021 Red Hat, Inc.

Authors:
 Markus Armbruster <armbru@redhat.com>
 John Snow <jsnow@redhat.com>

This work is licensed under the terms of the GNU GPL, version 2.
See the COPYING file in the top-level directory.
    )AnyDictGenericListOptionalSequenceTypeVarUnion   )c_namemcgen)QAPISchemaMonolithicCVisitor)
QAPISchemaQAPISchemaAlternativesQAPISchemaArrayTypeQAPISchemaBranchesQAPISchemaBuiltinTypeQAPISchemaEntityQAPISchemaEnumMemberQAPISchemaFeatureQAPISchemaIfCondQAPISchemaObjectTypeQAPISchemaObjectTypeMemberQAPISchemaTypeQAPISchemaVariant)QAPISourceInfoNzAnnotated[_Value]_ValueT)boundc                   @   s(   e Zd ZdZdeeee dddZdS )	Annotatedz
    Annotated generally contains a SchemaInfo-like type (as a dict),
    But it also used to wrap comments/ifconds around scalar leaf values,
    for the benefit of features and enums.
    N)valueifcondcommentc                 C   s   || _ || _|| _d S N)r   r!   r    )selfr   r    r!    r$   B/home2/Puru_Virtio_Blk/virtio-demo/qemu/scripts/qapi/introspect.py__init__Z   s    zAnnotated.__init__)N)	__name__
__module____qualname____doc__r   r   r   strr&   r$   r$   r$   r%   r   R   s
    r   F)objlevel
dict_valuereturnc                 C   s  t tddd}t| trd}|r*J |d}| jrN|||d| j d 7 }| j rf|| j 7 }|t| j	|7 }| j r|d| j
  7 }|S d}|s|||7 }| d	u r|d
7 }n@t| tr|dt|  d7 }nt| tr|dt|   d7 }nt| trh|d7 }| D ]"}|t||d dd 7 }q|||d d 7 }|||d 7 }nt| tr|d7 }t|  D ]8\}}|||d dt|t||d dd 7 }q|||d d 7 }|||d 7 }ntdt| j d|dkr|d7 }|S )a  
    Convert the type tree into a QLIT C string, recursively.

    :param obj: The value to convert.
                This value may not be Annotated when dict_value is True.
    :param level: The indentation level for this particular value.
    :param dict_value: True when the value being processed belongs to a
                       dict key; which suppresses the output indent.
    )r-   r/   c                 S   s   | d d S )N    r$   )r-   r$   r$   r%   indentn   s    z_tree_to_qlit.<locals>.indentz=dict values cannot have attached comments or if-conditionals. z/* z */

NZ
QLIT_QNULLz
QLIT_QSTR()zQLIT_QBOOL(zQLIT_QLIST(((QLitObject[]) {
r
   z{}
z}))z QLIT_QDICT(((QLitDictEntry[]) {
z{{ {:s}, {:s} }},
T)r.   ztype 'z' not implementedr   ,)intr+   
isinstancer   r!   r    
is_presentgen_if_tree_to_qlitr   	gen_endifto_c_stringboollowerliststripdictsorteditemsformatNotImplementedErrortyper'   )r,   r-   r.   r2   msgretr   keyr$   r$   r%   r;   a   sV    



 
r;   )stringr/   c                 C   s   d|  dd dd d S )N"\z\\z\")replace)rK   r$   r$   r%   r=      s    r=   c                       s  e Zd Zeed fddZeddddZddd	d
Ze	edddZ
eedddZeedddZeee eee  dddZe dfeeeeef eee ddddZeee dddZeee dddZeee d d!d"Z ee!e" edd#d$d%Z#ee!e" eee ee e!e dd&d'd(Z$ee!e" eedd)d*d+Z%ee!e" eee ee e!e& dd,d-d.Z'ee!e" eee e(dd/d0d1Z)ee!e" eee e!e* e!e eeeeeedd2d3d4Z+ee!e" eee e!e* edd5d6d7Z,  Z-S )8QAPISchemaGenIntrospectVisitor)prefixunmaskc                    sH   t  |ddt || _d | _g | _g | _i | _| j	t
d|d d S )Nzqapi-introspectz  * QAPI/QMP schema introspectionzA
#include "qemu/osdep.h"
#include "%(prefix)sqapi-introspect.h"

)rP   )superr&   r*   _unmask_schema_trees_used_types	_name_map_gencaddr   )r#   rP   rQ   	__class__r$   r%   r&      s    
z'QAPISchemaGenIntrospectVisitor.__init__N)schemar/   c                 C   s
   || _ d S r"   )rT   )r#   r\   r$   r$   r%   visit_begin   s    z*QAPISchemaGenIntrospectVisitor.visit_begin)r/   c                 C   s|   | j D ]}||  qt| jddd }| jtdt|d | jtdt|t| j	d d | _
g | _	g | _ i | _d S )NF)protectZqmp_schema_qlitzA
#include "qapi/qmp/qlit.h"

extern const QLitObject %(c_name)s;
)r   z-
const QLitObject %(c_name)s = %(c_string)s;
)r   Zc_string)rV   visitr   _prefix_genhrY   r   rX   r;   rU   rT   rW   )r#   typnamer$   r$   r%   	visit_end   s    


z(QAPISchemaGenIntrospectVisitor.visit_end)entityr/   c                 C   s   t |t S r"   )r8   r   )r#   re   r$   r$   r%   visit_needed   s    z+QAPISchemaGenIntrospectVisitor.visit_needed)rc   r/   c                 C   s2   | j r
|S || jvr(dt| j | j|< | j| S )Nz%d)rS   rW   len)r#   rc   r$   r$   r%   _name   s
    
z$QAPISchemaGenIntrospectVisitor._name)rb   r/   c                 C   s   | j d usJ | dkr4| j d}|s.J |}n0t|trd|j dkrd| j d}|s`J |}|| jvrz| j| t|tr|j	S t|trd| 
|j d S | |j	S )Nr7   ZintList[])rT   	json_typelookup_typer8   r   element_typerV   appendr   rc   	_use_typerh   )r#   rb   Ztype_intZtype_intlistr$   r$   r%   ro      s$    



z(QAPISchemaGenIntrospectVisitor._use_type)featuresr/   c                 C   s   dd | D S )Nc                 S   s   g | ]}t |j|jqS r$   r   rc   r    ).0fr$   r$   r%   
<listcomp>       z@QAPISchemaGenIntrospectVisitor._gen_features.<locals>.<listcomp>r$   )rp   r$   r$   r%   _gen_features   s    z,QAPISchemaGenIntrospectVisitor._gen_featuresr$   )rc   mtyper,   r    rp   r/   c                 C   sl   d}|dvr2| j s(d| | d| }| |}||d< ||d< |rT| ||d< | jt||| dS )a  
        Build and append a SchemaInfo object to self._trees.

        :param name: The SchemaInfo's name.
        :param mtype: The SchemaInfo's meta-type.
        :param obj: Additional SchemaInfo members, as appropriate for
                    the meta-type.
        :param ifcond: Conditionals to apply to the SchemaInfo.
        :param features: The SchemaInfo's features.
                         Will be omitted from the output if empty.
        N)commandeventbuiltinarrayrL   z" = rc   z	meta-typerp   )rS   rh   rv   rU   rn   r   )r#   rc   rw   r,   r    rp   r!   r$   r$   r%   	_gen_tree   s    
z(QAPISchemaGenIntrospectVisitor._gen_tree)memberr/   c                 C   s,   d|j i}|jr | |j|d< t||jS )Nrc   rp   )rc   rp   rv   r   r    r#   r}   r,   r$   r$   r%   _gen_enum_member  s
    z/QAPISchemaGenIntrospectVisitor._gen_enum_memberc                 C   sD   |j | |jd}|jr"d |d< |jr8| |j|d< t||jS )N)rc   rG   defaultrp   )rc   ro   rG   optionalrp   rv   r   r    r~   r$   r$   r%   _gen_object_member$  s    
z1QAPISchemaGenIntrospectVisitor._gen_object_member)variantr/   c                 C   s    |j | |jd}t||jS )N)caserG   )rc   ro   rG   r   r    )r#   r   r,   r$   r$   r%   _gen_variant0  s    
z+QAPISchemaGenIntrospectVisitor._gen_variant)rc   infork   r/   c                 C   s   |  |dd|i d S )Nrz   z	json-typer|   )r#   rc   r   rk   r$   r$   r%   visit_builtin_type8  s    z1QAPISchemaGenIntrospectVisitor.visit_builtin_type)rc   r   r    rp   membersrP   r/   c                    s4     |d fdd|D dd |D d|| d S )Nenumc                    s   g | ]}  |qS r$   )r   rr   mr#   r$   r%   rt   C  ru   zBQAPISchemaGenIntrospectVisitor.visit_enum_type.<locals>.<listcomp>c                 S   s   g | ]}t |j|jqS r$   rq   r   r$   r$   r%   rt   D  ru   )r   valuesr   )r#   rc   r   r    rp   r   rP   r$   r   r%   visit_enum_type<  s    z.QAPISchemaGenIntrospectVisitor.visit_enum_type)rc   r   r    rm   r/   c                 C   s*   |  |}| d| d dd|i| d S )Nri   rj   r{   zelement-type)ro   r|   )r#   rc   r   r    rm   elementr$   r$   r%   visit_array_typeH  s    
z/QAPISchemaGenIntrospectVisitor.visit_array_type)rc   r   r    rp   r   branchesr/   c                    sT   d fdd|D i}|r>|j j|d<  fdd|jD |d<  |d||| d S )Nr   c                    s   g | ]}  |qS r$   )r   r   r   r$   r%   rt   U  ru   zIQAPISchemaGenIntrospectVisitor.visit_object_type_flat.<locals>.<listcomp>tagc                    s   g | ]}  |qS r$   )r   )rr   vr   r$   r%   rt   Y  ru   variantsobject)
tag_memberrc   r   r|   )r#   rc   r   r    rp   r   r   r,   r$   r   r%   visit_object_type_flatO  s    z5QAPISchemaGenIntrospectVisitor.visit_object_type_flat)rc   r   r    rp   alternativesr/   c                    s*     |dd fdd|jD i|| d S )N	alternater   c                    s$   g | ]}t d  |ji|jqS )rG   )r   ro   rG   r    r   r   r$   r%   rt   b  s   zGQAPISchemaGenIntrospectVisitor.visit_alternate_type.<locals>.<listcomp>)r|   r   )r#   rc   r   r    rp   r   r$   r   r%   visit_alternate_type\  s    z3QAPISchemaGenIntrospectVisitor.visit_alternate_type)rc   r   r    rp   arg_typeret_typegensuccess_responseboxed	allow_ooballow_preconfig	coroutiner/   c                 C   s^   | j d usJ |p| j j}|p$| j j}| || |d}|
rH|
|d< | |d||| d S )N)arg-typezret-typez	allow-oobrx   )rT   the_empty_object_typero   r|   )r#   rc   r   r    rp   r   r   r   r   r   r   r   r   r,   r$   r$   r%   visit_commandh  s    z,QAPISchemaGenIntrospectVisitor.visit_command)rc   r   r    rp   r   r   r/   c                 C   s:   | j d usJ |p| j j}| |dd| |i|| d S )Nry   r   )rT   r   r|   ro   )r#   rc   r   r    rp   r   r   r$   r$   r%   visit_event{  s
    z*QAPISchemaGenIntrospectVisitor.visit_event).r'   r(   r)   r+   r>   r&   r   r]   rd   r   rf   rh   r   ro   staticmethodr   r   r   r   rv   r   r   r   r|   r   SchemaInfoEnumMemberr   r   SchemaInfoObjectMemberr   r   SchemaInfoObjectVariantr   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r$   r$   rZ   r%   rO      s~   
	rO   )r\   
output_dirrP   
opt_unmaskr/   c                 C   s"   t ||}| | || d S r"   )rO   r_   write)r\   r   rP   r   visr$   r$   r%   gen_introspect  s    

r   )r   F)4r*   typingr   r   r   r   r   r   r   r	   commonr   r   r   r   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   sourcer   Z_Stubr+   r>   Z_ScalarZ
_NonScalarZ_ValueZ	JSONValuer   Z
SchemaInfor   ZSchemaInfoObjectr   r   ZSchemaInfoCommandr   r   r7   r;   r=   rO   r   r$   r$   r$   r%   <module>   s<   (<  G \