Skip to content

Commit 9199d38

Browse files
committed
Support protoc Kotlin code generation
1 parent b616f68 commit 9199d38

File tree

7 files changed

+46
-1
lines changed

7 files changed

+46
-1
lines changed

bom/application/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6249,6 +6249,12 @@
62496249
</exclusion>
62506250
</exclusions>
62516251
</dependency>
6252+
<dependency>
6253+
<groupId>com.google.protobuf</groupId>
6254+
<artifactId>protobuf-kotlin</artifactId>
6255+
<version>${protobuf-kotlin.version}</version>
6256+
<scope>compile</scope>
6257+
</dependency>
62526258
<dependency>
62536259
<groupId>com.google.protobuf</groupId>
62546260
<artifactId>protoc</artifactId>

docs/src/main/asciidoc/grpc-generation-reference.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ quarkus.generate-code.grpc.scan-for-proto-exclude."<groupId>:<artifactId>"=foo/p
165165

166166
Note that `:` characters in the property keys must be escaped.
167167

168+
== Kotlin code generation
169+
170+
`protoc` also supports https://protobuf.dev/reference/kotlin/kotlin-generated/[generating Kotlin code] in addition to the generated Java code.
171+
172+
By default, the Kotlin code generation is enabled if the dependency `io.quarkus:quarkus-kotlin` is present.
173+
174+
To explicitly en-/disable this feature, set the `quarkus.generate-code.grpc.kotlin.generate` property in your `application.properties` file to `true` or `false`.
175+
176+
177+
IMPORTANT: When using Gradle, you also have to include `com.google.protobuf:protobuf-kotlin` as a `compileOnly` dependency in your project.
178+
168179
== Skipping code generation
169180

170181
You can skip gRPC code generation using:

extensions/grpc/codegen/src/main/java/io/quarkus/grpc/codegen/GrpcCodeGen.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Locale;
2424
import java.util.Map;
2525
import java.util.Set;
26+
import java.util.function.Predicate;
2627
import java.util.stream.Collectors;
2728
import java.util.stream.Stream;
2829

@@ -66,8 +67,11 @@ public class GrpcCodeGen implements CodeGenProvider {
6667

6768
private static final String USE_ARG_FILE = "quarkus.generate-code.grpc.use-arg-file";
6869

70+
private static final String GENERATE_KOTLIN = "quarkus.generate-code.grpc.kotlin.generate";
71+
6972
private Executables executables;
7073
private String input;
74+
private boolean hasQuarkusKotlinDependency;
7175

7276
@Override
7377
public String providerId() {
@@ -95,6 +99,7 @@ public Path getInputDirectory() {
9599
@Override
96100
public void init(ApplicationModel model, Map<String, String> properties) {
97101
this.input = properties.get("quarkus.grpc.codegen.proto-directory");
102+
this.hasQuarkusKotlinDependency = containsQuarkusKotlin(model.getDependencies());
98103
}
99104

100105
@Override
@@ -162,6 +167,10 @@ public boolean trigger(CodeGenContext context) throws CodeGenException {
162167
"--grpc_out=" + outDir,
163168
"--java_out=" + outDir));
164169

170+
if (shouldGenerateKotlin(context.config())) {
171+
command.add("--kotlin_out=" + outDir);
172+
}
173+
165174
if (shouldGenerateDescriptorSet(context.config())) {
166175
command.add(String.format("--descriptor_set_out=%s", getDescriptorSetOutputFile(context)));
167176
}
@@ -296,6 +305,11 @@ private boolean isGeneratingFromAppDependenciesEnabled(Config config) {
296305
.filter(value -> !"none".equals(value)).isPresent();
297306
}
298307

308+
private boolean shouldGenerateKotlin(Config config) {
309+
return config.getOptionalValue(GENERATE_KOTLIN, Boolean.class).orElse(
310+
hasQuarkusKotlinDependency);
311+
}
312+
299313
private boolean shouldGenerateDescriptorSet(Config config) {
300314
return config.getOptionalValue(GENERATE_DESCRIPTOR_SET, Boolean.class).orElse(FALSE);
301315
}
@@ -526,6 +540,16 @@ private static void writePluginExeCmd(Path pluginPath, BufferedWriter writer) th
526540
writer.newLine();
527541
}
528542

543+
private static boolean containsQuarkusKotlin(Collection<ResolvedDependency> dependencies) {
544+
return dependencies.stream().anyMatch(new Predicate<ResolvedDependency>() {
545+
@Override
546+
public boolean test(ResolvedDependency rd) {
547+
return rd.getGroupId().equalsIgnoreCase("io.quarkus")
548+
&& rd.getArtifactId().equalsIgnoreCase("quarkus-kotlin");
549+
}
550+
});
551+
}
552+
529553
private static class Executables {
530554

531555
final Path protoc;

integration-tests/gradle/src/main/resources/grpc-multi-module-no-java/application/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies {
1111
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
1212
implementation("io.quarkus:quarkus-arc")
1313
implementation("io.quarkus:quarkus-grpc")
14+
compileOnly("com.google.protobuf:protobuf-kotlin")
1415

1516
testImplementation("io.quarkus:quarkus-junit5")
1617
testImplementation("io.rest-assured:rest-assured")

integration-tests/gradle/src/main/resources/kotlin-grpc-project/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ repositories {
1515
}
1616

1717
dependencies {
18+
compileOnly 'com.google.protobuf:protobuf-kotlin'
1819
implementation 'io.quarkus:quarkus-kotlin'
1920
implementation 'io.quarkus:quarkus-grpc'
2021
implementation 'io.quarkus:quarkus-smallrye-graphql'

integration-tests/gradle/src/main/resources/kotlin-grpc-project/src/main/kotlin/org/acme/ExampleResource.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import jakarta.ws.rs.Produces
66
import jakarta.ws.rs.core.MediaType
77

88
import io.quarkus.example.HelloMsg
9+
import io.quarkus.example.helloMsg
910

1011
@Path("/hello")
1112
class ExampleResource {
1213

1314
@GET
1415
@Produces(MediaType.TEXT_PLAIN)
15-
fun hello() = "hello" + HelloMsg.Status.TEST_ONE.getNumber()
16+
fun hello() = "hello" + helloMsg { status = HelloMsg.Status.TEST_ONE }.statusValue
1617
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<grpc-jprotoc.version>1.2.2</grpc-jprotoc.version>
8585
<protoc.version>3.25.5</protoc.version>
8686
<protobuf-java.version>${protoc.version}</protobuf-java.version>
87+
<protobuf-kotlin.version>4.29.3</protobuf-kotlin.version>
8788
<proto-google-common-protos.version>2.53.0</proto-google-common-protos.version>
8889

8990
<!-- Used in the build parent and test BOM (for the junit 5 plugin) and in the BOM (for the API) -->

0 commit comments

Comments
 (0)