package Ġde . fh do . lemma . model _ processing . builtin _ ph ases . code _ generation Ċ Ċ import Ġde . fh do . lemma . model _ processing . annotations . Code Generation Property Provider Ċ import Ġde . fh do . lemma . model _ processing . annotations . Model Processing Phase Ċ import Ġde . fh do . lemma . model _ processing . annotations . Cons umes Basic CommandLine Option Ċ import Ġde . fh do . lemma . model _ processing . annotations . find Annotated Classes Ċ import Ġde . fh do . lemma . model _ processing . as File Ċ import Ġde . fh do . lemma . model _ processing . builtin _ ph ases . code _ generation . Available Code Generation Modules . missing Dependency Ċ import Ġde . fh do . lemma . model _ processing . builtin _ ph ases . intermediate _ model _ validation . Intermediate Model Validation Phase Ċ import Ġde . fh do . lemma . model _ processing . ph ases . Abstract Model Processing Phase Ċ import Ġde . fh do . lemma . model _ processing . command _ line . Basic CommandLine Ċ import Ġde . fh do . lemma . model _ processing . command _ line . Basic Option Ċ import Ġde . fh do . lemma . model _ processing . command _ line . parse CommandLine Ċ import Ġde . fh do . lemma . model _ processing . contains Any Ċ import Ġde . fh do . lemma . model _ processing . debug Phase Ċ import Ġde . fh do . lemma . model _ processing . debug Phase Arguments Ċ import Ġde . fh do . lemma . model _ processing . extends Implements Or Exception Ċ import Ġde . fh do . lemma . model _ processing . is Child Path Of Ċ import Ġde . fh do . lemma . model _ processing . ph ases . Model Kind Ċ import Ġde . fh do . lemma . model _ processing . ph ases . Phase Exception Ċ import Ġde . fh do . lemma . model _ processing . println Error Ċ import Ġde . fh do . lemma . model _ processing . println Phase Error Ċ import Ġde . fh do . lemma . model _ processing . println Warning Ċ import Ġjava . util . Array Deque Ċ import Ġjava . util . Deque Ċ import Ġjava . util . LinkedList Ċ Ċ private Ġtype alias ĠModule Arguments Ġ= ĠMap < String , ĠList < String >> Ċ Ċ /** Ċ Ġ* ĠImplementation Ġof Ġthe Ġmodel Ġprocessor 's Ġcode Ġgeneration Ġphase . Ċ Ġ* Ċ Ġ* Ġ@ author Ġ[ Fl orian ĠR ade m acher ]( mailto : fl orian . r ade m acher @ fh - d ort m und . de ) Ċ Ġ*/ Ċ @ Model Processing Phase (" code _ generation ", ĠInter mediate Model Validation Phase :: class ) Ċ @ Cons umes Basic CommandLine Option ( Basic Option . TARGET _ FOLDER ) Ċ internal Ġclass ĠCode Generation Phase Ġ: ĠAbstract Model Processing Phase () Ġ{ ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExecute Ġthe Ġphase ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġprocess ( args : ĠArray < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġdebug Phase Arguments ( args ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠHandle Ġpassed Ġtarget Ġfolder Ġ*/ ĊĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Target Ġfolder Ġ\" ${ Basic CommandLine . target Folder !! }\" Ġwill Ġbe Ġused Ġfor Ġcode Ġgeneration ." Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Phase CommandLine . allow Code Generation Outside Target Folder ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" ĠHowever , Ġuser Ġallowed Ġcode Ġgeneration Ġoutside Ġthe Ġtarget Ġfolder ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĠGet Ġcode Ġgeneration Ġproperties Ġfrom Ġprovider , Ġif Ġany Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġproperty Provider Ġ= Ġfind Code Generation Property Provider ( processor Implementation Package ) ĊĠĠĠĠĠĠĠ Ġif Ġ( property Provider Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Found Ġcode Ġgeneration Ġproperty Ġprovider Ġ${ property Provider :: class . java . name } Ġin Ġprocessor Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" implementation Ġpackage Ġ\"$ processor Implementation Package \"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcode Generation Properties Ġ= Ġproperty Provider ?. getProperties () Ġ?: Ġempty Map () ĊĠĠĠĠĠĠĠ Ġif Ġ( code Generation Properties . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Got Ġthe Ġfollowing Ġproperties Ġfrom Ġthe Ġcode Ġgeneration Ġproperty Ġprovider :" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcode Generation Properties . forEach Ġ{ Ġdebug Phase Ġ{ Ġ"\ t - Ġ${ it . key } Ġ= Ġ${ it . value }" Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( property Provider Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Code Ġgeneration Ġproperty Ġprovider Ġdid Ġnot Ġyield Ġany Ġproperties " Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĠFind Ġavailable Ġcode Ġgeneration Ġmodules Ġ*/ ĊĠĠĠĠĠĠĠ ĠAvailable Code Generation Modules . initialize ( processor Implementation Package , Ġcode Generation Properties ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠParse Ġcommand line Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġcode Generation Module Names Ġ= ĠAvailable Code Generation Modules . getAll Module Names (). toList () ĊĠĠĠĠĠĠĠ Ġval Ġ( phase Specific Arguments , Ġmodule Specific Arguments ) Ġ= Ġparse CommandLine ( args , Ġcode Generation Module Names ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPhase CommandLine ( phase Specific Arguments ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠPhase Exception ( ex . message ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĠHandle Ġcommands Ġthat Ġmight Ġinterrupt Ġthe Ġphase 's Ġexecution Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġinterrupt Execution Ġ= Ġhandle Interrupt ing Commands ( code Generation Properties ) ĊĠĠĠĠĠĠĠ Ġif Ġ( interrupt Execution ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĊĠĠĠĠĠĠĠ Ġ/* ĠExecute Ġcode Ġgeneration Ġmodules Ġfor Ġmodel Ġkinds Ġ*/ ĊĠĠĠĠĠĠĠ Ġexecute Code Generation Modules ( Model Kind . SOURCE , Ġphase Specific Arguments , Ġmodule Specific Arguments ) ĊĠĠĠĠĠĠĠ Ġexecute Code Generation Modules ( Model Kind . INTER MEDI ATE , Ġphase Specific Arguments , Ġmodule Specific Arguments ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHelper Ġto Ġfind Ġthe Ġcode Ġgeneration Ġproperty Ġprovider Ġon Ġthe Ġclasspath ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġfind Code Generation Property Provider ( processor Package Ġ: ĠString ) Ġ: ĠCode Generation Property Provider I ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġannotated Classes Ġ= Ġfind Annotated Classes ( processor Package , ĠCode Generation Property Provider :: class ) ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Classes . isEmpty () Ġ-> Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġannotated Classes . size Ġ> Ġ 1 Ġ-> Ġthrow ĠPhase Exception (" Amb iguous Ġcode Ġgeneration Ġproperty Ġproviders . ĠOnly Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" one Ġclass Ġin Ġprocessor Ġimplementation Ġpackage Ġ\"$ processor Package \" Ġmay Ġbe Ġannotated Ġas Ġbeing Ġa Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" code Ġgeneration Ġproperty Ġprovider ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġprovider Info Ġ= Ġannotated Classes . first () ĊĠĠĠĠĠĠĠ Ġprovider Info . extends Implements Or Exception (" Code Ġgeneration Ġproperty Ġprovider ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpected Interface Ġ= ĠCode Generation Property Provider I :: class ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġprovider Info ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. load Class ( Code Generation Property Provider I :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. getDeclared Constructor () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. newInstance () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHandle ĠCLI Ġcommands Ġthat Ġmight Ġinterrupt Ġthe Ġexecution Ġof Ġthe Ġcode Ġgeneration Ġphase Ġ( returns Ġtrue , Ġif Ġthe Ġphase ĊĠĠĠĠ Ġ* Ġshall Ġbe Ġinterrupted Ġafter Ġa Ġcertain Ġcommand ) ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġhandle Interrupt ing Commands ( code Generation Properties : ĠMap < String , ĠString >) Ġ: ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠPrint Ġproperties ĊĠĠĠĠĠĠĠ Ġif Ġ( Phase CommandLine . print Properties ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( code Generation Properties . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcode Generation Properties . forEach Ġ{ Ġprintln ("${ it . key } Ġ= Ġ${ it . value }") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" No Ġproperties Ġfound Ġfor Ġcode Ġgeneration Ġphase ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠPrint Ġnames Ġof Ġavailable Ġgeneration Ġmodules ĊĠĠĠĠĠĠĠ Ġif Ġ( Phase CommandLine . print Modules ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprint Available Modules For Kind ( Model Kind . SOURCE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprint Available Modules For Kind ( Model Kind . INTER MEDI ATE ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠHelper Ġto Ġprint Ġthe Ġcode Ġgeneration Ġmodules Ġavailable Ġfor Ġthe Ġgiven Ġ[ Model Kind ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġprint Available Modules For Kind ( model Kind : ĠModel Kind ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmodule Infos Ġ= ĠAvailable Code Generation Modules . get Modules ( model Kind ) ĊĠĠĠĠĠĠĠ Ġprintln (" Available Ġcode Ġgeneration Ġmodules Ġfor Ġ${ model Kind . label } Ġmodel :") ĊĠĠĠĠĠĠĠ Ġmodule Infos . sorted By Ġ{ Ġit . name Ġ}. forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\ t - Ġ${ it . name } Ġ( language Ġnamespace : Ġ${ it . language Namespace }" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . depends On . isNotEmpty ()) Ġ", Ġdepends Ġon : Ġ${ it . depends On }" Ġelse Ġ"" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . explicit ly Inv oked ) Ġ", Ġexplicit Ġinvocation Ġrequired )" Ġelse Ġ")" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExecute Ġall Ġcode Ġgeneration Ġmodules Ġavailable Ġfor Ġa Ġcertain Ġ[ Model Kind ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġexecute Code Generation Modules ( model Kind : ĠModel Kind , Ġphase Specific Arguments : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġmodule Specific Arguments : ĠMap < String , ĠList < String >>) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkind Label Ġ= Ġmodel Kind . label ĊĊĠĠĠĠĠĠĠ Ġ/* ĠCheck Ġif Ġmatching Ġcode Ġgeneration Ġmodules Ġexist Ġ*/ ĊĠĠĠĠĠĠĠ Ġif Ġ(! Available Code Generation Modules . exist Modules ( model Kind )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" No Ġcode Ġgeneration Ġmodules Ġfor Ġ$ kind Label Ġmodel Ġfound . ĠCode Ġgeneration Ġfor Ġthis Ġmodel Ġkind Ġaborted ." ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĠCalculate Ġmodule Ġexecution Ġplan Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġexecution Plan Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( modules To Execute , Ġonly Explicit ly Inv oked Modules ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ= Ġdetermine Modules To Execute ( model Kind , Ġmodule Specific Arguments ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodules To Execute . calculate Execution Plan ( only Explicit ly Inv oked Modules ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠModule Execution Determin ation Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln Phase Error ( this , Ġex . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĠExecute Ġcode Ġgeneration Ġmodules Ġaccording Ġto Ġthe Ġcalculated Ġexecution Ġplan Ġ*/ ĊĠĠĠĠĠĠĠ Ġif Ġ(! execution Plan . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Calculated Ġexecution Ġplan Ġfor Ġcode Ġgeneration Ġmodules Ġconcerning Ġ$ kind Label Ġmodel :" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecution Plan . forEach Indexed Ġ{ Ġindex , Ġmodule Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\ t ${ index + 1 }. Ġ${ module . name }" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( module . explicit ly Inv oked ) Ġ" Ġ( explicit Ġinvocation Ġrequired )" Ġelse Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecution Plan . execute ( model Kind , Ġphase Specific Arguments , Ġmodule Specific Arguments ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDetermine Ġthe Ġcode Ġgeneration Ġmodules Ġto Ġexecute Ġfor Ġthe Ġgiven Ġ[ Model Kind ]. ĠThe Ġboolean Ġflag Ġof Ġthe Ġreturned ĊĠĠĠĠ Ġ* Ġ[ Pair ] Ġspecifies Ġif Ġthe Ġuser Ġpassed ĠCLI Ġarguments Ġto Ġthe Ġprocessor Ġthat Ġmake Ġit Ġnecessary Ġto Ġonly Ġexecute Ġthose ĊĠĠĠĠ Ġ* Ġcode Ġgeneration Ġmodules , Ġwhich Ġrequire Ġexplicit Ġinvocation . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġdetermine Modules To Execute ( model Kind : ĠModel Kind , Ġmodule Arguments : ĠModule Arguments ) ĊĠĠĠĠĠĠĠ Ġ: ĠPair < List < Code Generation Module Registration Info >, ĠBoolean > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkind Label Ġ= Ġmodel Kind . label ĊĊĠĠĠĠĠĠĠ Ġ/* ĠDetermine Ġmodules Ġto Ġexecute Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġcandidate Modules Ġ= ĠAvailable Code Generation Modules . get Modules ( model Kind ) ĊĠĠĠĠĠĠĠ Ġval Ġnames Of Explicit ly Inv oked Modules Ġ= ĠAvailable Code Generation Modules . get Names Of All Explicit ly Inv oked Modules () ĊĠĠĠĠĠĠĠ Ġval Ġ( modules To Execute , Ġonly Explicit ly Inv oked Modules ) Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠUser Ġexplicitly Ġrequested Ġto Ġonly Ġinvoke Ġthose Ġmodules Ġthat Ġwere Ġspecified Ġon Ġthe Ġcommand line ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPhase CommandLine . invoke Only Specified Modules Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcandidate Modules . filter Ġ{ Ġit . name Ġin Ġmodule Arguments . keys Ġ} Ġto Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġcase Ġan Ġexplicitly Ġinvoked Ġmodule Ġwas Ġstated Ġon Ġthe Ġcommand line , Ġonly Ġinvoke Ġthose Ġmodules Ġthat ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġrequire Ġexplicit Ġinvocation Ġ( this Ġbehavior Ġis Ġconsistent Ġwith Ġthat Ġof Ġ[ Abstract Model Processor ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodule Arguments . keys . contains Any ( names Of Explicit ly Inv oked Modules ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAvailable Code Generation Modules . get Explicit ly Inv oked Modules ( model Kind ) Ġto Ġtrue ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠInvoke Ġall Ġmodules Ġthat Ġdo Ġnot Ġrequire Ġexplicit Ġinvocation ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġcandidate Modules . filter Ġ{ Ġ! it . explicit ly Inv oked Ġ} Ġto Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( modules To Execute . isEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" No Ġexecutable Ġcode Ġgeneration Ġmodules Ġdetermin able Ġfor Ġ$ kind Label Ġmodel . ĠMaybe Ġthe Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Phase CommandLine . IN VOKE _ ONLY _ SPECIFIED _ MODULES _ OPTION _ NAME } Ġoption Ġwas Ġspecified Ġwithout Ġa Ġmodule Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" or Ġonly Ġmodules Ġof Ġthe Ġopposite Ġmodel Ġkind Ġwere Ġselected Ġfor Ġexecution ?" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠModules Ġthat Ġrequire Ġexplicit Ġinvocation Ġcannot Ġspecify Ġdependencies Ġto Ġother Ġmodules Ġvia Ġthe Ġdepends On ĊĠĠĠĠĠĠĠ Ġ// Ġannotation Ġparameter ĊĠĠĠĠĠĠĠ Ġelse Ġif Ġ(! only Explicit ly Inv oked Modules ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmissing Dependency Ġ= Ġmodules To Execute . missing Dependency ( model Kind ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( missing Dependency Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠModule Execution Determin ation Exception (" Some Ġcode Ġgeneration Ġmodules Ġfor Ġ$ kind Label Ġmodel Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" depend Ġon Ġmodule Ġ\"$ missing Dependency \", Ġwhich Ġwas Ġnot Ġfound Ġin Ġprocessor Ġimplementation Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" package Ġ\"$ processor Implementation Package \" . ĠMaybe Ġthe Ġmodule Ġwas Ġexcluded Ġwith Ġthe Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Phase CommandLine . IN VOKE _ ONLY _ SPECIFIED _ MODULES _ OPTION _ NAME } Ġoption ?") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġmodules To Execute Ġto Ġonly Explicit ly Inv oked Modules ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠException Ġto Ġcommunicate Ġthat Ġcode Ġgeneration Ġmodule Ġexecution Ġis Ġnot Ġfe asible Ġand Ġthe Ġwhole Ġphase Ġis Ġto Ġbe ĊĠĠĠĠ Ġ* Ġaborted ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġclass ĠModule Execution Determin ation Exception ( override Ġval Ġmessage : ĠString ) Ġ: ĠPhase Exception ( message ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠExecute Ġa Ġstack Ġof Ġcode Ġgeneration Ġmodules Ġfrom Ġtheir Ġ[ Code Generation Module Registration Info ] Ġfor Ġa Ġgiven ĊĠĠĠĠ Ġ* Ġ[ Model Kind ] ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠDe que < Code Generation Module Registration Info >. execute ( model Kind : ĠModel Kind , Ġphase Arguments : ĠList < String >, ĊĠĠĠĠĠĠĠ Ġall Module Arguments : ĠModule Arguments ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkind Label Ġ= Ġmodel Kind . label ĊĊĠĠĠĠĠĠĠ Ġ/* ĠExecute Ġthe Ġmodules Ġand Ġgather Ġall Ġgenerated Ġfiles Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġall Generated Files Ġ= Ġmutable Map Of < String , ĠCharset Aware FileContent >() ĊĠĠĠĠĠĠĠ ĠforEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmodule Arguments Ġ= Ġall Module Arguments [ it . name ]?. to Typed Array () Ġ?: Ġempty Array () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( module Arguments . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Executing Ġcode Ġgeneration Ġmodule Ġ\" ${ it . name }\" Ġfor Ġ$ kind Label Ġmodel Ġwith Ġarguments Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\" ${ module Arguments . join ToString () }\ "" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Executing Ġcode Ġgeneration Ġmodule Ġ\" ${ it . name }\" Ġfor Ġ$ kind Label Ġmodel Ġwithout Ġarguments " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠActual Ġmodule Ġexecution ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgenerated Files Ġ= Ġit . instance . execute ( phase Arguments . to Typed Array (), Ġmodule Arguments ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( generated Files . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Module Ġgenerated Ġthe Ġfollowing Ġfiles Ġfor Ġ$ kind Label Ġmodel :" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgenerated Files . forEach Ġ{ Ġpath , Ġ( content , Ġcharset ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ"\ t - Ġ$ path Ġ( charset : Ġ${ charset . name ()}, Ġcharacter Ġcount : Ġ${ content . length })" Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Module Ġdid Ġnot Ġgenerate Ġany Ġfiles Ġfor Ġ$ kind Label Ġmodel " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġall Generated Files . put All ( generated Files ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( all Generated Files . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprintln (" No Ġfiles Ġwere Ġgenerated Ġby Ġcode Ġgeneration Ġmodules Ġfor Ġ$ kind Label Ġmodel ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/* ĠWrite Ġgenerated Ġcontents Ġto Ġfiles Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġtarget Folder Ġ= ĠBasic CommandLine . target Folder !! ĊĠĠĠĠĠĠĠ Ġdebug Phase Ġ{ Ġ" Writing Ġgenerated Ġfile Ġcontents Ġto Ġdisk " Ġ} ĊĠĠĠĠĠĠĠ Ġfor Ġ(( filepath , Ġcontent ) Ġin Ġall Generated Files ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! Phase CommandLine . allow Code Generation Outside Target Folder Ġ&& Ġ!( filepath Ġis Child Path Of Ġtarget Folder )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln Warning (" Generated Ġfile Ġ\"$ filepath \" Ġis Ġnot Ġa Ġchild Ġof Ġgeneration Ġtarget Ġfolder Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"\" $ target Folder \" Ġand Ġcode Ġgeneration Ġoutside Ġthe Ġtarget Ġfolder Ġis Ġnot Ġallowed . ĠIf Ġyou Ġwant Ġto Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" enable Ġcode Ġgeneration Ġoutside Ġthe Ġtarget Ġfolder , Ġinvoke Ġthe Ġcode Ġgeneration Ġphase Ġwith Ġthe Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"${ Phase CommandLine . ALLOW _ CODE _ GENER ATION _ OUT SIDE _ TARGET _ FOLDER _ OPTION _ NAME } Ġoption ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfile Ġ= Ġfilepath . as File () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Phase CommandLine . preserve Existing Files Ġ&& Ġfile . exists ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln Warning (" File Ġ\"$ filepath \" Ġalready Ġexists Ġand Ġwill Ġnot Ġbe Ġoverridden , Ġbecause Ġthe Ġcode Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" generation Ġphase Ġwas Ġinvoked Ġwith Ġthe Ġ${ Phase CommandLine . PRE SER VE _ EXIST ING _ FILES _ OPTION _ NAME } Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" option ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . parent File . mkdir s () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfile . write Text ( content . first , Ġcontent . second ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprintln Error (" Error Ġwhile Ġwriting Ġgenerated Ġcontents Ġto Ġtarget Ġfile Ġ\"$ filepath \": Ġ${ ex . message }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠHelper Ġto Ġcalculate Ġan Ġexecution Ġplan Ġfor Ġthis Ġlist Ġof Ġ[ Abstract Code Generation Module ] s Ġrepresented Ġas Ċ Ġ* Ġ[ Code Generation Module Registration Info ] s . ĠNote Ġthat Ġthe Ġfunction Ġrequires Ġthe Ġ[ Code Generation Module Registration Info ] s Ċ Ġ* Ġto Ġconcern Ġonly Ġa Ġsingle Ġ[ Model Kind ] Ġand Ġwill Ġotherwise Ġthrow Ġan Ġ[ IllegalArgumentException ]. Ċ Ġ* Ċ Ġ* Ġ@ author Ġ[ Fl orian ĠR ade m acher ]( mailto : fl orian . r ade m acher @ fh - d ort m und . de ) Ċ Ġ*/ Ċ private Ġfun ĠList < Code Generation Module Registration Info >. calculate Execution Plan ( only Explicit ly Inv oked Modules : ĠBoolean ) ĊĠĠĠ Ġ: ĠDe que < Code Generation Module Registration Info > Ġ{ ĊĠĠĠ Ġif Ġ( isEmpty ()) ĊĠĠĠĠĠĠĠ Ġreturn ĠArray Deque () ĊĊĠĠĠ Ġrequire ( map Ġ{ Ġit . model Kind Ġ}. toSet (). size Ġ== Ġ 1 ) Ġ{ Ġ" Amb iguous Ġmodel Ġkinds Ġdetected Ġin Ġexecution Ġplan Ġcalculation " Ġ} ĊĠĠĠ Ġval Ġmodel Kind Ġ= Ġthis [ 0 ]. model Kind ĊĊĠĠĠ Ġval Ġindependent Modules Ġ= Ġfilter Ġ{ Ġit . depends On . isEmpty () Ġ}. map Ġ{ Ġit . name Ġ} ĊĠĠĠ Ġval Ġexecution Plan Ġ= ĠLinkedList < String >( independent Modules ) ĊĊĠĠĠ Ġ/* ĊĠĠĠĠ Ġ* ĠCalculate Ġthe Ġexecution Ġplan . ĠEffect ively , Ġthe Ġexecution Ġplan Ġis Ġa Ġstack Ġwhose Ġelements ' Ġordering Ġcorresponds Ġto ĊĠĠĠĠ Ġ* Ġthe Ġmodules ' Ġexecution . ĠIndependent Ġmodules Ġwill Ġalways Ġbe Ġexecuted Ġbefore Ġdependent Ġmodules . ĠThe Ġordering Ġof Ġthe ĊĠĠĠĠ Ġ* Ġdependent Ġmodules Ġreflect s Ġtheir Ġdependency Ġspecifications , Ġi . e ., Ġdependent Ġmodules Ġwill Ġbe Ġexecuted Ġafter Ġthe ĊĠĠĠĠ Ġ* Ġmodules Ġthey Ġdepend Ġon Ġwere Ġexecuted . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠThe Ġalgorithm Ġto Ġbuild Ġthe Ġ" dependent " Ġpart Ġof Ġthe Ġexecution Ġplan Ġconsists Ġof Ġthe Ġfollowing Ġsteps : ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġ( 1 ) ĠSetup Ġa Ġstack Ġof Ġmodules Ġwhose Ġpossible Ġ" dependent s ", Ġi . e ., Ġthe Ġmodules Ġthat Ġdepend Ġon Ġthem , Ġshall Ġbe ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠ Ġchecked . ĠInit ially , Ġthis Ġstack Ġholds Ġall Ġmodules Ġthat Ġdefinitely Ġhave Ġdepend ents Ġas Ġreflected Ġby Ġthe ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠ Ġlist Ġof Ġdependency Ġrelationships Ġpassed Ġto Ġthis Ġfunction . ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġ( 2 . 1 ) ĠFor Ġeach Ġdependency Ġand Ġits Ġdepend ents , Ġdetermine Ġthe Ġlowest Ġindex Ġin Ġthe Ġexecution Ġplan Ġat Ġwhich Ġthe ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġdependency Ġcan Ġbe Ġinserted Ġso Ġthat Ġeach Ġdependent 's Ġexecution Ġis Ġplanned Ġafter Ġthe Ġdependency . ĠIf Ġthe ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġmodule Ġhas Ġno Ġdepend ents Ġor Ġnone Ġof Ġits Ġdepend ents Ġare Ġin Ġthe Ġplan Ġyet , Ġthe Ġmodule Ġis Ġappended Ġto Ġthe ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġstack . ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġ( 2 . 2 ) ĠCheck Ġfor Ġcircular Ġdependencies Ġby Ġchecking Ġthe Ġstack Ġentries Ġthat Ġwere Ġplaced Ġbefore Ġthe Ġdependency ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġfor Ġdepend ents , Ġi . e ., Ġcheck Ġif Ġa Ġdependent 's Ġexecution Ġwas Ġpreviously Ġdetermined Ġto Ġneed Ġto Ġhappen ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġbefore Ġthe Ġone Ġof Ġthe Ġcurrent Ġdependency , Ġon Ġwhich Ġthe Ġdependent Ġalso Ġdepends . ĠC onse quent ly , Ġdependency ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġand Ġdependent Ġwere Ġdetermined Ġto Ġdepend Ġon Ġeach Ġother Ġ( possibly Ġindirect ly ), Ġwhich Ġis Ġessentially Ġthe ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġdefinition Ġof Ġcircular Ġdependency . ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġ( 2 . 3 ) ĠIn Ġcase Ġno Ġcircular Ġdependency Ġwas Ġdetected , Ġadd Ġdependency Ġto Ġthe Ġposition Ġthe Ġexecution Ġplan ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠĠĠ Ġdetermined Ġstep Ġ( 2 . 1 ). ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġ( 3 ) ĠAdd Ġdepend ents Ġto Ġthe Ġstack Ġof Ġdepend ents Ġto Ġcheck Ġan Ġgoto Ġ( 1 ) Ġor Ġquit Ġthe Ġplanning , Ġin Ġcase Ġthe Ġstack ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠ Ġis Ġempty Ġand Ġno Ġfurther Ġdepend ents Ġto Ġcheck Ġexist . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġmodules With Depend ents Ġ= Ġif Ġ(! only Explicit ly Inv oked Modules ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠAvailable Code Generation Modules . get Names Of Module sWith Depend ents ( model Kind ) ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġempty Set () ĊĠĠĠ Ġval Ġcheck Depend ents For Ġ= ĠArray Deque ( modules With Depend ents ) ĊĠĠĠ Ġwhile Ġ( check Depend ents For . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcurrent Dependency Ġ= Ġcheck Depend ents For . pop () ĊĠĠĠĠĠĠĠ Ġval Ġdepend ents Ġ= ĠAvailable Code Generation Modules . get Depend ents ( model Kind , Ġcurrent Dependency ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġmax Position Before Depend ents Ġ= Ġif Ġ( dependent s . isNotEmpty ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdepend ents . map { Ġexecution Plan . indexOf ( it ) Ġ}. min () !! ĊĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ- 1 ĊĊĠĠĠĠĠĠĠ Ġif Ġ( max Position Before Depend ents Ġ> Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmodules Before Ġ= Ġexecution Plan . sub List ( 0 , Ġmax Position Before Depend ents Ġ+ Ġ 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcircular Dependency Ġ= Ġif Ġ( dependent s . isNotEmpty ()) Ġmodules Before . find Ġ{ Ġit Ġin Ġdepend ents Ġ} Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( circular Dependency Ġ!= Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠPhase Exception (" Circular Ġdependency Ġdetected : ĠCode Ġgeneration Ġmodule Ġ\"$ current Dependency \" Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" depends Ġon Ġ\"$ circular Dependency \" Ġand Ġvice Ġvers a , Ġpossibly Ġindirect ly ") ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmax Position Before Depend ents Ġ= Ġexecution Plan . size ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! execution Plan . contains ( current Dependency )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexecution Plan . add ( max Position Before Depend ents , Ġcurrent Dependency ) ĊĊĠĠĠĠĠĠĠ Ġcheck Depend ents For . addAll ( dependent s ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġresult Ġ= ĠArray Deque < Code Generation Module Registration Info >() ĊĠĠĠ Ġval Ġmodule Info ByName Ġ= Ġthis . associate By Ġ{ Ġit . name Ġ} ĊĠĠĠ Ġexecution Plan . forEach Ġ{ Ġresult . add ( module Info ByName [ it ] !! ) Ġ} ĊĠĠĠ Ġreturn Ġresult Ċ }