/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 8 ĠSquare , ĠInc . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġcom . squareup . mos hi . kotlin . codegen Ċ Ċ import Ġcom . squareup . kotlin po et . ARRAY Ċ import Ġcom . squareup . kotlin po et . Annotation Spec Ċ import Ġcom . squareup . kotlin po et . Code Block Ċ import Ġcom . squareup . kotlin po et . File Spec Ċ import Ġcom . squareup . kotlin po et . Fun Spec Ċ import Ġcom . squareup . kotlin po et . K Modifier Ċ import Ġcom . squareup . kotlin po et . Name Allocator Ċ import Ġcom . squareup . kotlin po et . Parameter Spec Ċ import Ġcom . squareup . kotlin po et . Parameterized TypeName . Companion . parameter ized By Ċ import Ġcom . squareup . kotlin po et . Property Spec Ċ import Ġcom . squareup . kotlin po et . Type Spec Ċ import Ġcom . squareup . kotlin po et . Type Variable Name Ċ import Ġcom . squareup . kotlin po et . as ClassName Ċ import Ġcom . squareup . kotlin po et . as TypeName Ċ import Ġcom . squareup . mos hi . Json Adapter Ċ import Ġcom . squareup . mos hi . Json DataException Ċ import Ġcom . squareup . mos hi . Json Reader Ċ import Ġcom . squareup . mos hi . Json Writer Ċ import Ġcom . squareup . mos hi . M oshi Ċ import Ġme . e ug eni om ar let ti . kotlin . metadata . is Data Class Ċ import Ġme . e ug eni om ar let ti . kotlin . metadata . shadow . metadata . Proto Buf . Visibility Ċ import Ġme . e ug eni om ar let ti . kotlin . metadata . visibility Ċ import Ġjava . lang . reflect . Type Ċ import Ġjavax . lang . model . element . Type Element Ċ Ċ /** ĠGenerates Ġa ĠJSON Ġadapter Ġfor Ġa Ġtarget Ġtype . Ġ*/ Ċ internal Ġclass ĠAdapter Generator ( ĊĠ Ġtarget : ĠTarget Type , ĊĠ Ġprivate Ġval Ġproperty List : ĠList < Property Generator > Ċ ) Ġ{ ĊĠ Ġprivate Ġval ĠclassName Ġ= Ġtarget . name ĊĠ Ġprivate Ġval Ġis Data Class Ġ= Ġtarget . proto . is Data Class ĊĠ Ġprivate Ġval Ġvisibility Ġ= Ġtarget . proto . visibility !! ĊĠ Ġprivate Ġval Ġtype Variables Ġ= Ġtarget . type Variables ĊĊĠ Ġprivate Ġval Ġname Allocator Ġ= ĠName Allocator () ĊĠ Ġprivate Ġval Ġadapter Name Ġ= Ġ"${ className . simple Names . join ToString ( separator Ġ= Ġ"_ ")} Json Adapter " ĊĠ Ġprivate Ġval Ġoriginal Element Ġ= Ġtarget . element ĊĠ Ġprivate Ġval Ġoriginal TypeName Ġ= Ġtarget . element . as Type (). as TypeName () ĊĊĠ Ġprivate Ġval Ġm oshi Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" mos hi "), ĊĠĠĠĠĠ ĠM oshi :: class ). build () ĊĠ Ġprivate Ġval Ġtypes Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" types "), ĊĠĠĠĠĠ ĠARRAY . parameter ized By ( Type :: class . as TypeName ())) ĊĠĠĠĠĠ Ġ. build () ĊĠ Ġprivate Ġval Ġreader Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" reader "), ĊĠĠĠĠĠ ĠJson Reader :: class ) ĊĠĠĠĠĠ Ġ. build () ĊĠ Ġprivate Ġval Ġwriter Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" writer "), ĊĠĠĠĠĠ ĠJson Writer :: class ) ĊĠĠĠĠĠ Ġ. build () ĊĠ Ġprivate Ġval Ġvalue Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" value "), ĊĠĠĠĠĠ Ġoriginal TypeName . copy ( nullable Ġ= Ġtrue )) ĊĠĠĠĠĠ Ġ. build () ĊĠ Ġprivate Ġval Ġjson Adapter TypeName Ġ= ĠJson Adapter :: class . as ClassName (). parameter ized By ( original TypeName ) ĊĊĠ Ġ// Ġselect Name () ĠAPI Ġsetup ĊĠ Ġprivate Ġval Ġoptions Property Ġ= ĠProperty Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" options "), ĠJson Reader . Options :: class . as TypeName (), ĊĠĠĠĠĠ ĠK Modifier . PRIVATE ) ĊĠĠĠĠĠ Ġ. initializer ("% T . of (${ property List . join ToString (", Ġ") Ġ{ ĊĠĠĠĠĠĠĠ ĠCode Block . of ("% S ", Ġit . json Name ). toString () ĊĠĠĠĠĠ Ġ} })", ĠJson Reader . Options :: class . as TypeName ()) ĊĠĠĠĠĠ Ġ. build () ĊĊĠ Ġfun Ġgenerate File ( generated Option : ĠType Element ?): ĠFile Spec Ġ{ ĊĠĠĠ Ġfor Ġ( property Ġin Ġproperty List ) Ġ{ ĊĠĠĠĠĠ Ġproperty . allocate Names ( name Allocator ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġresult Ġ= ĠFile Spec . builder ( className . packageName , Ġadapter Name ) ĊĠĠĠ Ġresult . add Comment (" Code Ġgenerated Ġby Ġm oshi - kotlin - codegen . ĠDo Ġnot Ġedit .") ĊĠĠĠ Ġresult . add Type ( generate Type ( generated Option )) ĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate Type ( generated Option : ĠType Element ?): ĠType Spec Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= ĠType Spec . class Builder ( adapter Name ) ĊĠĠĠĠĠĠĠ Ġ. add Origin ating Element ( original Element ) ĊĊĠĠĠ Ġgenerated Option ?. let Ġ{ ĊĠĠĠĠĠ Ġresult . add Annotation ( Annotation Spec . builder ( it . as ClassName ()) ĊĠĠĠĠĠĠĠĠĠ Ġ. add Member (" value Ġ= Ġ[% S ]", ĠJson Class Code gen Processor :: class . java . canonical Name ) ĊĠĠĠĠĠĠĠĠĠ Ġ. add Member (" comments Ġ= Ġ% S ", Ġ" https :// github . com / square / mos hi ") ĊĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . super class ( json Adapter TypeName ) ĊĊĠĠĠ Ġif Ġ( type Variables . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġresult . add Type Variables ( type Variables ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO Ġmake Ġthis Ġconfigurable . ĠRight Ġnow Ġit Ġjust Ġmatches Ġthe Ġsource Ġmodel ĊĠĠĠ Ġif Ġ( visibility Ġ== ĠVisibility . INTERNAL ) Ġ{ ĊĠĠĠĠĠ Ġresult . add Modifiers ( K Modifier . INTERNAL ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . primary Constructor ( generate Constructor ()) ĊĊĠĠĠ Ġval Ġtype Renderer : ĠType Renderer Ġ= Ġobject Ġ: ĠType Renderer () Ġ{ ĊĠĠĠĠĠ Ġoverride Ġfun Ġrender Type Variable ( type Variable : ĠType Variable Name ): ĠCode Block Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġindex Ġ= Ġtype Variables . indexOf First Ġ{ Ġit Ġ== Ġtype Variable Ġ} ĊĠĠĠĠĠĠĠ Ġcheck ( index Ġ!= Ġ- 1 ) Ġ{ Ġ" Unexpected Ġtype Ġvariable Ġ$ type Variable " Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠCode Block . of ("% N [% L ]", Ġtypes Param , Ġindex ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . addProperty ( options Property ) ĊĠĠĠ Ġfor Ġ( unique Adapter Ġin Ġproperty List . distinct By Ġ{ Ġit . delegate Key Ġ}) Ġ{ ĊĠĠĠĠĠ Ġresult . addProperty ( unique Adapter . delegate Key . generate Property ( ĊĠĠĠĠĠĠĠĠĠ Ġname Allocator , Ġtype Renderer , Ġm oshi Param , Ġunique Adapter . name )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . addFunction ( generate ToString Fun ()) ĊĠĠĠ Ġresult . addFunction ( generate FromJson Fun ()) ĊĠĠĠ Ġresult . addFunction ( generate ToJson Fun ()) ĊĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate Constructor (): ĠFun Spec Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= ĠFun Spec . constructor Builder () ĊĠĠĠ Ġresult . add Parameter ( mos hi Param ) ĊĊĠĠĠ Ġif Ġ( type Variables . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġresult . add Parameter ( types Param ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate ToString Fun (): ĠFun Spec Ġ{ ĊĠĠĠ Ġreturn ĠFun Spec . builder (" toString ") ĊĠĠĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OVERRIDE ) ĊĠĠĠĠĠĠĠ Ġ. returns ( String :: class ) ĊĠĠĠĠĠĠĠ Ġ. add Statement (" return Ġ% S ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Generated Json Adapter (${ original TypeName . raw Type (). simple Names . join ToString (".") }) ") ĊĠĠĠĠĠĠĠ Ġ. build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġjson DataException ( ĊĠĠĠ Ġdescription : ĠString , ĊĠĠĠ Ġidentifier : ĠString , ĊĠĠĠ Ġcondition : ĠString , ĊĠĠĠ Ġreader : ĠParameter Spec ĊĠ Ġ): ĠCode Block Ġ{ ĊĠĠĠ Ġreturn ĠCode Block . of ("% T (% T (% S ). append (% S ). append (% S ). append (% N . path ). toString ()) ", ĊĠĠĠĠĠĠĠ ĠJson DataException :: class , ĠStringBuilder :: class , Ġdescription , Ġidentifier , Ġcondition , Ġreader ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate FromJson Fun (): ĠFun Spec Ġ{ ĊĠĠĠ Ġval Ġresult Name Ġ= Ġname Allocator . new Name (" result ") ĊĊĠĠĠ Ġval Ġresult Ġ= ĠFun Spec . builder (" fromJson ") ĊĠĠĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OVERRIDE ) ĊĠĠĠĠĠĠĠ Ġ. add Parameter ( reader Param ) ĊĠĠĠĠĠĠĠ Ġ. returns ( original TypeName ) ĊĊĠĠĠ Ġfor Ġ( property Ġin Ġproperty List ) Ġ{ ĊĠĠĠĠĠ Ġresult . add Code ("% L ", Ġproperty . generate Local Property ()) ĊĠĠĠĠĠ Ġif Ġ( property . different iate Absent From Null ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Code ("% L ", Ġproperty . generate Local Is Present Property ()) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . add Statement ("% N . begin Object ()", Ġreader Param ) ĊĠĠĠ Ġresult . begin Control Flow (" while Ġ(% N . hasNext ()) ", Ġreader Param ) ĊĠĠĠ Ġresult . begin Control Flow (" when Ġ(% N . select Name (% N )) ", Ġreader Param , Ġoptions Property ) ĊĊĠĠĠ Ġproperty List . forEach Indexed Ġ{ Ġindex , Ġproperty Ġ-> ĊĠĠĠĠĠ Ġif Ġ( property . different iate Absent From Null ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . begin Control Flow ("% L Ġ-> Ġ", Ġindex ) ĊĠĠĠĠĠĠĠ Ġif Ġ( property . delegate Key . nullable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% N Ġ= Ġ% N . fromJson (% N )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġexception Ġ= Ġjson DataException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Non - null Ġvalue Ġ' ", Ġproperty . local Name , Ġ"' Ġwas Ġnull Ġat Ġ", Ġreader Param ) ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% N Ġ= Ġ% N . fromJson (% N ) Ġ?: Ġthrow Â· % L ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param , Ġexception ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġresult . add Statement ("% N Ġ= Ġtrue ", Ġproperty . local Is Present Name ) ĊĠĠĠĠĠĠĠ Ġresult . end Control Flow () ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( property . delegate Key . nullable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% L Ġ-> Ġ% N Ġ= Ġ% N . fromJson (% N )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex , Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġexception Ġ= Ġjson DataException ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Non - null Ġvalue Ġ' ", Ġproperty . local Name , Ġ"' Ġwas Ġnull Ġat Ġ", Ġreader Param ) ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% L Ġ-> Ġ% N Ġ= Ġ% N . fromJson (% N ) Ġ?: Ġthrow Â· % L ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġindex , Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . begin Control Flow ("- 1 Ġ-> ") ĊĠĠĠ Ġresult . add Comment (" Unknown Ġname , Ġskip Ġit .") ĊĠĠĠ Ġresult . add Statement ("% N . skip Name ()", Ġreader Param ) ĊĠĠĠ Ġresult . add Statement ("% N . skip Value ()", Ġreader Param ) ĊĠĠĠ Ġresult . end Control Flow () ĊĊĠĠĠ Ġresult . end Control Flow () Ġ// Ġwhen ĊĠĠĠ Ġresult . end Control Flow () Ġ// Ġwhile ĊĠĠĠ Ġresult . add Statement ("% N . end Object ()", Ġreader Param ) ĊĊĠĠĠ Ġ// ĠCall Ġthe Ġconstructor Ġproviding Ġonly Ġrequired Ġparameters . ĊĠĠĠ Ġvar Ġhas Optional Parameters Ġ= Ġfalse ĊĠĠĠ Ġresult . add Code (" Â « var Ġ% N Ġ= Ġ% T (", Ġresult Name , Ġoriginal TypeName ) ĊĠĠĠ Ġvar Ġseparator Ġ= Ġ"\ n " ĊĠĠĠ Ġfor Ġ( property Ġin Ġproperty List ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! property . has Constructor Parameter ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġif Ġ( property . has Default ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhas Optional Parameters Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġresult . add Code ( separator ) ĊĠĠĠĠĠ Ġresult . add Code ("% N Ġ= Ġ% N ", Ġproperty . name , Ġproperty . local Name ) ĊĠĠĠĠĠ Ġif Ġ( property . isRequired ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Code (" Ġ?: Ġthrow Â· % L ", Ġjson DataException ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Required Ġproperty Ġ' ", Ġproperty . local Name , Ġ"' Ġmissing Ġat Ġ", Ġreader Param )) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġseparator Ġ= Ġ", \ n " ĊĠĠĠ Ġ} ĊĠĠĠ Ġresult . add Code (" ) Â» \ n ", Ġoriginal TypeName ) ĊĊĠĠĠ Ġ// ĠCall Ġeither Ġthe Ġconstructor Ġagain , Ġor Ġthe Ġcopy () Ġmethod , Ġthis Ġtime Ġproviding Ġany Ġoptional ĊĠĠĠ Ġ// Ġparameters Ġthat Ġwe Ġhave . ĊĠĠĠ Ġif Ġ( has Optional Parameters ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( is Data Class ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Code (" Â « % 1 N Ġ= Ġ% 1 N . copy (", Ġresult Name ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Code (" Â « % 1 N Ġ= Ġ% 2 T (", Ġresult Name , Ġoriginal TypeName ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġseparator Ġ= Ġ"\ n " ĊĠĠĠĠĠ Ġfor Ġ( property Ġin Ġproperty List ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! property . has Constructor Parameter ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcontinue Ġ// ĠNo Ġconstructor Ġparameter Ġfor Ġthis Ġproperty . ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( is Data Class Ġ&& Ġ! property . has Default ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġcontinue Ġ// ĠProperty Ġalready Ġassigned . ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġresult . add Code ( separator ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġproperty . different iate Absent From Null Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Code ("% 2 N Ġ= Ġif Ġ(% 3 N ) Ġ% 4 N Ġelse Ġ% 1 N .% 2 N ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Name , Ġproperty . name , Ġproperty . local Is Present Name , Ġproperty . local Name ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġproperty . isRequired Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Code ("% 1 N Ġ= Ġ% 2 N ", Ġproperty . name , Ġproperty . local Name ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . add Code ("% 2 N Ġ= Ġ% 3 N Ġ?: Ġ% 1 N .% 2 N ", Ġresult Name , Ġproperty . name , Ġproperty . local Name ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġseparator Ġ= Ġ", \ n " ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġresult . add Code (" Â» )\ n ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠAssign Ġproperties Ġnot Ġpresent Ġin Ġthe Ġconstructor . ĊĠĠĠ Ġfor Ġ( property Ġin Ġproperty List ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( property . has Constructor Parameter ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue Ġ// ĠProperty Ġalready Ġhandled . ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġif Ġ( property . different iate Absent From Null ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Statement ("% 1 N .% 2 N Ġ= Ġif Ġ(% 3 N ) Ġ% 4 N Ġelse Ġ% 1 N .% 2 N ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Name , Ġproperty . name , Ġproperty . local Is Present Name , Ġproperty . local Name ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Statement ("% 1 N .% 2 N Ġ= Ġ% 3 N Ġ?: Ġ% 1 N .% 2 N ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Name , Ġproperty . name , Ġproperty . local Name ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . add Statement (" return Ġ% 1 N ", Ġresult Name ) ĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate ToJson Fun (): ĠFun Spec Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= ĠFun Spec . builder (" toJson ") ĊĠĠĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OVERRIDE ) ĊĠĠĠĠĠĠĠ Ġ. add Parameter ( writer Param ) ĊĠĠĠĠĠĠĠ Ġ. add Parameter ( value Param ) ĊĊĠĠĠ Ġresult . begin Control Flow (" if Ġ(% N Ġ== Ġnull )", Ġvalue Param ) ĊĠĠĠ Ġresult . add Statement (" throw Â· % T (% S )", ĠNullPointerException :: class , ĊĠĠĠĠĠĠĠ Ġ"${ value Param . name } Ġwas Ġnull ! ĠWrap Ġin Ġ. null Safe () Ġto Ġwrite Ġnullable Ġvalues .") ĊĠĠĠ Ġresult . end Control Flow () ĊĊĠĠĠ Ġresult . add Statement ("% N . begin Object ()", Ġwriter Param ) ĊĠĠĠ Ġproperty List . forEach Ġ{ Ġproperty Ġ-> ĊĠĠĠĠĠ Ġresult . add Statement ("% N . name (% S )", Ġwriter Param , Ġproperty . json Name ) ĊĠĠĠĠĠ Ġresult . add Statement ("% N . toJson (% N , Ġ% N .% L )", ĊĠĠĠĠĠĠĠĠĠ Ġname Allocator [ property . delegate Key ], Ġwriter Param , Ġvalue Param , Ġproperty . name ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġresult . add Statement ("% N . end Object ()", Ġwriter Param ) ĊĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} Ċ } Ċ