package Ġcom . intellij . aws . cloudformation Ċ Ċ import Ġcom . intellij . aws . cloudformation . model . C fn Node Ċ import Ġcom . intellij . json . psi . Json File Ċ import Ġcom . intellij . openapi . util . Key Ċ import Ġcom . intellij . psi . Psi File Ċ import Ġorg . jetbrains . yaml . psi . YAML File Ċ import Ġjava . lang . reflect . Accessible Object Ċ import Ġjava . lang . reflect . Field Ċ import Ġjava . lang . reflect . Modifier Ċ Ċ object ĠCloudFormation Parser Ġ{ ĊĠ Ġprivate Ġval ĠPAR SED _ KEY Ġ= ĠKey . create < Cloud Formation Parsed File >(" CF N _ PAR SED _ FILE ") ĊĊĠ Ġfun Ġparse ( psi File : ĠPsi File ): ĠCloudFormation Parsed File Ġ{ ĊĠĠĠ Ġval Ġcached Ġ= Ġpsi File . getUser Data ( PAR SED _ KEY ) ĊĠĠĠ Ġif Ġ( cached Ġ!= Ġnull Ġ&& Ġcached . file Modification Stamp Ġ== Ġpsi File . modification Stamp ) Ġ{ ĊĠĠĠĠĠ Ġreturn Ġcached ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġassert ( Cloud Formation Psi Utils . is Cloud Formation File ( psi File )) Ġ{ Ġpsi File . name Ġ+ Ġ" Ġis Ġnot Ġa ĠCloudFormation Ġfile " Ġ} ĊĊĠĠĠ Ġval Ġparsed Ġ= Ġwhen Ġ( psi File ) Ġ{ ĊĠĠĠĠĠ Ġis ĠJson File Ġ-> ĠJson Cloud Formation Parser . parse ( psi File ) ĊĠĠĠĠĠ Ġis ĠYAML File Ġ-> ĠYaml Cloud Formation Parser . parse ( psi File ) ĊĠĠĠĠĠ Ġelse Ġ-> Ġerror (" Unsupported ĠP SI Ġfile Ġtype : Ġ" Ġ+ Ġpsi File . java Class . name ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġassert All Nodes Are Mapped ( parsed ) ĊĊĠĠĠ Ġpsi File . put UserData ( PAR SED _ KEY , Ġparsed ) ĊĊĠĠĠ Ġreturn Ġparsed ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġassert All Nodes Are Mapped ( parsed : ĠCloudFormation Parsed File ) Ġ{ ĊĠĠĠ Ġfun Ġis Good Field ( field : ĠField ): ĠBoolean Ġ= ĊĠĠĠĠĠ Ġfield . name . indexOf ('$ ') Ġ== Ġ- 1 Ġ&& Ġ! Modifier . is Transient ( field . modifiers ) Ġ&& Ġ! Modifier . is Static ( field . modifiers ) ĊĊĠĠĠ Ġval Ġseen Ġ= Ġmutable Set Of < Any >() ĊĊĠĠĠ Ġfun Ġprocess Instance ( obj : ĠAny , Ġparent : ĠAny ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( seen . contains ( obj )) Ġreturn ĊĠĠĠĠĠ Ġseen . add ( obj ) ĊĊĠĠĠĠĠ Ġif Ġ( obj Ġis ĠC fn Node ) Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġparsed . get Psi Element ( obj ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( t : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġerror (" Node Ġ$ obj Ġunder Ġ$ parent Ġis Ġnot Ġmapped ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġif Ġ( obj Ġis ĠCollection <* >) Ġ{ ĊĠĠĠĠĠĠĠ Ġobj . forEach Ġ{ Ġit ?. let Ġ{ Ġprocess Instance ( it , Ġparent ) Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġval Ġfields Ġ= Ġobj . java Class . declared Fields ĊĠĠĠĠĠ ĠAccess ible Object . setAccessible ( fields , Ġtrue ) ĊĊĠĠĠĠĠ Ġfields ĊĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġis Good Field ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. map NotNull Ġ{ Ġit . get ( obj ) Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ. forEach Ġ{ Ġprocess Instance ( it , Ġobj ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprocess Instance ( parsed . root , Ġparsed . root ) ĊĠ Ġ} Ċ }