diff --git a/compiler/src/main/java/io/grpc/kotlin/generator/TopLevelConstantsGenerator.kt b/compiler/src/main/java/io/grpc/kotlin/generator/TopLevelConstantsGenerator.kt index 44f8a60c..d46aa0a8 100644 --- a/compiler/src/main/java/io/grpc/kotlin/generator/TopLevelConstantsGenerator.kt +++ b/compiler/src/main/java/io/grpc/kotlin/generator/TopLevelConstantsGenerator.kt @@ -43,7 +43,13 @@ class TopLevelConstantsGenerator(config: GeneratorConfig): ServiceCodeGenerator( .getter( FunSpec.getterBuilder() .addAnnotation(JvmStatic::class) - .addStatement("return %T.get%LMethod()", service.grpcClass, method.methodName) + .addStatement("return %T.%L()", + service.grpcClass, + method.methodName + .toMemberSimpleName() + .withPrefix("get") + .withSuffix("Method") + ) .build() ) .build() diff --git a/compiler/src/main/java/io/grpc/kotlin/generator/protoc/ProtoMethodName.kt b/compiler/src/main/java/io/grpc/kotlin/generator/protoc/ProtoMethodName.kt index 05031cc4..0ed4ee1b 100644 --- a/compiler/src/main/java/io/grpc/kotlin/generator/protoc/ProtoMethodName.kt +++ b/compiler/src/main/java/io/grpc/kotlin/generator/protoc/ProtoMethodName.kt @@ -22,8 +22,23 @@ import com.google.protobuf.Descriptors.MethodDescriptor /** Represents the unqualified name of an RPC method in a proto file, in UpperCamelCase. */ data class ProtoMethodName(val name: String) : CharSequence by name { - fun toMemberSimpleName(): MemberSimpleName = - MemberSimpleName(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, name)) + fun toMemberSimpleName(): MemberSimpleName { + val name = MemberSimpleName(CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, name)) + if (containsSpecialCharacters(name)) { + return handleSpecialCharacters(name) + } + return name + } + + private fun containsSpecialCharacters(name: MemberSimpleName): Boolean { + return name.contains("_") + } + + private fun handleSpecialCharacters(name: MemberSimpleName): MemberSimpleName { + return name.split("_") + .map(::MemberSimpleName) + .reduce { acc, simpleName -> acc + simpleName } + } override fun toString() = name } diff --git a/compiler/src/test/java/io/grpc/kotlin/generator/protoc/ProtoMethodNameTest.kt b/compiler/src/test/java/io/grpc/kotlin/generator/protoc/ProtoMethodNameTest.kt new file mode 100644 index 00000000..8a9c18e7 --- /dev/null +++ b/compiler/src/test/java/io/grpc/kotlin/generator/protoc/ProtoMethodNameTest.kt @@ -0,0 +1,28 @@ +package io.grpc.kotlin.generator.protoc + +import com.google.common.truth.Truth.assertThat +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.JUnit4 + +/** Tests for [ProtoMethodName]. */ +@RunWith(JUnit4::class) +class ProtoMethodNameTest { + @Test + fun toMemberSimpleNameWithSingleUnderscore(){ + assertThat(ProtoMethodName("say_hello").toMemberSimpleName()) + .isEqualTo(MemberSimpleName("sayHello")) + } + + @Test + fun toMemberSimpleNameWithMultipleUnderscores(){ + assertThat(ProtoMethodName("say_hello_again").toMemberSimpleName()) + .isEqualTo(MemberSimpleName("sayHelloAgain")) + } + + @Test + fun toMemberSimpleNameWithRecommendedNamingStyle(){ + assertThat(ProtoMethodName("SayHello").toMemberSimpleName()) + .isEqualTo(MemberSimpleName("sayHello")) + } +} \ No newline at end of file diff --git a/compiler/src/test/proto/testing/rpc_name_contains_underscore.proto b/compiler/src/test/proto/testing/rpc_name_contains_underscore.proto new file mode 100644 index 00000000..196e091b --- /dev/null +++ b/compiler/src/test/proto/testing/rpc_name_contains_underscore.proto @@ -0,0 +1,9 @@ +syntax = "proto3"; +package io.grpc.testing.underscore; +option java_multiple_files = true; +service NameContainsUnderscore { + rpc say_hello (HelloRequest) returns (HelloReply); + rpc say_hello_again (HelloRequest) returns (HelloReply); +} +message HelloRequest {} +message HelloReply {} \ No newline at end of file