
    2hB                    ~   d dl Z d dlZd dlZd dlZd Z e             d dlmZ d dlmZ d dlmZ dddd	d
dddddddZd Z	d Z
d Zd Zd ZddddddddddddZd Z G d d ej                  Z G d! d"e          Z G d# d$e          Z G d% d&e          Z G d' d(e          Z G d) d*e          Z G d+ d,e          Z G d- d.ej                  Z G d/ d0e          Z G d1 d2e          Z G d3 d4e          Z G d5 d6e          Z G d7 d8e          Z G d9 d:e          Z G d; d<e          Z G d= d>e          Z  G d? d@e          Z!e"dAk    rd dlmZ dBZ#dCZ$dDZ% ej&        e#          Z'e'(                    dEdFdGdH)                    e#I          J           e'(                    dKe$dLdMN           e'(                    dOdPdQdRS           e'(                    dTdUdQdVS           e'(                    dWdXdQdYS           e'*                                Z+e+j,        se+j-        e+_,         ej.        e+          Z/ ej0        e+e#          Z1 e            Z2e23                    e/           e2j4        r<dZ Z5 ej6        e+d[e+j7        z             Z8 ej9        e+j,        e8e5e1d\d]g^           e8gZ:ng Z:e+j;        re:d_gz  Z:d` Z< ej6        e+e+j7                  Z= ej9        e+j,        e=e<e1d\g dae:b           dc Z>g Z?e+j;        re?g ddz  Z? ej6        e+e%          Z@ ej9        e+j-        e@e>e1dee?e=gb           dS dS )f    Nc                     t           j                            t          j        t          j                                        } t           j                            | d          }t           j                            t           j                            t           j        	                    |                              }|t          j        vr"t          j                            d|           d S d S )Nz..r   )ospathdirnameinspectgetfilecurrentframejoinnormpathabspathrealpathsysinsert)currentpath
searchpaths     u/home/metal/girl-os-victor/victor-clad/victorEmitters/../../victor-clad/tools/message-buffers/emitters/CPP_emitter.py_modify_pathr      s    '//'/'2F2H2H"I"IJJKk400J!!"'//"'2B2B:2N2N"O"OPPJ!!:&&&&& "!    )ast)clad)emitterutilboolint8_tint16_tint32_tint64_tuint8_tuint16_tuint32_tuint64_tfloatdouble)r   int_8int_16int_32int_64uint_8uint_16uint_32uint_64float_32float_64c                    t          | t          j                  rG| j        t          vr't          d                    | j                            t          | j                 S t          | t          j                  rdS t          | t          j                  st          | t          j	                  r$t          | j
        t          j                  sMt          | j
        t          j                  st          | j
        t          j	                  rt          d          t          | t          j                  r(d                    t          | j
                            S t          | j        t                    r.d                    t          | j
                  | j                  S d                    t          | j
                  | j                  S |                                 S )	N;Error: {0} was expected to be a primitive type, but is not.zstd::string*Error: Arrays of arrays are not supported.zstd::vector<{member_type}>member_typez8std::array<{member_type}, static_cast<size_t>({length})>r1   lengthz#std::array<{member_type}, {length}>)
isinstancer   BuiltinTypename_type_translations
ValueErrorformatPascalStringTypeVariableArrayTypeFixedArrayTyper1   cpp_value_typer3   strfully_qualified_nametypes    r   r=   r=   3   s   $(( +y...Zaabfbkllmmm!$),,	D#.	/	/ +}	D#/	0	0 +JtSEW4X4X +4+S-ABB 	(D,c.CDD	(4+S-?@@	( IJJJc344 	(/66*4+;<< 7 > > > $+s++ (RYY .t/? @ @; Z ( ( ( =CC .t/? @ @; D ( ( ( ((***r   c                 *   t          | t          j                  rG| j        t          vr't          d                    | j                            t          | j                 S t          | t          j                  rdS t          | t          j                  st          | t          j	                  rt          | j
        t          j                  sMt          | j
        t          j                  st          | j
        t          j	                  rt          d          t          | t          j                  r(d                    t          | j
                            S d                    t          | j
                  | j                  S | j        S )Nr.   basic_stringr/   zvector<{member_type}>r0   zarray<{member_type}, {length}>r2   )r4   r   r5   r6   r7   r8   r9   r:   r;   r<   r1   r=   r3   r@   s    r   cpp_value_type_destructorrD   N   sj   $(( y...Zaabfbkllmmm!$),,	D#.	/	/ ~	D#/	0	0 JtSEW4X4X 4+S-ABB 
	$D,c.CDD
	$4+S-?@@
	$ IJJJc344 	$*11*4+;<< 2 > > > 4::*4+;<<{ ; $ $ $ yr   c                 j    t          | t          j                  pt          | t          j                  S N)r4   r   r5   DefinedTyper@   s    r   is_trivial_typerH   d   s%    dCO,,Q
40Q0QQr   c                      t          |           S rF   )rH   r@   s    r   is_pass_by_valuerJ   g   s    4   r   c                     t          |           rt          |           S d                    t          |                     S )Nzconst {value_type}&)
value_type)rJ   r=   r9   r@   s    r   cpp_parameter_typerM   j   s@     Md###$++~d7K7K+LLLr   zasBool()zasInt()z	asInt64()zasUInt()z
asUInt64()z	asFloat()z
asDouble()c                     t          | t          j                  rG| j        t          vr't          d                    | j                            t          | j                 S t          | t          j                  rdS d S )Nr.   z
asString())r4   r   r5   r6   _jsoncpp_as_method_translationsr8   r9   r:   r@   s    r   jsoncpp_as_methodrP   ~   sq    $(( y;;;Zaabfbkllmmm.ty99	D#.	/	/ |tr   c                   .    e Zd ZdZej        dfdZd ZdS )BaseEmitterzBase class for emitters.Nc                 "    || _         || _        d S rF   )outputoptions)selfrT   rU   s      r   __init__zBaseEmitter.__init__   s    r   c                     d S rF    rV   nodeargskwargss       r   visit_IncludeDeclzBaseEmitter.visit_IncludeDecl       r   )__name__
__module____qualname____doc__r   stdoutrW   r^   rY   r   r   rR   rR      sD        !j$    
    r   rR   c                   8    e Zd Zd Zd Zd Zd Zd Zd Zd Z	dS )	HNamespaceEmitterc                 <   d}|                                 D ]f\  }}|r4t          |t          j                  s| j                            d            | j        |g|R i | t          |t          j                  }g|r| j                            d           d S d S )NF
)childrenr4   r   IncludeDeclrT   writevisit)rV   r[   r\   r]   last_was_includec_namecs          r   visit_DeclListz HNamespaceEmitter.visit_DeclList   s      	> 	>IFA (
1co(F(F (!!$'''DJq*4***6***)!S_== 	$Kd#####	$ 	$r   c                     t          j        |j        | j        j                  }| j                            d                    |                     d S )Nz#include "{0}"
)r   get_included_filer6   rU   header_output_extensionrT   rk   r9   )rV   r[   r\   r]   new_header_file_names        r   r^   z#HNamespaceEmitter.visit_IncludeDecl   sH    *<TYHlmm,334HIIJJJJJr   c                     | j                             d                    |j                              | j        |g|R i | | j                             d                    |j                             d S Nznamespace {namespace_name} {{

)namespace_namez"}} // namespace {namespace_name}

)rT   rk   r9   r6   generic_visitrZ   s       r   visit_NamespaceDeclz%HNamespaceEmitter.visit_NamespaceDecl   s    =DDTXT]D^^___41$111&111@GGW[W`Gaabbbbbr   c                 X     t          | j        | j                  j        |g|R i | d S rF   )HEnumEmitterrT   rU   rl   rZ   s       r   visit_EnumDeclz HNamespaceEmitter.visit_EnumDecl   s9    5T[$,//5dLTLLLVLLLLLr   c                 X     t          | j        | j                  j        |g|R i | d S rF   )HStructEmitterrT   rU   rl   rZ   s       r   visit_MessageDeclz#HNamespaceEmitter.visit_MessageDecl   9    7t{DL117NtNNNvNNNNNr   c                 X     t          | j        | j                  j        |g|R i | d S rF   )HUnionEmitterrT   rU   rl   rZ   s       r   visit_UnionDeclz!HNamespaceEmitter.visit_UnionDecl   s9    6dk4<006tMdMMMfMMMMMr   c                 X     t          | j        | j                  j        |g|R i | d S rF   )HEnumConceptEmitterrT   rU   rl   rV   r[   r\   kargss       r   visit_EnumConceptDeclz'HNamespaceEmitter.visit_EnumConceptDecl   s:    <DK66<TRDRRRERRRRRr   N)
r`   ra   rb   rp   r^   ry   r|   r   r   r   rY   r   r   rf   rf      s        $ $ $K K Kc c c
M M MO O ON N NS S S S Sr   rf   c                   ,    e Zd Zd Zd Zd Zd Zd ZdS )CPPNamespaceEmitterc                     d S rF   rY   rZ   s       r   r^   z%CPPNamespaceEmitter.visit_IncludeDecl   r_   r   c                 X     t          | j        | j                  j        |g|R i | d S rF   )CPPEnumEmitterrT   rU   rl   rZ   s       r   r|   z"CPPNamespaceEmitter.visit_EnumDecl   r   r   c                 X     t          | j        | j                  j        |g|R i | d S rF   )CPPStructEmitterrT   rU   rl   rZ   s       r   r   z%CPPNamespaceEmitter.visit_MessageDecl   s:    9dl339$PPPPPPPPPr   c                 X     t          | j        | j                  j        |g|R i | d S rF   )CPPUnionEmitterrT   rU   rl   rZ   s       r   r   z#CPPNamespaceEmitter.visit_UnionDecl   s9    8T\228OOOOOOOOOr   c                 X     t          | j        | j                  j        |g|R i | d S rF   )CPPEnumConceptEmitterrT   rU   rl   r   s       r   r   z)CPPNamespaceEmitter.visit_EnumConceptDecl   s:    >dk4<88>tTdTTTeTTTTTr   N)r`   ra   rb   r^   r|   r   r   r   rY   r   r   r   r      sm          O O OQ Q QP P PU U U U Ur   r   c                   2    e Zd Zd Zd Zd Zd Zd Zd ZdS )r{   c                 d   t          |j        |j        t          |j                                                  d          }|                     ||           |                     ||           |                     ||           | 	                    ||           | 
                    ||           d S Nr   )	enum_name	enum_hashenum_storage_typeenum_member_count)dictr6   hash_strr=   storage_typebuiltin_type
emitPrefix
emitHeaderemitMembers
emitFooter
emitSuffixrV   r[   globalss      r   r|   zHEnumEmitter.visit_EnumDecl   s    im,T->-K-K-M-MNN	
 
 
 	g&&&g&&&w'''g&&&g&&&&&r   c                 z    | j         j        r.| j                            t	          j        d                     d S d S )Nz            #ifndef CLAD_CPP_WARN_UNUSED_RESULT
            #define CLAD_CPP_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
            #endif

            )rU   emitJSONrT   rk   textwrapdedentr   s      r   r   zHEnumEmitter.emitPrefix   sP    <  	Kho /       	 	r   c                     |j         r9| j                             t          j        d          j        di |           d S | j                             t          j        d          j        di |           d S )Nzt                // ENUM {enum_name}
                enum class {enum_name} : {enum_storage_type} {{
                zn                // ENUM {enum_name}
                enum {enum_name} : {enum_storage_type} {{
                rY   )	cpp_classrT   rk   r   r   r9   r   s      r   r   zHEnumEmitter.emitHeader   s    N 		)K ho /   ' ' &' ' ( ( ( ( (
 K ho /   ' ' &' ' ( ( ( ( (r   c                 :    | j                             d           d S )N};

rT   rk   r   s      r   r   zHEnumEmitter.emitFooter   s    (#####r   c                    d|d<   | j                             d          5  |                                rg }|                                D ]o}d                    |j                  }d                    t          |j                            }d}|dxx         dz  cc<   |                    |||f           p| j                             |           d d d            d S # 1 swxY w Y   d S )	Nr   r      {member_name}member_name = {initializer},initializer )	rT   indentmembersr9   r6   r>   valueappendwrite_with_aligned_whitespace)rV   r[   r   piecesmemberstartmiddleends           r   r   zHEnumEmitter.emitMembers   sT   '(#$["" 	B 	B||~~ 
B"llnn 8 8F+22v{2KKE077CDUDU7VVFC/000A5000MM5&#"6777799&AAA	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	B 	Bs   B5C""C&)C&c                    | j                              dj        d
i |           | j                              dj        d
i |           | j        j        re| j                             d           | j                              dj        d
i |           | j                              dj        d
i |           n| j                             d           | j                              dj        d
i |           | j                              dj        d
i |           | j                              d	j        d
i |           d S )Nz/const char* EnumToString(const {enum_name} m);
z[inline const char* {enum_name}ToString(const {enum_name} m) {{ return EnumToString(m); }}

zmtemplate<typename T>
CLAD_CPP_WARN_UNUSED_RESULT bool EnumFromString(const std::string& str, T& enumOutput);
zjCLAD_CPP_WARN_UNUSED_RESULT bool {enum_name}FromString(const std::string& str, {enum_name}& enumOutput);

z8{enum_name} {enum_name}FromString(const std::string&);

rh   z.extern const char* {enum_name}VersionHashStr;
z2extern const uint8_t {enum_name}VersionHash[16];

zLconstexpr {enum_storage_type} {enum_name}NumEntries = {enum_member_count};

rY   )rT   rk   r9   rU   r   r   s      r   r   zHEnumEmitter.emitSuffix   s   SLS^^V]^^___  Ay  A  L  L  DK  L  L  	M  	M  	M<  	$K  P  Q  Q  QK  T  M  T  _  _  W^  _  _  `  `  `KaZalldkllmmmmKd###RKR]]U\]]^^^WPWbbZabbcccqjq||t{||}}}}}r   N)	r`   ra   rb   r|   r   r   r   r   r   rY   r   r   r{   r{      sv        ' ' '  
) 
) 
)$ $ $B B B~ ~ ~ ~ ~r   r{   c                   2    e Zd Zd Zd Zd Zd Zd Zd ZdS )r   c                 |   t          |j        |j        t          |j                                                  d          }|                     ||           |                     ||           |                     ||           | j	        j
        r|                     ||           |                     ||           d S r   )r   r6   r   r=   r   r   emitToStringHeaderemitToStringMembersemitToStringFooterrU   r   emitStringToEnumr   r   s      r   r|   zCPPEnumEmitter.visit_EnumDecl  s    im,T->-K-K-M-MNN	
 
 
 	g...  w///g...<  	1!!$000g&&&&&r   c                 t    | j                              t          j        d          j        di |           d S )Nzo            const char* EnumToString(const {enum_name} m)
            {{
            	switch(m) {{
            rY   rT   rk   r   r   r9   r   s      r   r   z!CPPEnumEmitter.emitToStringHeader  \     (/ +   	# # "	# # 	$ 	$ 	$ 	$ 	$r   c                 ^    | j                             t          j        d                     d S )Nzn            		default: return nullptr;
            	}
            	return nullptr;
            }

            rT   rk   r   r   r   s      r   r   z!CPPEnumEmitter.emitToStringFooter#  s9    (/ +   	 	 	 	 	r   c           	      P   d|d<   | j                             d          5  |                                D ]W}|dxx         dz  cc<   |j        s>| j                              t          j        d          j        dd|j        i|           X	 d d d            d S # 1 swxY w Y   d S )Nr   r      r   z                        case {enum_name}::{member_name}:
                        	return "{member_name}";
                        r   rY   )	rT   r   r   is_duplicaterk   r   r   r9   r6   rV   r[   r   r   s       r   r   z"CPPEnumEmitter.emitToStringMembers,  sJ   '(#$["" 	I 	I,,.. I I+,,,1,,,* IK%% '$ho 7 ' ' $'H 'H 17'H @G'H 'H I I II	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	I 	Is   A-BB"Bc           
         | j                              t          j        d          j        ddt          |                                          i|           | j                             d          5  | j                              dj        di |           |                                D ].}| j                              dj        dd|j        i|           /| j                             d           | j                              t          j        d          j        di |           d d d            n# 1 swxY w Y   | j                             d	           | j                              t          j        d
          j        di |           | j                              t          j        d          j        di |           | j                             d          5  | j                              t          j        d          j        dd|                                d         j        i|           d d d            n# 1 swxY w Y   | j                             d	           d S )Nz            template<>
            bool EnumFromString(const std::string& str, {enum_name}& enumOutput)
            {{
            
num_valuesr   zOstatic const std::unordered_map<std::string, {enum_name}> stringToEnumMap = {{
z2	{{"{member_name}", {enum_name}::{member_name}}},
r   r   z                auto it = stringToEnumMap.find(str);
                if(it == stringToEnumMap.end()) {{
                  return false;
                }}

                enumOutput = it->second;
                return true;
            }

z        bool {enum_name}FromString(const std::string& str, {enum_name}& enumOutput)
        {{
          return EnumFromString(str, enumOutput);
        }}

        zU        {enum_name} {enum_name}FromString(const std::string& str)
        {{
        a              {enum_name} returnVal;
            if( !EnumFromString(str, returnVal) ) {{
              #ifndef NDEBUG
              std::cerr << "error: string '" << str << "' is not a valid {enum_name} value" << std::endl;
              #endif // NDEBUG
              assert(false && "string must be a valid {enum_name} value");
              return {enum_name}::{first_val};
            }}
            else {{
              return returnVal;
            }}
            	first_valr   rY   )	rT   rk   r   r   r9   lenr   r   r6   r   s       r   r   zCPPEnumEmitter.emitStringToEnum7  s    (/ +   	C C $'t||~~#6#6	C ;B	C C 	D 	D 	D ["" 	$ 	$Kwpw  C  C  {B  C  C  D  D  D,,.. E E!!"_"X"_  #D  #Dlrlw  #D  |C  #D  #D  E  E  E  EKh'''K ho /   # # "# # $ $ $	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$  	'""" (/ +       	  	  	  	 (/ +       	  	  	 
 ["" 	F 	FK ho /   E E #',,.."3"8E =DE E F F F	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	F 	'"""""s&   3B:D99D= D=&AI		IIc           	      >   | j                              dj        di |           | j                              dj        di |           t          j        |d                   }| j                             d          5  t          |          D ][\  }}d}|t          |          dz
  k    rd}| j                             d                    t          |          |	                     \	 d d d            n# 1 swxY w Y   | j                             d
           d S )Nz8const char* {enum_name}VersionHashStr = "{enum_hash}";

z/const uint8_t {enum_name}VersionHash[16] = {{ 
r   r   ,r   r   {hex_byte}{separator} hex_byte	separator
};

rY   	rT   rk   r9   r   decode_hex_stringr   	enumerater   hexrV   r[   r   hex_dataibyter   s          r   r   zCPPEnumEmitter.emitSuffixo  s   ]V]hh`ghhiiiSLS^^V]^^___01EFF["" 	X 	X$X.. X X4	X*++ "I!!":"A"A3t99LU #B #W #W X X X X	X	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	*%%%%%s   ?A,C88C<?C<N)	r`   ra   rb   r|   r   r   r   r   r   rY   r   r   r   r     sr        ' ' '$ $ $  	I 	I 	I5# 5# 5#p& & & & &r   r   c                   Z    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd ZdS )r~   r   c                    t          |j        |j        |                                                                          }|                     ||           | j                            | j                  5  | 	                    ||           | 
                    ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                                dk    r"| j        j        r|                     ||           |                                dk    r=| j        j        r1|j        r*t)          j        |          r|                     ||           d d d            n# 1 swxY w Y   |                     ||           d S )N)message_namemessage_hashobject_type	structure)r   r6   r   r   upperr   rT   r   body_indentr   emitConstructorsemitPack
emitUnpackemitSizeemitEquality
emitInvokerU   emitPropertiesr   default_constructorr   (_do_all_members_have_default_constructoremitJSONSerializerr   r   s      r   r   z HStructEmitter.visit_MessageDecl  s   ((**0022
 
 
 	g&&&[ 011 	; 	;T7+++!!$000MM$(((OOD'***MM$(((dG,,,OOD'***!![00T\5P0##D'222!![00\* ;-; I$OO; ++D':::!	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	; 	;$ 	g&&&&&s   6D*F,,F03F0c                 t    | j                              t          j        d          j        di |           d S )Nzi            // {object_type} {message_name}
            struct {message_name}
            {{
            rY   r   r   s      r   r   zHStructEmitter.emitHeader  r   r   c                     | j                             d           | j                              dj        di |           | j                              dj        di |           d S )Nr   z1extern const char* {message_name}VersionHashStr;
z5extern const uint8_t {message_name}VersionHash[16];

rY   rT   rk   r9   r   s      r   r   zHStructEmitter.emitFooter  sv    (###UNU``X_``aaaZSZee]deefffffr   c                    |                                 D ]}| j                            d                    t	          |j                  |j                             |j        rT|j        }|j        }|j        dk    rt          |          nt          |          }| j                            d|z             | j                            d           | j                            d           d S )N{member_type} {member_name}r1   r   r   z = %sz;
rh   )r   rT   rk   r9   r=   rA   r6   initr   r   r>   )rV   r[   r   r   initial_value
member_val
member_strs          r   r   zHStructEmitter.emitMembers  s    llnn 		% 		%FK;BB*6;77"K C ) ) * * * { 8 &*0
0=0Be0K0KS___QTU_Q`Q`
!!'J"6777Ke$$$$$r   c                     d                     d |                                D                       }| j                            t	          j        d                    |                               d S )Nz, c                     g | ]	}|j         
S rY   )r6   ).0ms     r   
<listcomp>z-HStructEmitter.emitInvoke.<locals>.<listcomp>  s    >>>!qv>>>r   z
            template <typename Callable>
            void Invoke(Callable&& func) const {{
               func({0});
            }}
            )r
   r   rT   rk   r   r   r9   )rV   r[   r   	paramsStrs       r   r   zHStructEmitter.emitInvoke  sp    II>>t||~~>>>??	(/ +
 y!!# # 	$ 	$ 	$ 	$ 	$r   c           	         | j                             t          j        d                     t	          j        |          }|j        r9|r7| j                             t          j         dj        di |                     | j                             t          j         dj        di |                     |                                r| j                              dj        di |           | j         	                    d          5  t          |                                          D ]\  }}| j                             d                    t          |j                  |j                             |t          |                                          dz
  k     r| j                             d           | j                             d	           	 d d d            n# 1 swxY w Y   t          |                                          D ]\  }}|d
k    r| j                             d           n| j                             d           | j                             d                    |j                             | j                             d           | j                             d           | j                             t          j         dj        di |                     d S )Nz1            /**** Constructors ****/
            z<                {message_name}() = default;
                ak              {message_name}(const {message_name}& other) = default;
            {message_name}({message_name}& other) = default;
            {message_name}({message_name}&& other) noexcept = default;
            {message_name}& operator=(const {message_name}& other) = default;
            {message_name}& operator=({message_name}&& other) = default;

            zexplicit {message_name}(r   r   r   z,
z)
r   :r   z {member_name}({member_name})r   rh   z{}

z            explicit {message_name}(const uint8_t* buff, size_t len);
            explicit {message_name}(const CLAD::SafeMessageBuffer& buffer);

            rY   )rT   rk   r   r   r   r   r   r9   r   r   r   rM   rA   r6   r   )rV   r[   r   $all_members_have_default_constructorr   r   s         r   r   zHStructEmitter.emitConstructors  sq   (/ +   	 	 	 0;/cdh/i/i,# 	((L 	(Kho / //& /&$/& /& ' ' ( ( ( 	(/ + + +" +" !+" +" # # 	$ 	$ 	$ <<>> 	(K?8?JJ'JJKKK ##A&& 1 1!*4<<>>!:!: 1 1IAvK%%&C&J&J$6v{$C$C$*K 'K '1 '1 2 2 2 3t||~~..222))%0000))%000011 1 1 1 1 1 1 1 1 1 1 1 1 1 1 't||~~66 ( (	666K%%c****K%%c***!!"A"H"HU[U`"H"a"abbb!!$''''Kh'''(/ + + 	+" +" !	+" +" # # 	$ 	$ 	$ 	$ 	$s   CG$$G(+G(c                 ^    | j                             t          j        d                     d S )Nz            /**** Pack ****/
            size_t Pack(uint8_t* buff, size_t len) const;
            size_t Pack(CLAD::SafeMessageBuffer& buffer) const;

            r   r   s      r   r   zHStructEmitter.emitPack  9    (/ +   	 	 	 	 	r   c                 ^    | j                             t          j        d                     d S )Nz            /**** Unpack ****/
            size_t Unpack(const uint8_t* buff, const size_t len);
            size_t Unpack(const CLAD::SafeMessageBuffer& buffer);

            r   r   s      r   r   zHStructEmitter.emitUnpack  r  r   c                 :    | j                             d           d S Nzsize_t Size() const;

r   r   s      r   r   zHStructEmitter.emitSize      455555r   c                 t    | j                              t          j        d          j        di |           d S )Nz            bool operator==(const {message_name}& other) const;
            bool operator!=(const {message_name}& other) const;
            rY   r   r   s      r   r   zHStructEmitter.emitEquality  \     (/ +   # # "# # 	$ 	$ 	$ 	$ 	$r   c                    d }| j                             t          j        d                     |                                D ]}t          |j        t          j                  }|rt          |j                  ndt          |j                  z   dz   }| j                             t          j        d
                    ||j         ||j                                                 d S )Nc                     |                      d          } t          |           D ]N\  }}|                                r5| d |         | |                                         z   | |dz   d          z   c S O| S )N_r   )lstripr   isalpha
capitalize)r>   r   ro   s      r   prettifyNamez3HStructEmitter.emitProperties.<locals>.prettifyName  s    **S//C!# E E199;; Err7SV%6%6%8%883qstt9DDDDEJr   z(
        /**** Properties ****/
        zconst &z                {member_type} Get{pretty_name}() const {{ return {member_name}; }};
                void Set{pretty_name}({member_type} __value) {{ {member_name} = __value; }};

                )r1   r   pretty_name)rT   rk   r   r   r   r4   rA   r   r5   r=   r9   r6   )rV   r[   r   r  r   is_basic_typer1   s          r   r   zHStructEmitter.emitProperties  s   	 	 	 	(/ +   	 	 	 llnn 	= 	=F&v{CODDM9Fx.555HWeflfqWrWrLruxLxKKho / F + & ,V[ 9 9  ; ;	< < = = = =		= 	=r   c                 ^    | j                             t          j        d                     d S Nz            /**** JSON ****/
            Json::Value GetJSON() const;
            bool SetFromJSON(const Json::Value& json);

            r   r   s      r   r   z!HStructEmitter.emitJSONSerializer$  r  r   N)r`   ra   rb   r   r   r   r   r   r   r   r   r   r   r   r   r   rY   r   r   r~   r~   |  s        K' ' ':$ $ $g g g
     $ $ $1$ 1$ 1$f    6 6 6$ $ $= = =0    r   r~   c                   Z    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd ZdS )r   r   c                 P    | j                              dj        di |           d S )Nz!// {object_type} {message_name}

rY   r   r   s      r   r   zCPPStructEmitter.emitHeader2  s3    F?FQQQQRRRRRr   c           	      r   | j                             d           | j                              dj        di |           | j                              dj        di |           t          j        |d                   }| j                             d          5  t          |          D ][\  }}d}|t          |          dz
  k    rd}| j                             d	                    t          |          |
                     \	 d d d            n# 1 swxY w Y   | j                             d           d S )Nrh   z>const char* {message_name}VersionHashStr = "{message_hash}";

z2const uint8_t {message_name}VersionHash[16] = {{ 
r   r   r   r   r   r   r   r   rY   r   r   s          r   r   zCPPStructEmitter.emitFooter5  s   $c\cnnfmnnoooVOVaaY`aabbb01HII["" 	X 	X$X.. X X4	X*++ "I!!":"A"A3t99LU #B #W #W X X X X	X	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	*%%%%%   A,DDDc                     d S rF   rY   r   s      r   r   zCPPStructEmitter.emitMembersD  r_   r   c                    d}|                                 D ]}|j        d         j        }d|v r3|d|d         j        z   |                     |d                   z   dz   z  }Kt	          |j        t          j                  r|dz  }pt	          |j        t          j                  st	          |j        t          j	                  r|dz  }|dz  }|d d	         }|d
z  }|S )N(rA   	type_decl r   z "",z {},z 0,))
r   __dict__r6   (_CPPStructEmitter__init_explicit_membersr4   rA   r   r:   r;   r<   )rV   r[   arg_listr   member_dicts        r   __init_explicit_membersz(CPPStructEmitter.__init_explicit_membersI  s    llnn 
	& 
	&F /&1:Kk))C+k":"??$B^B^_jkv_wBxBxx{~~~fk3+?@@ &&HHS-BCC &zRXR]_b_qGrGr &&HH%HHCRC=Cr   c           	         t          j        |          }d}|s|                                D ]x}|j        d         j        }d|v r`|                     |d                   }|dk    r |d                    |j        |          z  }Y|d                    |j        |          z  }y| j                            t          j
         dj        d	d|i|                     d S )
Nr   rA   r&  z: {member_name}{arg_list})r   r,  z, {member_name}{arg_list}a              {message_name}::{message_name}(const CLAD::SafeMessageBuffer& buffer)
            {explicit_constructors}
            {{
            	Unpack(buffer);
            }}
          
            {message_name}::{message_name}(const uint8_t* buff, size_t len)
            : {message_name}::{message_name}({{const_cast<uint8_t*>(buff), len, false}})
            {{
            }}
            
            explicit_constructorsrY   )r   r   r   r*  r+  r9   r6   rT   rk   r   r   )rV   r[   r   r
  explicit_membersr   r-  r,  s           r   r   z!CPPStructEmitter.emitConstructorsZ  sV   /:/cdh/i/i,3 	` ,,.. 	` 	`$of5>+--#;;K<TUUH'2--(,G,N,N]c]hZb -O -d -d d(( ),G,N,N]c]hV^ -O -` -` `( 	(/ + + +L +L 0@+L DK+L +L M M 	N 	N 	N 	N 	Nr   c                     d S rF   rY   r   s      r   r   zCPPStructEmitter.emitInvoke|  r_   r   c           	         | j                             t          j         dj        di |                     | j                             d          5  t          | j         | j                  }|                                D ]#}|	                    |j
        |j                   $	 d d d            n# 1 swxY w Y   | j                             t          j        d                     d S )Na3              size_t {message_name}::Pack(uint8_t* buff, size_t len) const
            {{
            	CLAD::SafeMessageBuffer buffer(buff, len, false);
            	return Pack(buffer);
            }}

            size_t {message_name}::Pack(CLAD::SafeMessageBuffer& buffer) const
            {{
            r   r   z            	const size_t bytesWritten {buffer.GetBytesWritten()};
            	return bytesWritten;
            }

            rY   )rT   rk   r   r   r9   r   CPPPackStatementEmitterrU   r   rl   rA   r6   rV   r[   r   visitorr   s        r   r   zCPPStructEmitter.emitPack  sX   (/ 	+ 	+ 	+" 	+" !	+" 	+" 	# 	# 		$ 		$ 		$ ["" 	D 	D-dk4<HHG,,.. D Dfkv{CCCCD	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	(/ +   	 	 	 	 	   AB22B69B6c                    | j                              t          j        d          j        di |           | j                             d          5  t          | j         | j                  }|                                D ]#}|	                    |j
        |j                   $	 d d d            n# 1 swxY w Y   | j                             t          j        d                     d S )Na[              size_t {message_name}::Unpack(const uint8_t* buff, const size_t len)
            {{
            	const CLAD::SafeMessageBuffer buffer(const_cast<uint8_t*>(buff), len, false);
            	return Unpack(buffer);
            }}

            size_t {message_name}::Unpack(const CLAD::SafeMessageBuffer& buffer)
            {{
            r   r   zF            	return buffer.GetBytesRead();
            }

            rY   )rT   rk   r   r   r9   r   CPPUnpackStatementEmitterrU   r   rl   rA   r6   r5  s        r   r   zCPPStructEmitter.emitUnpack  sX    	(/ 	+ 	 	 	# 	# "	# 	# 		$ 		$ 		$ ["" 	D 	D/T\JJG,,.. D Dfkv{CCCCD	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	(/ +   	 	 	 	 	r7  c                 <   | j                              t          j        d          j        di |           | j                             d          5  t          | j         | j                  }|                                D ]V}| j                             d                    |j	                             |
                    |j        |j	                   W	 d d d            n# 1 swxY w Y   | j                             t          j        d                     d S )Nzk            size_t {message_name}::Size() const
            {{
            	size_t result = 0;
            r   z// {member_name}
r   7            	return result;
            }

            rY   )rT   rk   r   r   r9   r   CPPSizeStatementEmitterrU   r   r6   rl   rA   r5  s        r   r   zCPPStructEmitter.emitSize  s    (/ +   	# # "	# # 	$ 	$ 	$
 ["" 	D 	D-dk4<HHG,,.. D D!!"6"="=&+"="V"VWWWfkv{CCCCD	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D
 	(/ +   	 	 	 	 	s   BC%%C),C)c           	      h   | j                             t          j         dj        di |                     |                                r| j                             d          5  | j                             d           | j                             d          5  t          |                                          D ]X\  }}|dk    r| j                             d           | j                             d                    |j                             Y	 d d d            n# 1 swxY w Y   | j                             d           d d d            n# 1 swxY w Y   n| j                             d	           | j                             t          j         d
j        di |                     d S )Nzj            bool {message_name}::operator==(const {message_name}& other) const
            {{
            r   zreturn (r   z &&
z*this->{member_name} == other.{member_name}r   z);
return true;
z            }}

            bool {message_name}::operator!=(const {message_name}& other) const
            {{
            	return !(operator==(other));
            }}

            rY   )	rT   rk   r   r   r9   r   r   r   r6   )rV   r[   r   r   r   s        r   r   zCPPStructEmitter.emitEquality  sf   (/ + + +" +" !+" +" # # 	$ 	$ 	$ <<>> 
	0##A&& * *!!*---[''** x x%.t||~~%>%> x x	6q55 K--g666))*V*]*]jpju*]*v*vwwwwxx x x x x x x x x x x x x x x
 !!&)))* * * * * * * * * * * * * * * K.///(/ + + +" +" !+" +" # # 	$ 	$ 	$ 	$ 	$s7   '5EA;D$E$D(	(E+D(	,EEEc                     d S rF   rY   r   s      r   r   zCPPStructEmitter.emitProperties  r_   r   c                 P   | j                              t          j        d          j        d%i |           | j                             t          j        d                     d }|                                D ]}t          |j        t          j	        t          j
        f          r
t          |j        t          j                  s| j                             d          5  t          |j        j        t          j                  r|j        j        j        dk    rd}d}nd}d	}| j                             t          j        d
                              |j                            d          |j         |d|j        j                  ||                     d d d            n# 1 swxY w Y   9| j                             d                    |j                            d          |j         ||j        |j                                       | j                             t          j        d                     | j                              t          j        d          j        d%i |           | j                             d          5  |                                D ]}|j                            d          }| j                             d                    |                     | j                             d          5  t#          |j                  I| j                             d                    ||j        t#          |j                                       nt          |j        t          j	        t          j
        f          rq| j                             d                    |                     t          |j        t          j	                  r3| j                             d                    |j                             | j                             d           | j                             d          5  t#          |j        j                  M| j                             d                    |j        t#          |j        j                                       n#t          |j        j        t          j                  r| j                             d          5  | j                             t          j        d                              |j        j        j        |j                             d d d            n# 1 swxY w Y   nw| j                             d          5  | j                             t          j        d                              |j                             d d d            n# 1 swxY w Y   d d d            n# 1 swxY w Y   | j                             d           nt          |j        t          j                  r| j                             d          5  | j                             t          j        d                               |j        j        ||j        !                     d d d            n# 1 swxY w Y   nx| j                             d          5  | j                             t          j        d"                              ||j        #                     d d d            n# 1 swxY w Y   d d d            n# 1 swxY w Y   | j                             d           	 d d d            n# 1 swxY w Y   | j                              t          j        d$          j        d%i |           d S )&NzD            Json::Value {message_name}::GetJSON() const
            z.        {
        	Json::Value root;

        c                     t          |t          j                  rd                    |           S t          |t          j                  rd                    |           S | S )NzEnumToString({member_name})r   z{member_name}.GetJSON())r4   r   rG   r9   CompoundType)r   r1   s     r   toJsonValuez8CPPStructEmitter.emitJSONSerializer.<locals>.toJsonValue  s_    +s77 #4;;;TTTK)9:: #077K7PPP""r   r   r   autoz(bool)zconst auto&r   z                        for({range_type} value : {member_name}) {{
                          root["{json_name}"].append({cast_prefix}{json_value});
                        }}
                        r  r   )	json_namer   
json_value
range_typecast_prefixz%	root["{json_name}"] = {json_value};
)rE  r   rF  z)
        	return root;
        }
        zx
            bool {message_name}::SetFromJSON(const Json::Value& root)
            {{
              try {{

            z&	if (root.isMember("{json_name}")) {{
)rE  z2	{member_name} = root["{json_name}"].{as_method};
)rE  r   	as_methodz)	auto& json_array = root["{json_name}"];
z*	{member_name}.resize(json_array.size());
r   z;	for(Json::ArrayIndex i = 0; i < json_array.size(); i++) {
z/	{member_name}[i] = json_array[i].{as_method};
)r   rI  z                                    if (!{enum_name}FromString(json_array[i].asString(), {member_name}[i])) {{
                                      return false;
                                    }}
                                    )r   r   z                                    if (!{member_name}[i].SetFromJSON(json_array[i])) {{
                                      return false;
                                    }}
                                    	}
z                            if (!{enum_name}FromString(root["{json_name}"].asString(), {member_name})) {{
                              return false;
                            }}
                            )r   rE  r   z                            if (!{member_name}.SetFromJSON(root["{json_name}"])) {{
                              return false;
                            }}
                            )rE  r   z
              }}
              catch(Json::LogicError) {{
                return false;
              }}

              return true;
            }}
            rY   )rT   rk   r   r   r9   r   r4   rA   r   r;   r<   r:   r   r1   r5   r6   r  rP   rG   )rV   r[   r   rC  r   rG  rH  rE  s           r   r   z#CPPStructEmitter.emitJSONSerializer  ss
    (/ +  # #!# # 	$ 	$ 	$ 	(/ +   	 	 		# 	# 	# llnn 	B 	BF&+(=s?Q'RSS B\fgmgrtw  uI  ]J  ]J B[''** > > "&+"93?KK )PVP[PgPlpvPvPv%+
&.%2
&(K%%ho 7 ' ' $Vfk.@.@.E.E06/:{7FKD[/\/\/90;	 $ = =	> > >> > > > > > > > > > > > > > >* !!"K"R"R]c]h]o]ops]t]t  CI  CN  [f  [f  gm  gr  tz  t  [@  [@"R  #A  #A  B  B  B  B(/ +   	 	 	
 	 (/ +  
 # #
 "# # 	$ 	$ 	$ ["" 2	+ 2	+,,.. 0+ 0+"K..s33	!!"L"S"S^g"S"h"hiii[''** +W +W(55A))*`*g*gr{  JP  JU  ar  sy  s~  a  a*g  +@  +@  A  A  A  A#FK#2GI[1\]] (W))*W*^*^ir*^*s*sttt%fk33HII ~ K--.\.c.cpvp{.c.|.|}}}))*ijjj![//22 J J01HIIU $ 1 12e2l2ly  zE  Qb  ci  cn  cz  Q{  Q{2l  3|  3|  !}  !}  !}  !}!+FK,CS_!U!U J%)[%7%7%:%: !r !r$(K$5$5ho G( 7) 7) *0&+:Q:Vdjdo)p)p	%r %r %r!r !r !r !r !r !r !r !r !r !r !r !r !r !r !r &*[%7%7%:%: !J !J$(K$5$5ho G( 7) 7) *0FK)H)H	%J %J %J!J !J !J !J !J !J !J !J !J !J !J !J !J !J !JJ J J J J J J J J J J J J J J$ ))'2222#FKAA W![//22 s s K--ho ?  /! /! "(&+2Biekep!q!q	s s ss s s s s s s s s s s s s s s "[//22 W W K--ho ?  /! /! "()!U!U	W W WW W W W W W W W W W W W W W WM+W +W +W +W +W +W +W +W +W +W +W +W +W +W +WX !!'****a0+2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+ 2	+h 	 (/ +   # # "# # 	$ 	$ 	$ 	$ 	$s  #B8F''F+	.F+	A:]$D>\0B%W"	1AUW"	UW"	UW"	9AW?W"	WW"	WW"	\0"W&&\0)W&*A\0AZ 	\0 Z$$\0'Z$(\0A\	\0\\0 \!\0$]$0\44]$7\48]$$](+](N)r`   ra   rb   r   r   r   r   r+  r   r   r   r   r   r   r   r   rY   r   r   r   r   .  s        KS S S& & &  
  " N  N  ND    ,  *  "$ $ $4  t$ t$ t$ t$ t$r   r   c                       e Zd ZdZd Zd ZdS )UnionDiscovererFc                     d S rF   rY   rV   r[   s     r   r^   z!UnionDiscoverer.visit_IncludeDeclR  r_   r   c                     d| _         d S )NT)foundrN  s     r   r   zUnionDiscoverer.visit_UnionDeclU  s    


r   N)r`   ra   rb   rP  r^   r   rY   r   r   rL  rL  N  s7        E      r   rL  c                   z    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd ZdS )r   c           
         t          |j        |j        d                    |j                  |                                d                    |                                          d|j                  }| j                             t          j	        d          j        di |           |
                                D ]_}t          d|j        t          |j                  d|}| j                             t          j	        d          j        di |           `|                     ||           | j                            d           | j                            d	          5  |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           |                     ||           | j        j        r*t9          j        |          r|                     ||           d d d            n# 1 swxY w Y   | j                            d
           | j                            d	          5  |                     ||           |                      ||           | !                    ||           d d d            n# 1 swxY w Y   | "                    ||           d S )N{union_name}Tag
union_nameUNIONrU  
union_hashtag_namequalified_union_namequalified_tag_namer   dupes_allowedz            // "Lookup Tables" for getting type by tag using template specializations
            template<{union_name}Tag tag>
            struct {union_name}_TagToType;

            )r   rL   z                template<>
                struct {union_name}_TagToType<{union_name}Tag::{member_name}> {{
                	using type = {value_type};
                }};
                zpublic:
r   z	private:
rY   )#r   r6   r   r9   r?   r\  rT   rk   r   r   r   r=   rA   r   r   emitUsingTagr   emitDestructor
emitGetTagemitTemplatedGetemitTemplatedCreateemitAccessorsr   r   r   r   rU   r   r   r   r   emitClearCurrentemitTagMemberemitUnionMembersr   rV   r[   r   r   localss        r   r   zHUnionEmitter.visit_UnionDeclZ  s   y}&---CC!%!:!:!<!<0774C\C\C^C^7__,. . . 	 (/ +  
 # #
 "# # 	$ 	$ 	$ llnn 	' 	'F "K)&+66   F
 K ho /  
 & &
 %& & ' ' ' ' 	g&&& 	+&&&["" 	7 	7dG,,,!!$000g...OOD'***!!$000$$T7333tW---OOD'***MM$(((MM$(((dG,,, |$ 7)]^b)c)c 7''g666!	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7 	7& 	,'''["" 	1 	1!!$000tW---!!$000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1
 	g&&&&&s&   ,D)J!!J%(J% AL//L36L3c                 t    | j                              t          j        d          j        di |           d S )Nze
            // {object_type} {union_name}
            class {union_name}
            {{
            rY   r   r   s      r   r   zHUnionEmitter.emitHeader  s\     (/ +  
 # #
 "# # 	$ 	$ 	$ 	$ 	$r   c                     | j                             d           | j                              dj        di |           | j                              dj        di |           d S )N};
z/extern const char* {union_name}VersionHashStr;
z3extern const uint8_t {union_name}VersionHash[16];

rY   r   r   s      r   r   zHUnionEmitter.emitFooter  sv    &!!!SLS^^V]^^___XQXcc[bccdddddr   c                 P    | j                              dj        di |           d S )Nzusing Tag = {tag_name};
rY   r   r   s      r   r]  zHUnionEmitter.emitUsingTag  s3    <5<GGwGGHHHHHr   c                     | j                              t          j        d          j        di |           | j                              t          j        d          j        di |           d S )Nae              /**** Constructors ****/
            {union_name}() :_tag(Tag::INVALID) {{ }}
            explicit {union_name}(const CLAD::SafeMessageBuffer& buff);
            explicit {union_name}(const uint8_t* buffer, size_t length);
            {union_name}(const {union_name}& other);
            {union_name}({union_name}&& other) noexcept;
            z            {union_name}& operator=(const {union_name}& other);
            {union_name}& operator=({union_name}&& other) noexcept;

            rY   r   r   s      r   r   zHUnionEmitter.emitConstructors  s     (/ +   # # "# # 	$ 	$ 	$ 	 (/ +   	# # "	# # 	$ 	$ 	$ 	$ 	$r   c                 P    | j                              dj        di |           d S )Nz&~{union_name}() {{ ClearCurrent(); }}
rY   r   r   s      r   r^  zHUnionEmitter.emitDestructor  s3    JCJUUWUUVVVVVr   c                 :    | j                             d           d S )Nz%Tag GetTag() const { return _tag; }

r   r   s      r   r_  zHUnionEmitter.emitGetTag  s    CDDDDDr   c                     | j                             d           | j                             d           | j                             d           | j                              dj        di |           d S )Nz.// Templated getter for union members by type
zX// NOTE: Always returns a reference, even for trivial types, unlike untemplated version
ztemplate<Tag tag>
zBconst typename {union_name}_TagToType<tag>::type & Get_() const;

rY   r   r   s      r   r`  zHUnionEmitter.emitTemplatedGet  sy    KLLLuvvv/000g`grrjqrrsssssr   c                     | j                             d           | j                             d           | j                              dj        di |           d S )NzI// Templated creator for making a union object out of one if its members
ztemplate <Tag tag>
zQstatic {union_name} Create_(typename {union_name}_TagToType<tag>::type member);

rY   r   r   s      r   ra  z!HUnionEmitter.emitTemplatedCreate  s    fggg0111vov  B  B  zA  B  B  	C  	C  	C  	C  	Cr   c           	         |                                 D ]j}t          d
|j        t          |j                  t          |j                  d|}| j                             dj        d
i |           | j                             dj        d
i |           | j	        r@| j	        j
        r4|d         r|j        s%| j                             dj        d
i |           | j                             dj        d
i |           | j                             dj        d
i |           t          |j                  s%| j                             dj        d
i |           | j                            d	           ld S )N)r   rL   parameter_typez/** {member_name} **/
zKstatic {union_name} Create{member_name}({value_type}&& new_{member_name});
r\  z9explicit {union_name}({value_type}&& new_{member_name});
z,{parameter_type} Get_{member_name}() const;
z<void Set_{member_name}({parameter_type} new_{member_name});
z:void Set_{member_name}({value_type}&& new_{member_name});
rh   rY   )r   r   r6   r=   rA   rM   rT   rk   r9   rU   helperConstructorshas_duplicatesrJ   rf  s        r   rb  zHUnionEmitter.emitAccessors  s   llnn 	$ 	$F "K)&+661&+>>  	 F K>7>HHHHIIIKsls}}v|}}~~~ | q ? qQ`Ia qioi~ q!!"e"^"e"o"ohn"o"opppKTMT^^W]^^___Kd]dnngmnnooo $FK00 r!!"f"_"f"p"pio"p"pqqqKd####+	$ 	$r   c                 n    | j                             d           | j                             d           d S )Nz.size_t Pack(uint8_t* buff, size_t len) const;
z5size_t Pack(CLAD::SafeMessageBuffer& buffer) const;

r   r   s      r   r   zHUnionEmitter.emitPack  s6    KLLLSTTTTTr   c                 n    | j                             d           | j                             d           d S )Nz6size_t Unpack(const uint8_t* buff, const size_t len);
z7size_t Unpack(const CLAD::SafeMessageBuffer& buffer);

r   r   s      r   r   zHUnionEmitter.emitUnpack  s6    STTTUVVVVVr   c                 :    | j                             d           d S r  r   r   s      r   r   zHUnionEmitter.emitSize  r  r   c                 t    | j                              t          j        d          j        di |           d S )Nz            bool operator==(const {union_name}& other) const;
            bool operator!=(const {union_name}& other) const;
            rY   r   r   s      r   r   zHUnionEmitter.emitEquality  r  r   c                 ^    | j                             t          j        d                     d S r  r   r   s      r   r   z HUnionEmitter.emitJSONSerializer  r  r   c                 :    | j                             d           d S )Nzvoid ClearCurrent();
r   r   s      r   rc  zHUnionEmitter.emitClearCurrent  s    233333r   c                 :    | j                             d           d S )NzTag _tag;

r   r   s      r   rd  zHUnionEmitter.emitTagMember  s    /*****r   c           	         | j                             d           | j                             d          5  |                                D ]H}| j                             d                    t          |j                  |j                             I	 d d d            n# 1 swxY w Y   | j                             d           d S )Nzunion {
r   z{member_type} _{member_name};
r   rj  )rT   rk   r   r   r9   r=   rA   r6   r   s       r   re  zHUnionEmitter.emitUnionMembers  s   +&&&["" 	. 	.,,.. . .!!"C"J"J .v{ ; ; & #K #- #- . . . ..	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.
 	&!!!!!s   AB  B$'B$N)r`   ra   rb   r   r   r   r]  r   r^  r_  r`  ra  rb  r   r   r   r   r   rc  rd  re  rY   r   r   r   r   X  s;       =' =' ='~$ $ $e e e
I I I$ $ $ W W WE E Et t tC C C
$ $ $0U U UW W W6 6 6$ $ $  4 4 4+ + +" " " " "r   r   c                        e Zd Zd Zd Zd ZdS )TagHUnionTagEmitterc                 L   t                      }|                    |           |j        ry| j                            d                    |j                              | j        |g|R i | | j                            d                    |j                             d S d S rv   )rL  rl   rP  rT   rk   r9   r6   rx   )rV   r[   r\   r]   
discoverers        r   ry   z'TagHUnionTagEmitter.visit_NamespaceDecl  s    $&&
 	gKAHHX\XaHbbcccDt5d555f555KDKK[_[dKeefffff	g 	gr   c           	         t          |j        d                    |j                  |                                d                    |                                          d          }|                                }|                     ||           | j                            t          j	         dj        di |                     d S )NrS  rT  rV  rU  rY  rZ  r[  r   zO            const char* {tag_name}ToString(const {tag_name} tag);

            rY   )
r   r6   r9   r?   r   emitTagsrT   rk   r   r   )rV   r[   r   r   s       r   r   z#TagHUnionTagEmitter.visit_UnionDecl  s    y&---CC!%!:!:!<!<0774C\C\C^C^7__! ! ! ,,..dG$$$(/ + + +" +" !+" +" # # 	$ 	$ 	$ 	$ 	$r   c                 r   | j                              dj        di |           | j                             d          5  g }|                                D ]}|j        rj|j        j        dk    rt          |j                  nt          |j                  }d                    |j
                  }d                    |          }nd                    |j
                  }d	}d
                    |j                  }|                    |||f            dj        di |}d                    |j                  }|                    ||f           | j                             |           d d d            n# 1 swxY w Y   | j                             t          j        d                     d S )Nz#enum class {tag_name} : uint8_t {{
r   r   r   r   r   r   z{member_name},r   z // {value})r   INVALIDz = {invalid_tag})invalid_tagz            };

            rY   )rT   rk   r9   r   r   r   rA   r   tagr>   r6   r   r  r   r   r   )	rV   r[   r   linesr   r   r   r   r   s	            r   r  zTagHUnionTagEmitter.emitTags#  s   G@GRR'RRSSS["" 	= 	=E,,.. 	3 	3;  5;[5E5N5N#fj///TWX^XbTcTcK+22v{2KKE077K7PPFF,333LLEF#***<<eVS12222$I$//w//E'..4;K.LLFLL%)))K55e<<<#	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	= 	=& 	(/ +   	 	 	 	 	s    D4F  FFN)r`   ra   rb   ry   r   r  rY   r   r   r~  r~  
  sD        g g g$ $ $    r   r~  c                       e Zd Zd ZdS )TagHHashEmitterc           	      H   t          |j        d                    |j                  |                                d                    |                                          d          }| j                             t          j        d          j        di |           d S )NrS  rT  rV  r  a*              template<>
            struct std::hash<{qualified_tag_name}>
            {{
            	size_t operator()({qualified_tag_name} t) const
            	{{
            		return static_cast<std::underlying_type<{qualified_tag_name}>::type>(t);
            	}}
            }};

            rY   )r   r6   r9   r?   rT   rk   r   r   r   s      r   r   zTagHHashEmitter.visit_UnionDeclA  s    y&---CC!%!:!:!<!<0774C\C\C^C^7__! ! ! 	 
(/ 
+ 
 
 
# 
# "
# 
# 
	$ 
	$ 
	$ 
	$ 
	$r   N)r`   ra   rb   r   rY   r   r   r  r  ?  s#        $ $ $ $ $r   r  c                   v    e Zd Zej        ddfdZd Zd Zd Zdd
Z	d Z
d Zd Zd Zd Zd Zd Zd Zd ZdS )r   Nr   c                 0    || _         || _        || _        d S rF   )rT   rU   prefix)rV   rT   rU   r  s       r   rW   zCPPUnionEmitter.__init__V  s    r   c           
         t          |j        |j        d                    |j                  |                                d                    |                                          d|j                  }|                     ||           |                     ||           |                     ||           | 	                    ||           | 
                    ||           |                     ||           |                     ||           | j        j        r*t          j        |          r|                     ||           |                     ||           |                     ||           |                     ||           d S )NrS  rT  rV  rW  )r   r6   r   r9   r?   r\  r   r   rb  r   r   r   r   rU   r   r   r   r   rc  emitTagToStringr   r   s      r   r   zCPPUnionEmitter.visit_UnionDecl[  s   y}&---CC!%!:!:!<!<0774C\C\C^C^7__,. . . 	g&&&dG,,,4)))g&&&dG$$$dG$$$$(((
 <  	3[%YZ^%_%_ 	3##D'222dG,,,T7+++g&&&&&r   c                 t    | j                              t          j        d          j        di |           d S )Nz7            // {object_type} {union_name}

            rY   r   r   s      r   r   zCPPUnionEmitter.emitHeaderz  r  r   c           	      r   | j                             d           | j                              dj        di |           | j                              dj        di |           t          j        |d                   }| j                             d          5  t          |          D ][\  }}d}|t          |          dz
  k    rd}| j                             d	                    t          |          |
                     \	 d d d            n# 1 swxY w Y   | j                             d           d S )Nrh   z:const char* {union_name}VersionHashStr = "{union_hash}";

z0const uint8_t {union_name}VersionHash[16] = {{ 
rX  r   r   r   r   r   r   r   rY   r   r   s          r   r   zCPPUnionEmitter.emitFooter  s   $_X_jjbijjkkkTMT__W^__```01FGG["" 	X 	X$X.. X X4	X*++ "I!!":"A"A3t99LU #B #W #W X X X X	X	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	X 	*%%%%%r"  TagGetTag()break;
c                 r   | j                             d                    |                     |                                D ]s}| j                             d                    |j        |                     | j                             d          5   ||           d d d            n# 1 swxY w Y   t| j                             d           | j                             d          5  | j                             |           d d d            n# 1 swxY w Y   | j                             d           d S )Nzswitch({argument}) {{
argumentz case {tag_type}::{member_name}:
)r   tag_typer   z	default:
}
)rT   rk   r9   r   r6   r   )rV   r[   r   callbackr  r  default_caser   s           r   
emitSwitchzCPPUnionEmitter.emitSwitch  s   3::H:MMNNNllnn 	! 	!FKAHHU[U`ksHttuuu##A&& ! !   ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 	,'''["" 	, 	,Kl+++	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	, 	%     s$   B++B/	2B/	+DDDc                      j                              t          j        d          j        di |            fd fd} j                              t          j        d          j        di |            j                             d          5                       ||d           d d d            n# 1 swxY w Y    j                             t          j        d                      j                              t          j        d	          j        di |            j                             d          5                       |||d           d d d            n# 1 swxY w Y    j                             t          j        d
                      j                              t          j        d          j        di |            j                             d          5                       ||d           d d d            n# 1 swxY w Y    j                             t          j        d                      j                              t          j        d          j        di |            j                             d          5                       |||d           d d d            n# 1 swxY w Y    j                             t          j        d                     d S )Na              {union_name}::{union_name}(const CLAD::SafeMessageBuffer& buff)
            : _tag(Tag::INVALID)
            {{
            	Unpack(buff);
            }}

            {union_name}::{union_name}(const uint8_t* buffer, size_t length)
            : _tag(Tag::INVALID)
            {{
            	CLAD::SafeMessageBuffer buff(const_cast<uint8_t*>(buffer), length);
            	Unpack(buff);
            }}

            c           	         t          | j                  raj                            d                    d                    | j                  | j        t          | j                                       nZj                            d                    d                    | j                  t          | j                                       j                            d           d S )Nz-this->{private_name} = other.{private_name};
_{member_name}r   )private_namer   r1   zBnew(&(this->{private_name})) {member_type}(other.{private_name});
r  r1   r  rH   rA   rT   rk   r9   r6   r=   r   rV   s    r   	copy_bodyz3CPPUnionEmitter.emitConstructors.<locals>.copy_body  s    v{++ >!!"R"Y"Y!1!8!8V[!8!Q!Q & .v{ ; ; #Z #= #= > > > >
 !!"g"n"n!1!8!8V[!8!Q!Q .v{ ; ; #o #= #= > > > Kj)))))r   c                 0   t          | j                  r |            nZj                            d                    d                    | j                  t          | j                                       j                            d           d S )NzMnew(&(this->{private_name})) {member_type}(std::move(other.{private_name}));
r  r   r  r  r  )r   r  rV   s    r   	move_bodyz3CPPUnionEmitter.emitConstructors.<locals>.move_body  s    v{++ >	&!!!!!!"r"y"y!1!8!8V[!8!Q!Q .v{ ; ; #z #= #= > > > Kj)))))r   z|            {union_name}::{union_name}(const {union_name}& other)
            : _tag(other._tag)
            {{
            r   z_tag = Tag::INVALID;
break;
r  z            }

            z            {union_name}::{union_name}({union_name}&& other) noexcept
            : _tag(other._tag)
            {{
            z>            	other.ClearCurrent();
            }

            z            {union_name}& {union_name}::operator=(const {union_name}& other)
            {{
            	if(this == &other) {{ return *this; }}
            	ClearCurrent();
            	_tag = other._tag;
            z6            	return *this;
            }

            z            {union_name}& {union_name}::operator=({union_name}&& other) noexcept
            {{
            	if(this == &other) {{ return *this; }}
            	ClearCurrent();
            	_tag = other._tag;
            zY            	other.ClearCurrent();
            	return *this;
            }

            rY   rT   rk   r   r   r9   r   r  )rV   r[   r   r  r  s   `   @r   r   z CPPUnionEmitter.emitConstructors  s    (/ +   # # "# # 	$ 	$ 	$ 
	* 
	* 
	* 
	* 
	*	* 	* 	* 	* 	* 	* 	 (/ +   	# # "	# # 	$ 	$ 	$
 ["" 	e 	eOOD'9CcOddd	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e(/ +   	 	 	 	 (/ +   	# # "	# # 	$ 	$ 	$
 ["" 	e 	eOOD'9CcOddd	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e(/ +   	 	 	 	 (/ +   # # "# # 	$ 	$ 	$ ["" 	e 	eOOD'9CcOddd	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e(/ +   	 	 	 	 (/ +   # # "# # 	$ 	$ 	$ ["" 	e 	eOOD'9CcOddd	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e 	e(/ +   	 	 	 	 	sH   B<<C C E**E.1E.2HHH KK
K
c           
      :   t                      }|                                D ]}t          d|j        d                    |j                  t	          |j                  t          |j                  d|}| j                             t          j
        d          j        di |           | j        r| j        j        r|d         r|j        s|d         }||v r?t          j        |j        d                    |||         j        |j                             |||<   | j                             t          j
        d          j        di |           | j                             t          j
        d	          j        di |           | j                            d
          5  t%          |j                  s&| j                             dj        di |           n%| j                             dj        di |           d d d            n# 1 swxY w Y   | j                             t          j
        d          j        di |           |d         }| j                             t          j
        d          j        di |           | j                             t          j
        d          j        di |           t'          |j                  s7| j                             t          j
        d          j        di |           d S )Nr  r   )r   r  rL   rr  z              {union_name} {union_name}::Create{member_name}({value_type}&& new_{member_name})
              {{
              	{union_name} m;
              	m.Set_{member_name}(new_{member_name});
              	return m;
              }}

              r\  rL   zgType-based helper constructors are being generated, but there are two objects of type {0}: {1} and {2}.a                       {union_name}::{union_name}({value_type}&& new_{member_name})
                    {{
                    	new(&this->{private_name}) {value_type}(std::move(new_{member_name}));
                    	_tag = Tag::{member_name};
                    }}

                    a                  {parameter_type} {union_name}::Get_{member_name}() const
                {{
                	assert(_tag == Tag::{member_name});
                	return this->{private_name};
                }}

                void {union_name}::Set_{member_name}({parameter_type} new_{member_name})
                {{
                	if(this->_tag == Tag::{member_name}) {{
                		this->{private_name} = new_{member_name};
                	}}
                	else {{
                		ClearCurrent();
                r   z<new(&this->{private_name}) {value_type}(new_{member_name});
z*this->{private_name} = new_{member_name};
ze                		_tag = Tag::{member_name};
                	}}
                }}

                a                  template<>
                const {value_type}& {union_name}::Get_<{union_name}::Tag::{member_name}>() const
                {{
                	assert(_tag == Tag::{member_name});
                	return this->{private_name};
                }}

                z                template<>
                {union_name} {union_name}::Create_<{union_name}::Tag::{member_name}>({value_type} member)
                {{
                	return Create{member_name}(std::move(member));
                }}

                a(                      void {union_name}::Set_{member_name}({value_type}&& new_{member_name})
                    {{
                    	if (this->_tag == Tag::{member_name}) {{
                    		this->{private_name} = std::move(new_{member_name});
                    	}}
                    	else {{
                    		ClearCurrent();
                    		new(&this->{private_name}) {value_type}(std::move(new_{member_name}));
                    		_tag = Tag::{member_name};
                    	}}
                    }}

                    rY   )r   r   r6   r9   r=   rA   rM   rT   rk   r   r   rU   rs  rt  r   exit_at_coordcoordr   rH   rJ   )rV   r[   r   value_typesr   rg  rL   s          r   rb  zCPPUnionEmitter.emitAccessors  sb   ffllnn j	+ j	+F "K-444MM)&+661&+>>	 
  F K ho /   $ $ #$ $ % % % | + ? +Q`Ia +ioi~ +#L1
,,-fl >NOUv&'
38"KP) P)* * *
 +1J'!! # (/ 3 # #  #* #* #)#* #* + + + K ho /   & & %& & ' ' '  ##A&& f f&v{33 fK%%&l&e&l&v&vou&v&vwwwwK%%&Z&S&Z&d&d]c&d&deee	f f f f f f f f f f f f f f f K ho /  
 & &
 %& & ' ' '  -JK ho /   & & %& & ' ' ' K ho /   & & %& & ' ' ' $FK00 +!! # (/ 3 # #  #* #* #)#* #* + + +{j	+ j	+s   *A HH	H	c                     t           j         j                   fd} j                             t	          j        d          j        di |            j                            d          5                       |||           d d d            n# 1 swxY w Y    j                            t	          j        d                     d S )Nc                                          | j        d                    | j                             j                            d           d S Nr  r   r  rl   rA   r9   r6   rT   rk   r   rV   r6  s    r   bodyz&CPPUnionEmitter.emitPack.<locals>.bodyo  W    MM&+,333LL  N N NKj)))))r   aP              size_t {union_name}::Pack(uint8_t* buff, size_t len) const
            {{
            	CLAD::SafeMessageBuffer buffer(buff, len, false);
            	return Pack(buffer);
            }}

            size_t {union_name}::Pack(CLAD::SafeMessageBuffer& buffer) const
            {{
            	buffer.Write(_tag);
            r   zI            	return buffer.GetBytesWritten();
            }

            rY   )	r4  rT   rU   rk   r   r   r9   r   r  rV   r[   r   r  r6  s   `   @r   r   zCPPUnionEmitter.emitPackm  sA   )$+t|DD	* 	* 	* 	* 	* 	*
 	 
(/ 
+ 
 
 
# 
# "
# 
# 
	$ 
	$ 
	$ ["" 	1 	1OOD'4000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1(/ +   	 	 	 	 	   4BBBc                     t           j         j                   fd} j                             t	          j        d          j        di |            j                            d          5                       |||d           d d d            n# 1 swxY w Y    j                            t	          j        d                     d S )Nc                 j   d                     | j                  }t          | j                  r                    | j        |           nJt          | j        t          j                  rj        	                    t          j        d                               |t          | j                                       j                            d          5                      | j        |           d d d            n# 1 swxY w Y   j        	                    d           noj        	                    t          j        d                               |t          | j                                                           | j        |           j        	                    d           d S )	Nr  r   z                    if (newTag != oldTag) {{
                    	new(&(this->{private_name})) {member_type}(buffer);
                    }}
                    else {{
                    r  r   r  z                    if (newTag == oldTag) {{
                    	ClearCurrent();
                    }}
                    new(&(this->{private_name})) {member_type}();
                    r  )r9   r6   rH   rA   rl   r4   r   rB  rT   rk   r   r   r=   r   )r   r  rV   r6  s     r   r  z(CPPUnionEmitter.emitUnpack.<locals>.body  s   +22v{2KKLv{++ Efk|DDDDFK)9:: E!!(/ 3 # #
  %1$26;$?$?   A AB B B [''** I IMM&+<MHHHI I I I I I I I I I I I I I I!!%(((( !!(/ 3 # #
  %1$26;$?$?   A AB B B fk|DDDKj)))))s   DDDa#              size_t {union_name}::Unpack(const uint8_t* buff, const size_t len)
            {{
            	const CLAD::SafeMessageBuffer buffer(const_cast<uint8_t*>(buff), len, false);
            	return Unpack(buffer);
            }}

            size_t {union_name}::Unpack(const CLAD::SafeMessageBuffer& buffer)
            {{
            	Tag newTag {{Tag::INVALID}};
            	const Tag oldTag {{GetTag()}};
            	buffer.Read(newTag);
            	if (newTag != oldTag) {{
            		ClearCurrent();
            	}}
            r   newTagr  zb            	_tag = newTag;
            	return buffer.GetBytesRead();
            }

            rY   )	r9  rT   rU   rk   r   r   r9   r   r  r  s   `   @r   r   zCPPUnionEmitter.emitUnpack  sV   +DKFF	* 	* 	* 	* 	* 	*: 	 (/ +   # # "# # 	$ 	$ 	$" ["" 	D 	DOOD'4(OCCC	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D 	D(/ +   	 	 	 	 	s   4BB!Bc                     t           j         j                   fd} j                             t	          j        d          j        di |            j                            d          5                       |||           d d d            n# 1 swxY w Y    j                            t	          j        d                     d S )Nc                                          | j        d                    | j                             j                            d           d S r  r  r  s    r   r  z&CPPUnionEmitter.emitSize.<locals>.body  r  r   z{            size_t {union_name}::Size() const
            {{
            	size_t result {{1}}; // tag = uint_8
            r   r;  rY   )	r<  rT   rU   rk   r   r   r9   r   r  r  s   `   @r   r   zCPPUnionEmitter.emitSize  sA   )$+t|DD	* 	* 	* 	* 	* 	* 	 (/ +   	# # "	# # 	$ 	$ 	$
 ["" 	1 	1OOD'4000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1(/ +   	 	 	 	 	r  c           	           fd} j                              t          j        d          j        di |            j                             d          5                       |||d           d d d            n# 1 swxY w Y    j                             t          j         dj        di |                     d S )Nc                     d                     | j                  }j                            d                     |                     d S )Nr  r   z5return this->{private_name} == other.{private_name};
r  )r9   r6   rT   rk   r   r  rV   s     r   r  z*CPPUnionEmitter.emitEquality.<locals>.body  s[    +22v{2KKLKV]]) ^ + + , , , , ,r   z            bool {union_name}::operator==(const {union_name}& other) const
            {{
            	if (this->_tag != other._tag) {{
            		return false;
            	}}
            r   r>  r  z            }}

            bool {union_name}::operator!=(const {union_name}& other) const
            {{
            	return !(operator==(other));
            }}

            rY   r  rV   r[   r   r  s   `   r   r   zCPPUnionEmitter.emitEquality  sa   	, 	, 	, 	, 	,
 	 (/ +   # # "# # 	$ 	$ 	$ ["" 	P 	POOD'4>NOOOO	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P 	P(/ + + +" +" !+" +" # # 	$ 	$ 	$ 	$ 	$s   A>>BBc                      j                              t          j        d          j        di |            fd} j                             d          5                       |||           d d d            n# 1 swxY w Y    j                             t          j        d                      j                              t          j        d          j        di |            j                             d          5  |                                D ]} j                             d                    |j                              j                             d          5  d	                    |j                  } j                             d
                    |t          |j
                                       t          |j
                  t          |j
        j        t          j                  rQ|j
        j                                        dk    r/ j                             d                    |                     nu j                             d                    |j                             nA j                             d                    |t          |j
                                        j                             d                    |j                             d d d            n# 1 swxY w Y    j                             d           	 d d d            n# 1 swxY w Y    j                             t          j        d                     d S )Nzp            Json::Value {union_name}::GetJSON() const
            {{
            	Json::Value root;
            c                    d                     | j                  }t          | j                  t	          | j        j        t          j                  rQ| j        j                                        dk    r/j	        
                    d                     |                     nbj	        
                    d                     | j                             n.j	        
                    d                     |                     j	        
                    d                     | j                             j	        
                    d	           d S )
Nr  r   r   z'root = this->{private_name}.GetJSON();
r  z&// {member_name} is not serializable.
z&root["value"] = this->{private_name};
z root["type"] = "{member_name}";
r  )r9   r6   rP   rA   r4   r&  r   MessageDeclr   rT   rk   r  s     r   r  z0CPPUnionEmitter.emitJSONSerializer.<locals>.body  s-   +22v{2KKL --5fk3S_EE q&+J_JkJkJmJmq|J|J|K%%&P&W&Weq&W&r&rssssK%%&O&V&Vcicn&V&o&opppp!!"K"R"R`l"R"m"mnnnKAHHU[U`HaabbbKj)))))r   r   z(        	return root;
        }
        a  
            bool {union_name}::SetFromJSON(const Json::Value& json)
            {{
              ClearCurrent();

              bool result = false;

              if(json.isMember("type")) {{
                std::string tagStr = json["type"].asString();

                try {{

                  if(tagStr == "INVALID") {{
                    // Already cleared, do nothing.
                    result = true;  
                  }}
               z&else if(tagStr == "{member_name}") {{
r   r  z,new(&(this->{private_name})) {member_type};
r  r   z1result = this->{private_name}.SetFromJSON(json);
r  zJ// {member_name} is not a structure, is not serializable.
result = false;
zAthis->{private_name} = json["value"].{as_method};
result = true;
)r  rI  z_tag = Tag::{member_name};
r  z
                }
                catch(Json::LogicError) {
                  result = false;
                }
              }

              return result;
            }

        rY   )rT   rk   r   r   r9   r   r  r   r6   r=   rA   rP   r4   r&  r   r  r   )rV   r[   r   r  r   r  s   `     r   r   z"CPPUnionEmitter.emitJSONSerializer  s    (/ +   	# # "	# # 	$ 	$ 	$
	* 
	* 
	* 
	* 
	* ["" 	1 	1OOD'4000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	(/ +   	 	 	
 	 (/ +    !# #  "!# # 	$ 	$ 	$$ ["" 	) 	),,.. ) )!!"K"R"R_e_j"R"k"klll[''** 
f 
f#3#:#:v{#:#S#SLK%%&U&\&\jv  ES  TZ  T_  E`  E`&\  'a  'a  b  b  b(55=%fk&;S_MM ^RXR]RgRsRsRuRu  zE  SE  SE K--.b.i.i  xD.i  /E  /E  F  F  F  F K--.|  /D  /D  QW  Q\  /D  /]  /]  ^  ^  ^  ^))*o*v*v  EQ  ]n  ou  oz  ]{  ]{*v  +|  +|  }  }  }K%%&D&K&KX^Xc&K&d&deee
f 
f 
f 
f 
f 
f 
f 
f 
f 
f 
f 
f 
f 
f 
f !!%(((()	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)" 	(/ +   	 	 	 	 	sJ   A<<B B A%L7)FL7L7LL7
LL77L;>L;c                 j     fd} j                              t          j        d          j        di |            j                             d          5                       |||           d d d            n# 1 swxY w Y    j                             t          j        d                     d S )Nc                    t          | j                  sZj                            d                    d                    | j                  t          | j                                       j                            d           d S )Nz!{private_name}.~{member_type}();
r  r   r  r  )rH   rA   rT   rk   r9   r6   rD   r  s    r   r  z.CPPUnionEmitter.emitClearCurrent.<locals>.body:  s    #FK00 I!!"F"M"M!1!8!8V[!8!Q!Q 9&+ F F #N #H #H I I I Kj)))))r   zI            void {union_name}::ClearCurrent()
            {{
            r   z=            	_tag = Tag::INVALID;
            }

            rY   r  r  s   `   r   rc  z CPPUnionEmitter.emitClearCurrent9  s(   	* 	* 	* 	* 	* 	 (/ +   # # "# # 	$ 	$ 	$ ["" 	1 	1OOD'4000	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1(/ +   	 	 	 	 	s   A<<B B c           	      ^     fd} j                              t          j        d          j        d	i             j                             d          5                       ||d         dd           d d d            n# 1 swxY w Y    j                             d           d S )
Nc                 `    j                              dj        dd| j        i           d S )Nzreturn "{member_name}";
r   rY   rT   rk   r9   r6   )r   r   rV   s    r   r  z-CPPUnionEmitter.emitTagToString.<locals>.bodyO  s<    K@9@ddV[d\cddeeeeer   zP            const char* {tag_name}ToString(const {tag_name} tag) {{
            r   rY  r  zreturn "INVALID";
)r  r  r  r  rY   r  r  s   ` ` r   r  zCPPUnionEmitter.emitTagToStringN  sC   	f 	f 	f 	f 	f 	f 	 (/ +  # #!# # 	$ 	$ 	$ ["" 	b 	bOOD'4 ,uK`  b b b	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	b 	%     s   "BBB)r  r  r  )r`   ra   rb   r   rd   rW   r   r   r   r  r   rb  r   r   r   r   r   rc  r  rY   r   r   r   r   U  s       !j$r    
' ' '>$ $ $& & &! ! ! !` ` `Dl+ l+ l+\  47 7 7r  *$ $ $2I I IV  *
! 
! 
! 
! 
!r   r   c                   2    e Zd Zd Zd Zd Zd Zd Zd ZdS )r4  c                 b    | j                             d                    |                     d S )Nz#buffer.Write(this->{member_name});
r   r   rV   r[   r   s      r   visit_BuiltinTypez)CPPPackStatementEmitter.visit_BuiltinType\  s1    @GGT_G``aaaaar   c                       | j         |i | d S rF   r  rV   r\   r]   s      r   visit_DefinedTypez)CPPPackStatementEmitter.visit_DefinedType_       //////r   c                     | j                             d                    t          |j                  |                     d S )Nz9buffer.WritePString<{length_type}>(this->{member_name});
length_typer   rT   rk   r9   r=   r  r  s      r   visit_PascalStringTypez.CPPPackStatementEmitter.visit_PascalStringTypeb  sP    V]]&t'788# ^ % % 	& 	& 	& 	& 	&r   c                 b    | j                             d                    |                     d S )Nz"this->{member_name}.Pack(buffer);
r   r   r  s      r   visit_CompoundTypez*CPPPackStatementEmitter.visit_CompoundTypeg  1    ?FFS^F__`````r   c                    t          |j        t          j                  rN| j                            d                    |j        t          |j        j	                  |                     d S t          |j        t          j
                  rU| j                            t          j        d                              |t          |j                                       d S t          |j        t                    rI| j                            d                    |j        t          |j                  |                     d S | j                            d                    |j        t          |j                  |                     d S )NzPbuffer.WritePStringFArray<{length}, {string_length_type}>(this->{member_name});
r3   string_length_typer                   for ({parameter_type} m : {member_name}) {{
                	m.Pack(buffer);
                }}
                r   rr  zWbuffer.WriteFArray<{member_type}, static_cast<size_t>({length})>(this->{member_name});
r3   r1   r   zBbuffer.WriteFArray<{member_type}, {length}>(this->{member_name});
)r4   r1   r   r:   rT   rk   r9   r3   r=   r  rB  r   r   rM   r>   r  s      r   visit_FixedArrayTypez,CPPPackStatementEmitter.visit_FixedArrayTypej  s   d&(<== 	.Kqxx{#1$2B2N#O#O' y ) ) * * * * * (#*:;; 	.Kho /   V#5d6F#G#G  I I	J J J J J $+s++ 	.!!"|  #D  #D; .t/? @ @ + #D #- #- . . . . .
 !!"g"n"n; .t/? @ @ + #o #- #- . . . . .r   c                    t          |j        t          j                  r[| j                            d                    t          |j                  t          |j        j                  |                     d S t          |j        t          j	                  r| j                            d                    t          |j                  |                     | j                            t          j        d                              |t          |j                                       d S | j                            d                    t          |j                  t          |j                  |                     d S )	Nz[buffer.WritePStringVArray<{array_length_type}, {string_length_type}>(this->{member_name});
array_length_typer  r   zFbuffer.Write(static_cast<{array_length_type}>({member_name}.size()));
)r  r   r  r  zGbuffer.WriteVArray<{member_type}, {length_type}>(this->{member_name});
r1   r  r   )r4   r1   r   r:   rT   rk   r9   r=   r  rB  r   r   rM   r  s      r   visit_VariableArrayTypez/CPPPackStatementEmitter.visit_VariableArrayType  s   d&(<== 	*K|  D  D"01A"B"B#1$2B2N#O#O' D ) ) * * * * * (#*:;; 	*Kgnn"01A"B"B' o ) ) * * * Kho /   V#5d6F#G#G  I I	J J J J J Khoo*4+;<<*4+;<<' p ) ) * * * * *r   N	r`   ra   rb   r  r  r  r  r  r  rY   r   r   r4  r4  Z  st        b b b0 0 0& & &
a a a. . .2* * * * *r   r4  c                   2    e Zd Zd Zd Zd Zd Zd Zd ZdS )r9  c                 b    | j                             d                    |                     d S )Nz"buffer.Read(this->{member_name});
r   r   r  s      r   r  z+CPPUnpackStatementEmitter.visit_BuiltinType  r  r   c                       | j         |i | d S rF   r  r  s      r   r  z+CPPUnpackStatementEmitter.visit_DefinedType  r  r   c                     | j                             d                    t          |j                  |                     d S )Nz8buffer.ReadPString<{length_type}>(this->{member_name});
r  r  r  s      r   r  z0CPPUnpackStatementEmitter.visit_PascalStringType  sP    U\\&t'788# ] % % 	& 	& 	& 	& 	&r   c                 b    | j                             d                    |                     d S )Nz$this->{member_name}.Unpack(buffer);
r   r   r  s      r   r  z,CPPUnpackStatementEmitter.visit_CompoundType  s1    AHHU`Haabbbbbr   c                    t          |j        t          j                  rN| j                            d                    |j        t          |j        j	                  |                     d S t          |j        t          j
                  rI| j                            d                    t          |j                  |j        |                     d S t          |j        t                    rI| j                            d                    |j        t          |j                  |                     d S | j                            d                    |j        t          |j                  |                     d S )NzObuffer.ReadPStringFArray<{length}, {string_length_type}>(this->{member_name});
r  zMbuffer.ReadCompoundTypeFArray<{member_type}, {length}>(this->{member_name});
)r1   r3   r   zVbuffer.ReadFArray<{member_type}, static_cast<size_t>({length})>(this->{member_name});
r  zAbuffer.ReadFArray<{member_type}, {length}>(this->{member_name});
)r4   r1   r   r:   rT   rk   r9   r3   r=   r  rB  r>   r  s      r   r  z.CPPUnpackStatementEmitter.visit_FixedArrayType  s   d&(<== 	.Kpww{#1$2B2N#O#O' x ) ) * * * * * (#*:;; 	.Knuu+D,<==( v * * + + + + +
 $+s++ 	.!!"{  #C  #C; .t/? @ @ + #C #- #- . . . . .
 !!"f"m"m; .t/? @ @ + #n #- #- . . . . .r   c                    t          |j        t          j                  r[| j                            d                    t          |j                  t          |j        j                  |                     d S t          |j        t          j	                  rV| j                            d                    t          |j                  t          |j                  |                     d S | j                            d                    t          |j                  t          |j                  |                     d S )NzZbuffer.ReadPStringVArray<{array_length_type}, {string_length_type}>(this->{member_name});
r  zRbuffer.ReadCompoundTypeVArray<{member_type}, {length_type}>(this->{member_name});
r  zFbuffer.ReadVArray<{member_type}, {length_type}>(this->{member_name});
)
r4   r1   r   r:   rT   rk   r9   r=   r  rB  r  s      r   r  z1CPPUnpackStatementEmitter.visit_VariableArrayType  sS   d&(<== 	*K{  C  C"01A"B"B#1$2B2N#O#O' C ) ) * * * * * (#*:;; 		*Kszz*4+;<<*4+;<<' { ) ) * * * * *
 Kgnn*4+;<<*4+;<<' o ) ) * * * * *r   Nr  rY   r   r   r9  r9    st        a a a0 0 0& & &
c c c. . ..* * * * *r   r9  c                   @    e Zd Zd Zd Zd Zd Zd Zd Zd Z	dd	Z
d
S )r<  c                 x    | j                             d                    |j        |j                             d S )Nzresult += {size}; // {type}
)sizerA   )rT   rk   r9   r  r6   r  s      r   r  z)CPPSizeStatementEmitter.visit_BuiltinType  sH    9@@ A , , 	- 	- 	- 	- 	-r   c                       | j         |i | d S rF   r  r  s      r   r  z)CPPSizeStatementEmitter.visit_DefinedType  r  r   c                     | j                             t          j        d                              |j        j        |j        j        |j        j        |                     d S )Nz            result += {length_size}; // {length_type} (string length)
            result += this->{member_name}.length(); // {member_type}
            )length_sizer  r1   r   )	rT   rk   r   r   r9   r  r  r6   r1   r  s      r   r  z.CPPSizeStatementEmitter.visit_PascalStringType  sm    (/ +    ,1 ,1 ,1'	  ) )	* 	* 	* 	* 	*r   c                 n    | j                             d                    ||j                             d S )Nz0result += this->{member_name}.Size(); // {type}
)r   rA   r  r  s      r   r  z*CPPSizeStatementEmitter.visit_CompoundType  sF    MTT#$) U 5 5 	6 	6 	6 	6 	6r   c                    t          |j        t          j                  rm| j                            d                    |j        j        j        |j        j        j	        |j
        |                     |                     ||d           d S t          |j        t          j                  r|                     ||           d S t          |j
        t                    rK| j                            d                    |j        j        |j        j	        |j
                             d S | j                            d                    |j        j        |j        j	        |j
                             d S )NzTresult += {string_length_size} * {length}; // {string_length_type} (string lengths)
)string_length_sizer  r3   r   r3   zUresult += {member_size} * static_cast<size_t>({length}); // {member_type} * {length}
)member_sizer1   r3   z@result += {member_size} * {length}; // {member_type} * {length}
)r4   r1   r   r:   rT   rk   r9   r  r  r6   r3   emitRecursiveSizerB  r>   r  s      r   r  z,CPPSizeStatementEmitter.visit_FixedArrayType  s   d&(<== 	)Ku||#'#3#?#D#'#3#?#D{'	 } ) ) * * *
 ""4h?????(#*:;; 	)""455555$+s++ 	)!!"z  #B  #B $ 0 5 $ 0 5; #B #( #( ) ) ) ) )
 !!"e"l"l $ 0 5 $ 0 5; #m #( #( ) ) ) ) )r   c                    | j                             d                    |j        j        |j        j                             t          |j        t          j	                  rg| j                             d                    |j        j        j        |j        j        j        |                     | 
                    ||d           d S t          |j        t          j                  r| 
                    ||           d S | j                             d                    |j        j        |j        j        |                     d S )Nz9result += {length_size}; // {length_type} (array length)
)r  r  fresult += {string_length_size} * this->{member_name}.size(); // {string_length_type} (string lengths)
r  r  r   r3   zGresult += {member_size} * this->{member_name}.size(); // {member_type}
)r  r1   r   )rT   rk   r9   r  r  r6   r4   r1   r   r:   r  rB  r  s      r   r  z/CPPSizeStatementEmitter.visit_VariableArrayType  s^   V]](-(- ^ / / 	0 	0 	0 d&(<== 	*K  H  O  O#'#3#?#D#'#3#?#D' O ) ) * * * ""4h?????(#*:;; 	*""455555Khoo ,1 ,1' p ) ) * * * * *r   c                     | j                             d                    |j        j        j        |j        j        j        |                     |                     ||d           d S )Nr  r  r3   )rT   rk   r9   r1   r  r  r6   r  r  s      r   emitPascalStringArraySizez1CPPSizeStatementEmitter.emitPascalStringArraySize  sy      D  K  K#/;@#/;@# K % % 	& 	& 	& 	t[(;;;;;r   Sizec                     | j                             t          j        d                              |j        j        t          |j                  ||                     d S )Nz            for ({parameter_type} m : this->{member_name}) {{
            	result += m.{size_method}();
            }}
            )r1   rr  r   size_method)rT   rk   r   r   r9   r1   r6   rM   )rV   r[   r   r  s       r   r  z)CPPSizeStatementEmitter.emitRecursiveSize  sl    (/ +    ,11$2BCC''	  ) )		* 	* 	* 	* 	*r   N)r  )r`   ra   rb   r  r  r  r  r  r  r  r  rY   r   r   r<  r<    s        - - -0 0 0* * *6 6 6) ) ),* * *$< < <	* 	* 	* 	* 	* 	*r   r<  c                       e Zd Zd Zd ZdS )r   c                     t          |j        |j        t          |j        j                  |j                  }|                     ||           d S N)enum_concept_nameenum_concept_hashenum_concept_return_typeenum_concept_type)r   r6   r   r=   return_typerA   enumr   r   s      r   r   z)HEnumConceptEmitter.visit_EnumConceptDecl$  sR    "i"m%3D4D4I%J%J"i	
 
 
 	g&&&&&r   c                     t          j        |d                   }| j                             dj        dd|i|           d S )Nr  z{enum_concept_return_type} {enum_concept_name}(const {enum_concept_type}& {argument_name}, const {enum_concept_return_type}& defaultValue);

argument_namerY   )r   _lower_first_char_of_stringrT   rk   r9   )rV   r[   r   r  s       r   r   zHEnumConceptEmitter.emitHeader.  s    #?H[@\]]  s  l  s  [  [  BO  [  SZ  [  [  	\  	\  	\  	\  	\r   N)r`   ra   rb   r   r   rY   r   r   r   r   "  s7        ' ' '\ \ \ \ \r   r   c                       e Zd Zd Zd ZdS )r   c                     t          |j        |j        t          |j        j                  |j                  }|                     ||           d S r  )r   r6   r   r=   r	  rA   r
  emitr   s      r   r   z+CPPEnumConceptEmitter.visit_EnumConceptDecl5  sR    "i"m%3D4D4I%J%J"i	
 
 
 			$     r   c                    t          j        |d                   }| j                             dj        dd|i|           | j                            d                    |                     |                                D ]f}| j                             dj        dd|j        i|           | j                            d                    |j        j        	                     g| j                            d
           | j                            d           | j                            d           | j                            d           d S )Nr  z{enum_concept_return_type} {enum_concept_name}(const {enum_concept_type}& {argument_name}, const {enum_concept_return_type}& defaultValue)
{{
r  z	switch({argument_name}) {{
)r  z+		case {enum_concept_type}::{member_name}:
r   z			return {member_value};
)member_valuez		default:
z			return defaultValue;
rJ  r   rY   )r   r  rT   rk   r9   r   r6   r   )rV   r[   r   r  r   s        r   r  zCPPEnumConceptEmitter.emit>  s|   #?H[@\]]  t  m  t  \  \  CP  \  T[  \  \  	]  	]  	]:AAP]A^^___llnn 	h 	hFKUNUyybhbmyqxyyzzzK>EESYS_SeEffgggg*+++8999'"""'"""""r   N)r`   ra   rb   r   r  rY   r   r   r   r   3  s2        ! ! !# # # # #r   r   __main__zC++z.hz.cppz-rz--header-output-directorydirz9The directory to output the {language} header file(s) to.)language)metavarhelpz--header-output-extensionextzOThe extension to use for header files. (Helps work around a CMake Xcode issue.))defaultr  r  z"--output-union-helper-constructorsrs  
store_truez3Emits helper union constructor, one for each member)destactionr  z--output-propertiesr   z<Emits accessors and mutators for all members of a structure.z--output-jsonr   zNEmits code to serialize all members in a structure to and from jsoncpp values.c                 |    t           t          fD ],} || t                                        t                     -d S N)rU   )r~  r  rU   rl   tree)rT   emitter_types     r   tag_output_header_callbackr!  k  sJ    !4o F B BVW555;;DAAAAB Br   r  T
functional)use_inclusion_guardssystem_headerszjson/json.hc                 b    t          | t                                        t                     d S r  )rf   rU   rl   r  rT   s    r   main_output_header_callbackr'  |  s)    &'22288>>>>>r   )arraycassertcstdintstringvectorzCLAD/SafeMessageBuffer.h)comment_linesr#  r$  local_headersc                 b    t          | t                                        t                     d S r  )r   rU   rl   r  r&  s    r   main_output_source_callbackr0    s)    FG444::4@@@@@r   )unordered_maplimitsiostreamF)Ar   r   r   r   r   r   r   r   r7   r=   rD   rH   rJ   rM   rO   rP   NodeVisitorrR   rf   r   r{   r   r~   r   rL  r   r~  r  r   r4  r9  r<  r   r   r`   r  default_header_extensionsource_extensionStandardArgumentParseroption_parseradd_argumentr9   
parse_argsrU   header_output_directoryoutput_directoryparser  get_comment_linesr-  union_discovererrl   rP  r!  get_output_filers   tag_output_headerwrite_c_file main_output_header_local_headersr   r'  main_output_headerr0  cfile_system_headersmain_output_sourcerY   r   r   <module>rG     s  (  				 



 ' ' '                      + + +6  ,R R R! ! !M M M # #   	 	 	 	 	#/ 	 	 	S S S S S S S SBU U U U U+ U U U"D~ D~ D~ D~ D~; D~ D~ D~Lo& o& o& o& o&\ o& o& o&bn n n n n[ n n nd^$ ^$ ^$ ^$ ^$~ ^$ ^$ ^$@	    co   p" p" p" p" p"K p" p" p"d3 3 3 3 3+ 3 3 3j$ $ $ $ $k $ $ $,C! C! C! C! C!k C! C! C!J=* =* =* =* =*k =* =* =*~6* 6* 6* 6* 6* 6* 6* 6*pO* O* O* O* O*k O* O* O*b\ \ \ \ \+ \ \ \"# # # # #L # # #4 z      H#6K6x@@Mt%@%HOOYaObb  d d d:D\fk^  ` ` `CJ^gsB  D D D4;KT`K  M M MZ]  _ _ _ &&((G* C*1*B';W%%D1K1'8DDM&((4    .	B 	B 	B 8K7IhAhii  !@BS&(>	+ 	+ 	+ 	+
 ->+>((+-( <(]O;(? ? ? 54Wg>]^^KW<>P##!fff68 8 8 8A A A  H G G GG44W>NOOKW57I##"+)*, , , , , ,G r   