diff --git a/extensions/grpc/deployment/src/test/proto/goodbyeworld.proto b/extensions/grpc/deployment/src/test/proto/goodbyeworld.proto
index f86e335ebe66df..ffdc1defd18f0a 100644
--- a/extensions/grpc/deployment/src/test/proto/goodbyeworld.proto
+++ b/extensions/grpc/deployment/src/test/proto/goodbyeworld.proto
@@ -10,7 +10,7 @@ package goodbyeworld;
// The farewell service definition.
service Farewell {
// Sends a farewell
- rpc SayGoodbye (GoodbyeRequest) returns (GoodbyeReply) {}
+ rpc Say_goodbye (GoodbyeRequest) returns (GoodbyeReply) {}
}
// The request message containing the user's name.
@@ -21,4 +21,4 @@ message GoodbyeRequest {
// The response message containing the farewells
message GoodbyeReply {
string message = 1;
-}
\ No newline at end of file
+}
diff --git a/extensions/grpc/protoc/pom.xml b/extensions/grpc/protoc/pom.xml
index 4c5c1266a7f6eb..15b8037182f6b3 100644
--- a/extensions/grpc/protoc/pom.xml
+++ b/extensions/grpc/protoc/pom.xml
@@ -27,6 +27,11 @@
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
diff --git a/extensions/grpc/protoc/src/main/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGenerator.java b/extensions/grpc/protoc/src/main/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGenerator.java
index 348b88c57c01d5..99d91812542b19 100644
--- a/extensions/grpc/protoc/src/main/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGenerator.java
+++ b/extensions/grpc/protoc/src/main/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGenerator.java
@@ -1,5 +1,6 @@
package io.quarkus.grpc.protoc.plugin;
+import java.beans.Introspector;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -8,6 +9,8 @@
import java.util.logging.Logger;
import java.util.stream.Collectors;
+import javax.lang.model.SourceVersion;
+
import com.google.common.base.Strings;
import com.google.common.html.HtmlEscapers;
import com.google.protobuf.DescriptorProtos;
@@ -137,7 +140,7 @@ private ServiceContext buildServiceContext(DescriptorProtos.ServiceDescriptorPro
private MethodContext buildMethodContext(DescriptorProtos.MethodDescriptorProto methodProto, ProtoTypeMap typeMap,
List locations, int methodNumber) {
MethodContext methodContext = new MethodContext();
- methodContext.methodName = lowerCaseFirst(methodProto.getName());
+ methodContext.methodName = adaptMethodName(methodProto.getName());
methodContext.inputType = typeMap.toJavaTypeName(methodProto.getInputType());
methodContext.outputType = typeMap.toJavaTypeName(methodProto.getOutputType());
methodContext.deprecated = methodProto.getOptions() != null && methodProto.getOptions().getDeprecated();
@@ -171,8 +174,31 @@ private MethodContext buildMethodContext(DescriptorProtos.MethodDescriptorProto
return methodContext;
}
- private String lowerCaseFirst(String s) {
- return Character.toLowerCase(s.charAt(0)) + s.substring(1);
+ static String adaptMethodName(String name) {
+ // We need to adjust the method name in the same way as the grpc-java compiler does:
+ // 1. Decapitalize
+ // 2. Replace an underscore and capitalize the following letter
+ // 3. Append the underscore for a java keyword
+ // (these rules are bit odd but we need to follow them unless we get rid of the grpc-java compiler)
+ // https://github.com/quarkusio/quarkus/issues/27170
+ name = Introspector.decapitalize(name);
+ if (name.contains("_")) {
+ StringBuilder res = new StringBuilder();
+ for (String str : name.split("_")) {
+ if (res.length() == 0) {
+ res.append(str);
+ } else {
+ res.append(Character.toUpperCase(str.charAt(0)));
+ if (str.length() > 1) {
+ res.append(str.substring(1));
+ }
+ }
+ }
+ name = res.toString();
+ } else if (SourceVersion.isKeyword(name)) {
+ name += "_";
+ }
+ return name;
}
private List generateFiles(List services) {
diff --git a/extensions/grpc/protoc/src/test/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGeneratorTest.java b/extensions/grpc/protoc/src/test/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGeneratorTest.java
new file mode 100644
index 00000000000000..d6efce57dd03b5
--- /dev/null
+++ b/extensions/grpc/protoc/src/test/java/io/quarkus/grpc/protoc/plugin/MutinyGrpcGeneratorTest.java
@@ -0,0 +1,18 @@
+package io.quarkus.grpc.protoc.plugin;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class MutinyGrpcGeneratorTest {
+
+ @Test
+ public void testAdaptMethodName() {
+ assertEquals("sayHello", MutinyGrpcGenerator.adaptMethodName("SayHello"));
+ assertEquals("sayHello", MutinyGrpcGenerator.adaptMethodName("Say_Hello"));
+ assertEquals("sayHello", MutinyGrpcGenerator.adaptMethodName("Say_hello"));
+ assertEquals("sayHelloAndBye", MutinyGrpcGenerator.adaptMethodName("Say_Hello_and_Bye"));
+ assertEquals("return", MutinyGrpcGenerator.adaptMethodName("return_"));
+ }
+
+}