U
    Zf6                     @   s  d Z ddlmZmZmZmZ ddlZddlZddlZddl	Z	ddl
Z
ddlZddlZddlZddlZddlmZ ddlmZmZ ddlmZ ddlmZ d	ZerddlZddlZeed
ZdZdZej edZ!e!j"ddddd dd#e Z$e!j"dej%e$d e!j"dej%dd e!j"ddej%dd e!j"dddd e!j"d d!ej%d"d e!j"d#d$ej%d%d e!j"d&d'd(eg d)d* e!& Z'e'j"d+d,d(eg d-d* e'j"d.d/d(eg d0d* d1d2 Z(e)d3kre( Z*dS )4z(
A command-line interface for StoneAPI.
    )absolute_importdivisionprint_functionunicode_literalsN   )parse_route_attr_filter)BackendExceptionCompiler)InvalidSpec)specs_to_irFargparse)Zobj_c_clientZobj_c_typesZobj_c_testsZ	js_clientZjs_typesZ
tsd_clientZ	tsd_typesZpython_typesZpython_type_stubsZpython_clientZswift_typesZswift_clienta*  Write your APIs in Stone. Use backends to translate your specification into a target language or format. The following describes arguments to the Stone CLI. To specify arguments that are specific to a backend, add "--" followed by arguments. For example, "stone python_client . example.spec -- -h".)descriptionz-vz	--verbosecountzPrint debugging statements.)actionhelpzEither the name of a built-in backend or the path to a backend module. Paths to backend modules must end with a .stoneg.py extension. The following backends are built-in: z, backend)typer   outputz&The folder to save generated files to.spec*zPath to API specifications. Each must have a .stone extension. If omitted or set to "-", the spec is read from stdin. Multiple namespaces can be provided over stdin by concatenating multiple specs together.)nargsr   r   z--clean-build
store_truez5The path to the template SDK for the target language.z-fz--filter-by-route-attra  Removes routes that do not match the expression. The expression must specify a route attribute on the left-hand side and a value on the right-hand side. Use quotes for strings and bytes. The only supported operators are "=" and "!=". For example, if "hide" is a route attribute, we can use this filter: "hide!=true". You can combine multiple expressions with "and"/"or" and use parentheses to enforce precedence.z-rz--route-whitelist-filtera+  Restrict datatype generation to only the routes specified in the whitelist and their dependencies. Input should be a file containing a JSON dict with the following form: {"route_whitelist": {}, "datatype_whitelist": {}} where each object maps namespaces to lists of routes or datatypes to whitelist.z-az--attributeappendzRoute attributes that the backend will have access to and presumably expose in generated code. Use ":all" to select all attributes defined in stone_cfg.Route. Note that you can filter (-f) by attributes that are not listed here.)r   r   defaultr   z-wz--whitelist-namespace-routeszIIf set, backends will only see the specified namespaces as having routes.z-bz--blacklist-namespace-routeszFIf set, backends will not see any routes for the specified namespaces.c               
   C   s  dt jkr<t jdt jd } t jt jdd d }nt jdd } g }t| }d}|jdkrntj}n@|jdkrtj}n.|jdkrtj	}d}nt
dt jd t d tj|d	 |jrB|jd
 drB|jd
 drBztd|jd
 j}W n> tk
r< } zt
d|t jd t d W 5 d}~X Y nX n|jrg }d}|jD ]}	|	dkrld}n|	dst
d|	 t jd t d nVtj|	st
d|	 t jd t d n*t|	dd}
||	|
 f W 5 Q R X qX|r|rt
dt jd t d |jr"|rg }|r4t
d tjr^td}|t jt _t j }nt jj }t!j"|dd }|#d}t$|dkr|d|d
 f nP|dd|%d
|%d
f f |r|dt$|d  d|%d
 f q|j&rFt'|j&|\}}|rJt
dt jd |D ]}t
|t jd q$t d nd}|j(r|t|j(dd}
t)*|
 }W 5 Q R X nd}zt+|||d}W nf t,k
r } zFt
d|j|j-|j.f t jd |rt
d t/0 t jd t d W 5 d}~X Y nX |dkrt
d!t jd t d |j1r|j1D ].}||j2kr*t
d"| t jd t d q*|j23 D ]&}|j4|j1krdg |_5i |_6i |_7qd|j8r|j8D ]L}||j2krt
d#| t jd t d n|j2| }g |_5i |_6i |_7q|rP|j23 D ]V}g }|j5D ]}|9|r|| qg |_5i |_6i |_7|D ]}|:| q:q|j;rt<|j;}d$|krd%d& |j=j>D }nt< }|j23 D ]<}|j5D ].}t?|j@A D ]}||kr|j@|= qqq|j=j>dd D ]:}|j4|kr
|j=j>B| |j=jC|j4= n|B|j4 q|rD|% }t
d'| t jd t d |jDtEkrftFd(|jD d)gd*}ntj|jDst
d+|jD t jd t d ntjG|jDst
d,|jD t jd t d ntHI|jDst
d-|jD t jd t d nftjJ|jD}|t jkrt j| ztd.|jD}W n, tKk
rX   t
d/|jD t jd  Y nX tH||||jL|jMd0}z|N  W nL tOk
r } z,t
d1|jD|jP|j/f t jd t d W 5 d}~X Y nX t jd
 d2s|S dS )3z The entry point for the program.z--r   NF   Tz+error: I can only be so garrulous, try -vv.)file)levelr   +z.pyapiz/error: Could not import API description due to:-z.stonez7error: Specification '%s' must have a .stone extension.z*error: Specification '%s' cannot be found.zutf-8)encodingzCerror: Do not specify stdin and specification files simultaneously.z!Reading specification from stdin.utf8	namespacezstdin.1z%snamespace%szstdin.%sznamespace%szError(s) in route filter:)debugroute_whitelist_filterz%s:%s: error: %sz>A traceback is included below in case this is a bug in Stone.
zAYou must fix the above parsing errors for generation to continue.z2error: Whitelisted namespace missing from spec: %sz2error: Blacklisted namespace missing from spec: %sz:allc                 S   s   h | ]
}|j qS  )name).0fieldr%   r%   -/tmp/pip-unpacked-wheel-vqb3mfeu/stone/cli.py	<setcomp>/  s     zmain.<locals>.<setcomp>z3error: Attribute not defined in stone_cfg.Route: %szstone.backends.%s )fromlistz$error: Backend '%s' cannot be found.z#error: Backend '%s' must be a file.z5error: Backend '%s' must have a .stoneg.py extension.Zuser_backendz9error: Importing backend '%s' module raised an exception:)clean_buildz%%s: error: %s raised an exception:
%sZstone)Qsysargvindex_cmdline_parser
parse_argsverboseloggingWARNINGINFODEBUGprintstderrexitbasicConfigr   
startswithendswithimpZload_sourcer   ImportErrorospathexistsopenr   readsixPY2codecs	getreaderstdinbufferioTextIOWrappersplitlenpopZfilter_by_route_attrr   r$   jsonloadsr   r
   linenomsg	traceback
format_excZwhitelist_namespace_routes
namespacesvaluesr&   ZroutesZroute_by_nameZroutes_by_nameZblacklist_namespace_routesevalZ	add_route	attributesetZroute_schemafieldslistattrskeysremoveZ_fields_by_namer   _builtin_backends
__import__isfiler	   Zis_stone_backenddirname	Exceptionr   r-   buildr   backend_name)Zcli_argsZbackend_argsargsr#   Zlogging_levelr   especsZread_from_stdinZ	spec_pathfZ
UTF8ReaderZ
stdin_textZstdin_bufferpartsZroute_filterZroute_filter_errorserrr$   Znamespace_namer"   Zfiltered_routesZrouter]   kr(   attrZbackend_moduleZnew_python_pathcr%   r%   r)   main   s   





,  

 



 
 












 

rp   __main__)+__doc__
__future__r   r   r   r   rG   r>   rK   rP   r4   r@   rE   r.   rT   Zcli_helpersr   compilerr   r	   Zfrontend.exceptionr
   Zfrontend.frontendr   Z_MYPYtyping	importlibimport_modulestrr   r`   Z_cmdline_descriptionArgumentParserr1   add_argumentjoinZ_backend_help	text_typeadd_mutually_exclusive_groupZ_filter_ns_grouprp   __name__r   r%   r%   r%   r)   <module>   s   		
 h
