U
    Zfe                     @   sb  d dl mZmZmZmZ d dlZd dlmZmZm	Z	m
Z
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mZmZmZmZ d dlmZm Z m!Z!m"Z"m#Z# dZ$e$rd dl%Z%d dl&Z&e&'e(dZ)e)j*dd	d
Z+e+j,ddde(dd e+j,ddde(dd e+j,ddde(dd e+j,dde(dd e+j,ddde(dd e+j,ddde(dd G d d! d!e!Z-dS )"    )absolute_importdivisionprint_functionunicode_literalsN)is_nullable_typeis_struct_typeis_union_typeis_void_typeunwrap_nullable)fmt_alloc_callfmt_camel_upper	fmt_classfmt_class_prefixfmt_funcfmt_func_argsfmt_func_args_declarationfmt_func_call
fmt_importfmt_property_strfmt_route_obj_classfmt_route_funcfmt_route_varfmt_routes_classfmt_signaturefmt_typefmt_var)base_file_commentcomment_prefixObjCBaseBackendstone_warningundocumentedFargparsezobjc-client-backendzGenerates a ObjC class with an object for each namespace, and in each namespace object, a method for each route. This class assumes that the obj_c_types backend was used with the same output directory.)progdescriptionz-mz--module-nameTzSThe name of the ObjC module to generate. Please exclude the {.h,.m} file extension.)requiredtypehelpz-cz--class-namez}The name of the ObjC class that contains an object for each namespace, and in each namespace object, a method for each route.z-tz--transport-client-namez:The name of the ObjC class that manages network API calls.z-wz--auth-typez(The auth type of the client to generate.)r%   r&   z-yz--client-argszFThe client-side route arguments to append to each route by style type.z-zz--style-to-requestz>The dict that maps a style type to a ObjC request object name.c                   @   s   e Zd ZdZeZi Zi 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dZd!ddZdd ZdS )"ObjCBackendz<Generates ObjC client base that implements route interfaces.c              
   C   s  |j  D ]8}d| j|< |jr
|jD ]}| |r$d| j|<  q
q$q
|j  D ]"}| D ]}t|| j|j< qZqN|j  D ]D}|jr|| j| r|t	|j| j
jt|jd| j
jddg}| dt	|j| j
j: | t || | |g  }| | | | W 5 Q R X | dt	|j| j
j | t | d |   | td	 |   d
g}|| | j|ddd }| | | d| j
j |   | | W 5 Q R X q|| d| j
j | | W 5 Q R X | d| j
j | | W 5 Q R X d S )NFT
{}ProtocolZDBStoneBaseDBRequestErrorszRoutes/{}.mzRoutes/{}.h!#import <Foundation/Foundation.h>DBTasksZDBNilObject)Zinclude_route_argsZinclude_route_deep_args@protocol {};zClient/{}.mzClient/{}.h)
namespacesvaluesnamespace_to_has_routesroutes_should_generate_routeZlinearize_data_typesr   obj_name_to_namespacenamer   args	auth_typer   formattransport_client_nameZoutput_to_relative_pathemit_rawr   Z_get_imports_mZ_get_namespace_route_imports_generate_imports_m_generate_routes_mr   emitr   Z_get_imports_hZ_generate_imports_h_generate_routes_hmodule_name_generate_client_m_generate_client_h)selfapi	namespaceroute	data_typeimport_classesZimports_classes_mZimport_classes_h rF   ?/tmp/pip-unpacked-wheel-vqb3mfeu/stone/backends/obj_c_client.pygeneratef   s    




 



zObjCBackend.generatec                    s    t  jjg}| fdd|j D 7 }|d jj  	|  
 jj tdd jjfg} jd|ddv  d	   X  d
 |j D ]<}|jr j| rd} |t|jt|j jj qW 5 Q R X W 5 Q R X W 5 Q R X dS )zGenerates client base implementation file. For each namespace, the client will
        have an object field that encapsulates each route in the particular namespace.c                    s,   g | ]$}|j r j| rt|j jjqS rF   r0   r/   r   r3   r4   r5   .0nsr@   rF   rG   
<listcomp>   s    
z2ObjCBackend._generate_client_m.<locals>.<listcomp>r(   clientid<{}>initWithTransportClientinstancetypefuncr4   return_typeself = [super init];z_transportClient = client;z%_{}Routes = [[{} alloc] init:client];N)r8   r   r4   r=   r-   r.   appendr6   r7   r9   block_m
class_namer   
block_funcr;   
block_initr0   r/   r   r3   r   r5   )r@   rA   rE   client_argsrB   Zbase_stringrF   rM   rG   r>      sD    





zObjCBackend._generate_client_mc           
   	      s    t  d  fdd|j D }|d |d  |     d     d jj	     t
 d} j|t
d	  t
  j jjd
d jj	fgd    |j D ]r}|jr܈ j| rdt|j} j|t
d	 dt|j}dt|j jj} t||d    qtdd jj	fg}d} j| jjt
d	 td|dd}	 d|	    W 5 Q R X     d dS )zGenerates client base header file. For each namespace, the client will
        have an object field that encapsulates each route in the particular namespace.r*   c                    s,   g | ]$}|j r j| rt|j jjqS rF   rI   rJ   rM   rF   rG   rN      s    
z2ObjCBackend._generate_client_h.<locals>.<listcomp>r)   r+   NS_ASSUME_NONNULL_BEGINr,   zBase client object that contains an instance field for each namespace, each of which contains references to all routes within that namespace. Fully-implemented API clients will inherit this class.prefixZtransportClientrP   )Z	protectedz!Routes within the `{}` namespace.z{}Routes{} *proptyprO   z5Initializes the `{}` object with a networking client.rQ   rR   rS   {};NS_ASSUME_NONNULL_ENDN)r8   r   r;   r-   r.   rW   r9   r6   r4   r7   r   emit_wrapped_textblock_hrY   r0   r/   r   r3   r   r5   r   r   r   )
r@   rA   rE   description_strrB   Z	class_docrb   rc   r\   init_signaturerF   rM   rG   r?      st    









zObjCBackend._generate_client_hc                 C   s.   |j ddD ]}| |kr dS qdS )Nauth,TF)attrsgetsplitstrip)r@   rC   Zdesired_auth_typer5   rF   rF   rG   _auth_type_in_route  s    zObjCBackend._auth_type_in_routec                 C   s   |  |do| jjdkS )NZnoauthuser)rp   r4   r5   r@   rC   rF   rF   rG   _route_is_special_noauth_case  s    z)ObjCBackend._route_is_special_noauth_casec                 C   s   |  || jjp| |S )N)rp   r4   r5   rs   rr   rF   rF   rG   r1     s    z"ObjCBackend._should_generate_routec                 C   s  |  t|j| jj tdd| jjfg}| jd|dd. | 	d | 
  | 	d W 5 Q R X W 5 Q R X | 	  t| jj}|jD ]B}| |sq|jd}t| jj}|| krl|| D ]}t|\}}	|| }
|	d	 }d
d |	d D }t|jrD| |jrD| ||\}}| |||||
| | ||\}}| |||||
| qq|| }
t|jr| |jr| ||\}}| |||g |
d | ||\}}| |||g |
d qW 5 Q R X dS )zoGenerates implementation file for namespace object that has as methods
        all routes within the namespace.rO   rP   initrR   rS   rV   z_client = client;styler   c                 S   s   g | ]}t |d d qS NtuplerK   Z	type_datarF   rF   rG   rN   :  s   z2ObjCBackend._generate_routes_m.<locals>.<listcomp>    N)rX   r   r3   r4   r5   r   r6   r7   rZ   r;   r[   jsonloadsstyle_to_requestr0   r1   rl   rm   r\   keysry   r   arg_data_type_struct_has_defaults_get_default_route_args_generate_route_m_get_route_args)r@   rB   Z	init_argsr   rC   
route_typer\   	args_datatask_type_keytype_data_dicttask_type_namefunc_suffix
extra_args
route_args_rF   rF   rG   r:     s       



   
 
 
   zObjCBackend._generate_routes_mc              	   C   s^  t |}ddt|jsdndfg}|D ]&\}	}
}||	|f ||	|
f q&| jdt||t|d|d | dt	|j
t|j
| t|jr| dt|jt|jj
 nRt|jsttt|jd	| |td
d |D d}| dt|j| tddt|jdt|d}| d| W 5 Q R X |   dS )z:Generates route method implementation for the given route.)rC   rC   argnil{}{}r`   rS   zDBRoute *route = {}.{};z{} *arg = {};)callerc                 S   s   g | ]}|d  |d  fqS )r   rF   rK   frF   rF   rG   rN   v  s     z1ObjCBackend._generate_route_m.<locals>.<listcomp>)r   Zcalleer4   zself.clientz	request{}ru   z
return {};N)listr	   r   rW   rZ   r6   r   r   r;   r   r3   r   r   r   r   r   r   Z_cstor_name_from_fields_namesr   r   rl   rm   )r@   rC   rB   r   r   r   r   Z	user_argsZtransport_argsr3   valuerc   Z	init_callZrequest_callrF   rF   rG   r   X  sT    


 zObjCBackend._generate_route_mc                 C   s  |  t | jdt|jtd |  t |    |  d |    | t|j| jj	2 d}| j|td |  t
dd| jjd |    tdd| jjfg}td|d	d
}d}| j|t|j| jj	td |  d| |    t| jj}|jD ]|}| |s$q|jd}t| jj}|| kr|| D ]}	t|	\}
}||
 }|d }dd |d D }dd |d D }t|jr| |jr| j||dd\}}| |||||| || | j||dd\}}| |||||| || qTnv|| }t|jr`| |jr`| j||dd\}}| |||g ||d | j||dd\}}| |||g ||d qW 5 Q R X |    |  d |    dS )zgGenerates header file for namespace object that has as methods
        all routes within the namespace.zRoutes for the `{}` namespacer^   r]   zRAn instance of the networking client that each route will use to submit a request.rO   rP   ra   rt   rR   rS   zIInitializes the `{}` namespace container object with a networking client.rd   ru   r   c                 S   s   g | ]}t |d d qS rv   rx   rz   rF   rF   rG   rN     s   z2ObjCBackend._generate_routes_h.<locals>.<listcomp>r{   c                 S   s   g | ]}|d  |d fqS )r   rw   rF   rz   rF   rF   rG   rN     s   Ttagr|   re   N)r;   r   rf   r6   r   r3   rg   r   r4   r5   r   r7   r   r   r}   r~   r   r0   r1   rl   rm   r\   r   ry   r   r   r   r   _generate_route_signaturer   )r@   rB   rh   Zroutes_obj_argsri   r   rC   r   r\   r   r   r   r   r   r   Z
extra_docsr   doc_listrF   rF   rG   r<     s    



  
      
     

  
       
   
zObjCBackend._generate_routes_hc                 C   s  |D ]\}}	}
| ||
f q|jr(dnd}dt||}| t |jr^| |j| j}n
d|}| j	|| tdd | t |D ](\}}| j	d||r|nt
tdd q| t d}|t|jd	d
dt|jd	d
d}| j	|tdd | t t|jst|jnd}t|js0t|jnd}d|||}| |}t|t|d|d}| d|| |   dS )z5Generates route method signature for the given route.zDEPRECATED: r|   r   zThe {} routex   )r_   widthz@param {} {}zt@return Through the response callback, the caller will receive a `{}` object on success or a `{}` object on failure.FT)r   Zno_ptrzDBNilObject *z{}<{}, {}> *z{}rS   z{}{};N)rW   
deprecatedr6   r   r;   r   docprocess_doc_docfrf   r    r   Zresult_data_typeZerror_data_typer	   _get_deprecation_warningr   r   )r@   rC   rB   r   r   r   r   r   r3   r   rc   r   	func_nameZ	route_docr   outputZresult_type_strZerror_type_strrU   Zroute_signaturerF   rF   rG   r     sd    


  



z%ObjCBackend._generate_route_signaturec                 C   sF   d}|j rBdt|}|j jr8|dt|j jj7 }d|}|S )z<Returns a deprecation tag / message, if route is deprecated.r|   z{} is deprecated.z Use {}.z __deprecated_msg("{}"))r   r6   r   Zbyr   r3   )r@   rC   resultmsgrF   rF   rG   r     s    
z$ObjCBackend._get_deprecation_warningFc           	   	      s   t |j\}}t|r^g }|jD ]&}|t|jt|j||j	df q  fdd|j
D }n^t|rt|jt|j|dfg}t|j|jr |j jndt|jfg}ng }g }||fS )zfReturns a list of name / value string pairs representing the arguments for
        a particular route.)r   has_defaultc                    s,   g | ]$}|j rt|j |j  jfqS rF   )r   r   r3   r   r   r   rM   rF   rG   rN   1  s    z/ObjCBackend._get_route_args.<locals>.<listcomp>r   zThe {} union)r
   r   r   
all_fieldsrW   r   r3   r   rD   r   fieldsr   r   r   r   r6   r   	r@   rB   rC   r   rD   r   arg_listfieldr   rF   rM   rG   r   '  s:    
  

 

zObjCBackend._get_route_argsc           	         sz   t |j\}}t|rjg }|jD ]2}|js t|js |t|j	t
|j|df q  fdd|jD }ng }g }||fS )znReturns a list of name / value string pairs representing the default arguments for
        a particular route.r   c                    s<   g | ]4}|j r|jst|jst|j |j  jfqS rF   )r   r   r   rD   r   r3   r   r   r   rM   rF   rG   rN   S  s
    
z7ObjCBackend._get_default_route_args.<locals>.<listcomp>)r
   r   r   r   r   r   rD   rW   r   r3   r   r   r   rF   rM   rG   r   C  s"    
 
z#ObjCBackend._get_default_route_argsc                 C   sh   |dkrd t|S |dkrTd|krJ|d\}}d t|| j| S t|S n|dkr`|S |S d S )NrC   z`{}`r   .z`{}` in `{}`)r%   vallink)r6   r   rn   r   r2   )r@   r   r   Zcls_namer   rF   rF   rG   r   ]  s     
zObjCBackend._docfN)F)F)__name__
__module____qualname____doc___cmdline_parserZcmdline_parserr2   r/   rH   r>   r?   rp   rs   r1   r:   r   r<   r   r   r   r   r   rF   rF   rF   rG   r'   _   s&   C$C;)c9

  
r'   ).
__future__r   r   r   r   r}   Zstone.irr   r   r   r	   r
   Zstone.backends.obj_c_helpersr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zstone.backends.obj_cr   r   r   r   r    Z_MYPYtyping	importlibimport_modulestrr!   ArgumentParserr   add_argumentr'   rF   rF   rF   rG   <module>   sn   L