package Ġio . john son lee . spi Ċ Ċ import Ġcom . google . auto . common . Annotation Mir rors . getAnnotation Value Ċ import Ġcom . google . auto . common . More Elements . getAnnotation Mirror Ċ import Ġcom . google . auto . common . More Types Ċ import Ġcom . google . auto . service . Auto Service Ċ import Ġcom . google . auto . service . processor . Auto Service Processor Ċ import Ġcom . squareup . jav ap o et . ClassName Ċ import Ġcom . squareup . jav ap o et . Java File Ċ import Ġcom . squareup . jav ap o et . Method Spec Ċ import Ġcom . squareup . jav ap o et . Parameterized TypeName Ċ import Ġcom . squareup . jav ap o et . Type Spec Ċ import Ġjava . io . PrintWriter Ċ import Ġjava . io . String Writer Ċ import Ġjavax . annotation . processing . Processing Environment Ċ import Ġjavax . annotation . processing . Round Environment Ċ import Ġjavax . annotation . processing . Supported Options Ċ import Ġjavax . lang . model . element . Annotation Mirror Ċ import Ġjavax . lang . model . element . Annotation Value Ċ import Ġjavax . lang . model . element . Element Ċ import Ġjavax . lang . model . element . Modifier Ċ import Ġjavax . lang . model . element . Package Element Ċ import Ġjavax . lang . model . element . Type Element Ċ import Ġjavax . lang . model . type . Declared Type Ċ import Ġjavax . lang . model . type . Type Mirror Ċ import Ġjavax . lang . model . util . Simple Annotation Value Visitor 8 Ċ import Ġjavax . tools . Diagnostic Ċ Ċ /** a Ċ Ġ* ĠPro cesses Ġ{@ link ĠAuto Service } Ġannotations Ġand Ġgenerates Ġthe Ġservice Ġprovider Ġcreator Ġclass Ċ Ġ* Ċ Ġ* Ġ@ author Ġj ohn son lee Ċ Ġ*/ Ċ @ Suppress (" Un stable Api Usage ") Ċ @ Supported Options (" debug ", Ġ" verify ") Ċ class ĠAuto Service Processor Ġ: ĠAuto Service Processor () Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġproviders Ġ= Ġmutable Map Of < String , ĠMutable List < String >>() ĊĊĠĠĠ Ġoverride Ġfun Ġprocess ( annotations : ĠMutable Set < out ĠType Element >, Ġround Env : ĠRound Environment ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġsuper . process ( annotations , Ġround Env ) Ġ&& Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( round Env . processing Over ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgenerate Provider Creators () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Annotations ( round Env ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . fatal Error ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġprocess Annotations ( round Env : ĠRound Environment ) Ġ{ ĊĠĠĠĠĠĠĠ Ġround Env . getElement s Annotated With ( Auto Service :: class . java ). also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . debug ( it . join ToString (", Ġ")) ĊĠĠĠĠĠĠĠ Ġ}. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġas ĠType Element ĊĠĠĠĠĠĠĠ Ġ}. forEach Ġ{ Ġimplement er Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġannotation Ġ= Ġget Annotation Mirror ( implement er , ĠAuto Service :: class . java ). get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproviders Ġ= Ġannotation . value Field Of Classes ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( providers . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . error (" No Ġservice Ġinterfaces Ġprovided Ġfor Ġelement !", Ġimplement er , Ġannotation ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproviders . forEach Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprovider Ġ= ĠMore Types . as Type Element ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( processing Env . check Implement er ( implement er , Ġprovider )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . providers . get Or Put ( provider . get Binary Name ( implement er . simple Name . toString ())) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmutable ListOf () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ+= Ġimplement er . get Binary Name ( implement er . simple Name . toString ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . error (" Service Providers Ġmust Ġimplement Ġtheir Ġservice Ġprovider Ġinterface . Ġ${ implement er . qualified Name } Ġdoes Ġnot Ġimplement Ġ${ provider . qualified Name }", Ġimplement er , Ġannotation ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġpublic Ġfinal Ġclass ĠImplement er _ Creator Ġimplements ĠCallable < Implement er > Ġ Ġ{ ĊĠĠĠĠ Ġ* ĠĠĠĠ ĠImplement er Ġcall () Ġ{ ĊĠĠĠĠ Ġ* ĠĠĠĠĠĠĠĠ Ġreturn Ġnew ĠImplement er (); ĊĠĠĠĠ Ġ* ĠĠĠĠ Ġ} ĊĠĠĠĠ Ġ* Ġ} ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġgenerate Provider Creators () Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠtypeOf Callable Ġ= ĠClass Name . get (" java . util . concurrent ", Ġ" Callable ") ĊĊĠĠĠĠĠĠĠ Ġthis . providers . entries . flatMap Ġ{ Ġ( k , Ġv ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġv . map Ġ{ Ġk Ġto Ġit Ġ} ĊĠĠĠĠĠĠĠ Ġ}. parallel Stream (). forEach Ġ{ Ġ(_, Ġimplement er ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpkg Ġ= Ġimplement er . substring Before Last ('.') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġimplement er . substring After Last ('.') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcreator Ġ= Ġ"${ name }_ Creator " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠtypeOf Implement er Ġ= ĠClass Name . get ( pkg , Ġname ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠtypeOf Callable Of Implement er Ġ= ĠParameter ized TypeName . get ( type Of Callable , ĠtypeOf Implement er ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġimplement er Creator Ġ= ĠType Spec . class Builder ( creator ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( Modifier . PUBLIC , ĠModifier . FINAL ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Super interface ( type Of Callable Of Implement er ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Method ( Method Spec . method Builder (" call ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Modifiers ( Modifier . PUBLIC , ĠModifier . FINAL ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Statement (" return Ġnew Ġ" Ġ+ Ġ'$ ' Ġ+ Ġ" T ()", ĠtypeOf Implement er ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. returns ( type Of Implement er ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġprocessing Env . debug (" Generating Ġ$ creator Ġ... ") ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJava File . builder ( pkg , Ġimplement er Creator ). build (). writeTo ( processing Env . filer ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ fun ĠType Element . get Binary Name ( className : ĠString ): ĠString Ġ{ ĊĠĠĠ Ġval Ġen closing Element Ġ= Ġthis . enc lo sing Element ĊĠĠĠ Ġif Ġ( enc lo sing Element Ġis ĠPackage Element ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( enc lo sing Element . is Unnamed ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠclassName ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġen closing Element . qualified Name . toString () Ġ+ Ġ"." Ġ+ ĠclassName ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġtype Element Ġ= Ġen closing Element Ġas ĠType Element ĊĠĠĠ Ġreturn Ġtype Element . get Binary Name ( type Element . simple Name . toString () Ġ+ Ġ"$ " Ġ+ ĠclassName ) Ċ } Ċ Ċ fun ĠProcessing Environment . check Implement er ( implement er : ĠType Element , Ġprovider : ĠType Element ): ĠBoolean Ġ{ ĊĠĠĠ Ġval Ġverify : ĠString ? Ġ= Ġthis . options [" verify "] ĊĠĠĠ Ġif Ġ( verify ?. to Boolean () Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĠĠĠ Ġreturn Ġtype Utils . is Subtype ( implement er . as Type (), Ġprovider . as Type ()) Ċ } Ċ Ċ fun ĠProcessing Environment . debug ( msg : ĠString ) Ġ{ ĊĠĠĠ Ġif Ġ( options . containsKey (" debug ")) Ġ{ ĊĠĠĠĠĠĠĠ Ġmess ager . print Message ( Diagnostic . Kind . NOTE , Ġmsg ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun ĠProcessing Environment . error ( msg : ĠString , Ġelement : ĠElement , Ġannotation : ĠAnnotation Mirror ) Ġ{ ĊĠĠĠ Ġmess ager . print Message ( Diagnostic . Kind . ERROR , Ġmsg , Ġelement , Ġannotation ) Ċ } Ċ Ċ fun ĠProcessing Environment . fatal Error ( e : ĠThrowable ) Ġ{ ĊĠĠĠ Ġval Ġstack trace Ġ= ĠString Writer (). use Ġ{ ĊĠĠĠĠĠĠĠ Ġe . printStackTrace ( PrintWriter ( it )) ĊĠĠĠ Ġ}. toString () ĊĠĠĠ Ġmess ager . print Message ( Diagnostic . Kind . ERROR , Ġstack trace ) Ċ } Ċ Ċ val ĠAnnotation Mirror . value Field Of Classes : ĠSet < Declared Type > ĊĠĠĠ Ġget () Ġ= Ġget Annotation Value ( this , Ġ" value "). accept ( object Ġ: ĠSimple Annotation Value Visitor 8 < Set < Declared Type >, ĠAny ?> () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Type ( type Mirror : ĠType Mirror , Ġv : ĠAny ?): ĠSet < Declared Type >? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġset Of ( More Types . as Declared ( type Mirror )) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit Array ( values : ĠList < Annotation Value >, Ġv : ĠAny ?): ĠSet < Declared Type >? Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġvalues . flatMap Ġ{ Ġvalue Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvalue . accept ( this , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ}. toSet () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}, Ġnull ) Ċ