Skip to content

Commit

Permalink
Merge pull request #27183 from mkouba/issue-27170
Browse files Browse the repository at this point in the history
gRPC -  align service names generated by quarkus with grpc-java
  • Loading branch information
mkouba committed Aug 10, 2022
2 parents 8044979 + 17787e7 commit f1e72f5
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 5 deletions.
4 changes: 2 additions & 2 deletions extensions/grpc/deployment/src/test/proto/goodbyeworld.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -21,4 +21,4 @@ message GoodbyeRequest {
// The response message containing the farewells
message GoodbyeReply {
string message = 1;
}
}
5 changes: 5 additions & 0 deletions extensions/grpc/protoc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ private ServiceContext buildServiceContext(DescriptorProtos.ServiceDescriptorPro
private MethodContext buildMethodContext(DescriptorProtos.MethodDescriptorProto methodProto, ProtoTypeMap typeMap,
List<DescriptorProtos.SourceCodeInfo.Location> 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();
Expand Down Expand Up @@ -171,8 +171,96 @@ 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) {
if (name == null || name.isEmpty()) {
return name;
}
// We need to adjust the method name in the same way as the grpc-java compiler does:
// 1. Decapitalize the first letter (unlike JavaBeans "URL" becomes "uRL")
// 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
StringBuilder ret = new StringBuilder();
ret.append(Character.toLowerCase(name.charAt(0)));
if (name.length() > 1) {
if (name.contains("_")) {
for (String str : name.substring(1).split("_")) {
if (ret.length() == 1) {
ret.append(str);
} else {
ret.append(Character.toUpperCase(str.charAt(0)));
if (str.length() > 1) {
ret.append(str.substring(1));
}
}
}
} else {
ret.append(name.substring(1));
}
if (isJavaKeyword(ret.toString())) {
ret.append("_");
}
}
return ret.toString();
}

private static boolean isJavaKeyword(String value) {
switch (value) {
case "public":
case "protected":
case "private":
case "abstract":
case "static":
case "final":
case "transient":
case "volatile":
case "synchronized":
case "native":
case "class":
case "interface":
case "extends":
case "package":
case "throws":
case "implements":
case "boolean":
case "byte":
case "char":
case "short":
case "int":
case "long":
case "float":
case "double":
case "void":
case "if":
case "else":
case "try":
case "catch":
case "finally":
case "do":
case "while":
case "for":
case "continue":
case "switch":
case "case":
case "default":
case "break":
case "throw":
case "return":
case "this":
case "new":
case "super":
case "import":
case "instanceof":
case "goto":
case "const":
case "null":
case "true":
case "false":
return true;
default:
return false;
}
}

private List<PluginProtos.CodeGeneratorResponse.File> generateFiles(List<ServiceContext> services) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
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("_SayHello", MutinyGrpcGenerator.adaptMethodName("_Say_hello"));
assertEquals("sayHelloAndBye", MutinyGrpcGenerator.adaptMethodName("Say_Hello_and_Bye"));
assertEquals("return_", MutinyGrpcGenerator.adaptMethodName("return"));
}

}

0 comments on commit f1e72f5

Please sign in to comment.