Skip to content

Commit

Permalink
Generate gRPC client code that calls new GrpcClient API (square#1450)
Browse files Browse the repository at this point in the history
* Generate gRPC client code that calls new GrpcClient API

* Update wire-grpc-tests
  • Loading branch information
Egor Andreevich authored Mar 5, 2020
1 parent cf30bef commit 03d0e98
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class GrpcClientTest {
.client(okhttpClient)
.baseUrl(mockService.url)
.build()
routeGuideService = grpcClient.create(RouteGuideClient::class)
routeGuideService = RouteGuideClient(grpcClient)
}

@After
Expand Down
51 changes: 25 additions & 26 deletions wire-grpc-tests/src/test/proto-grpc/routeguide/RouteGuideClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
package routeguide

import com.squareup.wire.GrpcCall
import com.squareup.wire.GrpcClient
import com.squareup.wire.GrpcMethod
import com.squareup.wire.GrpcStreamingCall
import com.squareup.wire.Service
import com.squareup.wire.WireRpc

/**
* Interface exported by the server.
*/
interface RouteGuideClient : Service {
class RouteGuideClient(
private val client: GrpcClient
) : Service {
/**
* A simple RPC.
*
Expand All @@ -19,12 +22,11 @@ interface RouteGuideClient : Service {
* A feature with an empty name is returned if there's no feature at the given
* position.
*/
@WireRpc(
path = "/routeguide.RouteGuide/GetFeature",
requestAdapter = "routeguide.Point#ADAPTER",
responseAdapter = "routeguide.Feature#ADAPTER"
)
fun GetFeature(): GrpcCall<Point, Feature>
fun GetFeature(): GrpcCall<Point, Feature> = client.newCall(GrpcMethod(
path = "/routeguide.RouteGuide/GetFeature",
requestAdapter = Point.ADAPTER,
responseAdapter = Feature.ADAPTER
))

/**
* A server-to-client streaming RPC.
Expand All @@ -34,36 +36,33 @@ interface RouteGuideClient : Service {
* repeated field), as the rectangle may cover a large area and contain a
* huge number of features.
*/
@WireRpc(
path = "/routeguide.RouteGuide/ListFeatures",
requestAdapter = "routeguide.Rectangle#ADAPTER",
responseAdapter = "routeguide.Feature#ADAPTER"
)
fun ListFeatures(): GrpcStreamingCall<Rectangle, Feature>
fun ListFeatures(): GrpcStreamingCall<Rectangle, Feature> = client.newStreamingCall(GrpcMethod(
path = "/routeguide.RouteGuide/ListFeatures",
requestAdapter = Rectangle.ADAPTER,
responseAdapter = Feature.ADAPTER
))

/**
* A client-to-server streaming RPC.
*
* Accepts a stream of Points on a route being traversed, returning a
* RouteSummary when traversal is completed.
*/
@WireRpc(
path = "/routeguide.RouteGuide/RecordRoute",
requestAdapter = "routeguide.Point#ADAPTER",
responseAdapter = "routeguide.RouteSummary#ADAPTER"
)
fun RecordRoute(): GrpcStreamingCall<Point, RouteSummary>
fun RecordRoute(): GrpcStreamingCall<Point, RouteSummary> = client.newStreamingCall(GrpcMethod(
path = "/routeguide.RouteGuide/RecordRoute",
requestAdapter = Point.ADAPTER,
responseAdapter = RouteSummary.ADAPTER
))

/**
* A Bidirectional streaming RPC.
*
* Accepts a stream of RouteNotes sent while a route is being traversed,
* while receiving other RouteNotes (e.g. from other users).
*/
@WireRpc(
path = "/routeguide.RouteGuide/RouteChat",
requestAdapter = "routeguide.RouteNote#ADAPTER",
responseAdapter = "routeguide.RouteNote#ADAPTER"
)
fun RouteChat(): GrpcStreamingCall<RouteNote, RouteNote>
fun RouteChat(): GrpcStreamingCall<RouteNote, RouteNote> = client.newStreamingCall(GrpcMethod(
path = "/routeguide.RouteGuide/RouteChat",
requestAdapter = RouteNote.ADAPTER,
responseAdapter = RouteNote.ADAPTER
))
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import com.squareup.kotlinpoet.jvm.jvmStatic
import com.squareup.wire.EnumAdapter
import com.squareup.wire.FieldEncoding
import com.squareup.wire.GrpcCall
import com.squareup.wire.GrpcClient
import com.squareup.wire.GrpcMethod
import com.squareup.wire.GrpcStreamingCall
import com.squareup.wire.Message
import com.squareup.wire.MessageSink
Expand All @@ -58,7 +60,6 @@ import com.squareup.wire.ProtoReader
import com.squareup.wire.ProtoWriter
import com.squareup.wire.WireEnum
import com.squareup.wire.WireField
import com.squareup.wire.WireRpc
import com.squareup.wire.schema.EnclosingType
import com.squareup.wire.schema.EnumType
import com.squareup.wire.schema.Field
Expand Down Expand Up @@ -146,13 +147,19 @@ class KotlinGenerator private constructor(
*/
fun generateService(service: Service, onlyRpc: Rpc? = null): TypeSpec {
val serviceName = generatedServiceName(service, onlyRpc)
val builder = TypeSpec.interfaceBuilder(serviceName)
val builder = TypeSpec.classBuilder(serviceName)
.apply {
if (service.documentation().isNotBlank()) {
addKdoc("%L\n", service.documentation().sanitizeKdoc())
}
}
.addSuperinterface(com.squareup.wire.Service::class.java)
.primaryConstructor(FunSpec.constructorBuilder()
.addParameter("client", GrpcClient::class)
.build())
.addProperty(PropertySpec.builder("client", GrpcClient::class, PRIVATE)
.initializer("client")
.build())

val rpcs = if (onlyRpc == null) service.rpcs() else listOf(onlyRpc)
for (rpc in rpcs) {
Expand All @@ -169,16 +176,7 @@ class KotlinGenerator private constructor(
servicePackageName: String?
): FunSpec {
val packageName = if (servicePackageName.isNullOrBlank()) "" else "$servicePackageName."

val wireRpcAnnotationSpec = AnnotationSpec.builder(WireRpc::class.asClassName())
.addMember("path = %S", "/$packageName$serviceName/${rpc.name}")
// TODO(oldergod|jwilson) Lets' use Profile for this.
.addMember("requestAdapter = %S", rpc.requestType!!.adapterString())
.addMember("responseAdapter = %S", rpc.responseType!!.adapterString())
.build()
val funSpecBuilder = FunSpec.builder(rpc.name)
.addModifiers(KModifier.ABSTRACT)
.addAnnotation(wireRpcAnnotationSpec)
.apply {
if (rpc.documentation.isNotBlank()) {
addKdoc("%L\n", rpc.documentation.sanitizeKdoc())
Expand Down Expand Up @@ -215,14 +213,27 @@ class KotlinGenerator private constructor(
}
}
} else {
val grpcMethod = CodeBlock.builder()
.addStatement("%T(⇥⇥", GrpcMethod::class)
.addStatement("path = %S,", "/$packageName$serviceName/${rpc.name}")
.addStatement("requestAdapter = %L,", rpc.requestType!!.getAdapterName())
.addStatement("responseAdapter = %L", rpc.responseType!!.getAdapterName())
.add("⇤⇤)")
.build()
when {
rpc.requestStreaming || rpc.responseStreaming -> {
funSpecBuilder.returns(
GrpcStreamingCall::class.asClassName().parameterizedBy(requestType, responseType))
funSpecBuilder
.returns(
GrpcStreamingCall::class.asClassName().parameterizedBy(requestType, responseType)
)
.addStatement("return client.newStreamingCall(%L)", grpcMethod)
}
else -> {
funSpecBuilder.returns(
GrpcCall::class.asClassName().parameterizedBy(requestType, responseType))
funSpecBuilder
.returns(
GrpcCall::class.asClassName().parameterizedBy(requestType, responseType)
)
.addStatement("return client.newCall(%L)", grpcMethod)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
package com.squareup.wire.protos.kotlin.services

import com.squareup.wire.GrpcCall
import com.squareup.wire.GrpcClient
import com.squareup.wire.GrpcMethod
import com.squareup.wire.Service
import com.squareup.wire.WireRpc

interface NoPackageServiceClient : Service {
@WireRpc(
path = "/NoPackageService/NoPackageMethod",
requestAdapter = "com.squareup.wire.protos.kotlin.services.NoPackageRequest#ADAPTER",
responseAdapter = "com.squareup.wire.protos.kotlin.services.NoPackageResponse#ADAPTER"
)
fun NoPackageMethod(): GrpcCall<NoPackageRequest, NoPackageResponse>
class NoPackageServiceClient(
private val client: GrpcClient
) : Service {
fun NoPackageMethod(): GrpcCall<NoPackageRequest, NoPackageResponse> = client.newCall(GrpcMethod(
path = "/NoPackageService/NoPackageMethod",
requestAdapter = NoPackageRequest.ADAPTER,
responseAdapter = NoPackageResponse.ADAPTER
))
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
package com.squareup.wire.protos.kotlin.services

import com.squareup.wire.GrpcCall
import com.squareup.wire.GrpcClient
import com.squareup.wire.GrpcMethod
import com.squareup.wire.Service
import com.squareup.wire.WireRpc

interface SomeServiceClient : Service {
@WireRpc(
path = "/squareup.protos.kotlin.SomeService/SomeMethod",
requestAdapter = "com.squareup.wire.protos.kotlin.services.SomeRequest#ADAPTER",
responseAdapter = "com.squareup.wire.protos.kotlin.services.SomeResponse#ADAPTER"
)
fun SomeMethod(): GrpcCall<SomeRequest, SomeResponse>
class SomeServiceClient(
private val client: GrpcClient
) : Service {
fun SomeMethod(): GrpcCall<SomeRequest, SomeResponse> = client.newCall(GrpcMethod(
path = "/squareup.protos.kotlin.SomeService/SomeMethod",
requestAdapter = SomeRequest.ADAPTER,
responseAdapter = SomeResponse.ADAPTER
))
}

0 comments on commit 03d0e98

Please sign in to comment.