/* Ċ Ġ* Ġ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 . api Ċ Ċ 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 . INT Ċ import Ġcom . squareup . kotlin po et . K Modifier Ċ import Ġcom . squareup . kotlin po et . Member Name Ċ import Ġcom . squareup . kotlin po et . Name Allocator Ċ import Ġcom . squareup . kotlin po et . Parameter Spec Ċ import Ġcom . squareup . kotlin po et . Parameterized TypeName Ċ 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 . TypeName Ċ 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 . kotlin po et . join To Code Ċ import Ġcom . squareup . mos hi . Json Adapter Ċ import Ġcom . squareup . mos hi . Json Reader Ċ import Ġcom . squareup . mos hi . Json Writer Ċ import Ġcom . squareup . mos hi . M oshi Ċ import Ġcom . squareup . mos hi . internal . Util Ċ import Ġcom . squareup . mos hi . kotlin . codegen . api . FromJson Component . Parameter Only Ċ import Ġcom . squareup . mos hi . kotlin . codegen . api . FromJson Component . Parameter Property Ċ import Ġcom . squareup . mos hi . kotlin . codegen . api . FromJson Component . Property Only Ċ import Ġjava . lang . reflect . Constructor Ċ import Ġjava . lang . reflect . Type Ċ import Ġorg . object web . asm . Type Ġas ĠA sm Type Ċ Ċ private Ġval ĠMO SH I _ UTIL Ġ= ĠUtil :: class . as ClassName () Ċ private Ġconst Ġval ĠTO _ STRING _ PREFIX Ġ= Ġ" Generated Json Adapter (" Ċ private Ġconst Ġval ĠTO _ STRING _ SIZE _ BASE Ġ= ĠTO _ STRING _ PREFIX . length Ġ+ Ġ 1 Ġ// Ġ 1 Ġis Ġthe Ġclosing Ġp aren Ċ Ċ /** ĠGenerates Ġa ĠJSON Ġadapter Ġfor Ġa Ġtarget Ġtype . Ġ*/ Ċ internal Ġclass ĠAdapter Generator ( ĊĠĠĠ Ġprivate Ġval Ġtarget : ĠTarget Type , ĊĠĠĠ Ġprivate Ġval Ġproperty List : ĠList < Property Generator > Ċ ) Ġ{ ĊĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġval ĠINT _ TYPE _ BLOCK Ġ= ĠCode Block . of ("% T :: class . java Primitive Type ", ĠINT ) ĊĠĠĠ Ġprivate Ġval ĠDEFAULT _ CON STRUCTOR _ MARKER _ TYPE _ BLOCK Ġ= ĠCode Block . of ( ĊĠĠĠĠĠĠĠ Ġ"% T . DEFAULT _ CON STRUCTOR _ MARKER ", ĠUtil :: class ) ĊĠĠĠ Ġprivate Ġval ĠCN _ MO SH I Ġ= ĠM oshi :: class . as ClassName () ĊĠĠĠ Ġprivate Ġval ĠCN _ TYPE Ġ= ĠType :: class . as ClassName () ĊĊĠĠĠ Ġprivate Ġval ĠCOMMON _ SUP PRESS Ġ= ĠarrayOf ( ĊĠĠĠĠĠĠĠ Ġ// Ġhttps :// github . com / square / mos hi / issues / 1 0 2 3 ĊĠĠĠĠĠĠĠ Ġ" DE PREC ATION ", ĊĠĠĠĠĠĠĠ Ġ// ĠBecause Ġwe Ġlook Ġit Ġup Ġreflect ively ĊĠĠĠĠĠĠĠ Ġ" unused ", ĊĠĠĠĠĠĠĠ Ġ// ĠBecause Ġwe Ġinclude Ġunders cores ĊĠĠĠĠĠĠĠ Ġ" ClassName ", ĊĠĠĠĠĠĠĠ Ġ// ĠBecause Ġwe Ġgenerate Ġredundant Ġ` out ` Ġvariance Ġfor Ġsome Ġgener ics Ġand Ġthere 's Ġno Ġway ĊĠĠĠĠĠĠĠ Ġ// Ġfor Ġus Ġto Ġknow Ġwhen Ġit 's Ġredundant . ĊĠĠĠĠĠĠĠ Ġ" RED UND ANT _ PRO JECTION ", ĊĠĠĠĠĠĠĠ Ġ// ĠBecause Ġwe Ġmay Ġgenerate Ġredundant Ġexplicit Ġtypes Ġfor Ġlocal Ġvars Ġwith Ġdefault Ġvalues . ĊĠĠĠĠĠĠĠ Ġ// ĠExample : Ġ' var Ġfoo Set : ĠBoolean Ġ= Ġfalse ' ĊĠĠĠĠĠĠĠ Ġ" Red undant Explicit Type ", ĊĠĠĠĠĠĠĠ Ġ// ĠName Allocator Ġwill Ġjust Ġadd Ġunders cores Ġto Ġdifferent iate Ġnames , Ġwhich ĠKotlin Ġdoesn 't ĊĠĠĠĠĠĠĠ Ġ// Ġlike Ġfor Ġsty list ic Ġreasons . ĊĠĠĠĠĠĠĠ Ġ" Local Variable Name " ĊĠĠĠ Ġ). let Ġ{ Ġsuppress ions Ġ-> ĊĠĠĠĠĠ ĠAnnotation Spec . builder ( Suppress :: class ) ĊĠĠĠĠĠĠĠĠĠ Ġ. add Member ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsuppress ions . indices . join ToString Ġ{ Ġ"% S " Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ* suppress ions ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġval Ġnon Transient Properties Ġ= Ġproperty List . filter Not Ġ{ Ġit . is Transient Ġ} ĊĠ Ġprivate Ġval ĠclassName Ġ= Ġtarget . typeName . raw Type () ĊĠ Ġprivate Ġval Ġvisibility Ġ= Ġtarget . visibility ĊĠ Ġprivate Ġval Ġtype Variables Ġ= Ġtarget . type Variables ĊĠ Ġprivate Ġval Ġtarget Constructor Params Ġ= Ġtarget . constructor . parameters ĊĠĠĠĠĠ Ġ. map Keys Ġ{ Ġ(_, Ġparam ) Ġ-> Ġparam . index Ġ} ĊĊĠ Ġprivate Ġval Ġname Allocator Ġ= ĠName Allocator () ĊĠ Ġprivate Ġval Ġadapter Name Ġ= Ġ"${ className . simple Names . join ToString ( separator Ġ= Ġ"_ ")} Json Adapter " ĊĠ Ġprivate Ġval Ġoriginal TypeName Ġ= Ġtarget . typeName . strip Type Var Variance () ĊĠ Ġprivate Ġval Ġoriginal Raw TypeName Ġ= Ġoriginal TypeName . raw Type () ĊĊĠ Ġprivate Ġval Ġm oshi Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" mos hi "), ĊĠĠĠĠĠ ĠCN _ MO SH I ). build () ĊĠ Ġprivate Ġval Ġtypes Param Ġ= ĠParameter Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" types "), ĊĠĠĠĠĠ ĠARRAY . parameter ized By ( CN _ TYPE )) ĊĠĠĠĠĠ Ġ. 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 (% L )", ĊĠĠĠĠĠĠĠĠĠ ĠJson Reader . Options :: class . as TypeName (), ĊĠĠĠĠĠĠĠĠĠ Ġnon Transient Properties ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĠCode Block . of ("% S ", Ġit . json Name ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. join To Code (", Ġ") ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ. build () ĊĊĠ Ġprivate Ġval Ġconstructor Property Ġ= ĠProperty Spec . builder ( ĊĠĠĠĠĠ Ġname Allocator . new Name (" constructor Ref "), ĊĠĠĠĠĠ ĠConstructor :: class . as ClassName (). parameter ized By ( original TypeName ). copy ( nullable Ġ= Ġtrue ), ĊĠĠĠĠĠ ĠK Modifier . PRIVATE ) ĊĠĠĠĠĠ Ġ. add Annotation ( Volatile :: class ) ĊĠĠĠĠĠ Ġ. mutable ( true ) ĊĠĠĠĠĠ Ġ. initializer (" null ") ĊĠĠĠĠĠ Ġ. build () ĊĊĠ Ġfun Ġprepare ( type Hook : Ġ( Type Spec ) Ġ-> ĠType Spec Ġ= Ġ{ Ġit Ġ}): ĠPrepared Adapter Ġ{ ĊĠĠĠ Ġfor Ġ( property Ġin Ġnon Transient Properties ) Ġ{ ĊĠĠĠĠĠ Ġproperty . allocate Names ( name Allocator ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġgenerated Adapter Ġ= Ġgenerate Type (). let ( type Hook ) ĊĠĠĠ Ġ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 ( generated Adapter ) ĊĠĠĠ Ġreturn ĠPrepared Adapter ( result . build (), Ġgenerated Adapter . create Pro guard Rule ()) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun ĠType Spec . create Pro guard Rule (): ĠPro guard Config Ġ{ ĊĠĠĠ Ġval Ġadapter Properties Ġ= Ġproperty Specs ĊĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġprop Ġ-> ĊĠĠĠĠĠĠĠĠĠ Ġprop . type . raw Type () Ġ== ĠJson Adapter :: class . as ClassName () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġprop Ġ-> Ġprop . annotations . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠ Ġ. map To ( mutable Set Of ()) Ġ{ Ġprop Ġ-> ĊĠĠĠĠĠĠĠĠĠ ĠQual ifier Adapter Property ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Ġ= Ġprop . name , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġqual ifiers Ġ= Ġprop . annotations . map To ( mutable Set Of ()) Ġ{ Ġit . className Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġadapter Constructor Params Ġ= Ġwhen Ġ( require NotNull ( primary Constructor ). parameters . size ) Ġ{ ĊĠĠĠĠĠĠ 1 Ġ-> ĠlistOf ( CN _ MO SH I . reflection Name ()) ĊĠĠĠĠĠĠ 2 Ġ-> ĠlistOf ( CN _ MO SH I . reflection Name (), Ġ"${ CN _ TYPE . reflection Name ()} [] ") ĊĠĠĠĠĠ Ġ// ĠShould Ġnever Ġhappen ĊĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unexpected Ġnumber Ġof Ġarguments Ġon Ġprimary Ġconstructor : Ġ$ primary Constructor ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġvar Ġhas Default Properties Ġ= Ġfalse ĊĠĠĠ Ġvar Ġparameter Types Ġ= Ġempty List < String >() ĊĠĠĠ Ġtarget . constructor . signature ?. let Ġ{ Ġconstructor Signature Ġ-> ĊĠĠĠĠĠ Ġif Ġ( constructor Signature . startsWith (" constructor - impl ")) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠInline Ġclass , Ġwe Ġdon 't Ġsupport Ġthis Ġyet . ĊĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġa Ġstatic Ġmethod Ġwith Ġsignature Ġlike Ġ' constructor - impl ( I ) I ' ĊĠĠĠĠĠĠĠ Ġreturn @ let ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġhas Default Properties Ġ= Ġproperty List . any Ġ{ Ġit . has Default Ġ} ĊĠĠĠĠĠ Ġparameter Types Ġ= ĠA sm Type . get Argument Types ( constructor Signature . remove Prefix ("< init > ")) ĊĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . to Reflection String () Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn ĠPro guard Config ( ĊĠĠĠĠĠĠĠ Ġtarget Class Ġ= ĠclassName , ĊĠĠĠĠĠĠĠ Ġadapter Name Ġ= Ġadapter Name , ĊĠĠĠĠĠĠĠ Ġadapter Constructor Params Ġ= Ġadapter Constructor Params , ĊĠĠĠĠĠĠĠ Ġtarget Constructor Has Defaults Ġ= Ġhas Default Properties , ĊĠĠĠĠĠĠĠ Ġtarget Constructor Params Ġ= Ġparameter Types , ĊĠĠĠĠĠĠĠ Ġqualifier Properties Ġ= Ġadapter Properties ĊĠĠĠ Ġ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate Type (): ĠType Spec Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= ĠType Spec . class Builder ( adapter Name ) ĊĠĠĠĠĠĠĠ Ġ. add Annotation ( COMMON _ SUP PRESS ) ĊĊĠĠĠ Ġresult . super class ( json Adapter TypeName ) ĊĊĠĠĠ Ġif Ġ( type Variables . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġresult . add Type Variables ( type Variables . map Ġ{ Ġit . strip Type Var Variance () Ġas ĠType Variable Name Ġ}) ĊĠĠĠĠĠ Ġ// Ġrequire ( types . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠĠ Ġ" Type Variable Ġmismatch : ĠExpect ing Ġ 1 Ġtype ( s ) Ġfor Ġgeneric Ġtype Ġvariables Ġ[ T ], Ġbut Ġreceived Ġ${ types . size } Ġwith Ġvalues Ġ$ types " ĊĠĠĠĠĠ Ġ// Ġ} ĊĠĠĠĠĠ Ġresult . add Initializer Block ( Code Block . builder () ĊĠĠĠĠĠĠĠĠĠ Ġ. begin Control Flow (" require ( types . size Ġ== Ġ% L )", Ġtype Variables . size ) ĊĠĠĠĠĠĠĠĠĠ Ġ. add Statement ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" build String Â· { Â· append (% S ). append (% L ). append (% S ). append (% S ). append (% S ). append (% L ) Â· }", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Type Variable Ġmismatch : ĠExpect ing Ġ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Variables . size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Ġ${ if Ġ( type Variables . size Ġ== Ġ 1 ) Ġ" type " Ġelse Ġ" types "} Ġfor Ġgeneric Ġtype Ġvariables Ġ[ ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtype Variables . join ToString (", Ġ") Ġ{ Ġit . name Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ], Ġbut Ġreceived Ġ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ types Param . name }. size " ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠ Ġ. end Control Flow () ĊĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO Ġmake Ġthis Ġconfigurable . ĠRight Ġnow Ġit Ġjust Ġmatches Ġthe Ġsource Ġmodel ĊĠĠĠ Ġif Ġ( visibility Ġ== ĠK Modifier . 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 Ġnon Transient Properties . 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 )) ĊĠĠĠ Ġ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 Ġ{ ĊĠĠĠ Ġval Ġname Ġ= Ġoriginal Raw TypeName . simple Names . join ToString (".") ĊĠĠĠ Ġval Ġsize Ġ= ĠTO _ STRING _ SIZE _ BASE Ġ+ Ġname . length ĊĠĠĠ Ġreturn ĠFun Spec . builder (" toString ") ĊĠĠĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OVERRIDE ) ĊĠĠĠĠĠĠĠ Ġ. returns ( String :: class ) ĊĠĠĠĠĠĠĠ Ġ. add Statement ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" return Ġ% M (% L ) Â· { Ġappend (% S ). append (% S ). append ('% L ') Ġ} ", ĊĠĠĠĠĠĠĠĠĠĠĠ ĠMember Name (" kotlin . text ", Ġ" build String "), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsize , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTO _ STRING _ PREFIX , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġname , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ")" ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġgenerate FromJson Fun ( class Builder : ĠType Spec . Builder ): ĠFun Spec Ġ{ ĊĠĠĠ Ġval Ġresult Ġ= ĠFun Spec . builder (" fromJson ") ĊĠĠĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OVERRIDE ) ĊĠĠĠĠĠĠĠ Ġ. add Parameter ( reader Param ) ĊĠĠĠĠĠĠĠ Ġ. returns ( original TypeName ) ĊĊĠĠĠ Ġfor Ġ( property Ġin Ġnon Transient Properties ) Ġ{ ĊĠĠĠĠĠ Ġresult . add Code ("% L ", Ġproperty . generate Local Property ()) ĊĠĠĠĠĠ Ġif Ġ( property . has Local Is Present Name ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Code ("% L ", Ġproperty . generate Local Is Present Property ()) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġproperties ByIndex Ġ= Ġproperty List . as Sequence () ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . has Constructor Parameter Ġ} ĊĠĠĠĠĠĠĠ Ġ. associate By Ġ{ Ġit . target . parameter Index Ġ} ĊĠĠĠ Ġval Ġcomponents Ġ= Ġmutable ListOf < FromJson Component >() ĊĊĠĠĠ Ġ// ĠAdd Ġparameters Ġ( Â ± Ġproperties ) Ġfirst , Ġtheir Ġindex Ġmatters ĊĠĠĠ Ġfor Ġ(( index , Ġparameter ) Ġin Ġtarget Constructor Params ) Ġ{ ĊĠĠĠĠĠ Ġval Ġproperty Ġ= Ġproperties ByIndex [ index ] ĊĠĠĠĠĠ Ġif Ġ( property Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcomponents Ġ+= ĠParameter Only ( parameter ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġcomponents Ġ+= ĠParameter Property ( parameter , Ġproperty ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠNow Ġadd Ġthe Ġremaining Ġproperties Ġthat Ġaren 't Ġparameters ĊĠĠĠ Ġfor Ġ( property Ġin Ġproperty List ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( property . target . parameter Index Ġin Ġtarget Constructor Params ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue Ġ// ĠAlready Ġhandled ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġif Ġ( property . is Transient ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue Ġ// ĠWe Ġdon 't Ġcare Ġabout Ġthese Ġoutside Ġof Ġconstructor Ġparameters ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġcomponents Ġ+= ĠProperty Only ( property ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠCalculate Ġhow Ġmany Ġmasks Ġwe 'll Ġneed . ĠRound Ġup Ġif Ġit 's Ġnot Ġeven ly Ġdiv isible Ġby Ġ 3 2 ĊĠĠĠ Ġval Ġproperty Count Ġ= Ġtarget Constructor Params . size ĊĠĠĠ Ġval Ġmask Count Ġ= Ġif Ġ( property Count Ġ== Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠ 0 ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġ( property Count Ġ+ Ġ 3 1 ) Ġ/ Ġ 3 2 ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// ĠAllocate Ġmask Ġnames ĊĠĠĠ Ġval Ġmask Names Ġ= ĠArray ( mask Count ) Ġ{ Ġindex Ġ-> ĊĠĠĠĠĠ Ġname Allocator . new Name (" mask $ index ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġuse Defaults Constructor Ġ= Ġcomponents . filter Is Instance < Parameter Component >() ĊĠĠĠĠĠĠĠ Ġ. any Ġ{ Ġit . parameter . has Default Ġ} ĊĠĠĠ Ġif Ġ( use Defaults Constructor ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠInitialize Ġall Ġour Ġmasks , Ġdefault ing Ġto Ġfully Ġunset Ġ(- 1 ) ĊĠĠĠĠĠ Ġfor Ġ( mask Name Ġin Ġmask Names ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . add Statement (" var Ġ% L Ġ= Ġ- 1 ", Ġmask Name ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠĠĠ Ġ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 ) ĊĊĠĠĠ Ġ// ĠWe Ġtrack Ġproperty Ġindex Ġand Ġmask Ġindex Ġseparately , Ġbecause Ġmask Ġindex Ġis Ġbased Ġon Ġ_ all _ ĊĠĠĠ Ġ// Ġconstructor Ġarguments , Ġwhile Ġproperty Ġindex Ġis Ġonly Ġbased Ġon Ġthe Ġindex Ġpassed Ġinto ĊĠĠĠ Ġ// ĠJson Reader . Options . ĊĠĠĠ Ġvar Ġproperty Index Ġ= Ġ 0 ĊĠĠĠ Ġval Ġconstructor Property Types Ġ= Ġmutable ListOf < Code Block >() ĊĊĠĠĠ Ġ// ĊĠĠĠ Ġ// ĠTrack Ġimportant Ġindices Ġfor Ġmasks . ĠMask s Ġgenerally Ġincrement Ġwith Ġeach Ġparameter Ġ( including ĊĠĠĠ Ġ// Ġtransient ). ĊĠĠĠ Ġ// ĊĠĠĠ Ġ// ĠMask Ġname Ġindex Ġis Ġan Ġindex Ġinto Ġthe Ġmask Names Ġarray Ġwe Ġinitialized Ġabove . ĊĠĠĠ Ġ// ĊĠĠĠ Ġ// ĠOnce Ġthe Ġmask Index Ġreaches Ġ 3 2 , Ġwe 've Ġfilled Ġup Ġthat Ġmask Ġand Ġhave Ġto Ġmove Ġto Ġthe Ġnext Ġmask ĊĠĠĠ Ġ// Ġname . ĠReset Ġthe Ġmask Index Ġrelative Ġto Ġhere Ġand Ġcontinue Ġincrement ing . ĊĠĠĠ Ġ// ĊĠĠĠ Ġvar Ġmask Index Ġ= Ġ 0 ĊĠĠĠ Ġvar Ġmask Name Index Ġ= Ġ 0 ĊĠĠĠ Ġval Ġupdate Mask Indexes Ġ= Ġ{ ĊĠĠĠĠĠ Ġmask Index ++ ĊĠĠĠĠĠ Ġif Ġ( mask Index Ġ== Ġ 3 2 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠMove Ġto Ġthe Ġnext Ġmask ĊĠĠĠĠĠĠĠ Ġmask Index Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġmask Name Index ++ ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfor Ġ( input Ġin Ġcomponents ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( input Ġis ĠParameter Only Ġ|| ĊĠĠĠĠĠĠĠĠĠ Ġ( input Ġis ĠParameter Property Ġ&& Ġinput . property . is Transient )) Ġ{ ĊĠĠĠĠĠĠĠ Ġupdate Mask Indexes () ĊĠĠĠĠĠĠĠ Ġconstructor Property Types Ġ+= Ġinput . type . as Type Block () ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( input Ġis ĠProperty Only Ġ&& Ġinput . property . is Transient ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġ// ĠWe 've Ġremoved Ġall Ġparameter - only Ġtypes Ġby Ġthis Ġpoint ĊĠĠĠĠĠ Ġval Ġproperty Ġ= Ġ( input Ġas ĠProperty Component ). property ĊĊĠĠĠĠĠ Ġ// ĠPro ceed Ġas Ġusual ĊĠĠĠĠĠ Ġif Ġ( property . has Local Is Present Name Ġ|| Ġproperty . has Constructor Default ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult . begin Control Flow ("% L Ġ-> ", Ġproperty 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 Ġ= Ġunexpected Null ( property , Ġreader Param ) ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% N Ġ= Ġ% N . fromJson (% N ) Ġ?: Ġthrow Â· % L ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param , Ġexception ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( property . has Constructor Default ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġinverted Ġ= Ġ( 1 Ġshl Ġmask Index ). inv () ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Comment ("\ $ mask Ġ= Ġ\$ mask Ġand Ġ( 1 Ġshl Ġ% L ). inv ()", Ġmask Index ) ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% 1 L Ġ= Ġ% 1 L Ġand Ġ 0 x % 2 L . toInt ()", Ġmask Names [ mask Name Index ], ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠInteger . to HexString ( inverted )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠPres ence Ġtracker Ġfor Ġa Ġmutable Ġproperty ĊĠĠĠĠĠĠĠĠĠ Ġ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 )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty Index , Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġexception Ġ= Ġunexpected Null ( property , Ġreader Param ) ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Statement ("% L Ġ-> Ġ% N Ġ= Ġ% N . fromJson (% N ) Ġ?: Ġthrow Â· % L ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty Index , Ġproperty . local Name , Ġname Allocator [ property . delegate Key ], Ġreader Param , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexception ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġif Ġ( property . has Constructor Parameter ) Ġ{ ĊĠĠĠĠĠĠĠ Ġconstructor Property Types Ġ+= Ġproperty . target . type . as Type Block () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġproperty Index ++ ĊĠĠĠĠĠ Ġupdate Mask Indexes () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ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 ) ĊĊĠĠĠ Ġvar Ġseparator Ġ= Ġ"\ n " ĊĊĠĠĠ Ġval Ġresult Name Ġ= Ġname Allocator . new Name (" result ") ĊĠĠĠ Ġval Ġhas Non Constructor Properties Ġ= Ġnon Transient Properties . any Ġ{ Ġ! it . has Constructor Parameter Ġ} ĊĠĠĠ Ġval Ġreturn Or Result Assignment Ġ= Ġif Ġ( has Non Constructor Properties ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠSave Ġthe Ġresult Ġvar Ġfor Ġreuse ĊĠĠĠĠĠ ĠCode Block . of (" val Ġ% N Ġ= Ġ", Ġresult Name ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠCode Block . of (" return Â· ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġif Ġ( use Defaults Constructor ) Ġ{ ĊĠĠĠĠĠ Ġclass Builder . addProperty ( constructor Property ) ĊĠĠĠĠĠ Ġ// ĠDynamic Ġdefault Ġconstructor Ġcall ĊĠĠĠĠĠ Ġval Ġnon Null Constructor Type Ġ= Ġconstructor Property . type . copy ( nullable Ġ= Ġfalse ) ĊĠĠĠĠĠ Ġval Ġargs Ġ= Ġconstructor Property Types ĊĠĠĠĠĠĠĠĠĠ Ġ. plus ( 0 . until ( mask Count ). map Ġ{ ĠINT _ TYPE _ BLOCK Ġ}) Ġ// ĠMask s , Ġone Ġevery Ġ 3 2 Ġparams ĊĠĠĠĠĠĠĠĠĠ Ġ. plus ( DEFAULT _ CON STRUCTOR _ MARKER _ TYPE _ BLOCK ) Ġ// ĠDefault Ġconstructor Ġmarker Ġis Ġalways Ġlast ĊĠĠĠĠĠĠĠĠĠ Ġ. join To Code (", Ġ") ĊĠĠĠĠĠ Ġval Ġcore Lookup Block Ġ= ĠCode Block . of ( ĊĠĠĠĠĠĠĠĠĠ Ġ"% T :: class . java . getDeclared Constructor (% L )", ĊĠĠĠĠĠĠĠĠĠ Ġoriginal Raw TypeName , ĊĠĠĠĠĠĠĠĠĠ Ġargs ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġval Ġlookup Block Ġ= Ġif Ġ( original TypeName Ġis ĠParameter ized TypeName ) Ġ{ ĊĠĠĠĠĠĠĠ ĠCode Block . of (" (% L Â· as Â· % T )", Ġcore Lookup Block , Ġnon Null Constructor Type ) ĊĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġcore Lookup Block ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġinitializer Block Ġ= ĠCode Block . of ( ĊĠĠĠĠĠĠĠĠĠ Ġ" this .% 1 N Â· ?: Ġ% 2 L . also Â· { Ġthis .% 1 N Â· = Ġit Ġ} ", ĊĠĠĠĠĠĠĠĠĠ Ġconstructor Property , ĊĠĠĠĠĠĠĠĠĠ Ġlookup Block ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġval Ġlocal Constructor Property Ġ= ĠProperty Spec . builder ( ĊĠĠĠĠĠĠĠĠĠ Ġname Allocator . new Name (" local Constructor "), ĊĠĠĠĠĠĠĠĠĠ Ġnon Null Constructor Type ) ĊĠĠĠĠĠĠĠĠĠ Ġ. add Annotation ( Annotation Spec . builder ( Suppress :: class ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Member ("% S ", Ġ" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠĠĠĠĠĠĠ Ġ. initializer ( initializer Block ) ĊĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠ Ġresult . add Code ("% L ", Ġlocal Constructor Property ) ĊĠĠĠĠĠ Ġresult . add Code ( ĊĠĠĠĠĠĠĠĠĠ Ġ" Â « % L % N . newInstance (", ĊĠĠĠĠĠĠĠĠĠ Ġreturn Or Result Assignment , ĊĠĠĠĠĠĠĠĠĠ Ġlocal Constructor Property ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġ// ĠStandard Ġconstructor Ġcall . ĠDon 't Ġomit Ġgener ics Ġfor Ġparameter ized Ġtypes Ġeven Ġif Ġthey Ġcan Ġbe ĊĠĠĠĠĠ Ġ// Ġinferred , Ġas Ġcalculating Ġthe Ġright Ġcondition Ġfor Ġinference Ġexceeds Ġthe Ġvalue Ġg ained Ġfrom ĊĠĠĠĠĠ Ġ// Ġbeing Ġless Ġped antic . ĊĠĠĠĠĠ Ġresult . add Code (" Â « % L % T (", Ġreturn Or Result Assignment , Ġoriginal TypeName ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfor Ġ( input Ġin Ġcomponents . filter Is Instance < Parameter Component >()) Ġ{ ĊĠĠĠĠĠ Ġresult . add Code ( separator ) ĊĠĠĠĠĠ Ġif Ġ( use Defaults Constructor ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( input Ġis ĠParameter Only Ġ|| Ġ( input Ġis ĠParameter Property Ġ&& Ġinput . property . is Transient )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġhave Ġto Ġuse Ġthe Ġdefault Ġprimitive Ġfor Ġthe Ġavailable Ġtype Ġin Ġorder Ġfor ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġinvoke Default Constructor Ġto Ġproperly Ġinvoke Ġit . ĠJust Ġusing Ġ" null " Ġisn 't Ġsafe Ġbecause ĊĠĠĠĠĠĠĠĠĠ Ġ// Ġthe Ġtransient Ġtype Ġmay Ġbe Ġa Ġprimitive Ġtype . ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Code ( input . type . raw Type (). default Primitive Value ()) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Code ("% N ", Ġ( input Ġas ĠParameter Property ). property . local Name ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( input Ġ! is ĠParameter Only ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġproperty Ġ= Ġ( input Ġas ĠParameter Property ). property ĊĠĠĠĠĠĠĠ Ġresult . add Code ("% N Ġ= Ġ% N ", Ġproperty . name , Ġproperty . local Name ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġif Ġ( input Ġis ĠProperty Component ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġproperty Ġ= Ġinput . property ĊĠĠĠĠĠĠĠ Ġif Ġ(! property . is Transient Ġ&& Ġproperty . isRequired ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġmissing Property Block Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCode Block . of ("% T . missing Property (% S , Ġ% S , Ġ% N )", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMO SH I _ UTIL , Ġproperty . local Name , Ġproperty . json Name , Ġreader Param ) ĊĠĠĠĠĠĠĠĠĠ Ġresult . add Code (" Ġ?: Ġthrow Â· % L ", Ġmissing Property Block ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġseparator Ġ= Ġ", \ n " ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( use Defaults Constructor ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠAdd Ġthe Ġmasks Ġand Ġa Ġnull Ġinstance Ġfor Ġthe Ġtrailing Ġdefault Ġmarker Ġinstance ĊĠĠĠĠĠ Ġresult . add Code (", \ n % L ,\ n null ", Ġmask Names . map Ġ{ ĠCode Block . of ("% L ", Ġit ) Ġ}. join To Code (", Ġ")) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġresult . add Code ("\ n Â» )\ n ") ĊĊĠĠĠ Ġ// ĠAssign Ġproperties Ġnot Ġpresent Ġin Ġthe Ġconstructor . ĊĠĠĠ Ġfor Ġ( property Ġin Ġnon Transient Properties ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( property . has Constructor Parameter ) Ġ{ ĊĠĠĠĠĠĠĠ Ġcontinue Ġ// ĠProperty Ġalready Ġhandled . ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġif Ġ( property . has Local Is Present Name ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ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 ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( has Non Constructor Properties ) Ġ{ ĊĠĠĠĠĠ Ġresult . add Statement (" return Â· % 1 N ", Ġresult Name ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġunexpected Null ( property : ĠProperty Generator , Ġreader : ĠParameter Spec ): ĠCode Block Ġ{ ĊĠĠĠ Ġreturn ĠCode Block . of ("% T . unexpected Null (% S , Ġ% S , Ġ% N )", ĊĠĠĠĠĠĠĠ ĠMO SH I _ UTIL , Ġproperty . local Name , Ġproperty . json Name , Ġreader ) ĊĠ Ġ} ĊĊĠ Ġ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 ) ĊĠĠĠ Ġnon Transient Properties . forEach Ġ{ Ġproperty Ġ-> ĊĠĠĠĠĠ Ġ// ĠWe Ġmanually Ġput Ġin Ġquotes Ġbecause Ġwe Ġknow Ġthe Ġjson Name Ġis Ġalready Ġescaped ĊĠĠĠĠĠ Ġresult . add Statement ("% N . name (% S )", Ġwriter Param , Ġproperty . json Name ) ĊĠĠĠĠĠ Ġresult . add Statement ("% N . toJson (% N , Ġ% N .% N )", ĊĠĠĠĠĠĠĠĠĠ Ġname Allocator [ property . delegate Key ], Ġwriter Param , Ġvalue Param , Ġproperty . name ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġresult . add Statement ("% N . end Object ()", Ġwriter Param ) ĊĊĠĠĠ Ġreturn Ġresult . build () ĊĠ Ġ} Ċ } Ċ Ċ /** ĠRepresents Ġa Ġprepared Ġadapter Ġwith Ġits Ġ[ spec ] Ġand Ġoptional Ġassociated Ġ[ pro guard Config ]. Ġ*/ Ċ internal Ġdata Ġclass ĠPrepared Adapter ( val Ġspec : ĠFile Spec , Ġval Ġpro guard Config : ĠPro guard Config ?) Ċ Ċ private Ġfun ĠA sm Type . to Reflection String (): ĠString Ġ{ ĊĠ Ġreturn Ġwhen Ġ( this ) Ġ{ ĊĠĠĠ ĠA sm Type . VOID _ TYPE Ġ-> Ġ" void " ĊĠĠĠ ĠA sm Type . BOOLEAN _ TYPE Ġ-> Ġ" boolean " ĊĠĠĠ ĠA sm Type . CHAR _ TYPE Ġ-> Ġ" char " ĊĠĠĠ ĠA sm Type . BYTE _ TYPE Ġ-> Ġ" byte " ĊĠĠĠ ĠA sm Type . SHORT _ TYPE Ġ-> Ġ" short " ĊĠĠĠ ĠA sm Type . INT _ TYPE Ġ-> Ġ" int " ĊĠĠĠ ĠA sm Type . FLOAT _ TYPE Ġ-> Ġ" float " ĊĠĠĠ ĠA sm Type . LONG _ TYPE Ġ-> Ġ" long " ĊĠĠĠ ĠA sm Type . DOUBLE _ TYPE Ġ-> Ġ" double " ĊĠĠĠ Ġelse Ġ-> Ġwhen Ġ( sort ) Ġ{ ĊĠĠĠĠĠ ĠA sm Type . ARRAY Ġ-> Ġ"${ elementType . to Reflection String ()} []" ĊĠĠĠĠĠ Ġ// ĠObject Ġtype ĊĠĠĠĠĠ Ġelse Ġ-> ĠclassName ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ private Ġinterface ĠProperty Component Ġ{ ĊĠ Ġval Ġproperty : ĠProperty Generator ĊĠ Ġval Ġtype : ĠType Name Ċ } Ċ Ċ private Ġinterface ĠParameter Component Ġ{ ĊĠ Ġval Ġparameter : ĠTarget Parameter ĊĠ Ġval Ġtype : ĠType Name Ċ } Ċ Ċ /** Ċ Ġ* ĠType Ġhierarchy Ġfor Ġdescribing Ġfrom Json () Ġcomponents . ĠSpecific ally Ġ- Ġparameters , Ġproperties , Ġand Ċ Ġ* Ġparameter Ġproperties . ĠAll Ġthree Ġof Ġthese Ġscenarios Ġparticip ate Ġin Ġfrom Json () Ġparsing . Ċ Ġ*/ Ċ private Ġsealed Ġclass ĠFrom Json Component Ġ{ ĊĊĠ Ġabstract Ġval Ġtype : ĠType Name ĊĊĠ Ġdata Ġclass ĠParameter Only ( ĊĠĠĠĠĠ Ġoverride Ġval Ġparameter : ĠTarget Parameter ĊĠ Ġ) Ġ: ĠFrom Json Component (), ĠParameter Component Ġ{ ĊĠĠĠ Ġoverride Ġval Ġtype : ĠType Name Ġ= Ġparameter . type ĊĠ Ġ} ĊĊĠ Ġdata Ġclass ĠProperty Only ( ĊĠĠĠĠĠ Ġoverride Ġval Ġproperty : ĠProperty Generator ĊĠ Ġ) Ġ: ĠFrom Json Component (), ĠProperty Component Ġ{ ĊĠĠĠ Ġoverride Ġval Ġtype : ĠType Name Ġ= Ġproperty . target . type ĊĠ Ġ} ĊĊĠ Ġdata Ġclass ĠParameter Property ( ĊĠĠĠĠĠ Ġoverride Ġval Ġparameter : ĠTarget Parameter , ĊĠĠĠĠĠ Ġoverride Ġval Ġproperty : ĠProperty Generator ĊĠ Ġ) Ġ: ĠFrom Json Component (), ĠParameter Component , ĠProperty Component Ġ{ ĊĠĠĠ Ġoverride Ġval Ġtype : ĠType Name Ġ= Ġparameter . type ĊĠ Ġ} Ċ } Ċ