/* Ċ Ġ* ĠCopyright Ġ 2 0 1 9 ĠD ones ky , ĠLLC Ċ Ġ* Ċ Ġ* Ġ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 Ġblock y . model Ċ Ċ import Ġblock y . model . expression . Expression Ċ import Ġjava . io . OutputStream Ċ import Ġjava . util . concurrent . atomic . Atomic Boolean Ċ Ċ internal Ġclass ĠIf Block ( ĊĠĠĠ Ġchildren : ĠList < Node >, ĊĠĠĠ Ġinternal Ġval Ġexpression : ĠExpression Ċ ) Ġ: ĠBlock (" if ", Ġchildren ), ĠContext Modifier Node Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġelse Blocks Ġby Ġlazy Ġ{ Ġchildren . filter Is Instance < Else Block >() Ġ} ĊĠĠĠ Ġprivate Ġval Ġblocks Ġby Ġlazy Ġ{ Ġchildren . filter Ġ{ Ġit Ġ! is ĠElse Block Ġ} Ġ} ĊĠĠĠ Ġprivate Ġval Ġmodify Blocks Ġby Ġlazy Ġ{ Ġblocks . filter Is Instance < Context Modifier Node >() Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmodify ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( expression . evaluate ( context )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodify Blocks . forEach Ġ{ Ġit . modify ( context ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdone Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Blocks . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( done . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . modify ( context , Ġdone ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwrite ( context : ĠContext , Ġout : ĠOutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( expression . evaluate ( context )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblocks . forEach Ġ{ Ġit . write ( context , Ġout ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdone Ġ= ĠAtomic Boolean ( false ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Blocks . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( done . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . write ( context , Ġout , Ġdone ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ"[ if Ġ($ expression ) Ġ${ children . join ToString ( separator Ġ= Ġ" Ġ" )} ]" ĊĠĠĠ Ġ} Ċ } Ċ Ċ internal Ġclass ĠElse Block ( ĊĠĠĠ Ġparent : ĠNode , ĊĠĠĠ Ġchildren : ĠList < Node >, ĊĠĠĠ Ġname : ĠString , ĊĠĠĠ Ġinternal Ġval Ġexpression : ĠExpression ? Ċ ) Ġ: ĠBlock ( name , Ġchildren ), ĠContext Modifier Node Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire (!( parent Ġ! is ĠIf Block Ġ&& Ġparent Ġ! is ĠElse Block )) Ġ{ Ġ" Else Ġblock Ġmust Ġbe Ġfrom Ġan Ġif / else Ġblock " Ġ} ĊĠĠĠĠĠĠĠ Ġrequire (!( parent Ġis ĠElse Block Ġ&& Ġparent . expression Ġ== Ġnull Ġ&& Ġexpression Ġ== Ġnull )) Ġ{ Ġ" Duplicate Ġcatch Ġall Ġelse Ġblock " Ġ} ĊĠĠĠĠĠĠĠ Ġrequire (!( name Ġ== Ġ" elseif " Ġ&& Ġexpression Ġ== Ġnull )) Ġ{ Ġ" elseif Ġmust Ġhave Ġan Ġexpression " Ġ} ĊĠĠĠĠĠĠĠ Ġrequire (!( name Ġ== Ġ" else " Ġ&& Ġexpression Ġ!= Ġnull )) Ġ{ Ġ" else Ġcannot Ġhave Ġan Ġexpression " Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġelse Blocks Ġby Ġlazy Ġ{ Ġchildren . filter Is Instance < Else Block >() Ġ} ĊĠĠĠ Ġprivate Ġval Ġblocks Ġby Ġlazy Ġ{ Ġchildren . filter Ġ{ Ġit Ġ! is ĠElse Block Ġ} Ġ} ĊĠĠĠ Ġprivate Ġval Ġmodify Blocks Ġby Ġlazy Ġ{ Ġchildren . filter Is Instance < Context Modifier Node >() Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġmodify ( context : ĠContext ) Ġ{ ĊĠĠĠĠĠĠĠ Ġmodify ( context , ĠAtomic Boolean ( false )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġwrite ( context : ĠContext , Ġout : ĠOutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġwrite ( context , Ġout , ĠAtomic Boolean ( false )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġmodify ( context : ĠContext , Ġdone : ĠAtomic Boolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( done . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ( expression Ġ== Ġnull Ġ|| Ġexpression . evaluate ( context )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdone . set ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmodify Blocks . forEach Ġ{ Ġit . modify ( context ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Blocks . forEach Ġ{ Ġit . modify ( context , Ġdone ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġwrite ( context : ĠContext , Ġout : ĠOutputStream , Ġdone : ĠAtomic Boolean ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( done . get ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ( expression Ġ== Ġnull Ġ|| Ġexpression . evaluate ( context )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdone . set ( true ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġblocks . forEach Ġ{ Ġit . write ( context , Ġout ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Blocks . forEach Ġ{ Ġit . write ( context , Ġout , Ġdone ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ" [$ name Ġ($ expression ) Ġ${ children . join ToString ( separator Ġ= Ġ" Ġ" )} ]" ĊĠĠĠ Ġ} Ċ }