/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 Ġ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 Ġapp . cash . temp est . internal Ċ Ċ import Ġapp . cash . temp est . Codec Ċ import Ġcom . amazonaws . services . dynamodb v 2 . model . AttributeValue Ċ import Ġkotlin . reflect . K Class Ċ import Ġkotlin . reflect . K Function Ċ import Ġkotlin . reflect . K Mutable Property 1 Ċ import Ġkotlin . reflect . K Parameter Ċ import Ġkotlin . reflect . K Property Ċ import Ġkotlin . reflect . K Property 1 Ċ import Ġkotlin . reflect . full . member Properties Ċ import Ġkotlin . reflect . full . primary Constructor Ċ import Ġkotlin . reflect . full . with Null ability Ċ import Ġkotlin . reflect . jvm . is Accessible Ċ import Ġkotlin . reflect . jvm . java Field Ċ Ċ internal Ġobject ĠIdentity Codec Ġ: ĠCodec < Any , ĠAny > Ġ{ ĊĠ Ġoverride Ġfun Ġto Db ( app Item : ĠAny ): ĠAny Ġ= Ġapp Item ĊĠ Ġoverride Ġfun Ġto App ( db Item : ĠAny ): ĠAny Ġ= Ġdb Item Ċ } Ċ Ċ /** Ċ Ġ* ĠThis Ġbind s Ġa Ġpair Ġof Ġobjects : Ġan Ġapp Ġitem Ġand Ġa Ġdb Ġitem . ĠThe Ġproperty Ġnames Ġof Ġapp Ġitem Ġis Ġa Ċ Ġ* Ġsubset Ġof Ġthat Ġof Ġdb Ġitem . ĠThe Ġapp Ġitem Ġcan Ġhave Ġa Ġprimary Ġconstructor , Ġvars , Ġand Ġvals , Ġwhile Ċ Ġ* Ġthe Ġdb Ġitem Ġcan Ġonly Ġhave Ġvars . Ċ Ġ*/ Ċ internal Ġclass ĠReflection Codec < A Ġ: ĠAny , ĠD Ġ: ĠAny > Ġprivate Ġconstructor ( ĊĠ Ġprivate Ġval Ġapp Item Constructor : ĠK Function < A > ?, ĊĠ Ġprivate Ġval Ġapp Item Class Factory : ĠClass Factory < A >, ĊĠ Ġprivate Ġval Ġdb Item Constructor : ĠK Function < D > ?, ĊĠ Ġprivate Ġval Ġdb Item Class Factory : ĠClass Factory < D >, ĊĠ Ġprivate Ġval Ġconstructor Parameters : ĠList < Constructor Parameter Binding < A , ĠD , ĠAny ? >>, ĊĠ Ġprivate Ġval Ġvar Bindings : ĠList < Var Binding < A , ĠD , ĠAny ? >>, ĊĠ Ġprivate Ġval Ġval Bindings : ĠList < Val Binding < A , ĠD , ĠAny ? >>, ĊĠ Ġprivate Ġval Ġprefix er : ĠPrefix er < D > Ċ ) Ġ: ĠCodec < A , ĠD > Ġ{ ĊĊĠ Ġoverride Ġfun Ġto Db ( app Item : ĠA ): ĠD Ġ{ ĊĠĠĠ Ġval Ġdb Item Ġ= Ġdb Item Constructor ?. call () Ġ?: Ġdb Item Class Factory . newInstance () ĊĠĠĠ Ġfor Ġ( binding Ġin Ġconstructor Parameters ) Ġ{ ĊĠĠĠĠĠ Ġbinding . set Db ( db Item , Ġbinding . getApp ( app Item )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġfor Ġ( binding Ġin Ġvar Bindings ) Ġ{ ĊĠĠĠĠĠ Ġbinding . set Db ( db Item , Ġbinding . getApp ( app Item )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġfor Ġ( binding Ġin Ġval Bindings ) Ġ{ ĊĠĠĠĠĠ Ġbinding . set Db ( db Item , Ġbinding . getApp ( app Item )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġprefix er . add Prefix ( db Item ) ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġto App ( db Item : ĠD ): ĠA Ġ{ ĊĠĠĠ Ġval Ġdb Item Ġ= Ġprefix er . remove Prefix ( db Item ) ĊĠĠĠ Ġval Ġconstructor Args Ġ= Ġconstructor Parameters ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . parameter Ġto Ġit . get Db ( db Item ) Ġ} ĊĠĠĠĠĠĠĠ Ġ. toMap () ĊĠĠĠ Ġval Ġapp Item Ġ= ĊĠĠĠĠĠ Ġapp Item Constructor ?. call By ( constructor Args ) Ġ?: Ġapp Item Class Factory . newInstance () ĊĠĠĠ Ġfor Ġ( binding Ġin Ġvar Bindings ) Ġ{ ĊĠĠĠĠĠ Ġbinding . set App ( app Item , Ġbinding . get Db ( db Item )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġapp Item ĊĠ Ġ} ĊĊĠ Ġinternal Ġclass ĠFactory Ġ{ ĊĊĠĠĠ Ġfun Ġcreate ( ĊĠĠĠĠĠ Ġitem Type : ĠK Class <* >, ĊĠĠĠĠĠ Ġitem Attributes : ĠMap < String , ĠItem Type . Attribute >, ĊĠĠĠĠĠ Ġraw ItemType : ĠRaw ItemType ĊĠĠĠ Ġ): ĠCodec < Any , ĠAny > Ġ{ ĊĠĠĠĠĠ Ġval Ġdb Item Constructor Ġ= Ġrequire NotNull ( raw ItemType . type . primary Constructor Ġ?: Ġraw ItemType . type . construct ors . single OrNull ()) ĊĠĠĠĠĠ Ġrequire ( db Item Constructor . parameters . isEmpty ()) Ġ{ Ġ" Expect Ġ${ raw ItemType . type } Ġto Ġhave Ġa Ġzero Ġargument Ġconstructor " Ġ} ĊĠĠĠĠĠ Ġval Ġapp Item Constructor Parameters Ġ= Ġitem Type . primary Constructor Parameters ĊĠĠĠĠĠ Ġval Ġraw Item Properties Ġ= Ġraw ItemType . type . member Properties . associate By Ġ{ Ġit . name Ġ} ĊĠĠĠĠĠ Ġval Ġconstructor Parameter Bindings Ġ= Ġmutable ListOf < Constructor Parameter Binding < Any , ĠAny , ĠAny ? >>() ĊĠĠĠĠĠ Ġval Ġvar Bindings Ġ= Ġmutable ListOf < Var Binding < Any , ĠAny , ĠAny ? >>() ĊĠĠĠĠĠ Ġval Ġval Bindings Ġ= Ġmutable ListOf < Val Binding < Any , ĠAny , ĠAny ? >>() ĊĠĠĠĠĠ Ġfor Ġ( property Ġin Ġitem Type . member Properties ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠpropertyName Ġ= Ġproperty . name ĊĠĠĠĠĠĠĠ Ġval Ġitem Attribute Ġ= Ġitem Attributes [ propertyName ] Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠ Ġval Ġmapped Properties Ġ= Ġitem Attribute . names ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġrequire NotNull ( raw Item Properties [ it ]) Ġ{ Ġ" Expect Ġ${ raw ItemType . type } Ġto Ġhave Ġproperty Ġ$ propertyName " Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġmapped Property Types Ġ= Ġmapped Properties . map Ġ{ Ġit . returnType Ġ}. distinct () ĊĠĠĠĠĠĠĠ Ġrequire ( mapped Property Types . size Ġ== Ġ 1 ) Ġ{ Ġ" Expect Ġmapped Ġproperties Ġof Ġ$ propertyName Ġto Ġhave Ġthe Ġsame Ġtype : Ġ${ mapped Properties . map Ġ{ Ġit . name Ġ}}" Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġexpected ReturnType Ġ= Ġrequire NotNull ( mapped Property Types . single ()). with Null ability ( false ) ĊĠĠĠĠĠĠĠ Ġval Ġactual ReturnType Ġ= Ġproperty . returnType . with Null ability ( false ) ĊĠĠĠĠĠĠĠ Ġrequire ( actual ReturnType Ġ== Ġexpected ReturnType ) Ġ{ Ġ" Expect Ġthe Ġreturn Ġtype Ġof Ġ$ item Type .${ property . name } Ġto Ġbe Ġ$ expected ReturnType Ġbut Ġwas Ġ$ actual ReturnType " Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( app Item Constructor Parameters . contains ( propertyName )) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġconstructor Parameter Bindings . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠConstructor Parameter Binding ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproperty Ġas ĠK Property 1 < Any , ĠAny ? >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġapp Item Constructor Parameters [ propertyName ] !! , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmapped Properties )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( property . is Var ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġvar Bindings . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠVar Binding ( property Ġas ĠK Property 1 < Any , ĠAny ? >, Ġmapped Properties )) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Bindings . add ( Val Binding ( property Ġas ĠK Property 1 < Any , ĠAny ? >, Ġmapped Properties )) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġval Ġprefix er Ġ= ĠPrefix er < Any >( item Attributes , Ġraw ItemType ) ĊĠĠĠĠĠ Ġreturn ĠReflection Codec ( ĊĠĠĠĠĠĠĠĠĠ Ġitem Type . primary Constructor , ĊĠĠĠĠĠĠĠĠĠ ĠClass Factory . create ( item Type . java ), ĊĠĠĠĠĠĠĠĠĠ Ġdb Item Constructor , ĊĠĠĠĠĠĠĠĠĠ ĠClass Factory . create ( raw ItemType . type . java ), ĊĠĠĠĠĠĠĠĠĠ Ġconstructor Parameter Bindings , ĊĠĠĠĠĠĠĠĠĠ Ġvar Bindings , ĊĠĠĠĠĠĠĠĠĠ Ġval Bindings , ĊĠĠĠĠĠĠĠĠĠ Ġprefix er ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠAdds Ġprefixes Ġto Ġand Ġremoves Ġprefixes Ġfrom Ġproperties Ġof Ġa Ġdb Ġitem . Ċ Ġ*/ Ċ private Ġclass ĠPrefix er < D Ġ: ĠAny >( ĊĠ Ġprivate Ġval Ġitem Attributes : ĠMap < String , ĠItem Type . Attribute >, ĊĠ Ġprivate Ġval Ġraw ItemType : ĠRaw ItemType Ċ ) Ġ{ ĊĊĠ Ġfun Ġadd Prefix ( db Item : ĠD ): ĠD Ġ{ ĊĠĠĠ Ġval Ġattribute Values Ġ= Ġraw ItemType . table Model . convert ( db Item ). to Mutable Map () ĊĠĠĠ Ġval Ġattribute Prefixes Ġ= Ġitem Attributes . values ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġattribute Ġ-> Ġattribute . prefix . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġattribute Ġ-> Ġattribute . names . map Ġ{ Ġit Ġto Ġattribute . prefix Ġ} Ġ} ĊĠĠĠ Ġfor Ġ(( attribute Name , Ġprefix ) Ġin Ġattribute Prefixes ) Ġ{ ĊĠĠĠĠĠ Ġval Ġattribute Value Ġ= Ġattribute Values [ attribute Name ] ĊĠĠĠĠĠ Ġif Ġ( attribute Value Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġattribute Values [ attribute Name ] Ġ= ĠAttribute Value ( prefix ) ĊĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġrequire NotNull ( attribute Value . s ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Expect Ġ${ raw ItemType . type }. $ attribute Name Ġto Ġbe Ġmapped Ġto Ġa Ġstring " ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġattribute Values [ attribute Name ] Ġ= ĠAttribute Value ( prefix Ġ+ Ġattribute Value . s ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġraw ItemType . table Model . un convert ( attribute Values ) Ġas ĠD ĊĠ Ġ} ĊĊĠ Ġfun Ġremove Prefix ( db Item : ĠD ): ĠD Ġ{ ĊĠĠĠ Ġval Ġattribute Values Ġ= Ġraw ItemType . table Model . convert ( db Item ). to Mutable Map () ĊĠĠĠ Ġval Ġattribute Prefixes Ġ= Ġitem Attributes . values ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġattribute Ġ-> Ġattribute . prefix . isNotEmpty () Ġ} ĊĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġattribute Ġ-> Ġattribute . names . map Ġ{ Ġit Ġto Ġattribute . prefix Ġ} Ġ} ĊĠĠĠ Ġfor Ġ(( attribute Name , Ġprefix ) Ġin Ġattribute Prefixes ) Ġ{ ĊĠĠĠĠĠ Ġval Ġattribute Value Ġ= Ġrequire NotNull ( attribute Values [ attribute Name ]) ĊĠĠĠĠĠ Ġrequire NotNull ( attribute Value . s ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" Expect Ġ${ raw ItemType . type }. $ attribute Name Ġto Ġbe Ġmapped Ġto Ġa Ġstring " ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġattribute Values [ attribute Name ] Ġ= ĠAttribute Value ( attribute Value . s . remove Prefix ( prefix )) ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġraw ItemType . table Model . un convert ( attribute Values ) Ġas ĠD ĊĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠOne Ġapp Ġitem Ġproperty Ġmaps Ġto Ġone Ġor Ġmore Ġdb Ġitem Ġproperties . Ċ Ġ*/ Ċ private Ġsealed Ġclass ĠBinding < A , ĠD , ĠP > Ġ{ ĊĠ Ġabstract Ġval Ġapp Property : ĠK Property 1 < A , ĠP > ĊĠ Ġabstract Ġval Ġdb Properties : ĠList < K Property 1 < D , ĠP >> ĊĊĠ Ġfun Ġget App ( value : ĠA ) Ġ= Ġapp Property . get ( value ) ĊĊĠ Ġfun Ġget Db ( value : ĠD ) Ġ= Ġdb Properties [ 0 ]. get ( value ) ĊĊĠ Ġfun Ġset Db ( result : ĠD , Ġvalue : ĠP ) Ġ{ ĊĠĠĠ Ġfor Ġ( raw Property Ġin Ġdb Properties ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ(! raw Property . is Accessible ) Ġ{ ĊĠĠĠĠĠĠĠ Ġraw Property . java Field ?. try Set Accessible () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ( raw Property Ġas ĠK Mutable Property 1 < D , ĠP >). set ( result , Ġvalue ) ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠConstructor Parameter Binding < A , ĠD , ĠP >( ĊĠ Ġoverride Ġval Ġapp Property : ĠK Property 1 < A , ĠP >, ĊĠ Ġval Ġparameter : ĠK Parameter , ĊĠ Ġoverride Ġval Ġdb Properties : ĠList < K Property 1 < D , ĠP >> Ċ ) Ġ: ĠBinding < A , ĠD , ĠP >() Ċ Ċ private Ġclass ĠVal Binding < A , ĠD , ĠP >( ĊĠ Ġoverride Ġval Ġapp Property : ĠK Property 1 < A , ĠP >, ĊĠ Ġoverride Ġval Ġdb Properties : ĠList < K Property 1 < D , ĠP >> Ċ ) Ġ: ĠBinding < A , ĠD , ĠP >() Ċ Ċ private Ġclass ĠVar Binding < A , ĠD , ĠP >( ĊĠ Ġoverride Ġval Ġapp Property : ĠK Property 1 < A , ĠP >, ĊĠ Ġoverride Ġval Ġdb Properties : ĠList < K Property 1 < D , ĠP >> Ċ ) Ġ: ĠBinding < A , ĠD , ĠP >() Ġ{ ĊĊĠ Ġfun Ġset App ( result : ĠA , Ġvalue : ĠP ) Ġ{ ĊĠĠĠ Ġapp Property . force Set ( result , Ġvalue ) ĊĠ Ġ} Ċ } Ċ Ċ val ĠK Property <* >. is Var : ĠBoolean ĊĠ Ġget () Ġ= Ġjava Field Ġ!= Ġnull Ċ Ċ fun Ġ< T , ĠR > ĠK Property 1 < T , ĠR >. force Set ( receiver : ĠT , Ġvalue : ĠR ) Ġ{ ĊĠ Ġif Ġ(! is Accessible ) Ġ{ ĊĠĠĠ Ġjava Field !!. try Set Accessible () ĊĠ Ġ} ĊĠ Ġif Ġ( this Ġis ĠK Mutable Property 1 < T , ĠR >) Ġ{ ĊĠĠĠ Ġset ( receiver , Ġvalue ) ĊĠĠĠ Ġreturn ĊĠ Ġ} ĊĠ Ġjava Field !!. set ( receiver , Ġvalue ) Ċ } Ċ