// ĠCopyright Ġ 2 0 0 0 - 2 0 1 8 ĠJetBrains Ġs . r . o . ĠUse Ġof Ġthis Ġsource Ġcode Ġis Ġgoverned Ġby Ġthe ĠApache Ġ 2 . 0 Ġlicense Ġthat Ġcan Ġbe Ġfound Ġin Ġthe ĠLICENSE Ġfile . Ċ package Ġorg . jetbrains . protocol Reader Ċ Ċ import Ġorg . jetbrains . json Protocol . JsonObject Based Ċ import Ġjava . lang . reflect . Method Ċ import Ġjava . util .* Ċ Ċ internal Ġconst Ġval ĠFIELD _ PREFIX Ġ= Ġ'_' Ċ Ċ internal Ġconst Ġval ĠNAME _ VAR _ NAME Ġ= Ġ"_ n " Ċ Ċ private Ġfun Ġassign Field ( out : ĠText Output , ĠfieldName : ĠString ) Ġ= Ġout . append ( FIELD _ PREFIX ). append ( fieldName ). append (" Ġ= Ġ") Ċ Ċ internal Ġclass ĠType Ref < T >( val Ġtype Class : ĠClass < T >) Ġ{ ĊĠ Ġvar Ġtype : ĠType Writer < T >? Ġ= Ġnull Ċ } Ċ Ċ internal Ġclass ĠType Writer < T >( val Ġtype Class : ĠClass < T >, Ġjson Super Class : ĠType Ref < *> ?, Ġprivate Ġval Ġvolatile Fields : ĠList < Volatile Field Binding >, Ġprivate Ġval Ġmethod Handler Map : ĠLinkedHashMap < Method , ĠMethod Handler >, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ/** ĠLo aders Ġthat Ġshould Ġread Ġvalues Ġand Ġsave Ġthem Ġin Ġfield Ġarray Ġon Ġparse Ġtime . Ġ*/ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġfield Lo aders : ĠList < Field Loader >, Ġprivate Ġval Ġhas Lazy Fields : ĠBoolean ) Ġ{ ĊĊĠ Ġ/** ĠSub type Ġaspects Ġof Ġthe Ġtype Ġor Ġnull Ġ*/ ĊĠ Ġval Ġsubtype Aspect Ġ= Ġif Ġ( json Super Class Ġ== Ġnull ) Ġnull Ġelse ĠExisting Subtype Aspect ( json Super Class ) ĊĊĠ Ġfun Ġwrite Inst antiate Code ( scope : ĠClass Scope , Ġout : ĠText Output ) Ġ{ ĊĠĠĠ Ġwrite Inst antiate Code ( scope , Ġfalse , Ġout ) ĊĠ Ġ} ĊĊĠ Ġfun Ġwrite Inst antiate Code ( scope : ĠClass Scope , Ġdeferred Reading : ĠBoolean , Ġout : ĠText Output ) Ġ{ ĊĠĠĠ Ġval ĠclassName Ġ= Ġscope . getType Impl Reference ( this ) ĊĠĠĠ Ġif Ġ( deferred Reading Ġ|| Ġsubtype Aspect Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġout . append ( className ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠ Ġsubtype Aspect . write Inst antiate Code ( className , Ġout ) ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġfun Ġwrite ( file Scope : ĠFile Scope ) Ġ{ ĊĠĠĠ Ġval Ġout Ġ= Ġfile Scope . output ĊĠĠĠ Ġval Ġvalue Impl ClassName Ġ= Ġfile Scope . getType Impl ShortName ( this ) ĊĠĠĠ Ġout . append (" private Ġclass Ġ"). append ( value Impl ClassName ). append (' (' ). append ( JSON _ READ ER _ PARAMETER _ DEF ). comma (). append (" pre Read Name : ĠString ?") ĊĠĠĠ Ġsubtype Aspect ?. write Super Field Java ( out ) ĊĠĠĠ Ġout . append (" ) Ġ: Ġ"). append ( type Class . canonical Name ). open Block () ĊĊĠĠĠ Ġif Ġ( has Lazy Fields Ġ|| ĠJsonObject Based :: class . java . isAssignableFrom ( type Class )) Ġ{ ĊĠĠĠĠĠ Ġout . append (" private Ġvar Ġ"). append ( PENDING _ INPUT _ READ ER _ NAME ). append (": Ġ"). append ( JSON _ READ ER _ CLASS _ NAME ). append (" ? Ġ= Ġreader . sub Reader () !! "). new Line () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġclass Scope Ġ= Ġfile Scope . new Class Scope () ĊĠĠĠ Ġfor Ġ( field Ġin Ġvolatile Fields ) Ġ{ ĊĠĠĠĠĠ Ġfield . writeField Declaration ( class Scope , Ġout ) ĊĠĠĠĠĠ Ġout . new Line () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfor Ġ( loader Ġin Ġfield Lo aders ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( loader . as Impl ) Ġ{ ĊĠĠĠĠĠĠĠ Ġout . append (" override ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġout . append (" private ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġout . append (" Ġvar Ġ"). append Name ( loader ) ĊĊĠĠĠĠĠ Ġfun Ġadd Type () Ġ{ ĊĠĠĠĠĠĠĠ Ġout . append (": Ġ") ĊĠĠĠĠĠĠĠ Ġloader . value Reader . append Finished Value TypeName ( out ) ĊĠĠĠĠĠĠĠ Ġout . append (" ? Ġ= Ġnull ") ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġif Ġ( loader . value Reader Ġis ĠPrimitive Value Reader ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠdefaultValue Ġ= Ġloader . defaultValue Ġ?: Ġloader . value Reader . defaultValue ĊĠĠĠĠĠĠĠ Ġif Ġ( defaultValue Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġout . append (" Ġ= Ġ"). append ( defaultValue ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġadd Type () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġadd Type () ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġout . new Line () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( field Lo aders . isNotEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġout . new Line () ĊĠĠĠ Ġ} ĊĠĠĠ Ġwrite Constructor Method ( class Scope , Ġout ) ĊĠĠĠ Ġout . new Line () ĊĊĠĠĠ Ġsubtype Aspect ?. write Parse Method ( class Scope , Ġout ) ĊĊĠĠĠ Ġfor Ġ(( key , Ġvalue ) Ġin Ġmethod Handler Map . entries ) Ġ{ ĊĠĠĠĠĠ Ġout . new Line () ĊĠĠĠĠĠ Ġvalue . write Method Implementation Java ( class Scope , Ġkey , Ġout ) ĊĠĠĠĠĠ Ġout . new Line () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġwrite Base Methods ( out ) ĊĠĠĠ Ġsubtype Aspect ?. write Get Super Method Java ( out ) ĊĊĠĠĠ Ġwrite Equals Method ( value Impl ClassName , Ġout ) ĊĊĠĠĠ Ġout . indent Out (). append (' }') ĊĠ Ġ} ĊĊĠ Ġ/** ĊĠĠ Ġ* ĠGenerates ĠJava Ġimplementation Ġof Ġstandard Ġmethods Ġof ĠJSON Ġtype Ġclass Ġ( if Ġneeded ): ĊĠĠ Ġ* Ġ{@ link Ġorg . jetbrains . json Protocol . JsonObject Based # get Deferred Reader ()} ĊĠĠ Ġ*/ ĊĠ Ġprivate Ġfun Ġwrite Base Methods ( out : ĠText Output ) Ġ{ ĊĠĠĠ Ġval Ġmethod : ĠMethod ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ Ġmethod Ġ= Ġtype Class . getMethod (" get Deferred Reader ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġcatch Ġ( ignored : ĠNoSuch Method Exception ) Ġ{ ĊĠĠĠĠĠ Ġ// ĠMethod Ġnot Ġfound , Ġskip . ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġout . new Line () ĊĠĠĠ Ġwrite Method Declaration Java ( out , Ġmethod ) ĊĠĠĠ Ġout . append (" Ġ= Ġ"). append ( PENDING _ INPUT _ READ ER _ NAME ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġwrite Equals Method ( value Impl ClassName : ĠString , Ġout : ĠText Output ) Ġ{ ĊĠĠĠ Ġif Ġ( field Lo aders . isEmpty ()) Ġ{ ĊĠĠĠĠĠ Ġreturn ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġout . new Line (). append (" override Ġfun Ġequals ( other : ĠAny ?): ĠBoolean Ġ= Ġ") ĊĠĠĠ Ġout . append (" other Ġis Ġ"). append ( value Impl ClassName ) ĊĊĠĠĠ Ġ// Ġat Ġfirst Ġwe Ġshould Ġcompare Ġprimitive Ġvalues , Ġthen Ġenums , Ġthen Ġstring , Ġthen Ġobjects ĊĠĠĠ Ġfun Ġfield Weight ( reader : ĠValue Reader ): ĠInt Ġ{ ĊĠĠĠĠĠ Ġvar Ġw Ġ= Ġ 1 0 ĊĠĠĠĠĠ Ġif Ġ( reader Ġis ĠPrimitive Value Reader ) Ġ{ ĊĠĠĠĠĠĠĠ Ġw -- ĊĠĠĠĠĠĠĠ Ġif Ġ( reader . className Ġ!= Ġ" String ") Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġw -- ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġif Ġ( reader Ġis ĠEnum Reader ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġ- 1 Ġas Ġprimitive , Ġ- 1 Ġas Ġnot Ġa Ġstring ĊĠĠĠĠĠĠĠ Ġw Ġ-= Ġ 2 ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġreturn Ġw ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfor Ġ( loader Ġin Ġfield Lo aders . sorted With ( Comparator < Field Loader > Ġ{ Ġf 1 , Ġf 2 Ġ-> Ġfield Weight (( f 1 . value Reader )) Ġ- Ġfield Weight (( f 2 . value Reader )) })) Ġ{ ĊĠĠĠĠĠ Ġout . append (" Ġ&& Ġ") ĊĠĠĠĠĠ Ġout . append Name ( loader ). append (" Ġ== Ġ"). append (" other . "). append Name ( loader ) ĊĠĠĠ Ġ} ĊĠĠĠ Ġout . new Line () ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġwrite Constructor Method ( class Scope : ĠClass Scope , Ġout : ĠText Output ) Ġ{ ĊĠĠĠ Ġout . append (" init "). block Ġ{ ĊĠĠĠĠĠ Ġif Ġ( field Lo aders . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġout . append ( READ ER _ NAME ). append (". skip Value () ") ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠ Ġout . append (" var Ġ"). append ( NAME _ VAR _ NAME ). append (" Ġ= Ġpre Read Name ") ĊĠĠĠĠĠĠĠ Ġout . new Line (). append (" if Ġ( "). append ( NAME _ VAR _ NAME ). append (" Ġ== Ġnull Ġ&& Ġreader . hasNext () Ġ&& Ġreader . begin Object (). hasNext ()) "). block Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġout . append ( NAME _ VAR _ NAME ). append (" Ġ= Ġreader . next Name () ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġout . new Line () ĊĊĠĠĠĠĠĠĠ Ġwrite Read Fields ( out , Ġclass Scope ) ĊĊĠĠĠĠĠĠĠ Ġ// Ġwe Ġdon 't Ġread Ġall Ġdata Ġif Ġwe Ġhave Ġlazy Ġfields , Ġso , Ġwe Ġshould Ġnot Ġcheck Ġend Ġof Ġstream ĊĠĠĠĠĠĠĠ Ġ// if Ġ(! has Lazy Fields ) Ġ{ ĊĠĠĠĠĠĠĠ Ġout . new Line (). new Line (). append ( READ ER _ NAME ). append (". end Object () ") ĊĠĠĠĠĠĠĠ Ġ//} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġwrite Read Fields ( out : ĠText Output , Ġclass Scope : ĠClass Scope ) Ġ{ ĊĠĠĠ Ġval Ġstop If All Fields W ere Read Ġ= Ġhas Lazy Fields ĊĠĠĠ Ġval Ġhas Only One Field Loader Ġ= Ġfield Lo aders . size Ġ== Ġ 1 ĊĠĠĠ Ġval Ġis Tr aced Stop Ġ= Ġstop If All Fields W ere Read Ġ&& Ġ! has Only One Field Loader ĊĠĠĠ Ġif Ġ( is Tr aced Stop ) Ġ{ ĊĠĠĠĠĠ Ġout . new Line (). append (" var Ġi Ġ= Ġ 0 ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġout . new Line (). append (" loop @ Ġwhile Ġ( "). append ( NAME _ VAR _ NAME ). append (" Ġ!= Ġnull ) "). block Ġ{ ĊĠĠĠĠĠ Ġ( out Ġ+ Ġ" when Ġ(" Ġ+ ĠNAME _ VAR _ NAME Ġ+ Ġ") "). block Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġis First Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġfor Ġ( field Loader Ġin Ġfield Lo aders ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Loader . skip Read ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is First ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . new Line () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġout . append ('" ') ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( field Loader . json Name . first () Ġ== Ġ'$ ') Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . append ('\\ ') ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġout . append ( field Loader . json Name ). append ('" '). append (" Ġ-> Ġ") ĊĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop If All Fields W ere Read Ġ&& Ġ! is Tr aced Stop ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . open Block () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġval Ġprimitive Value Name Ġ= Ġif Ġ( field Loader . value Reader Ġis ĠObject Value Reader ) Ġfield Loader . value Reader . primitive Value Name Ġelse Ġnull ĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( primitive Value Name Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . append (" if Ġ( reader . peek () Ġ== Ġcom . google . gson . stream . Json Token . BEGIN _ OBJECT ) "). open Block () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġout . append Name ( field Loader ). append (" Ġ= Ġ") ĊĊĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfield Loader . value Reader . write Read Code ( class Scope , Ġfalse , Ġout ) ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġcatch Ġ( e : ĠUnsupportedOperationException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . append (" throw ĠUnsupportedOperationException () "). new Line () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( primitive Value Name Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . close Block (). new Line (). append (" else "). block Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassign Field ( out , Ġ"${ primitive Value Name } Type ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout . append (" reader . peek () "). new Line () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġassign Field ( out , Ġprimitive Value Name ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Ġ+ Ġ" reader . next String ( true )" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( stop If All Fields W ere Read Ġ&& Ġ! is Tr aced Stop ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . new Line (). append ( READ ER _ NAME ). append (". skip Values () "). new Line (). append (" break @ loop "). close Block () ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġif Ġ( is First ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis First Ġ= Ġfalse ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġout . new Line (). append (" else Ġ-> ") ĊĠĠĠĠĠĠĠ Ġif Ġ( is Tr aced Stop ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġout . block Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . append (" reader . skip Value () ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . new Line () Ġ+ ĠNAME _ VAR _ NAME Ġ+ Ġ" Ġ= Ġreader . next Name OrNull ()" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout . new Line () Ġ+ Ġ" continue @ loop " ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġout . space (). append (" reader . skip Value () ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġout . new Line () Ġ+ ĠNAME _ VAR _ NAME Ġ+ Ġ" Ġ= Ġreader . next Name OrNull ()" ĊĊĠĠĠĠĠ Ġif Ġ( is Tr aced Stop ) Ġ{ ĊĠĠĠĠĠĠĠ Ġout . new Line (). new Line (). append (" if Ġ( i ++ Ġ== Ġ"). append ( field Lo aders . size Ġ- Ġ 1 ). append (" ) "). block Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġ( out Ġ+ ĠREAD ER _ NAME Ġ+ Ġ". skip Values () "). new Line () Ġ+ Ġ" break " ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ }