/* Ċ Ġ* ĠCopyright Ġ 2 0 2 0 ĠgRPC Ġauthors . Ċ Ġ* Ċ Ġ* Ġ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 Ġio . grpc . kotlin . generator Ċ Ċ import Ġcom . google . common . annotations . Visible ForTesting Ċ import Ġcom . google . protobuf . Descriptors . MethodDescriptor Ċ import Ġcom . google . protobuf . Descriptors . Service Descriptor Ċ import Ġcom . squareup . kotlin po et . Annotation Spec Ċ import Ġcom . squareup . kotlin po et . ClassName Ċ import Ġcom . squareup . kotlin po et . Code Block Ċ import Ġcom . squareup . kotlin po et . Fun Spec Ċ import Ġcom . squareup . kotlin po et . K Modifier Ċ import Ġcom . squareup . kotlin po et . Member Name Ċ import Ġcom . squareup . kotlin po et . Member Name . Companion . member Ċ import Ġcom . squareup . kotlin po et . Parameter Spec Ċ import Ġcom . squareup . kotlin po et . Parameterized TypeName . Companion . parameter ized By Ċ import Ġcom . squareup . kotlin po et . Type Spec Ċ import Ġcom . squareup . kotlin po et . as ClassName Ċ import Ġio . grpc . Server Service Definition Ċ import Ġio . grpc . Status Ċ import Ġio . grpc . Status Exception Ċ import Ġio . grpc . kotlin . Abstract Coroutine Server Impl Ċ import Ġio . grpc . kotlin . Server Calls Ċ import Ġio . grpc . kotlin . generator . protoc . Declarations Ċ import Ġio . grpc . kotlin . generator . protoc . Generator Config Ċ import Ġio . grpc . kotlin . generator . protoc . Member Simple Name Ċ import Ġio . grpc . kotlin . generator . protoc . builder Ċ import Ġio . grpc . kotlin . generator . protoc . class Builder Ċ import Ġio . grpc . kotlin . generator . protoc . declarations Ċ import Ġio . grpc . kotlin . generator . protoc . methodName Ċ import Ġio . grpc . kotlin . generator . protoc . of Ċ import Ġio . grpc . kotlin . generator . protoc . serviceName Ċ import Ġkotlinx . coroutines . Cancellation Exception Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlin . coroutines . Coroutine Context Ċ import Ġkotlin . coroutines . Empty Coroutine Context Ċ Ċ /** Ċ Ġ* ĠGenerator Ġfor Ġabstract Ġclasses Ġof Ġthe Ġform Ġ` My Service Coroutine Impl Base `. Ċ Ġ*/ Ċ class ĠGr pc Coroutine Server Generator ( config : ĠGenerator Config ): ĠService Code Generator ( config ) Ġ{ ĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġprivate Ġconst Ġval ĠIMP L _ BASE _ SUFFIX Ġ= Ġ" Coroutine Impl Base " ĊĊĠĠĠ Ġprivate Ġval ĠF LOW : ĠClass Name Ġ= ĠFlow :: class . as ClassName () ĊĠĠĠ Ġprivate Ġval ĠUN ARY _ REQUEST _ NAME : ĠMember Simple Name Ġ= ĠMember Simple Name (" request ") ĊĠĠĠ Ġprivate Ġval ĠST REAM ING _ REQUEST _ NAME : ĠMember Simple Name Ġ= ĠMember Simple Name (" requests ") ĊĊĠĠĠ Ġprivate Ġval Ġcoroutine Context Parameter : ĠParameter Spec Ġ= ĊĠĠĠĠĠ ĠParameter Spec ĊĠĠĠĠĠĠĠ Ġ. builder (" coroutine Context ", ĠCor outine Context :: class ) ĊĠĠĠĠĠĠĠ Ġ. defaultValue ("% T ", ĠEmpty Coroutine Context :: class ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġprivate Ġval ĠSERVER _ SERVICE _ DEFINITION _ BUILDER _ FACTORY : ĠMember Name Ġ= ĊĠĠĠĠĠ ĠServer Service Definition :: class . member (" builder ") ĊĊĠĠĠ Ġprivate Ġval ĠUN ARY _ S MD : ĠMember Name Ġ= ĠServer Calls :: class . member (" unary Server Method Definition ") ĊĠĠĠ Ġprivate Ġval ĠCLIENT _ STREAM ING _ S MD : ĠMember Name Ġ= ĊĠĠĠĠĠ ĠServer Calls :: class . member (" client Streaming Server Method Definition ") ĊĠĠĠ Ġprivate Ġval ĠSERVER _ STREAM ING _ S MD : ĠMember Name Ġ= ĊĠĠĠĠĠ ĠServer Calls :: class . member (" server Streaming Server Method Definition ") ĊĠĠĠ Ġprivate Ġval ĠB IDI _ STREAM ING _ S MD : ĠMember Name Ġ= ĊĠĠĠĠĠ ĠServer Calls :: class . member (" b idi Streaming Server Method Definition ") ĊĊĠĠĠ Ġprivate Ġval ĠUN IMPLEMENTED _ STATUS : ĠMember Name Ġ= ĊĠĠĠĠĠ ĠStatus :: class . member (" UN IMPLEMENTED ") ĊĠ Ġ} ĊĊĠ Ġoverride Ġfun Ġgenerate ( service : ĠService Descriptor ): ĠDecl arations Ġ= Ġdeclarations Ġ{ ĊĠĠĠ Ġadd Type ( impl Class ( service )) ĊĠ Ġ} ĊĊĠ Ġfun Ġimpl Class ( service : ĠService Descriptor ): ĠType Spec Ġ{ ĊĠĠĠ Ġval Ġservice Impl ClassName Ġ= Ġservice . serviceName . to Class Simple Name (). with Suffix ( IMPL _ BASE _ SUFFIX ) ĊĊĠĠĠ Ġval Ġstub s : ĠList < MethodImpl Stub > Ġ= Ġservice . methods . map Ġ{ Ġservice Method Stub ( it ) Ġ} ĊĠĠĠ Ġval Ġimpl Builder Ġ= ĠType Spec ĊĠĠĠĠĠ Ġ. class Builder ( service Impl ClassName ) ĊĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . AB STR ACT ) ĊĠĠĠĠĠ Ġ. add K doc ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠ ĠS ke let al Ġimplementation Ġof Ġthe Ġ% L Ġservice Ġbased Ġon ĠKotlin Ġcor outines . ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent (), ĊĠĠĠĠĠĠĠ Ġservice . fullName ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ. primary Constructor ( ĊĠĠĠĠĠĠĠ ĠFun Spec . constructor Builder () ĊĠĠĠĠĠĠĠĠĠ Ġ. add Parameter ( coroutine Context Parameter ) ĊĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ. super class ( Abstract Coroutine Server Impl :: class ) ĊĠĠĠĠĠ Ġ. add Super class Constructor Parameter ("% N ", Ġcoroutine Context Parameter ) ĊĊĠĠĠ Ġvar Ġserver Service Definition Builder Ġ= ĊĠĠĠĠĠ ĠCode Block . of ("% M (% M ()) ", ĠSERVER _ SERVICE _ DEFINITION _ BUILDER _ FACTORY , Ġservice . grpc Descriptor ) ĊĊĠĠĠ Ġfor Ġ( stub Ġin Ġstub s ) Ġ{ ĊĠĠĠĠĠ Ġimpl Builder . addFunction ( stub . method Spec ) ĊĠĠĠĠĠ Ġserver Service Definition Builder Ġ= ĠCode Block . of ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠĠĠ Ġ% L ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. add Method (% L ) ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent (), ĊĠĠĠĠĠĠĠ Ġserver Service Definition Builder , ĊĠĠĠĠĠĠĠ Ġstub . server Method Def ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġimpl Builder . addFunction ( ĊĠĠĠĠĠ ĠFun Spec . builder (" bind Service ") ĊĠĠĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OVERRIDE , ĠK Modifier . FINAL ) ĊĠĠĠĠĠĠĠ Ġ. returns ( Server Service Definition :: class ) ĊĠĠĠĠĠĠĠ Ġ. add Statement (" return Ġ% L . build ()", Ġserver Service Definition Builder ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġreturn Ġimpl Builder . build () ĊĠ Ġ} ĊĊĠ Ġ@ Visible ForTesting ĊĠ Ġdata Ġclass ĠMethod Impl Stub ( ĊĠĠĠ Ġval Ġmethod Spec : ĠFun Spec , ĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠA Ġ[ Code Block ] Ġthat Ġcomputes Ġa Ġ[ Server Method Definition ] Ġbased Ġon Ġan Ġimplementation Ġof ĊĠĠĠĠ Ġ* Ġthe Ġfunction Ġdescribed Ġin Ġ[ method Spec ]. ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġval Ġserver Method Def : ĠCode Block ĊĠ Ġ) ĊĊĠ Ġ@ Visible ForTesting ĊĠ Ġfun Ġservice Method Stub ( method : ĠMethod Descriptor ): ĠMethod Impl Stub Ġ= Ġwith ( config ) Ġ{ ĊĠĠĠ Ġval Ġrequest Type Ġ= Ġmethod . input Type . message Class () ĊĠĠĠ Ġval Ġrequest Param Ġ= Ġif Ġ( method . is Client Streaming ) Ġ{ ĊĠĠĠĠĠ ĠParameter Spec . of ( STREAM ING _ REQUEST _ NAME , ĠF LOW . parameter ized By ( request Type )) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ ĠParameter Spec . of ( UNARY _ REQUEST _ NAME , Ġrequest Type ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġmethod Spec Builder Ġ= ĠFun Spec . builder ( method . methodName . to Member Simple Name ()) ĊĠĠĠĠĠ Ġ. add Modifiers ( K Modifier . OPEN ) ĊĠĠĠĠĠ Ġ. add Parameter ( request Param ) ĊĠĠĠĠĠ Ġ. add Statement ( ĊĠĠĠĠĠĠĠ Ġ" throw Ġ% T (% M . with Description (% S )) ", ĊĠĠĠĠĠĠĠ ĠStatus Exception :: class , ĊĠĠĠĠĠĠĠ ĠUN IMPLEMENTED _ STATUS , ĊĠĠĠĠĠĠĠ Ġ" Method Ġ${ method . fullName } Ġis Ġunimplemented " ĊĠĠĠĠĠ Ġ) ĊĊĠĠĠ Ġif Ġ( method . options . deprecated ) Ġ{ ĊĠĠĠĠĠ Ġmethod Spec Builder . add Annotation ( ĊĠĠĠĠĠĠĠ ĠAnnotation Spec . builder ( Deprecated :: class ) ĊĠĠĠĠĠĠĠĠĠ Ġ. add Member ("% S ", Ġ" The Ġunderlying Ġservice Ġmethod Ġis Ġmarked Ġdeprecated .") ĊĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġresponse Type Ġ= Ġmethod . output Type . message Class () ĊĠĠĠ Ġif Ġ( method . is Server Streaming ) Ġ{ ĊĠĠĠĠĠ Ġmethod Spec Builder . returns ( FLOW . parameter ized By ( response Type )) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġmethod Spec Builder . returns ( response Type ) ĊĠĠĠĠĠ Ġmethod Spec Builder . add Modifiers ( K Modifier . SUS PEND ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġmethod Spec Builder . add K doc ( stub K Doc ( method , Ġrequest Param )) ĊĊĠĠĠ Ġval Ġmethod Spec Ġ= Ġmethod Spec Builder . build () ĊĊĠĠĠ Ġval Ġs md Factory Ġ= Ġif Ġ( method . is Server Streaming ) Ġ{ ĊĠĠĠĠĠ Ġif Ġ( method . is Client Streaming ) ĠB IDI _ STREAM ING _ S MD Ġelse ĠSERVER _ STREAM ING _ S MD ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġif Ġ( method . is Client Streaming ) ĠCLIENT _ STREAM ING _ S MD Ġelse ĠUN ARY _ S MD ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġserver Method Def Ġ= ĊĠĠĠĠĠ ĠCode Block . of ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠĠĠ Ġ% M ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext Ġ= Ġthis . context , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdescriptor Ġ= Ġ% L , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimplementation Ġ= Ġ:: % N ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent (), ĊĠĠĠĠĠĠĠ Ġs md Factory , ĊĠĠĠĠĠĠĠ Ġmethod . descriptor Code , ĊĠĠĠĠĠĠĠ Ġmethod Spec ĊĠĠĠĠĠ Ġ) ĊĊĠĠĠ ĠMethod Impl Stub ( method Spec , Ġserver Method Def ) ĊĠ Ġ} ĊĊĠ Ġprivate Ġfun Ġstub K Doc ( ĊĠĠĠ Ġmethod : ĠMethod Descriptor , ĊĠĠĠ Ġrequest Param : ĠParameter Spec ĊĠ Ġ): ĠCode Block Ġ{ ĊĠĠĠ Ġval Ġk Doc Bindings Ġ= Ġmap Of ( ĊĠĠĠĠĠ Ġ" request Param " Ġto Ġrequest Param , ĊĠĠĠĠĠ Ġ" methodName " Ġto Ġmethod . fullName , ĊĠĠĠĠĠ Ġ" flow " Ġto ĠF LOW , ĊĠĠĠĠĠ Ġ" status " Ġto ĠStatus :: class , ĊĠĠĠĠĠ Ġ" status Exception " Ġto ĠStatus Exception :: class , ĊĠĠĠĠĠ Ġ" c ancellation Exception " Ġto ĠC ancellation Exception :: class , ĊĠĠĠĠĠ Ġ" il legal StateException " Ġto ĠIllegalStateException :: class ĊĠĠĠ Ġ) ĊĊĊĠĠĠ Ġval Ġk Doc Sections Ġ= Ġmutable ListOf < String >() ĊĊĠĠĠ Ġif Ġ( method . is Server Streaming ) Ġ{ ĊĠĠĠĠĠ Ġk Doc Sections . add (" Returns Ġa Ġ[% flow : T ] Ġof Ġresponses Ġto Ġan ĠRPC Ġfor Ġ% methodName : L .") ĊĠĠĠĠĠ Ġk Doc Sections . add ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠĠĠ ĠIf Ġcreating Ġor Ġcollecting Ġthe Ġreturned Ġflow Ġfails Ġwith Ġa Ġ[% status Exception : T ], Ġthe ĠRPC ĊĠĠĠĠĠĠĠĠĠ Ġwill Ġfail Ġwith Ġthe Ġcorresponding Ġ[% status : T ]. Ġ ĠIf Ġit Ġfails Ġwith Ġa ĊĠĠĠĠĠĠĠĠĠ Ġ[% c ancellation Exception : T ], Ġthe ĠRPC Ġwill Ġfail Ġwith Ġstatus Ġ` Status . CANCEL LED `. Ġ ĠIf Ġcreating ĊĠĠĠĠĠĠĠĠĠ Ġor Ġcollecting Ġthe Ġreturned Ġflow Ġfails Ġfor Ġany Ġother Ġreason , Ġthe ĠRPC Ġwill Ġfail Ġwith ĊĠĠĠĠĠĠĠĠĠ Ġ` Status . UNKNOWN ` Ġwith Ġthe Ġexception Ġas Ġa Ġcause . ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġk Doc Sections . add (" Returns Ġthe Ġresponse Ġto Ġan ĠRPC Ġfor Ġ% methodName : L .") ĊĠĠĠĠĠ Ġk Doc Sections . add ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠĠĠ ĠIf Ġthis Ġmethod Ġfails Ġwith Ġa Ġ[% status Exception : T ], Ġthe ĠRPC Ġwill Ġfail Ġwith Ġthe Ġcorresponding ĊĠĠĠĠĠĠĠĠĠ Ġ[% status : T ]. Ġ ĠIf Ġthis Ġmethod Ġfails Ġwith Ġa Ġ[% c ancellation Exception : T ], Ġthe ĠRPC Ġwill Ġfail ĊĠĠĠĠĠĠĠĠĠ Ġwith Ġstatus Ġ` Status . CANCEL LED `. Ġ ĠIf Ġthis Ġmethod Ġfails Ġfor Ġany Ġother Ġreason , Ġthe ĠRPC Ġwill ĊĠĠĠĠĠĠĠĠĠ Ġfail Ġwith Ġ` Status . UNKNOWN ` Ġwith Ġthe Ġexception Ġas Ġa Ġcause . ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( method . is Client Streaming ) Ġ{ ĊĠĠĠĠĠ Ġk Doc Sections . add ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠĠĠ Ġ@ param Ġ% request Param : N ĠA Ġ[% flow : T ] Ġof Ġrequests Ġfrom Ġthe Ġclient . Ġ ĠThis Ġflow Ġcan Ġbe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcollected Ġonly Ġonce Ġand Ġthrows Ġ[% il legal StateException : T ] Ġon Ġattempts Ġto Ġcollect ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġmore Ġthan Ġonce . ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġk Doc Sections . add ( ĊĠĠĠĠĠĠĠ Ġ""" ĊĠĠĠĠĠĠĠĠĠ Ġ@ param Ġ% request Param : N ĠThe Ġrequest Ġfrom Ġthe Ġclient . ĊĠĠĠĠĠĠĠ Ġ""" . trim Indent () ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn ĠCode Block ĊĠĠĠĠĠ Ġ. builder () ĊĠĠĠĠĠ Ġ. add Named ( k Doc Sections . join ToString ("\ n \ n "), Ġk Doc Bindings ) ĊĠĠĠĠĠ Ġ. build () ĊĠ Ġ} Ċ }