package Ġorg . kom apper . k sp Ċ Ċ import Ġcom . google . devtools . k sp . getDeclared Properties Ċ import Ġcom . google . devtools . k sp . symbol . KS Class Declaration Ċ import Ġcom . google . devtools . k sp . symbol . KS Node Ċ import Ġcom . google . devtools . k sp . symbol . KS Value Parameter Ċ import Ġcom . google . devtools . k sp . symbol . Modifier Ċ import Ġcom . google . devtools . k sp . visitor . K SE mpty Visitor Ċ Ċ internal Ġclass ĠEntity Visitor Ġ: ĠK SE mpty Visitor < Unit , ĠEntity Visit Result >() Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġdefault Handler ( node : ĠK S Node , Ġdata : ĠUnit ): ĠEntity Visit Result Ġ{ ĊĠĠĠĠĠĠĠ Ġerror (" The Ġnode Ġmust Ġbe ĠK S Class Declaration .") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit Class Declaration ( class Declaration : ĠK S Class Declaration , Ġdata : ĠUnit ): ĠEntity Visit Result Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfactory Ġ= ĠEntity Factory ( class Declaration ) ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentity Ġ= Ġfactory . create () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEntity Visit Result . Success ( entity ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠExit ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEntity Visit Result . Failure ( class Declaration , Ġe ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠEntity Factory ( private Ġval Ġclass Declaration : ĠK S Class Declaration ) Ġ{ ĊĠĠĠ Ġfun Ġcreate (): ĠEntity Ġ{ ĊĠĠĠĠĠĠĠ Ġvalidate KS Class Declaration ( class Declaration ) ĊĠĠĠĠĠĠĠ Ġval ĠtableName Ġ= ĠtableName ( class Declaration ) ĊĠĠĠĠĠĠĠ Ġval Ġmap Ġ= Ġclass Declaration . getDeclared Properties (). associate By Ġ{ Ġit . simple Name Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġall Properties Ġ= Ġclass Declaration . primary Constructor ?. parameters ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . map Ġ{ Ġparameter Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdeclaration Ġ= Ġmap [ parameter . name ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreport (" The Ġcorresponding Ġproperty Ġis Ġnot Ġfound .", Ġparameter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠcolumnName Ġ= ĠcolumnName ( parameter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= Ġparameter . type . resolve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠtypeName Ġ= Ġ( type . declaration . qualified Name Ġ?: Ġtype . declaration . simple Name ). asString () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnull ability Ġ= Ġtype . null ability ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkind Ġ= Ġproperty Kind ( parameter ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgenerator Kind Ġ= Ġid Generator Kind ( parameter , Ġkind ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProperty ( parameter , Ġdeclaration , ĠcolumnName , ĠtypeName , Ġnull ability , Ġkind , Ġgenerator Kind ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ?. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalidate Properties ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġempty Sequence () ĊĠĠĠĠĠĠĠ Ġval Ġid Properties Ġ= Ġall Properties . filter Ġ{ Ġit . kind Ġis ĠProperty Kind . Id Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġversion Property : ĠProperty ? Ġ= Ġall Properties . first OrNull Ġ{ Ġit . kind Ġis ĠProperty Kind . Version Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠcreatedAt Property : ĠProperty ? Ġ= Ġall Properties . first OrNull Ġ{ Ġit . kind Ġis ĠProperty Kind . CreatedAt Ġ} ĊĠĠĠĠĠĠĠ Ġval ĠupdatedAt Property : ĠProperty ? Ġ= Ġall Properties . first OrNull Ġ{ Ġit . kind Ġis ĠProperty Kind . UpdatedAt Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġignored Properties Ġ= Ġall Properties . filter Ġ{ Ġit . kind Ġis ĠProperty Kind . Ignore Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġproperties Ġ= Ġall Properties Ġ- Ġignored Properties ĊĠĠĠĠĠĠĠ Ġval Ġid Generator : ĠId Generator ? Ġ= Ġid Generator ( all Properties ) ĊĠĠĠĠĠĠĠ Ġreturn ĠEntity ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclass Declaration , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠtableName , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġproperties . toList (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Properties . toList (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġversion Property , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠcreatedAt Property , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠupdatedAt Property , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Generator ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalidate KS Class Declaration ( class Declaration : ĠK S Class Declaration ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmodifiers Ġ= Ġclass Declaration . modifiers ĊĠĠĠĠĠĠĠ Ġif Ġ(! modifiers . contains ( Modifier . DATA )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport ("@ Km Entity Ġmust Ġbe Ġapplied Ġto Ġdata Ġclass .", Ġclass Declaration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( modifiers . contains ( Modifier . PRIVATE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport ("@ Km Entity Ġcannot Ġbe Ġapplied Ġto Ġprivate Ġdata Ġclass .", Ġclass Declaration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( class Declaration . type Parameters . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport ("@ Km Entity Ġannotated Ġclass Ġmust Ġnot Ġhave Ġtype Ġparameters .", Ġclass Declaration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġvalidate Properties ( properties : ĠSequence < Property >) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( properties . any Duplicates Ġ{ Ġit . kind Ġis ĠProperty Kind . Version Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport (" Multiple Ġ@ Km Version Ġcannot Ġco exist Ġin Ġa Ġsingle Ġclass .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( properties . any Duplicates Ġ{ Ġit . kind Ġis ĠProperty Kind . CreatedAt Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport (" Multiple Ġ@ Km CreatedAt Ġcannot Ġco exist Ġin Ġa Ġsingle Ġclass .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( properties . any Duplicates Ġ{ Ġit . kind Ġis ĠProperty Kind . UpdatedAt Ġ}) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport (" Multiple Ġ@ Km UpdatedAt Ġcannot Ġco exist Ġin Ġa Ġsingle Ġclass .") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġpersistent Properties Ġ= Ġproperties . filter Ġ{ Ġit . kind Ġ! is ĠProperty Kind . Ignore Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( persistent Properties . none ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport (" Any Ġpersistent Ġproperties Ġare Ġnot Ġfound .", Ġclass Declaration ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġpersistent Properties . first OrNull Ġ{ Ġit . is Private () Ġ} ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport (" The Ġparameter Ġmust Ġnot Ġbe Ġprivate .", Ġit . parameter ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠtableName ( declaration : ĠK S Class Declaration ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġdeclaration . annotations ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . short Name . asString () Ġ== Ġ" Km Table " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġannotation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotation . arguments ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . name ?. asString () Ġ== Ġ" name " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . value ?. toString () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. first OrNull () Ġ?: Ġdeclaration . simple Name . asString (). toUpperCase () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠcolumnName ( parameter : ĠK S Value Parameter ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġparameter . annotations ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. as Sequence () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . short Name . asString () Ġ== Ġ" Km Column " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġannotation Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġannotation . arguments ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . name ?. asString () Ġ== Ġ" name " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . value ?. toString () Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. first OrNull () Ġ?: Ġparameter . toString (). toUpperCase () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġproperty Kind ( parameter : ĠK S Value Parameter ): ĠProperty Kind ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġid : ĠProperty Kind . Id ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġversion : ĠProperty Kind . Version ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar ĠcreatedAt : ĠProperty Kind . CreatedAt ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar ĠupdatedAt : ĠProperty Kind . UpdatedAt ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġignore : ĠProperty Kind . Ignore ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġfor Ġ( a Ġin Ġparameter . annotations ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( a . short Name . asString ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km Id " Ġ-> Ġid Ġ= ĠProperty Kind . Id ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km Version " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġversion Ġ= ĠProperty Kind . Version ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km CreatedAt " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠcreatedAt Ġ= ĠProperty Kind . CreatedAt ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km UpdatedAt " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠupdatedAt Ġ= ĠProperty Kind . UpdatedAt ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km Ignore " Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġignore Ġ= ĠProperty Kind . Ignore ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġkinds Ġ= ĠlistOf NotNull ( id , Ġversion , ĠcreatedAt , ĠupdatedAt , Ġignore ) ĊĠĠĠĠĠĠĠ Ġif Ġ( kind s . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( kind s . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġkinds . first (). also Ġ{ Ġit . check ( parameter ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġa 1 Ġ= Ġkinds [ 0 ]. annotation ĊĠĠĠĠĠĠĠ Ġval Ġa 2 Ġ= Ġkinds [ 1 ]. annotation ĊĠĠĠĠĠĠĠ Ġreport ("$ a 1 Ġand Ġ$ a 2 Ġcannot Ġco exist Ġon Ġthe Ġsame Ġparameter .", Ġparameter ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġid Generator Kind ( parameter : ĠK S Value Parameter , Ġproperty Kind : ĠProperty Kind ?): ĠId Generator Kind ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġidentity : ĠId Generator Kind . Identity ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġsequence : ĠId Generator Kind . Sequence ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġfor Ġ( a Ġin Ġparameter . annotations ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( a . short Name . asString ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km Identity Generator " Ġ-> Ġidentity Ġ= ĠId Generator Kind . Identity ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Km Sequence Generator " Ġ-> Ġsequence Ġ= ĠId Generator Kind . Sequence ( a ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġid Generator Kinds Ġ= ĠlistOf NotNull ( identity , Ġsequence ) ĊĠĠĠĠĠĠĠ Ġif Ġ( id Generator Kinds . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( id Generator Kinds . size Ġ== Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkind Ġ= Ġid Generator Kinds . first (). also Ġ{ Ġit . check ( parameter ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( property Kind Ġ! is ĠProperty Kind . Id ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreport ("${ kind . annotation } Ġand Ġ@ Km Id Ġmust Ġco exist Ġon Ġthe Ġsame Ġparameter .", Ġparameter ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġkind ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġa 1 Ġ= Ġid Generator Kinds [ 0 ]. annotation ĊĠĠĠĠĠĠĠ Ġval Ġa 2 Ġ= Ġid Generator Kinds [ 1 ]. annotation ĊĠĠĠĠĠĠĠ Ġreport ("$ a 1 Ġand Ġ$ a 2 Ġcannot Ġco exist Ġon Ġthe Ġsame Ġparameter .", Ġparameter ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġid Generator ( properties : ĠSequence < Property >): ĠId Generator ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġid Generator Properties Ġ= Ġproperties . filter Ġ{ Ġit . id Generator Kind Ġ!= Ġnull Ġ}. toList () ĊĠĠĠĠĠĠĠ Ġif Ġ( id Generator Properties . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġproperty Ġ= Ġid Generator Properties . first () ĊĠĠĠĠĠĠĠ Ġif Ġ( id Generator Properties . size Ġ> Ġ 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreport (" Multiple ĠGener ators Ġcannot Ġco exist Ġin Ġa Ġsingle Ġclass .", Ġproperty . parameter ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠId Generator ( property ) ĊĠĠĠ Ġ} Ċ } Ċ