Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kotlin protos #266

Merged
merged 9 commits into from
Oct 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ maven_install(
artifacts = [
"com.google.jimfs:jimfs:1.1",
"com.google.truth.extensions:truth-proto-extension:1.0.1",
"com.google.protobuf:protobuf-kotlin:3.18.0",
] + IO_GRPC_GRPC_KOTLIN_ARTIFACTS + IO_GRPC_GRPC_JAVA_ARTIFACTS,
generate_compat_repositories = True,
override_targets = dict(
Expand All @@ -56,16 +57,11 @@ grpc_java_repositories()

# Protocol Buffers
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")

protobuf_deps()

# Kotlin
load(
"@io_bazel_rules_kotlin//kotlin:kotlin.bzl",
"kotlin_repositories",
"kt_register_toolchains",
)

load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories")
kotlin_repositories()

load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains")
kt_register_toolchains()
76 changes: 48 additions & 28 deletions compiler/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
gRPC Kotlin Codegen Plugin for Protobuf Compiler
================================================

This generates the Kotlin interfaces out of the service definition from a
`.proto` file. It works with the Protobuf Compiler (`protoc`).
This generates the Kotlin interfaces out of the service definition from a`.proto` file. It works with the Protobuf Compiler (`protoc`) and uses a `protoc` plugin to generate Kotlin wrappers for the generated Java classes.
> Note: You can use the gRPC Kotlin compiler without using the protoc Kotlin compiler, but these instructions assume you want to use both together.

### Build Tool Plugins

Expand All @@ -11,38 +11,42 @@ Usually this compiler is used via a build tool plugin, like in Gradle, Maven, et
For Gradle, include the [protobuf plugin](https://github.com/google/protobuf-gradle-plugin) with at least version `0.8.13`, like:
```
plugins {
id("com.google.protobuf") version "SOME_VERSION"
id("com.google.protobuf") version "YOUR_PROTOBUF_PLUGIN_VERSION"
}
```

Add dependencies on `grpc-kotlin-stub` and a protobuf library like:
Add dependencies on `grpc-kotlin-stub` and protobuf libraries like:
```
dependencies {
implementation("io.grpc:grpc-kotlin-stub:SOME_VERSION")
implementation("io.grpc:grpc-protobuf:SOME_VERSION")
implementation("io.grpc:grpc-kotlin-stub:YOUR_GRPC_KOTLIN_VERSION")
implementation("io.grpc:grpc-protobuf:YOUR_GRPC_VERSION")
implementation("com.google.protobuf:protobuf-kotlin:YOUR_PROTOBUF_VERSION")
}
```

Finally, setup the protobuf plugin:
```
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:SOME_VERSION"
artifact = "com.google.protobuf:protoc:YOUR_PROTOBUF_VERSION"
}
plugins {
id("grpc") {
artifact = "io.grpc:protoc-gen-grpc-java:SOME_VERSION"
artifact = "io.grpc:protoc-gen-grpc-java:YOUR_GRPC_VERSION"
}
id("grpckt") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:SOME_VERSION:jdk7@jar"
artifact = "io.grpc:protoc-gen-grpc-kotlin:YOUR_GRPC_KOTLIN_VERSION:jdk7@jar"
}
}
generateProtoTasks {
ofSourceSet("main").forEach {
all().forEach {
it.plugins {
id("grpc")
id("grpckt")
}
it.builtins {
id("kotlin")
}
}
}
}
Expand All @@ -55,44 +59,60 @@ For Maven, include the [protobuf plugin](https://www.xolstice.org/protobuf-maven
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:SOME_VERSION:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:SOME_VERSION:exe:${os.detected.classifier}</pluginArtifact>
<protocPlugins>
<protocPlugin>
<id>grpc-kotlin</id>
<groupId>io.grpc</groupId>
<artifactId>protoc-gen-grpc-kotlin</artifactId>
<version>SOME_VERSION</version>
<classifier>jdk7</classifier>
<mainClass>io.grpc.kotlin.generator.GeneratorRunner</mainClass>
</protocPlugin>
</protocPlugins>
</configuration>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
<configuration>
<protocArtifact>com.google.protobuf:protoc:YOUR_PROTOBUF_VERSION:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:YOUR_GRPC_VERSION:exe:${os.detected.classifier}</pluginArtifact>
<protocPlugins>
<protocPlugin>
<id>grpc-kotlin</id>
<groupId>io.grpc</groupId>
<artifactId>protoc-gen-grpc-kotlin</artifactId>
<version>YOUR_GRPC_KOTLIN_VERSION</version>
<classifier>jdk7</classifier>
<mainClass>io.grpc.kotlin.generator.GeneratorRunner</mainClass>
</protocPlugin>
</protocPlugins>
</configuration>
</execution>
<execution>
<id>compile-kt</id>
<goals>
<goal>compile-custom</goal>
</goals>
<configuration>
<protocArtifact>com.google.protobuf:protoc:YOUR_PROTOBUF_VERSION:exe:${os.detected.classifier}</protocArtifact>
<outputDirectory>${project.build.directory}/generated-sources/protobuf/kotlin</outputDirectory>
<pluginId>kotlin</pluginId>
</configuration>
</execution>
</executions>
</plugin>
```

Make sure you include a dependency on `stub` and a protobuf library like:
Make sure you include a dependency on `stub` and protobuf libraries like:
```
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-kotlin-stub</artifactId>
<version>SOME_VERSION</version>
<version>YOUR_GRPC_KOTLIN_VERSION</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>SOME_VERSION</version>
<version>YOUR_PROTOBUF_VERSION</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-kotlin</artifactId>
<version>YOUR_PROTOBUF_VERSION</version>
</dependency>
```

Expand Down
8 changes: 4 additions & 4 deletions examples/android/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {

dependencies {
implementation(project(":stub-android"))
implementation("androidx.appcompat:appcompat:1.2.0")
implementation("androidx.appcompat:appcompat:1.3.1")
runtimeOnly("io.grpc:grpc-okhttp:${rootProject.ext["grpcVersion"]}")
}

Expand All @@ -15,7 +15,7 @@ android {

defaultConfig {
applicationId = "io.grpc.examples.hello"
minSdkVersion(23)
minSdkVersion(26)
targetSdkVersion(30)
versionCode = 1
versionName = "1.0"
Expand All @@ -31,7 +31,7 @@ android {
sourceSets["main"].java.srcDir("src/main/kotlin")

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import io.grpc.ManagedChannel
import io.grpc.ManagedChannelBuilder
import java.net.URL
import java.util.logging.Logger
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.runBlocking
import java.net.URL
import java.util.logging.Logger

// todo: suspend funs
class MainActivity : AppCompatActivity() {
Expand Down Expand Up @@ -58,7 +58,7 @@ class MainActivity : AppCompatActivity() {

fun sendReq() = runBlocking {
try {
val request = HelloRequest.newBuilder().setName(nameText.text.toString()).build()
val request = helloRequest { name = nameText.text.toString() }
jamesward marked this conversation as resolved.
Show resolved Hide resolved
val response = greeter.sayHello(request)
responseText.text = response.message
} catch (e: Exception) {
Expand Down
11 changes: 6 additions & 5 deletions examples/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
plugins {
id("com.android.application") version "4.1.1" apply false
id("com.google.protobuf") version "0.8.15" apply false
kotlin("jvm") version "1.4.32" apply false
id("org.jlleitschuh.gradle.ktlint") version "9.2.1"
id("com.google.protobuf") version "0.8.17" apply false
kotlin("jvm") version "1.5.31" apply false
id("org.jlleitschuh.gradle.ktlint") version "10.2.0"
}

// todo: move to subprojects, but how?
ext["grpcVersion"] = "1.37.0"
ext["grpcVersion"] = "1.39.0" // need to wait for grpc kotlin to move past this
ext["grpcKotlinVersion"] = "1.1.0" // CURRENT_GRPC_KOTLIN_VERSION
ext["protobufVersion"] = "3.15.8"
ext["protobufVersion"] = "3.18.1"
ext["coroutinesVersion"] = "1.5.2"

allprojects {
repositories {
Expand Down
12 changes: 6 additions & 6 deletions examples/client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,37 @@ dependencies {
tasks.register<JavaExec>("HelloWorldClient") {
dependsOn("classes")
classpath = sourceSets["main"].runtimeClasspath
main = "io.grpc.examples.helloworld.HelloWorldClientKt"
mainClass.set("io.grpc.examples.helloworld.HelloWorldClientKt")
}

tasks.register<JavaExec>("RouteGuideClient") {
dependsOn("classes")
classpath = sourceSets["main"].runtimeClasspath
main = "io.grpc.examples.routeguide.RouteGuideClientKt"
mainClass.set("io.grpc.examples.routeguide.RouteGuideClientKt")
}

tasks.register<JavaExec>("AnimalsClient") {
dependsOn("classes")
classpath = sourceSets["main"].runtimeClasspath
main = "io.grpc.examples.animals.AnimalsClientKt"
mainClass.set("io.grpc.examples.animals.AnimalsClientKt")
}

val helloWorldClientStartScripts = tasks.register<CreateStartScripts>("helloWorldClientStartScripts") {
mainClassName = "io.grpc.examples.helloworld.HelloWorldClientKt"
mainClass.set("io.grpc.examples.helloworld.HelloWorldClientKt")
applicationName = "hello-world-client"
outputDir = tasks.named<CreateStartScripts>("startScripts").get().outputDir
classpath = tasks.named<CreateStartScripts>("startScripts").get().classpath
}

val routeGuideClientStartScripts = tasks.register<CreateStartScripts>("routeGuideClientStartScripts") {
mainClassName = "io.grpc.examples.routeguide.RouteGuideClientKt"
mainClass.set("io.grpc.examples.routeguide.RouteGuideClientKt")
applicationName = "route-guide-client"
outputDir = tasks.named<CreateStartScripts>("startScripts").get().outputDir
classpath = tasks.named<CreateStartScripts>("startScripts").get().classpath
}

val animalsClientStartScripts = tasks.register<CreateStartScripts>("animalsClientStartScripts") {
mainClassName = "io.grpc.examples.animals.AnimalsClientKt"
mainClass.set("io.grpc.examples.animals.AnimalsClientKt")
applicationName = "animals-client"
outputDir = tasks.named<CreateStartScripts>("startScripts").get().outputDir
classpath = tasks.named<CreateStartScripts>("startScripts").get().classpath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ class AnimalsClient(private val channel: ManagedChannel) : Closeable {
private val sheepStub: SheepGrpcKt.SheepCoroutineStub by lazy { SheepGrpcKt.SheepCoroutineStub(channel) }

suspend fun bark() {
val request = BarkRequest.getDefaultInstance()
val request = barkRequest {}
val response = dogStub.bark(request)
println("Received: ${response.message}")
}

suspend fun oink() {
val request = OinkRequest.getDefaultInstance()
val request = oinkRequest {}
val response = pigStub.oink(request)
println("Received: ${response.message}")
}

suspend fun baa() {
val request = BaaRequest.getDefaultInstance()
val request = baaRequest {}
val response = sheepStub.baa(request)
println("Received: ${response.message}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ kt_jvm_binary(
main_class = "io.grpc.examples.animals.AnimalsClientKt",
deps = [
"//examples/protos/src/main/proto/io/grpc/examples/animals:animals_kt_grpc",
"//examples/protos/src/main/proto/io/grpc/examples/animals:animals_kt_proto",
"@com_google_protobuf//:protobuf_java_util",
"@io_grpc_grpc_java//netty",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ kt_jvm_binary(
main_class = "io.grpc.examples.helloworld.HelloWorldClientKt",
deps = [
"//examples/protos/src/main/proto/io/grpc/examples/helloworld:hello_world_kt_grpc",
"//examples/protos/src/main/proto/io/grpc/examples/helloworld:hello_world_kt_proto",
"@io_grpc_grpc_java//netty",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class HelloWorldClient(private val channel: ManagedChannel) : Closeable {
private val stub: GreeterCoroutineStub = GreeterCoroutineStub(channel)

suspend fun greet(name: String) {
val request = HelloRequest.newBuilder().setName(name).build()
val request = helloRequest { this.name = name }
val response = stub.sayHello(request)
println("Received: ${response.message}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ kt_jvm_binary(
resources = ["//examples/stub/src/main/resources/io/grpc/examples/routeguide:route_guide_db"],
deps = [
"//examples/protos/src/main/proto/io/grpc/examples/routeguide:route_guide_kt_grpc",
"//examples/protos/src/main/proto/io/grpc/examples/routeguide:route_guide_kt_proto",
"//examples/stub/src/main/kotlin/io/grpc/examples/routeguide:route_guide_stub",
"@com_google_protobuf//:protobuf_java_util",
"@io_grpc_grpc_java//netty",
Expand Down
Loading