/** Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 9 ĠDr . ĠDavid ĠH . ĠA keh ur st Ġ( http :// dr . david . h . ake hur st . net ) Ċ Ġ* Ċ Ġ* Ġ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 Ġnet . ake hur st . kotlin . json Ċ Ċ import Ġnet . ake hur st . kotlin x . collections . Stack Ċ Ċ class ĠJson Parser Exception Ġ: ĠRuntimeException Ġ{ ĊĠĠĠ Ġconstructor ( message : ĠString ) Ġ: Ġsuper ( message ) Ċ } Ċ Ċ class ĠJson Parser Ġ{ ĊĊĠĠĠ Ġval ĠTOKEN _ WH ITES PACE Ġ= ĠRegex ("\\ s +", ĠRegex Option . MULT IL INE ) ĊĠĠĠ Ġval ĠTOKEN _ STRING Ġ= ĠRegex ("\" (?: \\\\ ?( .| \ n ))* ? \"", ĠRegex Option . MULT IL INE ) ĊĠĠĠ Ġval ĠTOKEN _ NULL Ġ= Ġ" null " ĊĠĠĠ Ġval ĠTOKEN _ NUMBER Ġ= ĠRegex ("- ?( ?: 0 |[ 1 - 9 ]\\ d *)( ?: \\. \\ d + )? (?: [ e E ][ +- ]? \\ d + )? ") ĊĠĠĠ Ġval ĠTOKEN _ BOOLEAN Ġ= ĠRegex (" true | false ", ĠRegex Option . IGNORE _ CASE ) ĊĠĠĠ Ġval ĠTOKEN _ ARRAY _ START Ġ= Ġ"[" ĊĠĠĠ Ġval ĠTOKEN _ ARRAY _ END Ġ= Ġ" ]" ĊĠĠĠ Ġval ĠTOKEN _ OBJECT _ START Ġ= Ġ" {" ĊĠĠĠ Ġval ĠTOKEN _ OBJECT _ END Ġ= Ġ" }" ĊĠĠĠ Ġval ĠTOKEN _ PROPERTY _ SEP Ġ= Ġ":" ĊĠĠĠ Ġval ĠTOKEN _ SEP Ġ= Ġ"," ĊĊĊĠĠĠ Ġclass ĠSimple Scanner ( private Ġval Ġinput : ĠCharSequence ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġposition : ĠInt Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠ Ġfun Ġhas More (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . position Ġ< Ġthis . input . length ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġhas Next ( literal : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġthis . input . startsWith ( literal , Ġthis . position , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Opt In ( Experimental Std lib Api :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġhas Next ( pattern : ĠRegex ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpattern . matches At ( this . input , Ġthis . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// val Ġlooking At Ġ= Ġpattern . find ( this . input , Ġthis . position )?. range ?. start Ġ== Ġthis . position ĊĠĠĠĠĠĠĠĠĠĠ Ġ// Ġreturn Ġlooking At ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġnext ( literal : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ass umes Ġhas Next Ġalready Ġcalled ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . position Ġ+= Ġliteral . length ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġliteral ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Opt In ( Experimental Std lib Api :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġnext ( pattern : ĠRegex ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// val Ġm Ġ= Ġpattern . find ( this . input , Ġthis . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// val Ġlooking At Ġ= Ġ( m ?. range ?. start Ġ== Ġthis . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġm Ġ= Ġpattern . match At ( this . input , Ġthis . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlooking At Ġ= Ġ( m ?. range ?. start Ġ== Ġthis . position ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( looking At ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmatch Ġ= Ġm ?. value Ġ?: Ġthrow ĠJson Parser Exception (" Should Ġnever Ġhappen ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . position Ġ+= Ġm . value . length ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġmatch ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠJson Parser Exception (" Error Ġscanning Ġfor Ġpattern Ġ${ pattern } Ġat ĠPosition Ġ${ this . position }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġprocess ( input : ĠString ): ĠJson Document Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdoc Ġ= ĠJson Document (" json ") ĊĠĠĠĠĠĠĠ Ġif Ġ( input . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠJson Parser Exception (" Expected ĠJson Ġcontent Ġbut Ġinput Ġwas Ġempty ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġscanner Ġ= ĠSimple Scanner ( input ) ĊĠĠĠĠĠĠĠ Ġval Ġpath Ġ= ĠStack < String >() ĊĠĠĠĠĠĠĠ Ġval Ġname Stack Ġ= ĠStack < String >() ĊĠĠĠĠĠĠĠ Ġval Ġvalue Stack Ġ= ĠStack < JsonValue >() ĊĠĠĠĠĠĠĠ Ġwhile Ġ( scanner . hasMore ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ WH ITES PACE ) Ġ-> Ġscanner . next ( TOKEN _ WH ITES PACE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ NULL ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ NULL ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( Json Null ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ BOOLEAN ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġscanner . next ( TOKEN _ BOOLEAN ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( Json Boolean ( value . to Boolean ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ NUMBER ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġscanner . next ( TOKEN _ NUMBER ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( Json Number ( value )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ STRING ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġscanner . next ( TOKEN _ STRING ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecoded Ġ= ĠJson String . decode ( value . drop ( 1 ). drop Last ( 1 )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( Json String ( decoded )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ ARRAY _ START ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ ARRAY _ START ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . push (" 0 ") Ġ// Ġpath Ġsegment Ġfor Ġfirst Ġelement ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( JsonArray ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// check Ġfor Ġempty Ġarray ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( scanner . hasMore () Ġ&& Ġscanner . hasNext ( TOKEN _ WH ITES PACE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ WH ITES PACE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scanner . hasNext ( TOKEN _ ARRAY _ END )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ ARRAY _ END ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ ARRAY _ END ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ ARRAY _ END ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġvalue Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpeek Ġ= Ġvalue Stack . peek () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peek Ġis ĠJson Array ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek . addElement ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠJson Parser Exception (" Expected Ġan ĠArray Ġbut Ġwas Ġa Ġ${ peek :: class }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ SEP ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ SEP ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġvalue Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpeek Ġ= Ġvalue Stack . peek () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( peek ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJson Array Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek . addElement ( value ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . push ( peek . elements . size . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠJsonObject Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġname Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek . setProperty ( name , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠJson Parser Exception (" Expected Ġan ĠArray Ġor Ġan ĠObject Ġbut Ġwas Ġa Ġ${ peek :: class }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ OBJECT _ START ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ OBJECT _ START ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( Json Un refer enc ableObject ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// check Ġfor Ġempty Ġobject ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( scanner . hasMore () Ġ&& Ġscanner . hasNext ( TOKEN _ WH ITES PACE )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ WH ITES PACE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( scanner . hasNext ( TOKEN _ OBJECT _ END )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ OBJECT _ END ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ OBJECT _ END ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ OBJECT _ END ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= Ġvalue Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpeek Ġ= Ġvalue Stack . peek () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( peek Ġis ĠJsonObject ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġname Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpeek . setProperty ( name , Ġvalue ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhandle Ġdifferent Ġkinds Ġof Ġobject ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠJson Reference ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( 1 Ġ== Ġpeek . property . size Ġ&& Ġpeek . property . containsKey ( Json . REF )) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġref Str Ġ= Ġpeek . property [ Json . REF ] !!. asString (). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġremove Ġleading Ġ'/' Ġthen Ġsplit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġref Str 1 Ġ= Ġref Str . substring ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġref Path Ġ= Ġif Ġ( ref Str 1 . isEmpty ()) Ġempty List < String >() Ġelse Ġref Str 1 . split ("/") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġref Ġ= ĠJson Reference ( doc , Ġref Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( ref ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠJson Reference ableObject ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ( peek . property . containsKey ( Json Document . TYPE ) Ġ&& Ġpeek . property [ Json Document . TYPE ] Ġ== ĠJson Document . Complex Object Kind . OBJECT . as Json String ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġj Path Ġ= Ġpath . elements . toList () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġobj Ġ= ĠJson Refer enc ableObject ( doc , Ġj Path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . pop () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobj . property Ġ= Ġpeek . property ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue Stack . push ( obj ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠJson Parser Exception (" Expected Ġan ĠObject Ġbut Ġwas Ġa Ġ${ peek :: class }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . hasNext ( TOKEN _ PROPERTY _ SEP ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġscanner . next ( TOKEN _ PROPERTY _ SEP ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġvalue Stack . pop (). asString (). value ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname Stack . push ( name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpath . push ( name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠJson Parser Exception (" Unexpected Ġcharacter Ġat Ġposition Ġ${ scanner . position } Ġ- Ġ'${ input . substring ( scanner . position )} '") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġdoc . root Ġ= Ġvalue Stack . pop () ĊĠĠĠĠĠĠĠ Ġreturn Ġdoc ĊĠĠĠ Ġ} Ċ }