package Ġformula ide . api . types Ċ Ċ import Ġkotlinx . serialization . Serializable Ċ import Ġkotlinx . serialization . Transient Ċ Ċ type alias ĠReference Id Ġ= ĠString Ċ Ċ /** Ċ Ġ* ĠSome Ġdata Ġthat Ġcan Ġbe Ġreferenced Ġfrom Ġsomewhere Ġelse . Ċ Ġ* Ġ@ see Ġid Ċ Ġ*/ Ċ interface ĠRefer enc able Ġ{ ĊĊ ĉ /** Ċĉ Ġ* ĠA Ġunique Ġidentifier Ġfor Ġthis Ġobject . Ċĉ Ġ* Ċĉ Ġ* ĠThe Ġidentifier Ġonly Ġneeds Ġto Ġbe Ġunique Ġin Ġthe Ġcontext Ġof Ġthis Ġobject , Ġnot Ġglobally : Ċĉ Ġ* Ġfor Ġexample , Ġan Ġobject Ġthat Ġcan Ġonly Ġappear Ġin Ġa Ġspecific Ġlist Ġonly Ġhas Ġto Ġhave Ġa Ġunique Ġidentifier Ċĉ Ġ* Ġin Ġthat Ġlist . Ċĉ Ġ*/ Ċ ĉ val Ġid : ĠReference Id Ċ } Ċ Ċ /** Ċ Ġ* ĠA Ġreference Ġto Ġsomething Ġelse . Ċ Ġ* Ċ Ġ* ĠOnly Ġthe Ġ[ id ] Ġis Ġserialized . Ċ Ġ* ĠAfter Ġde serialization , Ġone Ġcan Ġuse Ġ[ obj ] Ġto Ġuse Ġthe Ġreference Ġas Ġa Ġnormal Ġobject Ġinstead . Ċ Ġ*/ Ċ @ Serializable Ċ data Ġclass ĠRef < R Ġ: ĠRefer enc able >( Ċ ĉ val Ġid : ĠReference Id , Ċ ) Ġ{ ĊĊ ĉ /** Ċĉ Ġ* ĠCreates Ġa Ġreference Ġand Ġloads Ġit Ġautomatically . Ċĉ Ġ* Ġ@ see Ġcreate Ref Ċĉ Ġ*/ Ċ ĉ constructor ( referenced : ĠR ) Ġ: Ġthis ( referenced . id ) Ġ{ Ċĉ ĉ obj Ġ= Ġreferenced Ċ ĉ } ĊĊ ĉ @ Transient Ġ// ĠWe Ġdon 't Ġwant Ġthe Ġobject Ġto Ġbe Ġserialized , Ġjust Ġits ĠID Ċ ĉ private Ġvar Ġ_ obj : ĠR ? Ġ= Ġnull ĊĊ ĉ /** Ċĉ Ġ* ĠA Ġconvenience Ġutility Ġto Ġuse Ġthe Ġobject Ġcorresponding Ġto Ġthis Ġreference Ġinstead Ġof Ġthe Ġ[ id ] Ġitself . Ċĉ Ġ* Ċĉ Ġ* ĠIt Ġis Ġthe Ġdeveloper 's Ġresponsibility Ġto Ġprovide Ġthe Ġobject Ġcorresponding Ġto Ġthis Ġreference Ġ( through Ġ[ load ], Ġ[ load From ] Ġor Ġ[ obj ]' s Ġsetter ). Ċĉ Ġ* Ċĉ Ġ* ĠIt Ġis Ġallowed Ġto Ġload Ġthis Ġreference Ġmultiple Ġtimes Ġ( for Ġexample Ġif Ġthe Ġcorresponding Ġobject Ġis Ġimmutable Ġand Ġis Ġreplaced Ġby Ġa Ġcopy Ġwith Ġthe Ġsame Ġ[ id ]); Ġany Ġ[ load ] Ġoperation Ġover writes Ġthe Ġprevious Ġones . Ċĉ Ġ* Ċĉ Ġ* ĠOne Ġcan Ġuse Ġ[ loaded ] Ġto Ġcheck Ġwhether Ġthis Ġreference Ġhas Ġbeen Ġloaded Ġor Ġnot Ġ( and Ġtherefore Ġknow Ġif Ġit Ġis Ġsafe Ġto Ġaccess Ġ[ obj ]). Ċĉ Ġ* Ċĉ Ġ* Ġ@ throws ĠIllegalStateException ĠWhen Ġ[ obj ] Ġis Ġqueried Ġbefore Ġbeing Ġinitialized . Ċĉ Ġ*/ Ċ ĉ var Ġobj : ĠR Ċĉ ĉ get () Ġ= Ġ_ obj Ċĉĉ ĉ ?: Ġthrow ĠUn loaded Reference Exception ( this ) Ċĉ ĉ set ( value ) Ġ{ Ċĉĉ ĉ require ( value . id Ġ== Ġid ) Ġ{ Ġ" The Ġobject Ġgiven Ġto Ġthis Ġreference Ġmust Ġhave Ġthe Ġsame Ġid Ġas Ġthis Ġreference ; Ġexpected Ġ'$ id ' Ġbut Ġfound Ġ'${ value . id } '" Ġ} Ċĉĉ ĉ _ obj Ġ= Ġvalue Ċĉ ĉ } ĊĊ ĉ /** Ċĉ Ġ* Ġ` true ` Ġif Ġ` obj ` Ġis Ġsafe Ġto Ġaccess ; Ġ` false ` Ġif Ġaccessing Ġ` obj ` Ġwill Ġthrow Ġan Ġexception . Ċĉ Ġ*/ Ċ ĉ val Ġloaded : ĠBoolean Ċĉ ĉ get () Ġ= Ġ_ obj Ġ!= Ġnull ĊĊ ĉ /** Ċĉ Ġ* ĠLoads Ġan Ġ[ object ][ obj ] Ġinto Ġthis Ġreference . Ċĉ Ġ* ĠSemantic ally Ġequivalent Ġto Ġcalling Ġ[ obj ]' s Ġsetter . Ċĉ Ġ*/ Ċ ĉ fun Ġload ( obj : ĠR ) Ġ{ Ċĉ ĉ this . obj Ġ= Ġobj Ċ ĉ } ĊĊ ĉ /** Ċĉ Ġ* ĠLoads Ġan Ġobject Ġby Ġfinding Ġit Ġin Ġ[ objs ]. Ċĉ Ġ* Ċĉ Ġ* ĠIf Ġ[ allow NotFound ] Ġis Ġset Ġto Ġ` false `, Ġthe Ġfunction Ġwill Ġthrow Ġif Ġ[ objs ] Ġdoesn 't Ġhave Ġthe Ġcorrect Ġobject . Ċĉ Ġ* Ċĉ Ġ* ĠWhen Ġ[ lazy ] Ġis Ġset Ġto Ġ` true `, Ġthe Ġfunction Ġwill Ġonly Ġattempt Ġto Ġfind Ġone Ġof Ġthe Ġ[ objs ] Ġif Ġthe Ġreferenced Ġis Ġun loaded . Ċĉ Ġ* Ċĉ Ġ* Ġ@ see Ġload Ċĉ Ġ*/ Ċ ĉ fun Ġload From ( objs : ĠIterable < R >, Ġallow NotFound : ĠBoolean Ġ= Ġfalse , Ġlazy : ĠBoolean Ġ= Ġfalse ) Ġ{ Ċĉ ĉ if Ġ( lazy Ġ&& Ġloaded ) Ċĉĉ ĉ return ĊĊĉ ĉ val Ġcandidate Ġ= Ġobjs . find Ġ{ Ġit . id Ġ== Ġid Ġ} ĊĊĉ ĉ if Ġ( candidate Ġ!= Ġnull ) Ċĉĉ ĉ obj Ġ= Ġcandidate Ċĉ ĉ else Ġif Ġ(! allow NotFound ) Ċĉĉ ĉ throw ĠMissing Element To Load Reference Exception ( this , Ġobjs ) Ċ ĉ } ĊĊ ĉ override Ġfun ĠtoString () Ġ= Ġ"$ id Ġ${ if Ġ( loaded ) Ġ" âľĶ " Ġelse Ġ" âľ ĸ "} " ĊĊ ĉ comp anion Ġobject Ġ{ ĊĊĉ ĉ /** Ċĉĉ Ġ* ĠLoads Ġthis Ġreference Ġby Ġexecuting Ġ[ loader ], Ġonly Ġif Ġit Ġhas Ġnot Ġbeen Ġloaded Ġyet . Ċĉĉ Ġ*/ Ċĉ ĉ // Ġinline Ġto Ġallow Ġsuspend Ġlamb das Ċĉ ĉ inline Ġfun Ġ< R Ġ: ĠRefer enc able > ĠRef < R >. load ( Ċĉĉ ĉ lazy : ĠBoolean Ġ= Ġfalse , Ċĉĉ ĉ loader : Ġ( Reference Id ) Ġ-> ĠR , Ċĉ ĉ ) Ġ{ Ċĉĉ ĉ if Ġ(! lazy Ġ|| Ġ! loaded ) Ċĉĉĉ ĉ load ( loader ( id )) Ċĉ ĉ } ĊĊĉ ĉ /** Ċĉĉ Ġ* ĠLoads Ġthis Ġreference Ġby Ġfinding Ġit Ġin Ġ[ objs ], Ġonly Ġif Ġit Ġhas Ġnot Ġbeen Ġloaded Ġyet . Ċĉĉ Ġ*/ Ċĉ ĉ fun Ġ< R Ġ: ĠRefer enc able > ĠRef < R >. load If Ne cessary ( Ċĉĉ ĉ objs : ĠIterable < R >, Ċĉĉ ĉ allow NotFound : ĠBoolean Ġ= Ġfalse , Ċĉ ĉ ) Ġ= Ġload From ( objs , Ġallow NotFound , Ġlazy Ġ= Ġtrue ) ĊĊĉ ĉ /** Ċĉĉ Ġ* ĠConvenience Ġmethod Ġto Ġget Ġa Ġreference Ġon Ġan Ġobject . Ċĉĉ Ġ*/ Ċĉ ĉ fun Ġ< R Ġ: ĠRefer enc able > ĠR . create Ref () Ġ= ĠRef ( this ) ĊĊĉ ĉ fun ĠIterable < Refer enc able >. ids () Ġ= Ġmap Ġ{ Ġit . id Ġ} ĊĊĉ ĉ /** Ċĉĉ Ġ* ĠSpecial Ġreference Ġthat Ġcan Ġbe Ġused Ġfor Ġobjects Ġthat Ġare Ġbeing Ġcreated Ġand Ġthat Ġdo Ġnot Ġhave Ġan ĠID Ġyet . Ċĉĉ Ġ*/ Ċĉ ĉ const Ġval ĠSPECIAL _ TOKEN _ NEW : ĠReference Id Ġ= Ġ" special : un initialized " Ċ ĉ } ĊĊ ĉ class ĠUn loaded Reference Exception ( val Ġref : ĠRef <* >) Ġ: Ċĉ ĉ IllegalStateException (" C ette ĠrÃ© fÃ© rence Ġsur Ġ'${ ref . id }' Ġn ' est Ġpas Ġch arg Ã©e , Ġil Ġest Ġdon c Ġimpossible Ġd ' acc Ã© der ĠÃł Ġsa Ġvaleur ") ĊĊ ĉ class ĠMissing Element To Load Reference Exception ( val Ġref : ĠRef <* >, Ġelements : ĠIterable <* >) Ġ: Ċĉ ĉ IllegalStateException (" C ette ĠrÃ© fÃ© rence Ġsur Ġ'${ ref . id }' Ġne Ġpeut Ġpas ĠÃªtre Ġch arg Ã©e Ġpar Ġces ĠÃ©lÃ© ments : Ġ$ elements ") Ċ } Ċ