├── conformance ├── client │ ├── known-failing-stream-cases.txt │ ├── known-failing-unary-cases.txt │ ├── build.gradle.kts │ ├── standard-unary-config.yaml │ ├── lite-unary-config.yaml │ ├── standard-stream-config.yaml │ ├── lite-stream-config.yaml │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── connectrpc │ │ │ └── conformance │ │ │ └── client │ │ │ └── adapt │ │ │ ├── AnyMessage.kt │ │ │ ├── Invoker.kt │ │ │ ├── ClientResponseResult.kt │ │ │ ├── ClientCompatResponse.kt │ │ │ ├── UnaryClient.kt │ │ │ ├── SuspendCloseable.kt │ │ │ ├── ServerStreamClient.kt │ │ │ ├── RequestStream.kt │ │ │ └── ClientCompatRequest.kt │ ├── google-javalite │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── connectrpc │ │ │ └── conformance │ │ │ └── client │ │ │ └── javalite │ │ │ ├── JavaLiteBidiStreamClient.kt │ │ │ ├── JavaLiteClientStreamClient.kt │ │ │ ├── Main.kt │ │ │ ├── JavaLiteUnaryClient.kt │ │ │ ├── JavaLiteUnimplementedClient.kt │ │ │ ├── JavaLiteInvoker.kt │ │ │ ├── JavaLiteIdempotentUnaryClient.kt │ │ │ └── JavaLiteServerStreamClient.kt │ └── google-java │ │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── com │ │ │ └── connectrpc │ │ │ └── conformance │ │ │ └── client │ │ │ └── java │ │ │ ├── JavaBidiStreamClient.kt │ │ │ ├── JavaClientStreamClient.kt │ │ │ ├── Main.kt │ │ │ ├── JavaUnaryClient.kt │ │ │ ├── JavaUnimplementedClient.kt │ │ │ ├── JavaInvoker.kt │ │ │ ├── JavaIdempotentUnaryClient.kt │ │ │ └── JavaServerStreamClient.kt │ │ └── build.gradle.kts └── buf.gen.yaml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── examples ├── android │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── drawable-hdpi │ │ │ │ └── buf_logo.png │ │ │ ├── values │ │ │ │ ├── colors.xml │ │ │ │ ├── strings.xml │ │ │ │ └── themes.xml │ │ │ ├── layout │ │ │ │ ├── activity_main.xml │ │ │ │ ├── item.xml │ │ │ │ └── activity_eliza_chat.xml │ │ │ └── drawable │ │ │ │ └── line.xml │ │ │ ├── AndroidManifest.xml │ │ │ └── kotlin │ │ │ └── com │ │ │ └── connectrpc │ │ │ └── examples │ │ │ └── android │ │ │ ├── MainActivity.kt │ │ │ └── RecyclerView.kt │ ├── README.md │ └── build.gradle.kts ├── generated-google-javalite │ └── build.gradle.kts ├── generated-google-java │ └── build.gradle.kts ├── kotlin-google-java │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── connectrpc │ │ └── examples │ │ └── kotlin │ │ └── Main.kt ├── kotlin-google-javalite │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── com │ │ └── connectrpc │ │ └── examples │ │ └── kotlin │ │ └── Main.kt └── buf.gen.yaml ├── .github ├── CODE_OF_CONDUCT.md ├── pull_request_template.md ├── release.yml ├── dependabot.yml ├── workflows │ ├── add-to-project.yaml │ └── pr-title.yaml └── CONTRIBUTING.md ├── SECURITY.md ├── .gitignore ├── buf.yaml ├── MAINTAINERS.md ├── protoc-gen-connect-kotlin ├── buf.gen.yaml ├── proto │ ├── no_package.proto │ └── buf │ │ ├── deprecation │ │ └── v1 │ │ │ ├── file_deprecated.proto │ │ │ ├── method_deprecated.proto │ │ │ └── service_deprecated.proto │ │ ├── javamultiplefiles │ │ ├── enabled │ │ │ └── v1 │ │ │ │ ├── enabled.proto │ │ │ │ ├── enabled_empty.proto │ │ │ │ └── enabled_nested.proto │ │ ├── disabled │ │ │ └── v1 │ │ │ │ ├── disabled.proto │ │ │ │ ├── disabled_empty.proto │ │ │ │ └── disabled_nested.proto │ │ └── unspecified │ │ │ └── v1 │ │ │ ├── unspecified.proto │ │ │ ├── unspecified_empty.proto │ │ │ └── enabled_nested.proto │ │ ├── evilcomments │ │ └── v1 │ │ │ └── evilcomments.proto │ │ └── editions │ │ └── v1 │ │ └── editions.proto ├── src │ └── main │ │ └── kotlin │ │ └── com │ │ └── connectrpc │ │ └── protocgen │ │ └── connect │ │ ├── Main.kt │ │ └── internal │ │ ├── CodeGenerator.kt │ │ └── Parameters.kt └── build.gradle.kts ├── extensions ├── buf.gen.yaml ├── google-javalite │ ├── build.gradle.kts │ └── src │ │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── connectrpc │ │ │ └── extensions │ │ │ ├── JavaLiteErrorParser.kt │ │ │ ├── GoogleJavaLiteProtobufStrategy.kt │ │ │ └── GoogleLiteProtoAdapter.kt │ │ └── test │ │ └── kotlin │ │ └── com │ │ └── connectrpc │ │ └── extensions │ │ └── JavaLiteErrorParserTest.kt └── google-java │ ├── build.gradle.kts │ └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── connectrpc │ │ └── extensions │ │ ├── GoogleJavaJSONStrategy.kt │ │ ├── GoogleJavaProtobufStrategy.kt │ │ ├── JavaErrorParser.kt │ │ ├── GoogleJavaProtoAdapter.kt │ │ └── GoogleJavaJSONAdapter.kt │ └── test │ └── kotlin │ └── com │ └── connectrpc │ └── extensions │ └── JavaErrorParserTest.kt ├── gradle.properties ├── settings.gradle.kts ├── library ├── src │ ├── main │ │ └── kotlin │ │ │ └── com │ │ │ └── connectrpc │ │ │ ├── protocols │ │ │ ├── NetworkProtocol.kt │ │ │ ├── ConnectConstants.kt │ │ │ ├── GETConfiguration.kt │ │ │ ├── ErrorJSONModels.kt │ │ │ └── GRPCCompletion.kt │ │ │ ├── http │ │ │ ├── TracingInfo.kt │ │ │ ├── HTTPClientInterface.kt │ │ │ ├── HTTPResponse.kt │ │ │ └── Timeout.kt │ │ │ ├── AnyError.kt │ │ │ ├── StreamType.kt │ │ │ ├── UnaryBlockingCall.kt │ │ │ ├── RequestCompression.kt │ │ │ ├── ErrorDetailParser.kt │ │ │ ├── SerializationStrategy.kt │ │ │ ├── MethodSpec.kt │ │ │ ├── ConnectErrorDetail.kt │ │ │ ├── compression │ │ │ ├── GzipCompressionPool.kt │ │ │ └── CompressionPool.kt │ │ │ ├── impl │ │ │ ├── ServerOnlyStream.kt │ │ │ ├── BidirectionalStream.kt │ │ │ ├── UnaryCall.kt │ │ │ └── ClientOnlyStream.kt │ │ │ ├── Idempotency.kt │ │ │ ├── Codec.kt │ │ │ ├── StreamResult.kt │ │ │ ├── Interceptor.kt │ │ │ └── Code.kt │ └── test │ │ └── kotlin │ │ └── com │ │ └── connectrpc │ │ ├── ProtocolClientConfigTest.kt │ │ ├── ConnectExceptionTest.kt │ │ ├── compression │ │ └── GzipCompressionPoolTest.kt │ │ └── protocols │ │ └── EnvelopeTest.kt └── build.gradle.kts ├── okhttp └── build.gradle.kts └── gradlew.bat /conformance/client/known-failing-stream-cases.txt: -------------------------------------------------------------------------------- 1 | # Currently there are zero failing tests. -------------------------------------------------------------------------------- /conformance/client/known-failing-unary-cases.txt: -------------------------------------------------------------------------------- 1 | # Currently there are zero failing tests. -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connectrpc/connect-kotlin/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable-hdpi/buf_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/connectrpc/connect-kotlin/HEAD/examples/android/src/main/res/drawable-hdpi/buf_logo.png -------------------------------------------------------------------------------- /examples/android/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #161EDE 4 | 5 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Community Code of Conduct 2 | 3 | Connect follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | Security Policy 2 | =============== 3 | 4 | This project follows the [Connect security policy and reporting 5 | process](https://connectrpc.com/docs/governance/security). 6 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /examples/android/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Eliza Connect App 4 | I feel good. 5 | Send 6 | Eliza 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /**/build/* 2 | !/**/proto/build/* 3 | !/**/src/**/build/* 4 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 5 | !gradle-wrapper.jar 6 | /local.properties 7 | /.gradle 8 | /.idea 9 | *.iml 10 | /.tmp 11 | # Cache of project 12 | /.gradletasknamecache 13 | # Ignore Gradle GUI config 14 | /gradle-app.setting 15 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - ignore-for-release 5 | authors: 6 | - dependabot 7 | categories: 8 | - title: Enhancements 9 | labels: 10 | - enhancement 11 | - title: Bugfixes 12 | labels: 13 | - bug 14 | - title: Other changes 15 | labels: 16 | - "*" 17 | -------------------------------------------------------------------------------- /buf.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | modules: 3 | - path: protoc-gen-connect-kotlin/proto 4 | lint: 5 | use: 6 | - STANDARD 7 | except: 8 | - FIELD_NOT_REQUIRED 9 | - PACKAGE_NO_IMPORT_CYCLE 10 | ignore: 11 | - protoc-gen-connect-kotlin/proto/no_package.proto 12 | rpc_allow_same_request_response: true 13 | breaking: 14 | except: 15 | - EXTENSION_NO_DELETE 16 | - FIELD_SAME_DEFAULT 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "gradle" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | groups: 12 | kotlin: 13 | patterns: 14 | - "org.jetbrains.kotlin:*" 15 | - "com.google.devtools.ksp" 16 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | Maintainers 2 | =========== 3 | 4 | ## Current 5 | * [Peter Edge](https://github.com/bufdev), [Buf](https://buf.build) 6 | * [Michael Rebello](https://github.com/rebello95), [Airbnb](https://airbnb.com) 7 | * [Philip Warren](https://github.com/pkwarren), [Buf](https://buf.build) 8 | * [Josh Humphries](https://github.com/jhump), [Buf](https://buf.build) 9 | 10 | ## Former 11 | * [Alan Chiu](https://github.com/buildbreaker) 12 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | clean: true 3 | plugins: 4 | - local: ./protoc-gen-connect-kotlin/build/install/protoc-gen-connect-kotlin/bin/protoc-gen-connect-kotlin 5 | out: build/generated/sources/bufgen 6 | opt: 7 | - generateCallbackMethods=true 8 | - generateCoroutineMethods=true 9 | - protoc_builtin: java 10 | protoc_path: .tmp/bin/protoc 11 | out: build/generated/sources/bufgen 12 | -------------------------------------------------------------------------------- /examples/android/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /.github/workflows/add-to-project.yaml: -------------------------------------------------------------------------------- 1 | name: Add issues and PRs to project 2 | 3 | on: 4 | issues: 5 | types: 6 | - opened 7 | - reopened 8 | - transferred 9 | pull_request_target: 10 | types: 11 | - opened 12 | - reopened 13 | issue_comment: 14 | types: 15 | - created 16 | 17 | jobs: 18 | call-workflow-add-to-project: 19 | name: Call workflow to add issue to project 20 | uses: connectrpc/base-workflows/.github/workflows/add-to-project.yaml@main 21 | secrets: inherit 22 | -------------------------------------------------------------------------------- /extensions/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | managed: 3 | enabled: true 4 | override: 5 | - file_option: java_package_prefix 6 | value: "com.connectrpc" 7 | clean: true 8 | plugins: 9 | - protoc_builtin: java 10 | protoc_path: .tmp/bin/protoc 11 | out: google-java/build/generated/sources/bufgen 12 | - protoc_builtin: java 13 | protoc_path: .tmp/bin/protoc 14 | out: google-javalite/build/generated/sources/bufgen 15 | opt: lite 16 | inputs: 17 | - module: buf.build/googleapis/googleapis 18 | types: 19 | - google.rpc.Status 20 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | android.useAndroidX=true 2 | android.enableJetifier=true 3 | kotlin.code.style=official 4 | org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=1g -XX:+HeapDumpOnOutOfMemoryError 5 | org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled 6 | # For gradle-maven-publish plugin: https://vanniktech.github.io/gradle-maven-publish-plugin/central/ 7 | SONATYPE_CONNECT_TIMEOUT_SECONDS=300 8 | SONATYPE_CLOSE_TIMEOUT_SECONDS=900 9 | RELEASE_SIGNING_ENABLED=true 10 | skipAndroid=false 11 | android.nonTransitiveRClass=false 12 | android.nonFinalResIds=false 13 | -------------------------------------------------------------------------------- /conformance/client/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | } 4 | 5 | tasks { 6 | compileKotlin { 7 | compilerOptions { 8 | // Generated Kotlin code for protobuf uses OptIn annotation 9 | freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") 10 | } 11 | } 12 | } 13 | 14 | dependencies { 15 | implementation(project(":okhttp")) 16 | implementation(libs.kotlin.coroutines.core) 17 | implementation(libs.protobuf.javalite) 18 | implementation(libs.okio.core) 19 | implementation(libs.okhttp.tls) 20 | } 21 | -------------------------------------------------------------------------------- /examples/generated-google-javalite/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | java 4 | } 5 | 6 | tasks { 7 | compileKotlin { 8 | compilerOptions { 9 | freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") 10 | } 11 | } 12 | } 13 | 14 | sourceSets { 15 | main { 16 | java { 17 | srcDir("build/generated/sources/bufgen") 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation(libs.protobuf.javalite) 24 | api(project(":extensions:google-javalite")) 25 | 26 | implementation(project(":okhttp")) 27 | } 28 | -------------------------------------------------------------------------------- /examples/android/README.md: -------------------------------------------------------------------------------- 1 | # Eliza chat app example 2 | 3 | This example app uses the `Connect` library and provides an interface for 4 | [chatting with Eliza](https://buf.build/connectrpc/eliza) via an Android application. 5 | 6 | The app has support for chatting using a variety of protocols supported by 7 | the Connect-Kotlin library: 8 | 9 | - [Connect](https://connectrpc.com) + unary 10 | - [Connect](https://connectrpc.com) + streaming 11 | - [gRPC](https://grpc.io) + unary 12 | - [gRPC](https://grpc.io) + streaming 13 | - [gRPC-Web](https://grpc.io) + unary 14 | - [gRPC-Web](https://grpc.io) + streaming 15 | -------------------------------------------------------------------------------- /examples/generated-google-java/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | java 4 | } 5 | 6 | tasks { 7 | compileKotlin { 8 | compilerOptions { 9 | freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") 10 | } 11 | } 12 | } 13 | 14 | sourceSets { 15 | main { 16 | java { 17 | srcDir("build/generated/sources/bufgen") 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | implementation(libs.protobuf.java) 24 | implementation(libs.protobuf.java.util) 25 | api(project(":extensions:google-java")) 26 | 27 | implementation(project(":okhttp")) 28 | } 29 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/pr-title.yaml: -------------------------------------------------------------------------------- 1 | name: Lint PR Title 2 | # Prevent writing to the repository using the CI token. 3 | # Ref: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions 4 | permissions: 5 | pull-requests: read 6 | on: 7 | pull_request: 8 | # By default, a workflow only runs when a pull_request's activity type is opened, 9 | # synchronize, or reopened. We explicity override here so that PR titles are 10 | # re-linted when the PR text content is edited. 11 | types: 12 | - opened 13 | - edited 14 | - reopened 15 | - synchronize 16 | jobs: 17 | lint: 18 | uses: bufbuild/base-workflows/.github/workflows/pr-title.yaml@main 19 | -------------------------------------------------------------------------------- /examples/android/src/main/res/drawable/line.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /examples/kotlin-google-java/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | application 3 | kotlin("jvm") 4 | } 5 | 6 | application { 7 | mainClass.set("com.connectrpc.examples.kotlin.Main") 8 | } 9 | 10 | tasks { 11 | jar { 12 | manifest { 13 | attributes(mapOf("Main-Class" to application.mainClass.get())) 14 | } 15 | from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) { 16 | exclude("META-INF/**/*") 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation(project(":examples:generated-google-java")) 23 | implementation(project(":okhttp")) 24 | implementation(libs.okhttp.core) 25 | implementation(libs.kotlin.coroutines.core) 26 | } 27 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "connect-kotlin" 2 | 3 | include(":conformance:client") 4 | include(":conformance:client:google-java") 5 | include(":conformance:client:google-javalite") 6 | if (extra.has("skipAndroid") && extra.get("skipAndroid").toString().toBoolean()) { 7 | println("Skipping Android build (skipAndroid=true)") 8 | } else { 9 | include(":examples:android") 10 | } 11 | include(":examples:generated-google-java") 12 | include(":examples:generated-google-javalite") 13 | include(":examples:kotlin-google-java") 14 | include(":examples:kotlin-google-javalite") 15 | include(":extensions:google-java") 16 | include(":extensions:google-javalite") 17 | include(":library") 18 | include(":okhttp") 19 | include(":protoc-gen-connect-kotlin") 20 | -------------------------------------------------------------------------------- /examples/kotlin-google-javalite/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | application 3 | kotlin("jvm") 4 | } 5 | 6 | application { 7 | mainClass.set("com.connectrpc.examples.kotlin.Main") 8 | } 9 | 10 | tasks { 11 | jar { 12 | manifest { 13 | attributes(mapOf("Main-Class" to application.mainClass.get())) 14 | } 15 | from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) { 16 | exclude("META-INF/**/*") 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation(project(":examples:generated-google-javalite")) 23 | implementation(project(":okhttp")) 24 | implementation(libs.okhttp.core) 25 | implementation(libs.kotlin.coroutines.core) 26 | } 27 | -------------------------------------------------------------------------------- /conformance/client/standard-unary-config.yaml: -------------------------------------------------------------------------------- 1 | # This configures the features that this client 2 | # supports and that will be verified by the 3 | # conformance test suite. 4 | features: 5 | versions: 6 | - HTTP_VERSION_1 7 | - HTTP_VERSION_2 8 | protocols: 9 | - PROTOCOL_CONNECT 10 | - PROTOCOL_GRPC 11 | - PROTOCOL_GRPC_WEB 12 | codecs: 13 | - CODEC_PROTO 14 | - CODEC_JSON 15 | compressions: 16 | - COMPRESSION_IDENTITY 17 | - COMPRESSION_GZIP 18 | streamTypes: 19 | # This config file only runs unary RPC test cases, 20 | # so that we can run them all three ways: suspend, 21 | # callback, and blocking. 22 | - STREAM_TYPE_UNARY 23 | # TODO: get client certs working and uncomment this 24 | #supportsTlsClientCerts: true 25 | supportsMessageReceiveLimit: false 26 | -------------------------------------------------------------------------------- /conformance/client/lite-unary-config.yaml: -------------------------------------------------------------------------------- 1 | # This configures the features that this client 2 | # supports and that will be verified by the 3 | # conformance test suite. 4 | features: 5 | versions: 6 | - HTTP_VERSION_1 7 | - HTTP_VERSION_2 8 | protocols: 9 | - PROTOCOL_CONNECT 10 | - PROTOCOL_GRPC 11 | - PROTOCOL_GRPC_WEB 12 | codecs: 13 | - CODEC_PROTO 14 | # Lite does not support JSON 15 | compressions: 16 | - COMPRESSION_IDENTITY 17 | - COMPRESSION_GZIP 18 | streamTypes: 19 | # This config file only runs unary RPC test cases, 20 | # so that we can run them all three ways: suspend, 21 | # callback, and blocking. 22 | - STREAM_TYPE_UNARY 23 | # TODO: get client certs working and uncomment this 24 | #supportsTlsClientCerts: true 25 | supportsMessageReceiveLimit: false 26 | -------------------------------------------------------------------------------- /conformance/client/standard-stream-config.yaml: -------------------------------------------------------------------------------- 1 | # This configures the features that this client 2 | # supports and that will be verified by the 3 | # conformance test suite. 4 | features: 5 | versions: 6 | - HTTP_VERSION_1 7 | - HTTP_VERSION_2 8 | protocols: 9 | - PROTOCOL_CONNECT 10 | - PROTOCOL_GRPC 11 | - PROTOCOL_GRPC_WEB 12 | codecs: 13 | - CODEC_PROTO 14 | - CODEC_JSON 15 | compressions: 16 | - COMPRESSION_IDENTITY 17 | - COMPRESSION_GZIP 18 | streamTypes: 19 | # This config file only runs stream RPC test cases. 20 | - STREAM_TYPE_CLIENT_STREAM 21 | - STREAM_TYPE_SERVER_STREAM 22 | - STREAM_TYPE_HALF_DUPLEX_BIDI_STREAM 23 | - STREAM_TYPE_FULL_DUPLEX_BIDI_STREAM 24 | # TODO: get client certs working and uncomment this 25 | #supportsTlsClientCerts: true 26 | supportsMessageReceiveLimit: false 27 | -------------------------------------------------------------------------------- /conformance/client/lite-stream-config.yaml: -------------------------------------------------------------------------------- 1 | # This configures the features that this client 2 | # supports and that will be verified by the 3 | # conformance test suite. 4 | features: 5 | versions: 6 | - HTTP_VERSION_1 7 | - HTTP_VERSION_2 8 | protocols: 9 | - PROTOCOL_CONNECT 10 | - PROTOCOL_GRPC 11 | - PROTOCOL_GRPC_WEB 12 | codecs: 13 | - CODEC_PROTO 14 | # Lite does not support JSON 15 | compressions: 16 | - COMPRESSION_IDENTITY 17 | - COMPRESSION_GZIP 18 | streamTypes: 19 | # This config file only runs stream RPC test cases. 20 | - STREAM_TYPE_CLIENT_STREAM 21 | - STREAM_TYPE_SERVER_STREAM 22 | - STREAM_TYPE_HALF_DUPLEX_BIDI_STREAM 23 | - STREAM_TYPE_FULL_DUPLEX_BIDI_STREAM 24 | # TODO: get client certs working and uncomment this 25 | #supportsTlsClientCerts: true 26 | supportsMessageReceiveLimit: false 27 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/protocols/NetworkProtocol.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.protocols 16 | 17 | /** 18 | * The supported protocols: 19 | * Connect, GRPC, and GRPC-Web. 20 | */ 21 | enum class NetworkProtocol { 22 | CONNECT, 23 | GRPC, 24 | GRPC_WEB, 25 | } 26 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/no_package.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | message SayRequest { 18 | string sentence = 1; 19 | } 20 | 21 | message SayResponse { 22 | string sentence = 1; 23 | } 24 | 25 | service ElizaService { 26 | rpc Say(SayRequest) returns (SayResponse) {} 27 | } 28 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/http/TracingInfo.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.http 16 | 17 | /** 18 | * Tracing metadata for [HTTPClientInterface] and [com.connectrpc.Interceptor]. 19 | */ 20 | data class TracingInfo( 21 | // The underlying http status code 22 | val httpStatus: Int, 23 | ) 24 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/item.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/src/main/kotlin/com/connectrpc/protocgen/connect/Main.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.protocgen.connect 16 | 17 | import com.connectrpc.protocgen.connect.internal.Plugin 18 | 19 | class Main { 20 | companion object { 21 | @JvmStatic 22 | fun main(args: Array) { 23 | Plugin.run(Generator()) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/AnyError.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import okio.ByteString 18 | 19 | /** 20 | * This is a protobuf-runtime-agnostic representation of google.protobuf.Any 21 | * messages, which are used to represent error details in gRPC. 22 | */ 23 | class AnyError( 24 | val typeUrl: String, 25 | val value: ByteString = ByteString.EMPTY, 26 | ) 27 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/deprecation/v1/file_deprecated.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.deprecation.v1; 18 | 19 | option deprecated = true; 20 | 21 | message DeprecatedByFileRequest {} 22 | 23 | message DeprecatedByFileResponse {} 24 | 25 | service FileDeprecatedService { 26 | rpc DeprecatedByFile(DeprecatedByFileRequest) returns (DeprecatedByFileResponse) {} 27 | } 28 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/deprecation/v1/method_deprecated.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.deprecation.v1; 18 | 19 | message DeprecatedMethodRequest {} 20 | 21 | message DeprecatedMethodResponse {} 22 | 23 | service MethodDeprecatedService { 24 | rpc DeprecatedMethod(DeprecatedMethodRequest) returns (DeprecatedMethodResponse) { 25 | option deprecated = true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/deprecation/v1/service_deprecated.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.deprecation.v1; 18 | 19 | message DeprecatedByServiceRequest {} 20 | 21 | message DeprecatedByServiceResponse {} 22 | 23 | service ServiceDeprecatedService { 24 | option deprecated = true; 25 | rpc DeprecatedByService(DeprecatedByServiceRequest) returns (DeprecatedByServiceResponse) {} 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/StreamType.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | /** 18 | * Represents the RPC stream type. Set by the code generator on each [MethodSpec]. 19 | */ 20 | enum class StreamType { 21 | /** Unary RPC. */ 22 | UNARY, 23 | 24 | /** Client streaming RPC. */ 25 | CLIENT, 26 | 27 | /** Server streaming RPC. */ 28 | SERVER, 29 | 30 | /** Bidirectional streaming RPC. */ 31 | BIDI, 32 | } 33 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/enabled/v1/enabled.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.enabled.v1; 18 | 19 | option java_multiple_files = true; 20 | 21 | message EnabledRequest { 22 | string sentence = 1; 23 | } 24 | 25 | message EnabledResponse { 26 | string sentence = 1; 27 | } 28 | 29 | service EnabledService { 30 | rpc Enabled(EnabledRequest) returns (EnabledResponse) {} 31 | } 32 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/disabled/v1/disabled.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.disabled.v1; 18 | 19 | option java_multiple_files = false; 20 | 21 | message DisabledRequest { 22 | string sentence = 1; 23 | } 24 | 25 | message DisabledResponse { 26 | string sentence = 1; 27 | } 28 | 29 | service DisabledService { 30 | rpc Disabled(DisabledRequest) returns (DisabledResponse) {} 31 | } 32 | -------------------------------------------------------------------------------- /examples/android/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.android.application") 3 | id("kotlin-android") 4 | } 5 | 6 | android { 7 | compileSdk = 35 8 | 9 | defaultConfig { 10 | applicationId = "com.connectrpc.examples.android" 11 | minSdk = 28 12 | targetSdk = 35 13 | versionCode = 1 14 | versionName = "1.0" 15 | multiDexEnabled = true 16 | } 17 | 18 | compileOptions { 19 | sourceCompatibility = JavaVersion.VERSION_1_8 20 | targetCompatibility = JavaVersion.VERSION_1_8 21 | } 22 | namespace = "com.connectrpc.examples.android" 23 | } 24 | 25 | dependencies { 26 | implementation(libs.androidx.appcompat) 27 | implementation(libs.androidx.constraintLayout) 28 | implementation(libs.androidx.recyclerview) 29 | implementation(libs.android.multidex) 30 | implementation(libs.androidx.lifecycle.runtime.ktx) 31 | implementation(libs.android.material) 32 | 33 | implementation(project(":okhttp")) 34 | implementation(project(":examples:generated-google-javalite")) 35 | implementation(libs.okhttp.core) 36 | } 37 | -------------------------------------------------------------------------------- /examples/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 14 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/enabled/v1/enabled_empty.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.enabled.v1; 18 | 19 | option java_multiple_files = true; 20 | 21 | message EnabledEmpty { 22 | } 23 | 24 | message EnabledEmptyRPCRequest { 25 | } 26 | 27 | message EnabledEmptyRPCResponse { 28 | } 29 | 30 | service EnabledEmptyService { 31 | rpc EnabledEmptyRPC(EnabledEmptyRPCRequest) returns (EnabledEmptyRPCResponse); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/disabled/v1/disabled_empty.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.disabled.v1; 18 | 19 | option java_multiple_files = false; 20 | 21 | message DisabledEmpty { 22 | } 23 | 24 | message DisabledEmptyRPCRequest { 25 | } 26 | 27 | message DisabledEmptyRPCResponse { 28 | } 29 | 30 | service DisabledEmptyService { 31 | rpc DisabledEmptyRPC(DisabledEmptyRPCRequest) returns (DisabledEmptyRPCResponse); 32 | } 33 | -------------------------------------------------------------------------------- /examples/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | managed: 3 | enabled: true 4 | override: 5 | - file_option: java_package_prefix 6 | value: "com" 7 | clean: true 8 | plugins: 9 | - local: ./protoc-gen-connect-kotlin/build/install/protoc-gen-connect-kotlin/bin/protoc-gen-connect-kotlin 10 | out: generated-google-java/build/generated/sources/bufgen 11 | - protoc_builtin: java 12 | protoc_path: .tmp/bin/protoc 13 | out: generated-google-java/build/generated/sources/bufgen 14 | - protoc_builtin: kotlin 15 | protoc_path: .tmp/bin/protoc 16 | out: generated-google-java/build/generated/sources/bufgen 17 | - local: ./protoc-gen-connect-kotlin/build/install/protoc-gen-connect-kotlin/bin/protoc-gen-connect-kotlin 18 | out: generated-google-javalite/build/generated/sources/bufgen 19 | - protoc_builtin: java 20 | protoc_path: .tmp/bin/protoc 21 | out: generated-google-javalite/build/generated/sources/bufgen 22 | opt: lite 23 | - protoc_builtin: kotlin 24 | protoc_path: .tmp/bin/protoc 25 | out: generated-google-javalite/build/generated/sources/bufgen 26 | opt: lite 27 | inputs: 28 | - module: buf.build/connectrpc/eliza 29 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/unspecified/v1/unspecified.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.unspecified.v1; 18 | 19 | // Avoid using this option. 20 | //option java_multiple_files = false; 21 | 22 | message UnspecifiedRequest { 23 | string sentence = 1; 24 | } 25 | 26 | message UnspecifiedResponse { 27 | string sentence = 1; 28 | } 29 | 30 | service UnspecifiedService { 31 | rpc Unspecified(UnspecifiedRequest) returns (UnspecifiedResponse) {} 32 | } 33 | -------------------------------------------------------------------------------- /conformance/client/src/main/kotlin/com/connectrpc/conformance/client/adapt/AnyMessage.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.adapt 16 | 17 | import com.google.protobuf.ByteString 18 | 19 | /** 20 | * Corresponds to a google.protobuf.Any message. This is distinct 21 | * from the com.google.protobuf.Any Java class so that it can be 22 | * used without relying on a particular runtime (e.g. the lite vs. 23 | * standard runtimes). 24 | */ 25 | class AnyMessage( 26 | val typeUrl: String, 27 | val value: ByteString, 28 | ) 29 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/UnaryBlockingCall.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | /** 18 | * A [UnaryBlockingCall] contains the way to make a blocking RPC call and cancelling the RPC. 19 | */ 20 | interface UnaryBlockingCall { 21 | /** 22 | * Execute the underlying request. Can only be called once. 23 | * Subsequent calls will throw IllegalStateException. 24 | */ 25 | fun execute(): ResponseMessage 26 | 27 | /** 28 | * Cancel the underlying request. 29 | */ 30 | fun cancel() 31 | } 32 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/unspecified/v1/unspecified_empty.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.unspecified.v1; 18 | 19 | // Avoid using this option. 20 | //option java_multiple_files = false; 21 | 22 | message UnspecifiedEmpty { 23 | } 24 | 25 | message UnspecifiedEmptyRPCRequest { 26 | } 27 | 28 | message UnspecifiedEmptyRPCResponse { 29 | } 30 | 31 | service UnspecifiedEmptyService { 32 | rpc UnspecifiedEmptyRPC(UnspecifiedEmptyRPCRequest) returns (UnspecifiedEmptyRPCResponse); 33 | } 34 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/enabled/v1/enabled_nested.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.enabled.v1; 18 | 19 | option java_multiple_files = true; 20 | 21 | message EnabledOuterMessageNested { 22 | message InnerMessage {} 23 | } 24 | 25 | service EnabledInnerMessageService { 26 | // buf:lint:ignore RPC_REQUEST_STANDARD_NAME 27 | // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME 28 | rpc EnabledInnerMessageRPC(EnabledOuterMessageNested.InnerMessage) returns (EnabledOuterMessageNested.InnerMessage); 29 | } 30 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/disabled/v1/disabled_nested.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.disabled.v1; 18 | 19 | option java_multiple_files = false; 20 | 21 | message DisabledOuterMessageNested { 22 | message InnerMessage {} 23 | } 24 | 25 | service DisabledInnerMessageService { 26 | // buf:lint:ignore RPC_REQUEST_STANDARD_NAME 27 | // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME 28 | rpc DisabledInnerMessageRPC(DisabledOuterMessageNested.InnerMessage) returns (DisabledOuterMessageNested.InnerMessage); 29 | } 30 | -------------------------------------------------------------------------------- /library/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.JavadocJar.Dokka 2 | import com.vanniktech.maven.publish.KotlinJvm 3 | 4 | plugins { 5 | kotlin("jvm") 6 | id("org.jetbrains.dokka") 7 | id("com.vanniktech.maven.publish.base") 8 | alias(libs.plugins.ksp) 9 | } 10 | 11 | kotlin { 12 | compilerOptions.allWarningsAsErrors.set(true) 13 | } 14 | 15 | dependencies { 16 | testImplementation(libs.assertj) 17 | testImplementation(libs.junit) 18 | testImplementation(libs.mockito) 19 | 20 | // Part of API contract 21 | api(libs.kotlin.coroutines.core) 22 | api(libs.okio.core) 23 | 24 | implementation(libs.moshiKotlin) 25 | 26 | ksp(libs.moshiKotlinCodegen) 27 | } 28 | 29 | mavenPublishing { 30 | configure( 31 | KotlinJvm(javadocJar = Dokka("dokkaGeneratePublicationHtml")), 32 | ) 33 | } 34 | 35 | // Workaround for overriding the published library name to "connect-kotlin". 36 | // Otherwise, the plugin will take the library name. 37 | extensions.getByType().apply { 38 | publications 39 | .filterIsInstance() 40 | .forEach { publication -> 41 | publication.artifactId = "connect-kotlin" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/javamultiplefiles/unspecified/v1/enabled_nested.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.javamultiplefiles.unspecified.v1; 18 | 19 | // Avoid using this option. 20 | //option java_multiple_files = false; 21 | 22 | message UnspecifiedOuterMessageNested { 23 | message InnerMessage {} 24 | } 25 | 26 | service UnspecifiedInnerMessageService { 27 | 28 | // buf:lint:ignore RPC_REQUEST_STANDARD_NAME 29 | // buf:lint:ignore RPC_RESPONSE_STANDARD_NAME 30 | rpc UnspecifiedInnerMessageRPC(UnspecifiedOuterMessageNested.InnerMessage) returns (UnspecifiedOuterMessageNested.InnerMessage); 31 | } 32 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/evilcomments/v1/evilcomments.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package buf.evilcomments.v1; 18 | 19 | message EvilCommentsRequest {} 20 | 21 | message EvilCommentsResponse {} 22 | 23 | service EvilCommentsService { 24 | // This comment contains characters that should be escaped. 25 | // @ is valid in KDoc, but not in proto. 26 | // Comments in KDoc use C-style block comments, so */ and /* should be escaped. 27 | // [ and ] characters should also be escaped. 28 | // % characters should be escaped. 29 | rpc EvilComments(EvilCommentsRequest) returns (EvilCommentsResponse) {} 30 | } 31 | -------------------------------------------------------------------------------- /conformance/buf.gen.yaml: -------------------------------------------------------------------------------- 1 | version: v2 2 | managed: 3 | enabled: true 4 | clean: true 5 | plugins: 6 | # Java conformance. 7 | - local: ./protoc-gen-connect-kotlin/build/install/protoc-gen-connect-kotlin/bin/protoc-gen-connect-kotlin 8 | out: google-java/build/generated/sources/bufgen 9 | opt: 10 | - generateCallbackMethods=true 11 | - generateCoroutineMethods=true 12 | - generateBlockingUnaryMethods=true 13 | - protoc_builtin: java 14 | protoc_path: .tmp/bin/protoc 15 | out: google-java/build/generated/sources/bufgen 16 | - protoc_builtin: kotlin 17 | protoc_path: .tmp/bin/protoc 18 | out: google-java/build/generated/sources/bufgen 19 | # Javalite conformance. 20 | - local: ./protoc-gen-connect-kotlin/build/install/protoc-gen-connect-kotlin/bin/protoc-gen-connect-kotlin 21 | out: google-javalite/build/generated/sources/bufgen 22 | opt: 23 | - generateCallbackMethods=true 24 | - generateCoroutineMethods=true 25 | - generateBlockingUnaryMethods=true 26 | - protoc_builtin: java 27 | protoc_path: .tmp/bin/protoc 28 | out: google-javalite/build/generated/sources/bufgen 29 | opt: lite 30 | - protoc_builtin: kotlin 31 | protoc_path: .tmp/bin/protoc 32 | out: google-javalite/build/generated/sources/bufgen 33 | opt: lite 34 | -------------------------------------------------------------------------------- /okhttp/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.JavadocJar.Dokka 2 | import com.vanniktech.maven.publish.KotlinJvm 3 | 4 | plugins { 5 | kotlin("jvm") 6 | id("org.jetbrains.dokka") 7 | id("com.vanniktech.maven.publish.base") 8 | } 9 | 10 | kotlin { 11 | compilerOptions.allWarningsAsErrors.set(true) 12 | } 13 | 14 | dependencies { 15 | api(libs.okhttp.core) 16 | implementation(libs.kotlin.coroutines.core) 17 | 18 | api(project(":library")) 19 | 20 | testImplementation(libs.assertj) 21 | testImplementation(libs.okhttp.mockwebserver) 22 | testImplementation(libs.kotlin.coroutines.test) 23 | testImplementation(project(":extensions:google-java")) 24 | testImplementation(project(":examples:generated-google-java")) 25 | } 26 | 27 | mavenPublishing { 28 | configure( 29 | KotlinJvm(javadocJar = Dokka("dokkaGeneratePublicationHtml")), 30 | ) 31 | } 32 | 33 | // Workaround for overriding the published library name to "connect-kotlin-okhttp". 34 | // Otherwise, the plugin will take the library name. 35 | extensions.getByType().apply { 36 | publications 37 | .filterIsInstance() 38 | .forEach { publication -> 39 | publication.artifactId = "connect-kotlin-okhttp" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /conformance/client/google-javalite/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | application 4 | } 5 | 6 | application { 7 | mainClass.set("com.connectrpc.conformance.client.javalite.MainKt") 8 | } 9 | 10 | tasks { 11 | compileKotlin { 12 | compilerOptions { 13 | // Generated Kotlin code for protobuf uses RequiresOptIn annotation 14 | freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") 15 | } 16 | } 17 | jar { 18 | manifest { 19 | attributes(mapOf("Main-Class" to application.mainClass.get())) 20 | } 21 | from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) { 22 | exclude("META-INF/**/*") 23 | } 24 | } 25 | } 26 | 27 | sourceSets { 28 | main { 29 | java { 30 | srcDir("build/generated/sources/bufgen") 31 | } 32 | } 33 | } 34 | 35 | dependencies { 36 | implementation(project(":conformance:client")) 37 | implementation(project(":extensions:google-javalite")) 38 | implementation(project(":okhttp")) 39 | implementation(libs.kotlin.coroutines.core) 40 | implementation(libs.protobuf.kotlinlite) 41 | implementation(libs.protobuf.javalite) 42 | implementation(libs.okio.core) 43 | implementation(libs.okhttp.tls) 44 | } 45 | -------------------------------------------------------------------------------- /extensions/google-javalite/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.JavadocJar.Dokka 2 | import com.vanniktech.maven.publish.KotlinJvm 3 | 4 | plugins { 5 | kotlin("jvm") 6 | 7 | id("org.jetbrains.dokka") 8 | id("com.vanniktech.maven.publish.base") 9 | } 10 | 11 | kotlin { 12 | compilerOptions.allWarningsAsErrors.set(true) 13 | } 14 | 15 | dependencies { 16 | testImplementation(libs.assertj) 17 | testImplementation(libs.junit) 18 | 19 | implementation(project(":okhttp")) 20 | api(libs.okio.core) 21 | api(libs.protobuf.javalite) 22 | api(libs.protobuf.kotlinlite) 23 | implementation(libs.kotlin.reflect) 24 | } 25 | 26 | sourceSets { 27 | main { 28 | java { 29 | srcDir("build/generated/sources/bufgen") 30 | } 31 | } 32 | } 33 | 34 | mavenPublishing { 35 | configure( 36 | KotlinJvm(javadocJar = Dokka("dokkaGeneratePublicationHtml")), 37 | ) 38 | } 39 | 40 | // Workaround for overriding the published library name to "connect-kotlin". 41 | // Otherwise, the plugin will take the library name. 42 | extensions.getByType().apply { 43 | publications 44 | .filterIsInstance() 45 | .forEach { publication -> 46 | publication.artifactId = "connect-kotlin-google-javalite-ext" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /extensions/google-java/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.JavadocJar.Dokka 2 | import com.vanniktech.maven.publish.KotlinJvm 3 | 4 | plugins { 5 | kotlin("jvm") 6 | java 7 | id("org.jetbrains.dokka") 8 | id("com.vanniktech.maven.publish.base") 9 | } 10 | 11 | kotlin { 12 | compilerOptions.allWarningsAsErrors.set(true) 13 | } 14 | 15 | sourceSets { 16 | main { 17 | java { 18 | srcDir("build/generated/sources/bufgen") 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | testImplementation(libs.assertj) 25 | testImplementation(libs.junit) 26 | 27 | implementation(project(":okhttp")) 28 | api(libs.okio.core) 29 | api(libs.protobuf.java) 30 | api(libs.protobuf.kotlin) 31 | api(libs.protobuf.java.util) 32 | implementation(libs.kotlin.reflect) 33 | } 34 | 35 | mavenPublishing { 36 | configure( 37 | KotlinJvm(javadocJar = Dokka("dokkaGeneratePublicationHtml")), 38 | ) 39 | } 40 | 41 | // Workaround for overriding the published library name to "connect-kotlin". 42 | // Otherwise, the plugin will take the library name. 43 | extensions.getByType().apply { 44 | publications 45 | .filterIsInstance() 46 | .forEach { publication -> 47 | publication.artifactId = "connect-kotlin-google-java-ext" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /conformance/client/src/main/kotlin/com/connectrpc/conformance/client/adapt/Invoker.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.adapt 16 | 17 | /** 18 | * An RPC stub that allows for invoking RPC methods. 19 | * Each method of Invoker corresponds to an RPC method 20 | * of the conformance service and returns a client 21 | * object that can be used to actually invoke that RPC. 22 | */ 23 | interface Invoker { 24 | fun unaryClient(): UnaryClient<*, *> 25 | fun idempotentUnaryClient(): UnaryClient<*, *> 26 | fun unimplementedClient(): UnaryClient<*, *> 27 | fun clientStreamClient(): ClientStreamClient<*, *> 28 | fun serverStreamClient(): ServerStreamClient<*, *> 29 | fun bidiStreamClient(): BidiStreamClient<*, *> 30 | } 31 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/RequestCompression.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import com.connectrpc.compression.CompressionPool 18 | import okio.Buffer 19 | 20 | /** 21 | * Configuration used to specify if/how requests should be compressed. 22 | */ 23 | data class RequestCompression( 24 | // The minimum number of bytes that a request message should be for compression to be used. 25 | val minBytes: Int, 26 | // The compression pool that should be used for compressing outbound requests. 27 | val compressionPool: CompressionPool, 28 | ) { 29 | /** 30 | * Checks if the input buffer meets the compression requirements. 31 | */ 32 | fun shouldCompress(buffer: Buffer): Boolean { 33 | return buffer.size >= minBytes 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/ErrorDetailParser.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import kotlin.reflect.KClass 18 | 19 | /** 20 | * Completion parser is a helper for parsing stream completions. 21 | * 22 | * Both the Connect and gRPC protocol relies on the 23 | * status.proto as the structure of error payloads. 24 | */ 25 | interface ErrorDetailParser { 26 | /** 27 | * Unpack the given Any payload into the input class type. 28 | */ 29 | fun unpack(any: AnyError, clazz: KClass): E? 30 | 31 | /** 32 | * Parse the given bytes for a list of error details. The given 33 | * bytes will be the serialized form of a google.rpc.Status 34 | * Protobuf message. 35 | */ 36 | fun parseDetails(bytes: ByteArray): List 37 | } 38 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/SerializationStrategy.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import kotlin.reflect.KClass 18 | 19 | /** 20 | * The serialization strategy for completion events from gRPC or Connect. 21 | * 22 | * A base data type will need to implement a [SerializationStrategy]. 23 | */ 24 | interface SerializationStrategy { 25 | 26 | /** 27 | * The name of the serialization. Used in the content-type 28 | * header. 29 | */ 30 | fun serializationName(): String 31 | 32 | /** 33 | * Get the Codec to serialize and deserialize a payload. 34 | */ 35 | fun codec(clazz: KClass): Codec 36 | 37 | /** 38 | * @return The error detail parser for a specific base data type. 39 | */ 40 | fun errorDetailParser(): ErrorDetailParser 41 | } 42 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/MethodSpec.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import kotlin.reflect.KClass 18 | 19 | /** 20 | * Represents the minimum set of information to execute an RPC method. 21 | * Primarily used in generated code. 22 | * 23 | * @param path The path of the request. 24 | * @param requestClass The Kotlin Class for the request message. 25 | * @param responseClass The Kotlin Class for the response message. 26 | * @param idempotency The declared idempotency of a method. 27 | * @param streamType The method's stream type. 28 | */ 29 | class MethodSpec( 30 | val path: String, 31 | val requestClass: KClass, 32 | val responseClass: KClass, 33 | val streamType: StreamType, 34 | val idempotency: Idempotency = Idempotency.UNKNOWN, 35 | ) 36 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/proto/buf/editions/v1/editions.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | edition = "2023"; 16 | 17 | package buf.editions.v1; 18 | 19 | option features.field_presence = IMPLICIT; 20 | 21 | message EditionsRequest { 22 | message NestedMessage { 23 | string not_utf8 = 1 [ features.utf8_validation = NONE ]; 24 | } 25 | 26 | repeated NestedMessage nested = 1 [ 27 | features.repeated_field_encoding = EXPANDED, 28 | features.message_encoding = DELIMITED 29 | ]; 30 | } 31 | 32 | message EditionsResponse { 33 | enum NestedEnum { 34 | option features.enum_type = CLOSED; 35 | NESTED_ENUM_VALUE_UNSPECIFIED = 0; 36 | } 37 | 38 | NestedEnum enum = 1 [ features.field_presence = EXPLICIT ]; 39 | } 40 | 41 | service EditionsService { 42 | rpc Editions(EditionsRequest) returns (EditionsResponse) {} 43 | } 44 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/ConnectErrorDetail.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import okio.ByteString 18 | 19 | // A ConnectErrorDetail is a self-describing Protobuf message attached to a 20 | // [ConnectException]. 21 | // 22 | // Error details are sent over the network to clients, which can then work with 23 | // strongly-typed data rather than trying to parse a complex error message. For 24 | // example, you might use details to send a localized error message or retry 25 | // parameters to the client. 26 | // 27 | // The [com.google.rpc](https://googleapis.github.io/googleapis/java/all/latest/apidocs/com/google/rpc/package-summary.html) 28 | // package contains a variety of Protobuf messages commonly used as error details. 29 | data class ConnectErrorDetail( 30 | val type: String, 31 | val payload: ByteString, 32 | ) { 33 | val pb = AnyError(type, payload) 34 | } 35 | -------------------------------------------------------------------------------- /conformance/client/google-java/src/main/kotlin/com/connectrpc/conformance/client/java/JavaBidiStreamClient.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.java 16 | 17 | import com.connectrpc.Headers 18 | import com.connectrpc.conformance.client.adapt.BidiStreamClient 19 | import com.connectrpc.conformance.v1.BidiStreamRequest 20 | import com.connectrpc.conformance.v1.BidiStreamResponse 21 | import com.connectrpc.conformance.v1.ConformanceServiceClient 22 | 23 | class JavaBidiStreamClient( 24 | private val client: ConformanceServiceClient, 25 | ) : BidiStreamClient( 26 | BidiStreamRequest.getDefaultInstance(), 27 | BidiStreamResponse.getDefaultInstance(), 28 | ) { 29 | override suspend fun execute(headers: Headers): BidiStream { 30 | return BidiStream.new(client.bidiStream(headers)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /conformance/client/google-javalite/src/main/kotlin/com/connectrpc/conformance/client/javalite/JavaLiteBidiStreamClient.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.javalite 16 | 17 | import com.connectrpc.Headers 18 | import com.connectrpc.conformance.client.adapt.BidiStreamClient 19 | import com.connectrpc.conformance.v1.BidiStreamRequest 20 | import com.connectrpc.conformance.v1.BidiStreamResponse 21 | import com.connectrpc.conformance.v1.ConformanceServiceClient 22 | 23 | class JavaLiteBidiStreamClient( 24 | private val client: ConformanceServiceClient, 25 | ) : BidiStreamClient( 26 | BidiStreamRequest.getDefaultInstance(), 27 | BidiStreamResponse.getDefaultInstance(), 28 | ) { 29 | override suspend fun execute(headers: Headers): BidiStream { 30 | return BidiStream.new(client.bidiStream(headers)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /conformance/client/google-java/src/main/kotlin/com/connectrpc/conformance/client/java/JavaClientStreamClient.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.java 16 | 17 | import com.connectrpc.Headers 18 | import com.connectrpc.conformance.client.adapt.ClientStreamClient 19 | import com.connectrpc.conformance.v1.ClientStreamRequest 20 | import com.connectrpc.conformance.v1.ClientStreamResponse 21 | import com.connectrpc.conformance.v1.ConformanceServiceClient 22 | 23 | class JavaClientStreamClient( 24 | private val client: ConformanceServiceClient, 25 | ) : ClientStreamClient( 26 | ClientStreamRequest.getDefaultInstance(), 27 | ClientStreamResponse.getDefaultInstance(), 28 | ) { 29 | override suspend fun execute(headers: Headers): ClientStream { 30 | return ClientStream.new(client.clientStream(headers)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /conformance/client/google-javalite/src/main/kotlin/com/connectrpc/conformance/client/javalite/JavaLiteClientStreamClient.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.javalite 16 | 17 | import com.connectrpc.Headers 18 | import com.connectrpc.conformance.client.adapt.ClientStreamClient 19 | import com.connectrpc.conformance.v1.ClientStreamRequest 20 | import com.connectrpc.conformance.v1.ClientStreamResponse 21 | import com.connectrpc.conformance.v1.ConformanceServiceClient 22 | 23 | class JavaLiteClientStreamClient( 24 | private val client: ConformanceServiceClient, 25 | ) : ClientStreamClient( 26 | ClientStreamRequest.getDefaultInstance(), 27 | ClientStreamResponse.getDefaultInstance(), 28 | ) { 29 | override suspend fun execute(headers: Headers): ClientStream { 30 | return ClientStream.new(client.clientStream(headers)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /conformance/client/google-java/src/main/kotlin/com/connectrpc/conformance/client/java/Main.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.java 16 | 17 | import com.connectrpc.conformance.client.Client 18 | import com.connectrpc.conformance.client.ClientArgs 19 | import com.connectrpc.conformance.client.ConformanceClientLoop 20 | 21 | fun main(args: Array) { 22 | val clientArgs = ClientArgs.parseArgs(args) 23 | val loop = ConformanceClientLoop( 24 | JavaHelpers::unmarshalRequest, 25 | JavaHelpers::marshalResponse, 26 | clientArgs.verbose, 27 | ) 28 | val client = Client( 29 | args = clientArgs, 30 | invokerFactory = ::JavaInvoker, 31 | serializationFactory = JavaHelpers::serializationStrategy, 32 | payloadExtractor = JavaHelpers::extractPayload, 33 | ) 34 | loop.run(System.`in`, System.out, client) 35 | // TODO: catch any exception for better error output/logging? 36 | } 37 | -------------------------------------------------------------------------------- /conformance/client/src/main/kotlin/com/connectrpc/conformance/client/adapt/ClientResponseResult.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.adapt 16 | 17 | import com.connectrpc.ConnectException 18 | import com.connectrpc.Headers 19 | import com.google.protobuf.MessageLite 20 | 21 | /** 22 | * Represents the result of issuing an RPC. 23 | * 24 | * This corresponds to the connectrpc.conformance.v1.ClientResponseResult 25 | * proto message. Its presence is to provide a representation that 26 | * doesn't rely on either the standard or lite Protobuf runtime. 27 | */ 28 | class ClientResponseResult( 29 | val headers: Headers = emptyMap(), 30 | val payloads: List = emptyList(), 31 | val trailers: Headers = emptyMap(), 32 | val error: ConnectException? = null, 33 | val numUnsentRequests: Int = 0, 34 | 35 | /** 36 | * Set to underlying message or object during marshal. 37 | */ 38 | var raw: Any? = null, 39 | ) 40 | -------------------------------------------------------------------------------- /conformance/client/src/main/kotlin/com/connectrpc/conformance/client/adapt/ClientCompatResponse.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.adapt 16 | 17 | /** 18 | * Represents the response of a conformance request. This 19 | * describes the RPC result of invoking an RPC for a particular 20 | * conformance test case. 21 | * 22 | * This corresponds to the connectrpc.conformance.v1.ClientCompatResponse 23 | * proto message. Its presence is to provide a representation that 24 | * doesn't rely on either the standard or lite Protobuf runtime. 25 | * 26 | * This can represent a result received from an RPC server or an 27 | * error that prevented the RPC from being invoked. 28 | */ 29 | data class ClientCompatResponse( 30 | val testName: String, 31 | val result: Result, 32 | ) { 33 | 34 | sealed class Result { 35 | class ResponseResult(val response: ClientResponseResult) : Result() 36 | class ErrorResult(val error: String) : Result() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /conformance/client/google-javalite/src/main/kotlin/com/connectrpc/conformance/client/javalite/Main.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.javalite 16 | 17 | import com.connectrpc.conformance.client.Client 18 | import com.connectrpc.conformance.client.ClientArgs 19 | import com.connectrpc.conformance.client.ConformanceClientLoop 20 | 21 | fun main(args: Array) { 22 | val clientArgs = ClientArgs.parseArgs(args) 23 | val loop = ConformanceClientLoop( 24 | JavaLiteHelpers::unmarshalRequest, 25 | JavaLiteHelpers::marshalResponse, 26 | clientArgs.verbose, 27 | ) 28 | val client = Client( 29 | args = clientArgs, 30 | invokerFactory = ::JavaLiteInvoker, 31 | serializationFactory = JavaLiteHelpers::serializationStrategy, 32 | payloadExtractor = JavaLiteHelpers::extractPayload, 33 | ) 34 | loop.run(System.`in`, System.out, client) 35 | // TODO: catch any exception for better error output/logging? 36 | } 37 | -------------------------------------------------------------------------------- /conformance/client/src/main/kotlin/com/connectrpc/conformance/client/adapt/UnaryClient.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.conformance.client.adapt 16 | 17 | import com.connectrpc.Headers 18 | import com.connectrpc.ResponseMessage 19 | import com.connectrpc.UnaryBlockingCall 20 | import com.connectrpc.http.Cancelable 21 | import com.google.protobuf.MessageLite 22 | 23 | /** 24 | * The client of a unary RPC operation. This provides multiple ways 25 | * to invoke the RPC: suspend-based async, callback-based async, or 26 | * blocking. 27 | * 28 | * @param Req The request message type 29 | * @param Resp The response message type 30 | */ 31 | abstract class UnaryClient( 32 | val reqTemplate: Req, 33 | val respTemplate: Resp, 34 | ) { 35 | abstract suspend fun execute(req: Req, headers: Headers): ResponseMessage 36 | 37 | abstract fun execute(req: Req, headers: Headers, onFinish: (ResponseMessage) -> Unit): Cancelable 38 | 39 | abstract fun blocking(req: Req, headers: Headers): UnaryBlockingCall 40 | } 41 | -------------------------------------------------------------------------------- /conformance/client/google-java/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | kotlin("jvm") 3 | application 4 | } 5 | 6 | application { 7 | mainClass.set("com.connectrpc.conformance.client.java.MainKt") 8 | } 9 | 10 | tasks { 11 | compileKotlin { 12 | compilerOptions { 13 | // Generated Kotlin code for protobuf uses OptIn annotation 14 | freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn") 15 | } 16 | } 17 | jar { 18 | manifest { 19 | attributes(mapOf("Main-Class" to application.mainClass.get())) 20 | } 21 | from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) { 22 | exclude("META-INF/**/*") 23 | } 24 | } 25 | } 26 | 27 | sourceSets { 28 | main { 29 | java { 30 | srcDir("build/generated/sources/bufgen") 31 | } 32 | } 33 | } 34 | 35 | dependencies { 36 | implementation(project(":conformance:client")) { 37 | // Shared module depends on javalite, just for some core 38 | // classes that are shared across both java and javalite 39 | // runtimes, like ByteString and MessageLite. We must 40 | // exclude it here to avoid any classpath ambiguity since 41 | // we pull in the full runtime for this module. 42 | exclude(group = "com.google.protobuf", module = "protobuf-javalite") 43 | } 44 | implementation(project(":extensions:google-java")) 45 | implementation(project(":okhttp")) 46 | implementation(libs.kotlin.coroutines.core) 47 | implementation(libs.protobuf.kotlin) 48 | implementation(libs.protobuf.java) 49 | implementation(libs.okio.core) 50 | implementation(libs.okhttp.tls) 51 | } 52 | -------------------------------------------------------------------------------- /library/src/test/kotlin/com/connectrpc/ProtocolClientConfigTest.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import org.assertj.core.api.Assertions.assertThat 18 | import org.assertj.core.api.Assertions.fail 19 | import org.junit.Test 20 | import org.mockito.kotlin.mock 21 | import java.net.MalformedURLException 22 | 23 | class ProtocolClientConfigTest { 24 | 25 | @Test 26 | fun hostUri() { 27 | val config = ProtocolClientConfig( 28 | host = "https://connectrpc.com", 29 | serializationStrategy = mock { }, 30 | ) 31 | assertThat(config.baseUri.host).isEqualTo("connectrpc.com") 32 | assertThat(config.baseUri.toURL()).isNotNull() 33 | } 34 | 35 | @Test(expected = MalformedURLException::class) 36 | fun unsupportedSchemeErrorsWhenTranslatingToURL() { 37 | val config = ProtocolClientConfig( 38 | host = "xhtp://connectrpc.com", 39 | serializationStrategy = mock { }, 40 | ) 41 | config.baseUri.toURL() 42 | fail("expecting URL construction to fail") 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /library/src/test/kotlin/com/connectrpc/ConnectExceptionTest.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc 16 | 17 | import okio.ByteString.Companion.encodeUtf8 18 | import org.assertj.core.api.Assertions.assertThat 19 | import org.junit.Test 20 | import org.mockito.kotlin.mock 21 | import org.mockito.kotlin.whenever 22 | 23 | class ConnectExceptionTest { 24 | private val errorDetailParser: ErrorDetailParser = mock { } 25 | 26 | @Test 27 | fun connectErrorParsing() { 28 | val errorDetail = ConnectErrorDetail( 29 | "type", 30 | "value".encodeUtf8(), 31 | ) 32 | whenever(errorDetailParser.unpack(errorDetail.pb, String::class)).thenReturn("unpacked_value") 33 | val connectException = ConnectException( 34 | code = Code.UNKNOWN, 35 | ).withErrorDetails( 36 | errorParser = errorDetailParser, 37 | details = listOf( 38 | errorDetail, 39 | errorDetail, 40 | ), 41 | ) 42 | val parsedResult = connectException.unpackedDetails(String::class) 43 | assertThat(parsedResult).contains("unpacked_value", "unpacked_value") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /protoc-gen-connect-kotlin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.vanniktech.maven.publish.JavadocJar.Dokka 2 | import com.vanniktech.maven.publish.KotlinJvm 3 | 4 | plugins { 5 | application 6 | java 7 | kotlin("jvm") 8 | 9 | id("org.jetbrains.dokka") 10 | id("com.vanniktech.maven.publish.base") 11 | } 12 | 13 | application { 14 | mainClass.set("com.connectrpc.protocgen.connect.Main") 15 | } 16 | 17 | kotlin { 18 | compilerOptions.allWarningsAsErrors.set(true) 19 | } 20 | 21 | tasks { 22 | jar { 23 | manifest { 24 | attributes(mapOf("Main-Class" to application.mainClass.get())) 25 | } 26 | from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) { 27 | exclude("META-INF/**/*") 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation(project(":library")) 34 | implementation(libs.protobuf.java) 35 | implementation(libs.kotlinpoet) 36 | 37 | testImplementation(libs.junit) 38 | testImplementation(libs.assertj) 39 | testImplementation(libs.mockito) 40 | testImplementation(libs.kotlin.coroutines.core) 41 | } 42 | 43 | sourceSets { 44 | test { 45 | java { 46 | srcDir(layout.buildDirectory.dir("generated/sources/bufgen")) 47 | } 48 | } 49 | } 50 | 51 | mavenPublishing { 52 | configure( 53 | KotlinJvm(javadocJar = Dokka("dokkaGeneratePublicationHtml")), 54 | ) 55 | } 56 | 57 | // Workaround for overriding the published library name. 58 | // Otherwise, the plugin will take the library name. 59 | extensions.getByType().apply { 60 | publications 61 | .filterIsInstance() 62 | .forEach { publication -> 63 | publication.artifactId = "protoc-gen-connect-kotlin" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /library/src/main/kotlin/com/connectrpc/protocols/ConnectConstants.kt: -------------------------------------------------------------------------------- 1 | // Copyright 2022-2025 The Connect Authors 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package com.connectrpc.protocols 16 | 17 | const val ACCEPT_ENCODING = "accept-encoding" 18 | const val CONTENT_ENCODING = "content-encoding" 19 | const val CONTENT_TYPE = "content-type" 20 | const val CONNECT_STREAMING_CONTENT_ENCODING = "connect-content-encoding" 21 | const val CONNECT_STREAMING_ACCEPT_ENCODING = "connect-accept-encoding" 22 | const val CONNECT_PROTOCOL_VERSION_KEY = "connect-protocol-version" 23 | const val CONNECT_PROTOCOL_VERSION_VALUE = "1" 24 | const val CONNECT_TIMEOUT_MS = "connect-timeout-ms" 25 | 26 | const val GRPC_ACCEPT_ENCODING = "grpc-accept-encoding" 27 | const val GRPC_ENCODING = "grpc-encoding" 28 | const val GRPC_MESSAGE_TRAILER = "grpc-message" 29 | const val GRPC_STATUS_DETAILS_TRAILERS = "grpc-status-details-bin" 30 | const val GRPC_STATUS_TRAILER = "grpc-status" 31 | const val GRPC_TE_HEADER = "te" 32 | const val GRPC_WEB_USER_AGENT = "x-user-agent" 33 | const val GRPC_TIMEOUT = "grpc-timeout" 34 | 35 | const val USER_AGENT = "user-agent" 36 | 37 | object ConnectConstants { 38 | /** Version number of the connect-kotlin library */ 39 | val VERSION = javaClass.`package`?.implementationVersion ?: "dev" 40 | } 41 | -------------------------------------------------------------------------------- /examples/android/src/main/res/layout/activity_eliza_chat.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 18 | 26 | 32 |