diff --git a/LICENSE b/LICENSE index 02ae1cddce..03d3e19808 100644 --- a/LICENSE +++ b/LICENSE @@ -241,8 +241,4 @@ https://github.com/edazdarevic/CIDRUtils. The project is licensed under a MIT Li * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - -This product contains a modified portion of 'proto-gen-grpc-java' - a protobuf plugin used to generate grpc-java stubs, - under a "Apache License 2.0" license, see https://github.com/grpc/grpc-java/blob/v1.22.1/NOTICE.txt. All files are placed - under '/dubbo/compiler' + * THE SOFTWARE. \ No newline at end of file diff --git a/NOTICE b/NOTICE index 8d33f8649a..83785ff21b 100644 --- a/NOTICE +++ b/NOTICE @@ -13,12 +13,3 @@ Please visit the Netty web site for more information: Copyright 2014 The Netty Project - -This product contains code for the gRPC Project: - -The gRPC Project -================= -Please visit the gRPC web site for more information: - * http://grpc.io/ - -Copyright 2014 The gRPC Project diff --git a/compiler/.gradle/4.3/fileChanges/last-build.bin b/compiler/.gradle/4.3/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ad..0000000000 Binary files a/compiler/.gradle/4.3/fileChanges/last-build.bin and /dev/null differ diff --git a/compiler/.gradle/4.3/fileContent/annotation-processors.bin b/compiler/.gradle/4.3/fileContent/annotation-processors.bin deleted file mode 100644 index aa6e57ca22..0000000000 Binary files a/compiler/.gradle/4.3/fileContent/annotation-processors.bin and /dev/null differ diff --git a/compiler/.gradle/4.3/fileContent/fileContent.lock b/compiler/.gradle/4.3/fileContent/fileContent.lock deleted file mode 100644 index f0536e6df9..0000000000 Binary files a/compiler/.gradle/4.3/fileContent/fileContent.lock and /dev/null differ diff --git a/compiler/.gradle/4.3/fileHashes/fileHashes.bin b/compiler/.gradle/4.3/fileHashes/fileHashes.bin deleted file mode 100644 index d219abdf95..0000000000 Binary files a/compiler/.gradle/4.3/fileHashes/fileHashes.bin and /dev/null differ diff --git a/compiler/.gradle/4.3/fileHashes/fileHashes.lock b/compiler/.gradle/4.3/fileHashes/fileHashes.lock deleted file mode 100644 index 067763af78..0000000000 Binary files a/compiler/.gradle/4.3/fileHashes/fileHashes.lock and /dev/null differ diff --git a/compiler/.gradle/4.3/fileHashes/resourceHashesCache.bin b/compiler/.gradle/4.3/fileHashes/resourceHashesCache.bin deleted file mode 100644 index 827d8b9a13..0000000000 Binary files a/compiler/.gradle/4.3/fileHashes/resourceHashesCache.bin and /dev/null differ diff --git a/compiler/.gradle/4.3/nativeCompile/nativeCompile.bin b/compiler/.gradle/4.3/nativeCompile/nativeCompile.bin deleted file mode 100644 index 7c2e6cd733..0000000000 Binary files a/compiler/.gradle/4.3/nativeCompile/nativeCompile.bin and /dev/null differ diff --git a/compiler/.gradle/4.3/nativeCompile/nativeCompile.lock b/compiler/.gradle/4.3/nativeCompile/nativeCompile.lock deleted file mode 100644 index 91ced25a70..0000000000 Binary files a/compiler/.gradle/4.3/nativeCompile/nativeCompile.lock and /dev/null differ diff --git a/compiler/.gradle/4.3/taskHistory/taskHistory.bin b/compiler/.gradle/4.3/taskHistory/taskHistory.bin deleted file mode 100644 index 70d6d25643..0000000000 Binary files a/compiler/.gradle/4.3/taskHistory/taskHistory.bin and /dev/null differ diff --git a/compiler/.gradle/4.3/taskHistory/taskHistory.lock b/compiler/.gradle/4.3/taskHistory/taskHistory.lock deleted file mode 100644 index a68d1b7014..0000000000 Binary files a/compiler/.gradle/4.3/taskHistory/taskHistory.lock and /dev/null differ diff --git a/compiler/.gradle/4.9/fileChanges/last-build.bin b/compiler/.gradle/4.9/fileChanges/last-build.bin deleted file mode 100644 index f76dd238ad..0000000000 Binary files a/compiler/.gradle/4.9/fileChanges/last-build.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/fileContent/annotation-processors.bin b/compiler/.gradle/4.9/fileContent/annotation-processors.bin deleted file mode 100644 index ea3f5e801c..0000000000 Binary files a/compiler/.gradle/4.9/fileContent/annotation-processors.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/fileContent/fileContent.lock b/compiler/.gradle/4.9/fileContent/fileContent.lock deleted file mode 100644 index 6766d56ed0..0000000000 Binary files a/compiler/.gradle/4.9/fileContent/fileContent.lock and /dev/null differ diff --git a/compiler/.gradle/4.9/fileContent/parsedCSource.bin b/compiler/.gradle/4.9/fileContent/parsedCSource.bin deleted file mode 100644 index d63153f612..0000000000 Binary files a/compiler/.gradle/4.9/fileContent/parsedCSource.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/fileHashes/fileHashes.bin b/compiler/.gradle/4.9/fileHashes/fileHashes.bin deleted file mode 100644 index 656cb524f2..0000000000 Binary files a/compiler/.gradle/4.9/fileHashes/fileHashes.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/fileHashes/fileHashes.lock b/compiler/.gradle/4.9/fileHashes/fileHashes.lock deleted file mode 100644 index 4c4991c2eb..0000000000 Binary files a/compiler/.gradle/4.9/fileHashes/fileHashes.lock and /dev/null differ diff --git a/compiler/.gradle/4.9/fileHashes/resourceHashesCache.bin b/compiler/.gradle/4.9/fileHashes/resourceHashesCache.bin deleted file mode 100644 index fa0f984901..0000000000 Binary files a/compiler/.gradle/4.9/fileHashes/resourceHashesCache.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/nativeCompile/nativeCompile.bin b/compiler/.gradle/4.9/nativeCompile/nativeCompile.bin deleted file mode 100644 index f68f4d216d..0000000000 Binary files a/compiler/.gradle/4.9/nativeCompile/nativeCompile.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/nativeCompile/nativeCompile.lock b/compiler/.gradle/4.9/nativeCompile/nativeCompile.lock deleted file mode 100644 index 7e2f718a65..0000000000 Binary files a/compiler/.gradle/4.9/nativeCompile/nativeCompile.lock and /dev/null differ diff --git a/compiler/.gradle/4.9/taskHistory/taskHistory.bin b/compiler/.gradle/4.9/taskHistory/taskHistory.bin deleted file mode 100644 index 6467c7df94..0000000000 Binary files a/compiler/.gradle/4.9/taskHistory/taskHistory.bin and /dev/null differ diff --git a/compiler/.gradle/4.9/taskHistory/taskHistory.lock b/compiler/.gradle/4.9/taskHistory/taskHistory.lock deleted file mode 100644 index bfdcb35a65..0000000000 Binary files a/compiler/.gradle/4.9/taskHistory/taskHistory.lock and /dev/null differ diff --git a/compiler/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/compiler/.gradle/buildOutputCleanup/buildOutputCleanup.lock deleted file mode 100644 index 287f9ed659..0000000000 Binary files a/compiler/.gradle/buildOutputCleanup/buildOutputCleanup.lock and /dev/null differ diff --git a/compiler/.gradle/buildOutputCleanup/cache.properties b/compiler/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 0a578269a7..0000000000 --- a/compiler/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Tue Oct 09 11:40:48 CST 2018 -gradle.version=4.9 diff --git a/compiler/.gradle/buildOutputCleanup/outputFiles.bin b/compiler/.gradle/buildOutputCleanup/outputFiles.bin deleted file mode 100644 index 8bd6f36038..0000000000 Binary files a/compiler/.gradle/buildOutputCleanup/outputFiles.bin and /dev/null differ diff --git a/compiler/.gradle/vcsWorkingDirs/gc.properties b/compiler/.gradle/vcsWorkingDirs/gc.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/compiler/BUILD.bazel b/compiler/BUILD.bazel deleted file mode 100644 index 1a2f2f3826..0000000000 --- a/compiler/BUILD.bazel +++ /dev/null @@ -1,12 +0,0 @@ -cc_binary( - name = "grpc_java_plugin", - srcs = [ - "src/java_plugin/cpp/java_generator.cpp", - "src/java_plugin/cpp/java_generator.h", - "src/java_plugin/cpp/java_plugin.cpp", - ], - visibility = ["//visibility:public"], - deps = [ - "@com_google_protobuf//:protoc_lib", - ], -) diff --git a/compiler/README.md b/compiler/README.md deleted file mode 100644 index 6a8a643f3c..0000000000 --- a/compiler/README.md +++ /dev/null @@ -1,202 +0,0 @@ -# Dubbo customized version - -## Get Started, how to use -1. Add maven dependency to your project -```xml - - - - kr.motd.maven - os-maven-plugin - 1.6.1 - - - - - org.xolstice.maven.plugins - protobuf-maven-plugin - 0.5.1 - - com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier} - grpc-java - org.apache.dubbo:protoc-gen-dubbo-java:${proto_dubbo_plugin_version}:exe:${os.detected.classifier} - build/generated/source/proto/main/java - false - - dubbo - - - - - compile - compile-custom - test-compile - test-compile-custom - - - - - - org.codehaus.mojo - build-helper-maven-plugin - - - generate-sources - - add-source - - - - build/generated/source/proto/main/java - - - - - - - -``` - -2. Decide which protocol to use: Dubbo or gRPC - * Dubbo, ` dubbo` - * gRPC, ` grpc` - -3. Define service using IDL -```text -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "org.apache.dubbo.demo"; -option java_outer_classname = "DemoServiceProto"; -option objc_class_prefix = "DEMOSRV"; - -package demoservice; - -// The demo service definition. -service DemoService { - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} -``` - -4. Build -mvn clean compile - -## Customized - -1. Dubbo Interface -```java -public interface IGreeter { - - default public io.grpc.examples.helloworld.HelloReply sayHello(io.grpc.examples.helloworld.HelloRequest request) { - throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); - } - - default public com.google.common.util.concurrent.ListenableFuture sayHelloAsync( - io.grpc.examples.helloworld.HelloRequest request) { - throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); - } - - public void sayHello(io.grpc.examples.helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver); - -} -``` - -2. Dubbo Stub -```java -public static DubboGreeterStub getDubboStub(io.grpc.Channel channel) { - return new DubboGreeterStub(channel); -} - -public static class DubboGreeterStub implements IGreeter { - - private GreeterBlockingStub blockingStub; - private GreeterFutureStub futureStub; - private GreeterStub stub; - - public DubboGreeterStub(io.grpc.Channel channel) { - blockingStub = GreeterGrpc.newBlockingStub(channel); - futureStub = GreeterGrpc.newFutureStub(channel); - stub = GreeterGrpc.newStub(channel); - } - - public io.grpc.examples.helloworld.HelloReply sayHello(io.grpc.examples.helloworld.HelloRequest request) { - return blockingStub.sayHello(request); - } - - public com.google.common.util.concurrent.ListenableFuture sayHelloAsync( - io.grpc.examples.helloworld.HelloRequest request) { - return futureStub.sayHello(requesthttps://github.com/apache/dubbo-samples.git); - } - - public void sayHello(io.grpc.examples.helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver){ - stub.sayHello(request, responseObserver); - } - -} - -``` - -3. XxxImplBase implements DubboInterface -```java -public static abstract class GreeterImplBase implements io.grpc.BindableService, IGreeter { - - @java.lang.Override - public final io.grpc.examples.helloworld.HelloReply sayHello(io.grpc.examples.helloworld.HelloRequest request) { - throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); - } - - @java.lang.Override - public final com.google.common.util.concurrent.ListenableFuture sayHelloAsync( - io.grpc.examples.helloworld.HelloRequest request) { - throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); - } - - public void sayHello(io.grpc.examples.helloworld.HelloRequest request, - io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getSayHelloMethod(), responseObserver); - } - - ... -} -``` - -## Build locally - -To compile the plugin: -``` -$ ./gradlew java_pluginExecutable -``` - -To publish to local repository -``` -$ ./gradlew publishToMavenLocal -``` - -## Publish to maven repository - -Add gradle.properties -```properties -repositoryUser=user -repositoryPasword=pwd -``` - -Then, run -``` -$ ../gradlew publishMavenPublicationToDubboRepository -``` -Notice current groupId is `com.alibaba`. - - -Check [here](https://github.com/grpc/grpc-java/blob/master/compiler/README.md) for basic requirements and usage of protoc plugin. diff --git a/compiler/build.gradle b/compiler/build.gradle deleted file mode 100644 index f94fef70d0..0000000000 --- a/compiler/build.gradle +++ /dev/null @@ -1,406 +0,0 @@ -apply plugin: "cpp" -apply plugin: "com.google.protobuf" - -group = "org.apache.dubbo" -version = "1.19.0-SNAPSHOT" // CURRENT_GRPC_VERSION - -description = 'The protoc plugin for gRPC Java' - -apply plugin: "checkstyle" -apply plugin: "java" -apply plugin: "maven" -apply plugin: "maven-publish" -apply plugin: "idea" -apply plugin: "signing" -apply plugin: "jacoco" - -apply plugin: "me.champeau.gradle.jmh" -apply plugin: "com.google.osdetector" -// The plugin only has an effect if a signature is specified -apply plugin: "ru.vyarus.animalsniffer" - -apply plugin: "net.ltgt.errorprone" - -buildscript { - repositories { - maven { // The google mirror is less flaky than mavenCentral() - url "https://maven-central.storage-download.googleapis.com/repos/central/data/" - } - mavenLocal() - maven { url "https://plugins.gradle.org/m2/" } - } - dependencies { - classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.5" - classpath "com.diffplug.spotless:spotless-plugin-gradle:3.13.0" - classpath 'com.google.gradle:osdetector-gradle-plugin:1.4.0' - classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.4.5' - classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.6' - classpath "me.champeau.gradle:jmh-gradle-plugin:0.4.5" - classpath 'me.champeau.gradle:japicmp-gradle-plugin:0.2.5' - } -} - -import net.ltgt.gradle.errorprone.CheckSeverity - -def artifactStagingPath = "$buildDir/artifacts" as File -// Adds space-delimited arguments from the environment variable env to the -// argList. -def addEnvArgs = { env, argList -> - def value = System.getenv(env) - if (value != null) { - value.split(' +').each() { it -> argList.add(it) } - } -} - -// Adds corresponding "-l" option to the argList if libName is not found in -// LDFLAGS. This is only used for Mac because when building for uploadArchives -// artifacts, we add the ".a" files directly to LDFLAGS and without "-l" in -// order to get statically linked, otherwise we add the libraries through "-l" -// so that they can be searched for in default search paths. -def addLibraryIfNotLinked = { libName, argList -> - def ldflags = System.env.LDFLAGS - if (ldflags == null || !ldflags.contains('lib' + libName + '.a')) { - argList.add('-l' + libName) - } -} - -def String arch = rootProject.hasProperty('targetArch') ? rootProject.targetArch : osdetector.arch -def boolean vcDisable = rootProject.hasProperty('vcDisable') ? rootProject.vcDisable : false -def boolean usingVisualCpp // Whether VisualCpp is actually available and selected - -ext{ - def exeSuffix = osdetector.os == 'windows' ? ".exe" : "" - protocPluginBaseName = 'protoc-gen-dubbo-java' - javaPluginPath = "$rootDir/build/exe/java_plugin/$protocPluginBaseName$exeSuffix" - - nettyVersion = '4.1.32.Final' - googleauthVersion = '0.9.0' - guavaVersion = '26.0-android' - protobufVersion = '3.6.1' - protocVersion = protobufVersion - protobufNanoVersion = '3.0.0-alpha-5' - opencensusVersion = '0.19.2' - - libraries = [ - animalsniffer_annotations: "org.codehaus.mojo:animal-sniffer-annotations:1.17", - errorprone: "com.google.errorprone:error_prone_annotations:2.2.0", - gson: "com.google.code.gson:gson:2.7", - guava: "com.google.guava:guava:26.0-android", - hpack: 'com.twitter:hpack:0.10.1', - javax_annotation: 'javax.annotation:javax.annotation-api:1.2', - jsr305: 'com.google.code.findbugs:jsr305:3.0.2', - google_api_protos: 'com.google.api.grpc:proto-google-common-protos:1.12.0', - - // Keep the following references of tcnative version in sync whenever it's updated - // SECURITY.md (multiple occurrences) - // examples/example-tls/build.gradle - // examples/example-tls/pom.xml - netty_tcnative: 'io.netty:netty-tcnative-boringssl-static:2.0.20.Final', - - conscrypt: 'org.conscrypt:conscrypt-openjdk-uber:1.0.1', - re2j: 'com.google.re2j:re2j:1.2' - ] -} - -model { - toolChains { - // If you have both VC and Gcc installed, VC will be selected, unless you - // set 'vcDisable=true' - if (!vcDisable) { - visualCpp(VisualCpp) { - // Prefer vcvars-provided environment over registry-discovered environment - def String vsDir = System.getenv("VSINSTALLDIR") - def String winDir = System.getenv("WindowsSdkDir") - if (vsDir != null && winDir != null) { - installDir = vsDir - windowsSdkDir = winDir - } - } - } - gcc(Gcc) { - target("ppcle_64") - target("aarch_64") - } - clang(Clang) { - } - } - - platforms { - x86_32 { architecture "x86" } - x86_64 { architecture "x86_64" } - ppcle_64 { architecture "ppcle_64" } - aarch_64 { architecture "aarch_64" } - } - - components { - java_plugin(NativeExecutableSpec) { - if (arch in [ - 'x86_32', - 'x86_64', - 'ppcle_64', - 'aarch_64' - ]) { - // If arch is not within the defined platforms, we do not specify the - // targetPlatform so that Gradle will choose what is appropriate. - targetPlatform arch - } - baseName "$protocPluginBaseName" - } - } - - binaries { - all { - if (toolChain in Gcc || toolChain in Clang) { - cppCompiler.define("GRPC_VERSION", version) - cppCompiler.args "--std=c++0x" - addEnvArgs("CXXFLAGS", cppCompiler.args) - addEnvArgs("CPPFLAGS", cppCompiler.args) - if (osdetector.os == "osx") { - cppCompiler.args "-mmacosx-version-min=10.7", "-stdlib=libc++" - addLibraryIfNotLinked('protoc', linker.args) - addLibraryIfNotLinked('protobuf', linker.args) - } else if (osdetector.os == "windows") { - linker.args "-static", "-lprotoc", "-lprotobuf", "-static-libgcc", "-static-libstdc++", - "-s" - } else { - // Link protoc, protobuf, libgcc and libstdc++ statically. - // Link other (system) libraries dynamically. - // Clang under OSX doesn't support these options. - linker.args "-Wl,-Bstatic", "-lprotoc", "-lprotobuf", "-static-libgcc", - "-static-libstdc++", - "-Wl,-Bdynamic", "-lpthread", "-s" - } - addEnvArgs("LDFLAGS", linker.args) - } else if (toolChain in VisualCpp) { - usingVisualCpp = true - cppCompiler.define("GRPC_VERSION", version) - cppCompiler.args "/EHsc", "/MT" - if (rootProject.hasProperty('vcProtobufInclude')) { - cppCompiler.args "/I${rootProject.vcProtobufInclude}" - } - linker.args "libprotobuf.lib", "libprotoc.lib" - if (rootProject.hasProperty('vcProtobufLibs')) { - linker.args "/LIBPATH:${rootProject.vcProtobufLibs}" - } - } - } - } -} - -configurations { - testLiteCompile - testNanoCompile -} - -sourceSets { - testLite { - proto { setSrcDirs(['src/test/proto']) } - } - testNano { - proto { setSrcDirs(['src/test/proto']) } - } -} - - -compileTestJava { - options.compilerArgs += [ - "-Xlint:-cast" - ] - options.errorprone.excludedPaths = ".*/build/generated/source/proto/.*" -} - -compileTestLiteJava { - options.compilerArgs = compileTestJava.options.compilerArgs - // Protobuf-generated Lite produces quite a few warnings. - options.compilerArgs += [ - "-Xlint:-rawtypes", - "-Xlint:-unchecked", - "-Xlint:-fallthrough" - ] - options.errorprone.excludedPaths = ".*/build/generated/source/proto/.*" -} - -compileTestNanoJava { - options.compilerArgs = compileTestJava.options.compilerArgs - options.errorprone.excludedPaths = ".*/build/generated/source/proto/.*" -} - -protobuf { - protoc { - if (project.hasProperty('protoc')) { - path = project.protoc - } else { - // Since nano is removed from newer versions of protoc, use an older version for the - // while. This means we won't be able to test any descriptor.proto additions, but that - // should be fine for a while. - artifact = libraries.protoc_nano - } - } - plugins { - javalite { - if (project.hasProperty('protoc-gen-javalite')) { - path = project['protoc-gen-javalite'] - } else { - artifact = libraries.protoc_lite - } - } - grpc { path = javaPluginPath } - } - generateProtoTasks { - all().each { task -> - task.dependsOn 'java_pluginExecutable' - task.inputs.file javaPluginPath - } - ofSourceSet('test')*.plugins { grpc {} } - ofSourceSet('testLite')*.each { task -> - task.builtins { remove java } - task.plugins { - javalite {} - grpc { option 'lite' } - } - } - ofSourceSet('testNano').each { task -> - task.builtins { - remove java - javanano { option 'ignore_services=true' } - } - task.plugins { grpc { option 'nano' } } - } - } -} - -checkstyleTestNano { - source = fileTree(dir: "src/testNano", include: "**/*.java") -} - -println "*** Building codegen requires Protobuf version ${protocVersion}" -println "*** Please refer to https://github.com/apache/dubbo/blob/master/compiler/README.md" - -task buildArtifacts(type: Copy) { - dependsOn 'java_pluginExecutable' - from("$buildDir/exe") { - if (osdetector.os != 'windows') { - rename 'protoc-gen-dubbo-java', '$0.exe' - } - } - into artifactStagingPath -} - -archivesBaseName = "$protocPluginBaseName" - -task checkArtifacts { - dependsOn buildArtifacts - doLast { - if (!usingVisualCpp) { - def ret = exec { - executable 'bash' - args 'check-artifact.sh', osdetector.os, arch - } - if (ret.exitValue != 0) { - throw new GradleException("check-artifact.sh exited with " + ret.exitValue) - } - } else { - def exeName = "$artifactStagingPath/java_plugin/${protocPluginBaseName}.exe" - def os = new ByteArrayOutputStream() - def ret = exec { - executable 'dumpbin' - args '/nologo', '/dependents', exeName - standardOutput = os - } - if (ret.exitValue != 0) { - throw new GradleException("dumpbin exited with " + ret.exitValue) - } - def dlls = os.toString() =~ /Image has the following dependencies:\s+(.*)\s+Summary/ - if (dlls[0][1] != "KERNEL32.dll") { - throw new Exception("unexpected dll deps: " + dlls[0][1]); - } - os.reset() - ret = exec { - executable 'dumpbin' - args '/nologo', '/headers', exeName - standardOutput = os - } - if (ret.exitValue != 0) { - throw new GradleException("dumpbin exited with " + ret.exitValue) - } - def machine = os.toString() =~ / machine \(([^)]+)\)/ - def expectedArch = [x86_32: "x86", x86_64: "x64"][arch] - if (machine[0][1] != expectedArch) { - throw new Exception("unexpected architecture: " + machine[0][1]); - } - } - } -} - -// Exe files are skipped by Maven by default. Override it. -// Also skip jar files that is generated by the java plugin. -publishing { - repositories { - maven { - name "dubbo" - credentials { - username repositoryUser // 仓库发布用户名 - password repositoryPassword // 仓库发布用户密码 - } - if(project.version.endsWith('-SNAPSHOT')) { - url "https://repository.apache.org/content/repositories/snapshots" - } else { - url 'https://repository.apache.org/service/local/staging/deploy/maven2' // 仓库地址 - } - } - } - - publications { - maven(MavenPublication) { - // Removes all artifacts since grpc-compiler doesn't generates any Jar - artifacts = [] - artifactId 'protoc-gen-dubbo-java' - artifact("$artifactStagingPath/java_plugin/${protocPluginBaseName}.exe" as File) { - classifier osdetector.os + "-" + arch - extension "exe" - builtBy checkArtifacts - } - pom.withXml { - // This isn't any sort of Java archive artifact, and OSSRH doesn't enforce - // javadoc for 'pom' packages. 'exe' would be a more appropriate packaging - // value, but it isn't clear how that will be interpreted. In addition, - // 'pom' is typically the value used when building an exe with Maven. - asNode().project.packaging*.value = 'pom' - } - } - } -} - -signing { - useGpgCmd() - required false - sign publishing.publications.maven -} - -def configureTestTask(Task task, String dep, String extraPackage, String serviceName) { - test.dependsOn task - task.dependsOn "generateTest${dep}Proto" - if (osdetector.os != 'windows') { - task.executable "diff" - task.args "-u" - } else { - task.executable "fc" - } - // File isn't found on Windows if last slash is forward-slash - def slash = System.getProperty("file.separator") - task.args "$buildDir/generated/source/proto/test${dep}/grpc/io/grpc/testing/compiler${extraPackage}${slash}${serviceName}Grpc.java", - "$projectDir/src/test${dep}/golden/${serviceName}.java.txt" -} - -task testGolden(type: Exec) -task testLiteGolden(type: Exec) -task testNanoGolden(type: Exec) -task testDeprecatedGolden(type: Exec) -task testDeprecatedLiteGolden(type: Exec) -task testDeprecatedNanoGolden(type: Exec) -configureTestTask(testGolden, '', '', 'TestService') -configureTestTask(testLiteGolden, 'Lite', '', 'TestService') -configureTestTask(testNanoGolden, 'Nano', '/nano', 'TestService') -configureTestTask(testDeprecatedGolden, '', '', 'TestDeprecatedService') -configureTestTask(testDeprecatedLiteGolden, 'Lite', '', 'TestDeprecatedService') -configureTestTask(testDeprecatedNanoGolden, 'Nano', '/nano', 'TestDeprecatedService') diff --git a/compiler/check-artifact.sh b/compiler/check-artifact.sh deleted file mode 100755 index 05b57a1d1a..0000000000 --- a/compiler/check-artifact.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/bash - -# Check that the codegen artifacts are of correct architecture and don't have -# unexpected dependencies. -# To be run from Gradle. -# Usage: check-artifact -# and are ${os.detected.name} and ${os.detected.arch} from -# osdetector-gradle-plugin -OS=$1 -ARCH=$2 - -if [[ $# < 2 ]]; then - echo "No arguments provided. This script is intended to be run from Gradle." - exit 1 -fi - -# Under Cygwin, bash doesn't have these in PATH when called from Gradle which -# runs in Windows version of Java. -export PATH="/bin:/usr/bin:$PATH" - -E_PARAM_ERR=98 -E_ASSERT_FAILED=99 - -# Usage: fail ERROR_MSG -fail() -{ - echo "ERROR: $1" - echo - exit $E_ASSERT_FAILED -} - -# Usage: assertEq VAL1 VAL2 $LINENO -assertEq () -{ - lineno=$3 - if [ -z "$lineno" ]; then - echo "lineno not given" - exit $E_PARAM_ERR - fi - - if [[ "$1" != "$2" ]]; then - echo "Assertion failed: \"$1\" == \"$2\"" - echo "File \"$0\", line $lineno" # Give name of file and line number. - exit $E_ASSERT_FAILED - fi -} - -# Checks the artifact is for the expected architecture -# Usage: checkArch -checkArch () -{ - echo - echo "Checking format of $1" - if [[ "$OS" == windows || "$OS" == linux ]]; then - format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")" - echo Format=$format - if [[ "$OS" == linux ]]; then - if [[ "$ARCH" == x86_32 ]]; then - assertEq "$format" "elf32-i386" $LINENO - elif [[ "$ARCH" == x86_64 ]]; then - assertEq "$format" "elf64-x86-64" $LINENO - else - fail "Unsupported arch: $ARCH" - fi - else - # $OS == windows - if [[ "$ARCH" == x86_32 ]]; then - assertEq "$format" "pei-i386" $LINENO - elif [[ "$ARCH" == x86_64 ]]; then - assertEq "$format" "pei-x86-64" $LINENO - else - fail "Unsupported arch: $ARCH" - fi - fi - elif [[ "$OS" == osx ]]; then - format="$(file -b "$1" | grep -o "[^ ]*$")" - echo Format=$format - if [[ "$ARCH" == x86_32 ]]; then - assertEq "$format" "i386" $LINENO - elif [[ "$ARCH" == x86_64 ]]; then - assertEq "$format" "x86_64" $LINENO - else - fail "Unsupported arch: $ARCH" - fi - else - fail "Unsupported system: $OS" - fi - echo -} - -# Checks the dependencies of the artifact. Artifacts should only depend on -# system libraries. -# Usage: checkDependencies -checkDependencies () -{ - echo "Checking dependencies of $1" - if [[ "$OS" == windows ]]; then - dump_cmd='objdump -x '"$1"' | fgrep "DLL Name"' - white_list="KERNEL32\.dll\|msvcrt\.dll\|USER32\.dll" - elif [[ "$OS" == linux ]]; then - dump_cmd='ldd '"$1" - if [[ "$ARCH" == x86_32 ]]; then - white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2" - elif [[ "$ARCH" == x86_64 ]]; then - white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2" - fi - elif [[ "$OS" == osx ]]; then - set +x - dump_cmd='otool -L '"$1"' | fgrep dylib' - white_list="libz\.1\.dylib\|libc++.1.dylib\|libstdc++\.6\.dylib\|libSystem\.B\.dylib" - set -x - fi - if [[ -z "$white_list" || -z "$dump_cmd" ]]; then - fail "Unsupported platform $OS-$ARCH." - fi - echo "Checking for expected dependencies ..." - eval $dump_cmd | grep -i "$white_list" || fail "doesn't show any expected dependencies" - echo "Checking for unexpected dependencies ..." - eval $dump_cmd | grep -i -v "$white_list" - ret=$? - if [[ $ret == 0 ]]; then - fail "found unexpected dependencies (listed above)." - elif [[ $ret != 1 ]]; then - fail "Error when checking dependencies." - fi # grep returns 1 when "not found", which is what we expect - echo "Dependencies look good." - echo -} - -FILE="build/artifacts/java_plugin/protoc-gen-dubbo-java.exe" -checkArch "$FILE" && checkDependencies "$FILE" diff --git a/compiler/gradle/wrapper/gradle-wrapper.jar b/compiler/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 0d4a951687..0000000000 Binary files a/compiler/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/compiler/gradle/wrapper/gradle-wrapper.properties b/compiler/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index a95009c3b9..0000000000 --- a/compiler/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/compiler/gradlew b/compiler/gradlew deleted file mode 100755 index cccdd3d517..0000000000 --- a/compiler/gradlew +++ /dev/null @@ -1,172 +0,0 @@ -#!/usr/bin/env sh - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - -exec "$JAVACMD" "$@" diff --git a/compiler/gradlew.bat b/compiler/gradlew.bat deleted file mode 100644 index f9553162f1..0000000000 --- a/compiler/gradlew.bat +++ /dev/null @@ -1,84 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/compiler/pom.xml b/compiler/pom.xml new file mode 100644 index 0000000000..88f95e8783 --- /dev/null +++ b/compiler/pom.xml @@ -0,0 +1,178 @@ + + + + 4.0.0 + + org.apache + apache + 21 + + + org.apache.dubbo + dubbo-compiler + 0.0.1-SNAPSHOT + + jar + + + 3.6.0 + 3.0.2 + 1.8 + 1.8 + UTF-8 + + + + + com.salesforce.servicelibs + grpc-contrib + 0.8.1 + + + com.salesforce.servicelibs + jprotoc + 0.9.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven_compiler_version} + + -proc:none + true + ${java_source_version} + ${java_target_version} + ${file_encoding} + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven_jar_version} + + + + true + org.apache.dubbo.gen.grpc.DubboGrpcGenerator + + + + + + + + com.salesforce.servicelibs + canteen-maven-plugin + 1.0.0 + + + + bootstrap + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + + + verify + + sign + + + + + + + + + + dubbo-compiler + Dubbo customized RPC stub compiler. + https://github.com/apache/dubbo + 2011 + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + + + https://github.com/apache/dubbo + scm:git:https://github.com/apache/dubbo.git + scm:git:https://github.com/apache/dubbo.git + HEAD + + + + Development List + dev-subscribe@dubbo.apache.org + dev-unsubscribe@dubbo.apache.org + dev@dubbo.apache.org + + + Commits List + commits-subscribe@dubbo.apache.org + commits-unsubscribe@dubbo.apache.org + commits@dubbo.apache.org + + + Issues List + issues-subscribe@dubbo.apache.org + issues-unsubscribe@dubbo.apache.org + issues@dubbo.apache.org + + + + + dubbo.io + The Dubbo Project Contributors + dev-subscribe@dubbo.apache.org + http://dubbo.apache.org/ + + + + + The Apache Software Foundation + http://www.apache.org/ + + + + Github Issues + https://github.com/apache/dubbo/issues + + \ No newline at end of file diff --git a/compiler/src/java_plugin/cpp/java_dubbo_generator.cpp b/compiler/src/java_plugin/cpp/java_dubbo_generator.cpp deleted file mode 100644 index 8e7d7b19a7..0000000000 --- a/compiler/src/java_plugin/cpp/java_dubbo_generator.cpp +++ /dev/null @@ -1,580 +0,0 @@ -#include "java_generator.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Stringify helpers used solely to cast GRPC_VERSION -#ifndef STR -#define STR(s) #s -#endif - -#ifndef XSTR -#define XSTR(s) STR(s) -#endif - -#ifndef FALLTHROUGH_INTENDED -#define FALLTHROUGH_INTENDED -#endif - -namespace java_dubbo_generator { - -using google::protobuf::FileDescriptor; -using google::protobuf::ServiceDescriptor; -using google::protobuf::MethodDescriptor; -using google::protobuf::Descriptor; -using google::protobuf::io::Printer; -using google::protobuf::SourceLocation; -using std::to_string; - -// java keywords from: https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9 -static std::set java_keywords = { - "abstract", - "assert", - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", - "continue", - "default", - "do", - "double", - "else", - "enum", - "extends", - "final", - "finally", - "float", - "for", - "goto", - "if", - "implements", - "import", - "instanceof", - "int", - "interface", - "long", - "native", - "new", - "package", - "private", - "protected", - "public", - "return", - "short", - "static", - "strictfp", - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "try", - "void", - "volatile", - "while", - // additional ones added by us - "true", - "false", -}; - -// Adjust a method name prefix identifier to follow the JavaBean spec: -// - decapitalize the first letter -// - remove embedded underscores & capitalize the following letter -// Finally, if the result is a reserved java keyword, append an underscore. -static string MixedLower(const string& word) { - string w; - w += tolower(word[0]); - bool after_underscore = false; - for (size_t i = 1; i < word.length(); ++i) { - if (word[i] == '_') { - after_underscore = true; - } else { - w += after_underscore ? toupper(word[i]) : word[i]; - after_underscore = false; - } - } - if (java_keywords.find(w) != java_keywords.end()) { - return w + "_"; - } - return w; -} - -// Converts to the identifier to the ALL_UPPER_CASE format. -// - An underscore is inserted where a lower case letter is followed by an -// upper case letter. -// - All letters are converted to upper case -static string ToAllUpperCase(const string& word) { - string w; - for (size_t i = 0; i < word.length(); ++i) { - w += toupper(word[i]); - if ((i < word.length() - 1) && islower(word[i]) && isupper(word[i + 1])) { - w += '_'; - } - } - return w; -} - -static inline string LowerMethodName(const MethodDescriptor* method) { - return MixedLower(method->name()); -} - -static inline string MethodPropertiesFieldName(const MethodDescriptor* method) { - return "METHOD_" + ToAllUpperCase(method->name()); -} - -static inline string MethodPropertiesGetterName(const MethodDescriptor* method) { - return MixedLower("get_" + method->name() + "_method"); -} - -static inline string MethodIdFieldName(const MethodDescriptor* method) { - return "METHODID_" + ToAllUpperCase(method->name()); -} - -static inline bool ShouldGenerateAsLite(const Descriptor* desc) { - return false; -} - -static inline string MessageFullJavaName(bool nano, const Descriptor* desc) { - string name = google::protobuf::compiler::java::ClassName(desc); - if (nano && !ShouldGenerateAsLite(desc)) { - // XXX: Add "nano" to the original package - // (https://github.com/grpc/grpc-java/issues/900) - if (isupper(name[0])) { - // No java package specified. - return "nano." + name; - } - for (size_t i = 0; i < name.size(); ++i) { - if ((name[i] == '.') && (i < (name.size() - 1)) && isupper(name[i + 1])) { - return name.substr(0, i + 1) + "nano." + name.substr(i + 1); - } - } - } - return name; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -template -static void GrpcSplitStringToIteratorUsing(const string& full, - const char* delim, - ITR& result) { - // Optimize the common case where delim is a single character. - if (delim[0] != '\0' && delim[1] == '\0') { - char c = delim[0]; - const char* p = full.data(); - const char* end = p + full.size(); - while (p != end) { - if (*p == c) { - ++p; - } else { - const char* start = p; - while (++p != end && *p != c); - *result++ = string(start, p - start); - } - } - return; - } - - string::size_type begin_index, end_index; - begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { - end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); - return; - } - *result++ = full.substr(begin_index, (end_index - begin_index)); - begin_index = full.find_first_not_of(delim, end_index); - } -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static void GrpcSplitStringUsing(const string& full, - const char* delim, - std::vector* result) { - std::back_insert_iterator< std::vector > it(*result); - GrpcSplitStringToIteratorUsing(full, delim, it); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static std::vector GrpcSplit(const string& full, const char* delim) { - std::vector result; - GrpcSplitStringUsing(full, delim, &result); - return result; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static string GrpcEscapeJavadoc(const string& input) { - string result; - result.reserve(input.size() * 2); - - char prev = '*'; - - for (string::size_type i = 0; i < input.size(); i++) { - char c = input[i]; - switch (c) { - case '*': - // Avoid "/*". - if (prev == '/') { - result.append("*"); - } else { - result.push_back(c); - } - break; - case '/': - // Avoid "*/". - if (prev == '*') { - result.append("/"); - } else { - result.push_back(c); - } - break; - case '@': - // '@' starts javadoc tags including the @deprecated tag, which will - // cause a compile-time error if inserted before a declaration that - // does not have a corresponding @Deprecated annotation. - result.append("@"); - break; - case '<': - // Avoid interpretation as HTML. - result.append("<"); - break; - case '>': - // Avoid interpretation as HTML. - result.append(">"); - break; - case '&': - // Avoid interpretation as HTML. - result.append("&"); - break; - case '\\': - // Java interprets Unicode escape sequences anywhere! - result.append("\"); - break; - default: - result.push_back(c); - break; - } - - prev = c; - } - - return result; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -template -static string GrpcGetCommentsForDescriptor(const DescriptorType* descriptor) { - SourceLocation location; - if (descriptor->GetSourceLocation(&location)) { - return location.leading_comments.empty() ? - location.trailing_comments : location.leading_comments; - } - return string(); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static std::vector GrpcGetDocLines(const string& comments) { - if (!comments.empty()) { - // TODO(kenton): Ideally we should parse the comment text as Markdown and - // write it back as HTML, but this requires a Markdown parser. For now - // we just use
 to get fixed-width text formatting.
-
-    // If the comment itself contains block comment start or end markers,
-    // HTML-escape them so that they don't accidentally close the doc comment.
-    string escapedComments = GrpcEscapeJavadoc(comments);
-
-    std::vector lines = GrpcSplit(escapedComments, "\n");
-    while (!lines.empty() && lines.back().empty()) {
-      lines.pop_back();
-    }
-    return lines;
-  }
-  return std::vector();
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-template 
-static std::vector GrpcGetDocLinesForDescriptor(const DescriptorType* descriptor) {
-  return GrpcGetDocLines(GrpcGetCommentsForDescriptor(descriptor));
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-static void GrpcWriteDocCommentBody(Printer* printer,
-                                    const std::vector& lines,
-                                    bool surroundWithPreTag) {
-  if (!lines.empty()) {
-    if (surroundWithPreTag) {
-      printer->Print(" * 
\n");
-    }
-
-    for (size_t i = 0; i < lines.size(); i++) {
-      // Most lines should start with a space.  Watch out for lines that start
-      // with a /, since putting that right after the leading asterisk will
-      // close the comment.
-      if (!lines[i].empty() && lines[i][0] == '/') {
-        printer->Print(" * $line$\n", "line", lines[i]);
-      } else {
-        printer->Print(" *$line$\n", "line", lines[i]);
-      }
-    }
-
-    if (surroundWithPreTag) {
-      printer->Print(" * 
\n"); - } - } -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static void GrpcWriteDocComment(Printer* printer, const string& comments) { - printer->Print("/**\n"); - std::vector lines = GrpcGetDocLines(comments); - GrpcWriteDocCommentBody(printer, lines, false); - printer->Print(" */\n"); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static void GrpcWriteServiceDocComment(Printer* printer, - const ServiceDescriptor* service) { - // Deviating from protobuf to avoid extraneous docs - // (see https://github.com/google/protobuf/issues/1406); - printer->Print("/**\n"); - std::vector lines = GrpcGetDocLinesForDescriptor(service); - GrpcWriteDocCommentBody(printer, lines, true); - printer->Print(" */\n"); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -void GrpcWriteMethodDocComment(Printer* printer, - const MethodDescriptor* method) { - // Deviating from protobuf to avoid extraneous docs - // (see https://github.com/google/protobuf/issues/1406); - printer->Print("/**\n"); - std::vector lines = GrpcGetDocLinesForDescriptor(method); - GrpcWriteDocCommentBody(printer, lines, true); - printer->Print(" */\n"); -} - -enum StubType { - ASYNC_INTERFACE = 0, - BLOCKING_CLIENT_INTERFACE = 1, - FUTURE_CLIENT_INTERFACE = 2, - BLOCKING_SERVER_INTERFACE = 3, - ASYNC_CLIENT_IMPL = 4, - BLOCKING_CLIENT_IMPL = 5, - FUTURE_CLIENT_IMPL = 6, - ABSTRACT_CLASS = 7, -}; - -enum CallType { - ASYNC_CALL = 0, - BLOCKING_CALL = 1, - FUTURE_CALL = 2 -}; - -static void PrintMarshallerStaticBlock(const ServiceDescriptor* service, - std::map* vars, - Printer* p) { - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = google::protobuf::compiler::java::ClassName(method->input_type()); - (*vars)["output_type"] = google::protobuf::compiler::java::ClassName(method->output_type()); - p->Print( - *vars, - "private static final AtomicBoolean registered = new AtomicBoolean();\n\n"); - - p->Print( - *vars, - "private static Class init() {\n" - " Class clazz = null;\n" - " try {\n" - " clazz = Class.forName(DemoServiceDubbo.class.getName());\n" - " if (registered.compareAndSet(false, true)) {\n" - " $ProtobufUtils$.marshaller(\n" - " $input_type$.getDefaultInstance());\n" - " $ProtobufUtils$.marshaller(\n" - " $output_type$.getDefaultInstance());\n" - " }\n" - " } catch (ClassNotFoundException e) {\n" - " // ignore \n" - " }\n" - " return clazz;\n" - "}\n\n"); - } -} - -static void PrintDubboInterface( - const ServiceDescriptor* service, - std::map* vars, - Printer* p, bool generate_nano) { - const string service_name = service->name(); - (*vars)["service_name"] = service_name; - (*vars)["dubbo_interface"] = "I" + service_name; - - p->Print( - "/**\n " - "* Code generated for Dubbo\n " - "*/\n" - ); - p->Print( - *vars, - "public interface $dubbo_interface$ {\n\n" - " static Class clazz = init();\n\n"); - - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["lower_method_name"] = LowerMethodName(method); - - // Simple RPC - p->Print( - *vars, - " $output_type$ $lower_method_name$($input_type$ request);\n\n"); - // Simple Future RPC - p->Print( - *vars, - " $CompletableFuture$<$output_type$> $lower_method_name$Async(\n $input_type$ request);\n\n"); -// p->Print( -// *vars, -// "default $CompletableFuture$<$output_type$> $lower_method_name$Async(\n" -// " $input_type$ request) {\n return CompletableFuture.completedFuture($lower_method_name$(request));\n}\n\n"); - p->Outdent(); - } - - p->Outdent(); - p->Print(" }\n\n"); - -} - -static void PrintService(const ServiceDescriptor* service, - std::map* vars, - Printer* p, - bool disable_version) { - (*vars)["service_name"] = service->name(); - (*vars)["file_name"] = service->file()->name(); - (*vars)["service_class_name"] = ServiceClassName(service); - (*vars)["grpc_version"] = ""; - #ifdef GRPC_VERSION - if (!disable_version) { - (*vars)["grpc_version"] = " (version " XSTR(GRPC_VERSION) ")"; - } - #endif - // TODO(nmittler): Replace with WriteServiceDocComment once included by protobuf distro. - GrpcWriteServiceDocComment(p, service); - p->Print( - *vars, - "@$Generated$(\n" - " value = \"by gRPC proto compiler$grpc_version$\",\n" - " comments = \"Source: $file_name$\")\n"); - - if (service->options().deprecated()) { - p->Print(*vars, "@$Deprecated$\n"); - } - - p->Print( - *vars, - "public final class $service_class_name$ {\n\n"); - p->Indent(); - - PrintMarshallerStaticBlock(service, vars, p); - - p->Print( - *vars, - "private $service_class_name$() {}\n\n"); - - p->Print( - *vars, - "public static final String SERVICE_NAME = " - "\"$Package$$service_name$\";\n\n"); - - PrintDubboInterface(service, vars, p, false); - - p->Outdent(); - p->Print("}\n"); -} - -void PrintImports(Printer* p) { - p->Print( - "import " - "java.util.concurrent.CompletableFuture;\n"); - p->Print( - "import " - "java.util.concurrent.atomic.AtomicBoolean;\n"); -} - -void GenerateService(const ServiceDescriptor* service, - google::protobuf::io::ZeroCopyOutputStream* out, - ProtoFlavor flavor, - bool disable_version) { - // All non-generated classes must be referred by fully qualified names to - // avoid collision with generated classes. - std::map vars; - vars["String"] = "java.lang.String"; - vars["Deprecated"] = "java.lang.Deprecated"; - vars["Override"] = "java.lang.Override"; - vars["Iterator"] = "java.util.Iterator"; - vars["Generated"] = "javax.annotation.Generated"; - vars["CompletableFuture"] = - "java.util.concurrent.CompletableFuture"; - vars["AtomicBoolean"] = - "java.util.concurrent.atomic.AtomicBoolean"; - vars["ProtobufUtils"] = - "org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils"; - - Printer printer(out, '$'); - string package_name = ServiceJavaPackage(service->file(),false); - if (!package_name.empty()) { - printer.Print( - "package $package_name$;\n\n", - "package_name", package_name); - } - - PrintImports(&printer); - - // Package string is used to fully qualify method names. - vars["Package"] = service->file()->package(); - if (!vars["Package"].empty()) { - vars["Package"].append("."); - } - PrintService(service, &vars, &printer, false); -} - -string ServiceJavaPackage(const FileDescriptor* file, bool nano) { - string result = google::protobuf::compiler::java::ClassName(file); - size_t last_dot_pos = result.find_last_of('.'); - if (last_dot_pos != string::npos) { - result.resize(last_dot_pos); - } else { - result = ""; - } - if (nano) { - if (!result.empty()) { - result += "."; - } - result += "nano"; - } - return result; -} - -string ServiceClassName(const google::protobuf::ServiceDescriptor* service) { - return service->name() + "Dubbo"; -} - -} // namespace java_dubbo_generator diff --git a/compiler/src/java_plugin/cpp/java_generator.cpp b/compiler/src/java_plugin/cpp/java_generator.cpp deleted file mode 100644 index 98093ca968..0000000000 --- a/compiler/src/java_plugin/cpp/java_generator.cpp +++ /dev/null @@ -1,1558 +0,0 @@ -#include "java_generator.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Stringify helpers used solely to cast GRPC_VERSION -#ifndef STR -#define STR(s) #s -#endif - -#ifndef XSTR -#define XSTR(s) STR(s) -#endif - -#ifndef FALLTHROUGH_INTENDED -#define FALLTHROUGH_INTENDED -#endif - -namespace java_grpc_generator { - -using google::protobuf::FileDescriptor; -using google::protobuf::ServiceDescriptor; -using google::protobuf::MethodDescriptor; -using google::protobuf::Descriptor; -using google::protobuf::io::Printer; -using google::protobuf::SourceLocation; -using std::to_string; - -// java keywords from: https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9 -static std::set java_keywords = { - "abstract", - "assert", - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", - "continue", - "default", - "do", - "double", - "else", - "enum", - "extends", - "final", - "finally", - "float", - "for", - "goto", - "if", - "implements", - "import", - "instanceof", - "int", - "interface", - "long", - "native", - "new", - "package", - "private", - "protected", - "public", - "return", - "short", - "static", - "strictfp", - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "try", - "void", - "volatile", - "while", - // additional ones added by us - "true", - "false", -}; - -// Adjust a method name prefix identifier to follow the JavaBean spec: -// - decapitalize the first letter -// - remove embedded underscores & capitalize the following letter -// Finally, if the result is a reserved java keyword, append an underscore. -static string MixedLower(const string& word) { - string w; - w += tolower(word[0]); - bool after_underscore = false; - for (size_t i = 1; i < word.length(); ++i) { - if (word[i] == '_') { - after_underscore = true; - } else { - w += after_underscore ? toupper(word[i]) : word[i]; - after_underscore = false; - } - } - if (java_keywords.find(w) != java_keywords.end()) { - return w + "_"; - } - return w; -} - -// Converts to the identifier to the ALL_UPPER_CASE format. -// - An underscore is inserted where a lower case letter is followed by an -// upper case letter. -// - All letters are converted to upper case -static string ToAllUpperCase(const string& word) { - string w; - for (size_t i = 0; i < word.length(); ++i) { - w += toupper(word[i]); - if ((i < word.length() - 1) && islower(word[i]) && isupper(word[i + 1])) { - w += '_'; - } - } - return w; -} - -static inline string LowerMethodName(const MethodDescriptor* method) { - return MixedLower(method->name()); -} - -static inline string MethodPropertiesFieldName(const MethodDescriptor* method) { - return "METHOD_" + ToAllUpperCase(method->name()); -} - -static inline string MethodPropertiesGetterName(const MethodDescriptor* method) { - return MixedLower("get_" + method->name() + "_method"); -} - -static inline string MethodIdFieldName(const MethodDescriptor* method) { - return "METHODID_" + ToAllUpperCase(method->name()); -} - -static inline bool ShouldGenerateAsLite(const Descriptor* desc) { - return false; -} - -static inline string MessageFullJavaName(bool nano, const Descriptor* desc) { - string name = google::protobuf::compiler::java::ClassName(desc); - if (nano && !ShouldGenerateAsLite(desc)) { - // XXX: Add "nano" to the original package - // (https://github.com/grpc/grpc-java/issues/900) - if (isupper(name[0])) { - // No java package specified. - return "nano." + name; - } - for (size_t i = 0; i < name.size(); ++i) { - if ((name[i] == '.') && (i < (name.size() - 1)) && isupper(name[i + 1])) { - return name.substr(0, i + 1) + "nano." + name.substr(i + 1); - } - } - } - return name; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -template -static void GrpcSplitStringToIteratorUsing(const string& full, - const char* delim, - ITR& result) { - // Optimize the common case where delim is a single character. - if (delim[0] != '\0' && delim[1] == '\0') { - char c = delim[0]; - const char* p = full.data(); - const char* end = p + full.size(); - while (p != end) { - if (*p == c) { - ++p; - } else { - const char* start = p; - while (++p != end && *p != c); - *result++ = string(start, p - start); - } - } - return; - } - - string::size_type begin_index, end_index; - begin_index = full.find_first_not_of(delim); - while (begin_index != string::npos) { - end_index = full.find_first_of(delim, begin_index); - if (end_index == string::npos) { - *result++ = full.substr(begin_index); - return; - } - *result++ = full.substr(begin_index, (end_index - begin_index)); - begin_index = full.find_first_not_of(delim, end_index); - } -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static void GrpcSplitStringUsing(const string& full, - const char* delim, - std::vector* result) { - std::back_insert_iterator< std::vector > it(*result); - GrpcSplitStringToIteratorUsing(full, delim, it); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static std::vector GrpcSplit(const string& full, const char* delim) { - std::vector result; - GrpcSplitStringUsing(full, delim, &result); - return result; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static string GrpcEscapeJavadoc(const string& input) { - string result; - result.reserve(input.size() * 2); - - char prev = '*'; - - for (string::size_type i = 0; i < input.size(); i++) { - char c = input[i]; - switch (c) { - case '*': - // Avoid "/*". - if (prev == '/') { - result.append("*"); - } else { - result.push_back(c); - } - break; - case '/': - // Avoid "*/". - if (prev == '*') { - result.append("/"); - } else { - result.push_back(c); - } - break; - case '@': - // '@' starts javadoc tags including the @deprecated tag, which will - // cause a compile-time error if inserted before a declaration that - // does not have a corresponding @Deprecated annotation. - result.append("@"); - break; - case '<': - // Avoid interpretation as HTML. - result.append("<"); - break; - case '>': - // Avoid interpretation as HTML. - result.append(">"); - break; - case '&': - // Avoid interpretation as HTML. - result.append("&"); - break; - case '\\': - // Java interprets Unicode escape sequences anywhere! - result.append("\"); - break; - default: - result.push_back(c); - break; - } - - prev = c; - } - - return result; -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -template -static string GrpcGetCommentsForDescriptor(const DescriptorType* descriptor) { - SourceLocation location; - if (descriptor->GetSourceLocation(&location)) { - return location.leading_comments.empty() ? - location.trailing_comments : location.leading_comments; - } - return string(); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static std::vector GrpcGetDocLines(const string& comments) { - if (!comments.empty()) { - // TODO(kenton): Ideally we should parse the comment text as Markdown and - // write it back as HTML, but this requires a Markdown parser. For now - // we just use
 to get fixed-width text formatting.
-
-    // If the comment itself contains block comment start or end markers,
-    // HTML-escape them so that they don't accidentally close the doc comment.
-    string escapedComments = GrpcEscapeJavadoc(comments);
-
-    std::vector lines = GrpcSplit(escapedComments, "\n");
-    while (!lines.empty() && lines.back().empty()) {
-      lines.pop_back();
-    }
-    return lines;
-  }
-  return std::vector();
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-template 
-static std::vector GrpcGetDocLinesForDescriptor(const DescriptorType* descriptor) {
-  return GrpcGetDocLines(GrpcGetCommentsForDescriptor(descriptor));
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-static void GrpcWriteDocCommentBody(Printer* printer,
-                                    const std::vector& lines,
-                                    bool surroundWithPreTag) {
-  if (!lines.empty()) {
-    if (surroundWithPreTag) {
-      printer->Print(" * 
\n");
-    }
-
-    for (size_t i = 0; i < lines.size(); i++) {
-      // Most lines should start with a space.  Watch out for lines that start
-      // with a /, since putting that right after the leading asterisk will
-      // close the comment.
-      if (!lines[i].empty() && lines[i][0] == '/') {
-        printer->Print(" * $line$\n", "line", lines[i]);
-      } else {
-        printer->Print(" *$line$\n", "line", lines[i]);
-      }
-    }
-
-    if (surroundWithPreTag) {
-      printer->Print(" * 
\n"); - } - } -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static void GrpcWriteDocComment(Printer* printer, const string& comments) { - printer->Print("/**\n"); - std::vector lines = GrpcGetDocLines(comments); - GrpcWriteDocCommentBody(printer, lines, false); - printer->Print(" */\n"); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -static void GrpcWriteServiceDocComment(Printer* printer, - const ServiceDescriptor* service) { - // Deviating from protobuf to avoid extraneous docs - // (see https://github.com/google/protobuf/issues/1406); - printer->Print("/**\n"); - std::vector lines = GrpcGetDocLinesForDescriptor(service); - GrpcWriteDocCommentBody(printer, lines, true); - printer->Print(" */\n"); -} - -// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution. -void GrpcWriteMethodDocComment(Printer* printer, - const MethodDescriptor* method) { - // Deviating from protobuf to avoid extraneous docs - // (see https://github.com/google/protobuf/issues/1406); - printer->Print("/**\n"); - std::vector lines = GrpcGetDocLinesForDescriptor(method); - GrpcWriteDocCommentBody(printer, lines, true); - printer->Print(" */\n"); -} - -static void PrintMethodFields( - const ServiceDescriptor* service, std::map* vars, - Printer* p, ProtoFlavor flavor) { - p->Print("// Static method descriptors that strictly reflect the proto.\n"); - (*vars)["service_name"] = service->name(); - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["arg_in_id"] = to_string(2 * i); - (*vars)["arg_out_id"] = to_string(2 * i + 1); - (*vars)["method_name"] = method->name(); - (*vars)["input_type"] = MessageFullJavaName(flavor == ProtoFlavor::NANO, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(flavor == ProtoFlavor::NANO, - method->output_type()); - (*vars)["method_field_name"] = MethodPropertiesFieldName(method); - (*vars)["method_new_field_name"] = MethodPropertiesGetterName(method); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - bool client_streaming = method->client_streaming(); - bool server_streaming = method->server_streaming(); - if (client_streaming) { - if (server_streaming) { - (*vars)["method_type"] = "BIDI_STREAMING"; - } else { - (*vars)["method_type"] = "CLIENT_STREAMING"; - } - } else { - if (server_streaming) { - (*vars)["method_type"] = "SERVER_STREAMING"; - } else { - (*vars)["method_type"] = "UNARY"; - } - } - - if (flavor == ProtoFlavor::NANO) { - // TODO(zsurocking): we're creating two NanoFactories for each method right now. - // We could instead create static NanoFactories and reuse them if some methods - // share the same request or response messages. - if (!ShouldGenerateAsLite(method->input_type())) { - p->Print( - *vars, - "private static final int ARG_IN_$method_field_name$ = $arg_in_id$;\n"); - } - if (!ShouldGenerateAsLite(method->output_type())) { - p->Print( - *vars, - "private static final int ARG_OUT_$method_field_name$ = $arg_out_id$;\n"); - } - p->Print( - *vars, - "private static volatile $MethodDescriptor$<$input_type$,\n" - " $output_type$> $method_new_field_name$;\n" - "\n" - "public static $MethodDescriptor$<$input_type$,\n" - " $output_type$> $method_method_name$() {\n" - " $MethodDescriptor$<$input_type$, $output_type$> $method_new_field_name$;\n" - " if (($method_new_field_name$ = $service_class_name$.$method_new_field_name$) == null) {\n" - " synchronized ($service_class_name$.class) {\n" - " if (($method_new_field_name$ = $service_class_name$.$method_new_field_name$) == null) {\n" - " $service_class_name$.$method_new_field_name$ = $method_new_field_name$ = \n" - " $MethodDescriptor$.<$input_type$, $output_type$>newBuilder()\n" - " .setType($MethodType$.$method_type$)\n" - " .setFullMethodName(generateFullMethodName(\n" - " \"$Package$$service_name$\", \"$method_name$\"))\n" - " .setSampledToLocalTracing(true)\n"); - - (*vars)["ProtoLiteUtils"] = "io.grpc.protobuf.lite.ProtoLiteUtils"; - - if (ShouldGenerateAsLite(method->input_type())) { - p->Print( - *vars, - " .setRequestMarshaller($ProtoLiteUtils$.marshaller(\n" - " $input_type$.getDefaultInstance()))\n"); - } else { - p->Print( - *vars, - " .setRequestMarshaller($NanoUtils$.<$input_type$>marshaller(\n" - " new NanoFactory<$input_type$>(ARG_IN_$method_field_name$)))\n"); - } - if (ShouldGenerateAsLite(method->output_type())) { - p->Print( - *vars, - " .setResponseMarshaller($ProtoLiteUtils$.marshaller(\n" - " $output_type$.getDefaultInstance()))\n"); - } else { - p->Print( - *vars, - " .setResponseMarshaller($NanoUtils$.<$output_type$>marshaller(\n" - " new NanoFactory<$output_type$>(ARG_OUT_$method_field_name$)))\n"); - } - p->Print( - *vars, - " .build();\n" - " }\n" - " }\n" - " }\n" - " return $method_new_field_name$;\n" - "}\n" - "\n"); - } else { - if (flavor == ProtoFlavor::LITE) { - (*vars)["ProtoUtils"] = "io.grpc.protobuf.lite.ProtoLiteUtils"; - } else { - (*vars)["ProtoUtils"] = "io.grpc.protobuf.ProtoUtils"; - } - p->Print( - *vars, - "private static volatile $MethodDescriptor$<$input_type$,\n" - " $output_type$> $method_new_field_name$;\n" - "\n" - "@$RpcMethod$(\n" - " fullMethodName = SERVICE_NAME + '/' + \"$method_name$\",\n" - " requestType = $input_type$.class,\n" - " responseType = $output_type$.class,\n" - " methodType = $MethodType$.$method_type$)\n" - "public static $MethodDescriptor$<$input_type$,\n" - " $output_type$> $method_method_name$() {\n" - " $MethodDescriptor$<$input_type$, $output_type$> $method_new_field_name$;\n" - " if (($method_new_field_name$ = $service_class_name$.$method_new_field_name$) == null) {\n" - " synchronized ($service_class_name$.class) {\n" - " if (($method_new_field_name$ = $service_class_name$.$method_new_field_name$) == null) {\n" - " $service_class_name$.$method_new_field_name$ = $method_new_field_name$ = \n" - " $MethodDescriptor$.<$input_type$, $output_type$>newBuilder()\n" - " .setType($MethodType$.$method_type$)\n" - " .setFullMethodName(generateFullMethodName(\n" - " \"$Package$$service_name$\", \"$method_name$\"))\n" - " .setSampledToLocalTracing(true)\n" - " .setRequestMarshaller($ProtoUtils$.marshaller(\n" - " $input_type$.getDefaultInstance()))\n" - " .setResponseMarshaller($ProtoUtils$.marshaller(\n" - " $output_type$.getDefaultInstance()))\n"); - - (*vars)["proto_method_descriptor_supplier"] = service->name() + "MethodDescriptorSupplier"; - if (flavor == ProtoFlavor::NORMAL) { - p->Print( - *vars, - " .setSchemaDescriptor(new $proto_method_descriptor_supplier$(\"$method_name$\"))\n"); - } - - p->Print( - *vars, - " .build();\n"); - p->Print(*vars, - " }\n" - " }\n" - " }\n" - " return $method_new_field_name$;\n" - "}\n" - "\n"); - } - } - - if (flavor == ProtoFlavor::NANO) { - p->Print( - *vars, - "private static final class NanoFactory\n" - " implements io.grpc.protobuf.nano.MessageNanoFactory {\n" - " private final int id;\n" - "\n" - " NanoFactory(int id) {\n" - " this.id = id;\n" - " }\n" - "\n" - " @$Override$\n" - " public T newInstance() {\n" - " Object o;\n" - " switch (id) {\n"); - bool generate_nano = true; - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["method_field_name"] = MethodPropertiesFieldName(method); - if (!ShouldGenerateAsLite(method->input_type())) { - p->Print( - *vars, - " case ARG_IN_$method_field_name$:\n" - " o = new $input_type$();\n" - " break;\n"); - } - if (!ShouldGenerateAsLite(method->output_type())) { - p->Print( - *vars, - " case ARG_OUT_$method_field_name$:\n" - " o = new $output_type$();\n" - " break;\n"); - } - } - p->Print( - " default:\n" - " throw new AssertionError();\n" - " }\n" - " @java.lang.SuppressWarnings(\"unchecked\")\n" - " T t = (T) o;\n" - " return t;\n" - " }\n" - "}\n" - "\n"); - } -} - -enum StubType { - ASYNC_INTERFACE = 0, - BLOCKING_CLIENT_INTERFACE = 1, - FUTURE_CLIENT_INTERFACE = 2, - BLOCKING_SERVER_INTERFACE = 3, - ASYNC_CLIENT_IMPL = 4, - BLOCKING_CLIENT_IMPL = 5, - FUTURE_CLIENT_IMPL = 6, - ABSTRACT_CLASS = 7, -}; - -enum CallType { - ASYNC_CALL = 0, - BLOCKING_CALL = 1, - FUTURE_CALL = 2 -}; - -static void PrintBindServiceMethodBody(const ServiceDescriptor* service, - std::map* vars, - Printer* p, - bool generate_nano); - -// Prints a client interface or implementation class, or a server interface. -static void PrintStub( - const ServiceDescriptor* service, - std::map* vars, - Printer* p, StubType type, bool generate_nano) { - const string service_name = service->name(); - (*vars)["service_name"] = service_name; - string stub_name = service_name; - string client_name = service_name; - CallType call_type; - bool interface = false; - switch (type) { - case ASYNC_CLIENT_IMPL: - call_type = ASYNC_CALL; - stub_name += "Stub"; - break; - case BLOCKING_CLIENT_INTERFACE: - interface = true; - FALLTHROUGH_INTENDED; - case BLOCKING_CLIENT_IMPL: - call_type = BLOCKING_CALL; - stub_name += "BlockingStub"; - client_name += "BlockingClient"; - break; - case FUTURE_CLIENT_INTERFACE: - interface = true; - FALLTHROUGH_INTENDED; - case FUTURE_CLIENT_IMPL: - call_type = FUTURE_CALL; - stub_name += "FutureStub"; - client_name += "FutureClient"; - break; - case ASYNC_INTERFACE: - call_type = ASYNC_CALL; - interface = true; - break; - default: - GRPC_CODEGEN_FAIL << "Cannot determine class name for StubType: " << type; - } - (*vars)["stub_name"] = stub_name; - (*vars)["client_name"] = client_name; - - // Class head - if (!interface) { - GrpcWriteServiceDocComment(p, service); - } - - if (service->options().deprecated()) { - p->Print(*vars, "@$Deprecated$\n"); - } - - - p->Print( - *vars, - "public static final class $stub_name$ extends $AbstractStub$<$stub_name$> {\n"); - - p->Indent(); - - // Constructor and build() method - if (!interface) { - p->Print( - *vars, - "private $stub_name$($Channel$ channel) {\n"); - p->Indent(); - p->Print("super(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - p->Print( - *vars, - "private $stub_name$($Channel$ channel,\n" - " $CallOptions$ callOptions) {\n"); - p->Indent(); - p->Print("super(channel, callOptions);\n"); - p->Outdent(); - p->Print("}\n\n"); - p->Print( - *vars, - "@$Override$\n" - "protected $stub_name$ build($Channel$ channel,\n" - " $CallOptions$ callOptions) {\n"); - p->Indent(); - p->Print( - *vars, - "return new $stub_name$(channel, callOptions);\n"); - p->Outdent(); - p->Print("}\n"); - } - - // RPC methods - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - bool client_streaming = method->client_streaming(); - bool server_streaming = method->server_streaming(); - - if (call_type == BLOCKING_CALL && client_streaming) { - // Blocking client interface with client streaming is not available - continue; - } - - if (call_type == FUTURE_CALL && (client_streaming || server_streaming)) { - // Future interface doesn't support streaming. - continue; - } - - // Method signature - p->Print("\n"); - // TODO(nmittler): Replace with WriteMethodDocComment once included by the protobuf distro. - if (!interface) { - GrpcWriteMethodDocComment(p, method); - } - - if (method->options().deprecated()) { - p->Print(*vars, "@$Deprecated$\n"); - } - - p->Print("public "); - switch (call_type) { - case BLOCKING_CALL: - GRPC_CODEGEN_CHECK(!client_streaming) - << "Blocking client interface with client streaming is unavailable"; - if (server_streaming) { - // Server streaming - p->Print( - *vars, - "$Iterator$<$output_type$> $lower_method_name$(\n" - " $input_type$ request)"); - } else { - // Simple RPC - p->Print( - *vars, - "$output_type$ $lower_method_name$($input_type$ request)"); - } - break; - case ASYNC_CALL: - if (client_streaming) { - // Bidirectional streaming or client streaming - p->Print( - *vars, - "$StreamObserver$<$input_type$> $lower_method_name$(\n" - " $StreamObserver$<$output_type$> responseObserver)"); - } else { - // Server streaming or simple RPC - p->Print( - *vars, - "void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver)"); - } - break; - case FUTURE_CALL: - GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming) - << "Future interface doesn't support streaming. " - << "client_streaming=" << client_streaming << ", " - << "server_streaming=" << server_streaming; - p->Print( - *vars, - "$ListenableFuture$<$output_type$> $lower_method_name$(\n" - " $input_type$ request)"); - break; - } - - if (interface) { - p->Print(";\n"); - continue; - } - // Method body. - p->Print(" {\n"); - p->Indent(); - if (!interface) { - switch (call_type) { - case BLOCKING_CALL: - GRPC_CODEGEN_CHECK(!client_streaming) - << "Blocking client streaming interface is not available"; - if (server_streaming) { - (*vars)["calls_method"] = "blockingServerStreamingCall"; - (*vars)["params"] = "request"; - } else { - (*vars)["calls_method"] = "blockingUnaryCall"; - (*vars)["params"] = "request"; - } - p->Print( - *vars, - "return $calls_method$(\n" - " getChannel(), $method_method_name$(), getCallOptions(), $params$);\n"); - break; - case ASYNC_CALL: - if (server_streaming) { - if (client_streaming) { - (*vars)["calls_method"] = "asyncBidiStreamingCall"; - (*vars)["params"] = "responseObserver"; - } else { - (*vars)["calls_method"] = "asyncServerStreamingCall"; - (*vars)["params"] = "request, responseObserver"; - } - } else { - if (client_streaming) { - (*vars)["calls_method"] = "asyncClientStreamingCall"; - (*vars)["params"] = "responseObserver"; - } else { - (*vars)["calls_method"] = "asyncUnaryCall"; - (*vars)["params"] = "request, responseObserver"; - } - } - (*vars)["last_line_prefix"] = client_streaming ? "return " : ""; - p->Print( - *vars, - "$last_line_prefix$$calls_method$(\n" - " getChannel().newCall($method_method_name$(), getCallOptions()), $params$);\n"); - break; - case FUTURE_CALL: - GRPC_CODEGEN_CHECK(!client_streaming && !server_streaming) - << "Future interface doesn't support streaming. " - << "client_streaming=" << client_streaming << ", " - << "server_streaming=" << server_streaming; - (*vars)["calls_method"] = "futureUnaryCall"; - p->Print( - *vars, - "return $calls_method$(\n" - " getChannel().newCall($method_method_name$(), getCallOptions()), request);\n"); - break; - } - } - p->Outdent(); - p->Print("}\n"); - } - - p->Outdent(); - p->Print("}\n\n"); -} - -static void PrintImplBase( - const ServiceDescriptor* service, - std::map* vars, - Printer* p, bool generate_nano) { - const string service_name = service->name(); - (*vars)["service_name"] = service_name; - (*vars)["abstract_name"] = service_name + "ImplBase"; - string stub_name = service_name; - string client_name = service_name; - CallType call_type; - - (*vars)["dubbo_interface"] = "I" + service_name; - - p->Print( - *vars, - "public static abstract class $abstract_name$ implements $BindableService$, $dubbo_interface$ {\n\n"); - - p->Print(*vars, "private $dubbo_interface$ proxiedImpl;\n\n"); - p->Print(*vars, "public final void setProxiedImpl($dubbo_interface$ proxiedImpl) {\n"); - p->Print(*vars, " this.proxiedImpl = proxiedImpl;\n"); - p->Print(*vars, "}\n\n"); - - // RPC methods - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - bool client_streaming = method->client_streaming(); - bool server_streaming = method->server_streaming(); - - if (client_streaming) { - p->Print( - *vars, - "public $StreamObserver$<$input_type$> $lower_method_name$(\n" - " $StreamObserver$<$output_type$> responseObserver) {\n" - " return asyncUnimplementedStreamingCall($method_method_name$(), responseObserver);\n" - "}\n\n"); - - } else if (server_streaming) { - p->Print( - *vars, - "@$Override$\n" - "public final $Iterator$<$output_type$> $lower_method_name$(\n" - " $input_type$ request) {\n$default_method_body$\n}\n\n"); - p->Print( - *vars, - "public void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver) {\n" - " asyncUnimplementedUnaryCall($method_method_name$(), responseObserver);\n\n" - "}\n"); - } else { - // Simple RPC - p->Print( - *vars, - "@$Override$\n" - "public final $output_type$ $lower_method_name$" - "($input_type$ request) {\n$default_method_body$\n}\n\n"); - // Simple Future RPC - p->Print( - *vars, - "@$Override$\n" - "public final $ListenableFuture$<$output_type$> $lower_method_name$Async(\n" - " $input_type$ request) {\n$default_method_body$\n}\n\n"); - // Simple Stream RPC - p->Print( - *vars, - "public void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver) {\n" - " asyncUnimplementedUnaryCall($method_method_name$(), responseObserver);\n" - "}\n\n"); - } - p->Outdent(); - } - - p->Print("\n"); - p->Print( - *vars, - "@$Override$\n public final $ServerServiceDefinition$ bindService() {\n"); - (*vars)["instance"] = "proxiedImpl"; - PrintBindServiceMethodBody(service, vars, p, generate_nano); - p->Print("}\n"); - p->Outdent(); - p->Print("}\n\n"); -} - -static void PrintDubboInterface( - const ServiceDescriptor* service, - std::map* vars, - Printer* p, bool interface, bool generate_nano) { - const string service_name = service->name(); - (*vars)["service_name"] = service_name; - (*vars)["dubbo_interface"] = "I" + service_name; - if (interface) { - p->Print( - "/**\n " - "* Code generated for Dubbo\n " - "*/\n" - ); - p->Print( - *vars, - "public interface $dubbo_interface$ {\n\n"); - - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - bool client_streaming = method->client_streaming(); - bool server_streaming = method->server_streaming(); - - if (client_streaming) { - p->Print( - *vars, - "public $StreamObserver$<$input_type$> $lower_method_name$(\n" - " $StreamObserver$<$output_type$> responseObserver);\n\n"); - - } else if (server_streaming) { - p->Print( - *vars, - "default public $Iterator$<$output_type$> $lower_method_name$(\n" - " $input_type$ request) {\n$default_method_body$\n}\n\n"); - p->Print( - *vars, - "public void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver);\n\n"); - } else { - // Simple RPC - p->Print( - *vars, - "default public $output_type$ $lower_method_name$" - "($input_type$ request) {\n$default_method_body$\n}\n\n"); - // Simple Future RPC - p->Print( - *vars, - "default public $ListenableFuture$<$output_type$> $lower_method_name$Async(\n" - " $input_type$ request) {\n$default_method_body$\n}\n\n"); - // Simple Stream RPC - p->Print( - *vars, - "public void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver);\n\n"); - } - p->Outdent(); - } - - p->Outdent(); - p->Print("}\n\n"); - } - // Dubbo Stub - else { - (*vars)["dubbo_stub"] = "Dubbo" + service_name + "Stub"; - p->Print(*vars, "public static class $dubbo_stub$ implements $dubbo_interface$ {\n\n"); - - // Properties - p->Print("private "); p->Print(service_name.c_str()); p->Print("BlockingStub blockingStub;\n"); - p->Print("private "); p->Print(service_name.c_str()); p->Print("FutureStub futureStub;\n"); - p->Print("private "); p->Print(service_name.c_str()); p->Print("Stub stub;\n\n"); - - // Consustor - p->Print(*vars, "public $dubbo_stub$($Channel$ channel, $CallOptions$ callOptions) {\n" - " blockingStub = $service_class_name$.newBlockingStub(channel).build(channel, callOptions);\n" - " futureStub = $service_class_name$.newFutureStub(channel).build(channel, callOptions);\n" - " stub = $service_class_name$.newStub(channel).build(channel, callOptions);\n" - "}\n\n"); - - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - bool client_streaming = method->client_streaming(); - bool server_streaming = method->server_streaming(); - - if (client_streaming) { - p->Print( - *vars, - "public $StreamObserver$<$input_type$> $lower_method_name$(\n" - " $StreamObserver$<$output_type$> responseObserver) {\n" - " return stub.$lower_method_name$(responseObserver);\n" - "}\n\n"); - - } else if (server_streaming) { - p->Print( - *vars, - "public $Iterator$<$output_type$> $lower_method_name$(\n" - " $input_type$ request) {\n" - " return blockingStub.$lower_method_name$(request);\n" - "}\n\n"); - p->Print( - *vars, - "public void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver) {\n" - " stub.$lower_method_name$(request, responseObserver);\n" - "}\n\n"); - } else { - // Simple RPC - p->Print( - *vars, - "public $output_type$ $lower_method_name$" - "($input_type$ request) {\n" - " return blockingStub.$lower_method_name$(request);\n" - "}\n\n"); - // Simple Future RPC - p->Print( - *vars, - "public $ListenableFuture$<$output_type$> $lower_method_name$Async(\n" - " $input_type$ request) {\n" - " return futureStub.$lower_method_name$(request);\n" - "}\n\n"); - // Simple Stream RPC - p->Print( - *vars, - "public void $lower_method_name$($input_type$ request,\n" - " $StreamObserver$<$output_type$> responseObserver){\n" - " stub.$lower_method_name$(request, responseObserver);\n" - "}\n\n"); - } - p->Outdent(); - } - p->Outdent(); - p->Print("}\n\n"); - - p->Print(*vars, "public static $dubbo_stub$ getDubboStub($Channel$ channel, $CallOptions$ callOptions) {\n\n"); - p->Print(*vars, " return new $dubbo_stub$(channel, callOptions);\n"); - p->Print("}\n\n"); - } - p->Outdent(); -} - -static bool CompareMethodClientStreaming(const MethodDescriptor* method1, - const MethodDescriptor* method2) -{ - return method1->client_streaming() < method2->client_streaming(); -} - -// Place all method invocations into a single class to reduce memory footprint -// on Android. -static void PrintMethodHandlerClass(const ServiceDescriptor* service, - std::map* vars, - Printer* p, - bool generate_nano) { - // Sort method ids based on client_streaming() so switch tables are compact. - std::vector sorted_methods(service->method_count()); - for (int i = 0; i < service->method_count(); ++i) { - sorted_methods[i] = service->method(i); - } - stable_sort(sorted_methods.begin(), sorted_methods.end(), - CompareMethodClientStreaming); - for (size_t i = 0; i < sorted_methods.size(); i++) { - const MethodDescriptor* method = sorted_methods[i]; - (*vars)["method_id"] = to_string(i); - (*vars)["method_id_name"] = MethodIdFieldName(method); - p->Print( - *vars, - "private static final int $method_id_name$ = $method_id$;\n"); - } - p->Print("\n"); - (*vars)["service_name"] = service->name() + "ImplBase"; - (*vars)["dubbo_interface"] = "I" + service->name(); - p->Print( - *vars, - "private static final class MethodHandlers implements\n" - " io.grpc.stub.ServerCalls.UnaryMethod,\n" - " io.grpc.stub.ServerCalls.ServerStreamingMethod,\n" - " io.grpc.stub.ServerCalls.ClientStreamingMethod,\n" - " io.grpc.stub.ServerCalls.BidiStreamingMethod {\n" - " private final $dubbo_interface$ serviceImpl;\n" - " private final int methodId;\n" - "\n" - " MethodHandlers($dubbo_interface$ serviceImpl, int methodId) {\n" - " this.serviceImpl = serviceImpl;\n" - " this.methodId = methodId;\n" - " }\n\n"); - p->Indent(); - p->Print( - *vars, - "@$Override$\n" - "@java.lang.SuppressWarnings(\"unchecked\")\n" - "public void invoke(Req request, $StreamObserver$ responseObserver) {\n" - " switch (methodId) {\n"); - p->Indent(); - p->Indent(); - - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - if (method->client_streaming()) { - continue; - } - (*vars)["method_id_name"] = MethodIdFieldName(method); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - p->Print( - *vars, - "case $method_id_name$:\n" - " serviceImpl.$lower_method_name$(($input_type$) request,\n" - " ($StreamObserver$<$output_type$>) responseObserver);\n" - " break;\n"); - } - p->Print("default:\n" - " throw new AssertionError();\n"); - - p->Outdent(); - p->Outdent(); - p->Print(" }\n" - "}\n\n"); - - p->Print( - *vars, - "@$Override$\n" - "@java.lang.SuppressWarnings(\"unchecked\")\n" - "public $StreamObserver$ invoke(\n" - " $StreamObserver$ responseObserver) {\n" - " switch (methodId) {\n"); - p->Indent(); - p->Indent(); - - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - if (!method->client_streaming()) { - continue; - } - (*vars)["method_id_name"] = MethodIdFieldName(method); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - p->Print( - *vars, - "case $method_id_name$:\n" - " return ($StreamObserver$) serviceImpl.$lower_method_name$(\n" - " ($StreamObserver$<$output_type$>) responseObserver);\n"); - } - p->Print("default:\n" - " throw new AssertionError();\n"); - - p->Outdent(); - p->Outdent(); - p->Print(" }\n" - "}\n"); - - - p->Outdent(); - p->Print("}\n\n"); -} - -static void PrintGetServiceDescriptorMethod(const ServiceDescriptor* service, - std::map* vars, - Printer* p, - ProtoFlavor flavor) { - (*vars)["service_name"] = service->name(); - - - if (flavor == ProtoFlavor::NORMAL) { - (*vars)["proto_base_descriptor_supplier"] = service->name() + "BaseDescriptorSupplier"; - (*vars)["proto_file_descriptor_supplier"] = service->name() + "FileDescriptorSupplier"; - (*vars)["proto_method_descriptor_supplier"] = service->name() + "MethodDescriptorSupplier"; - (*vars)["proto_class_name"] = google::protobuf::compiler::java::ClassName(service->file()); - p->Print( - *vars, - "private static abstract class $proto_base_descriptor_supplier$\n" - " implements $ProtoFileDescriptorSupplier$, $ProtoServiceDescriptorSupplier$ {\n" - " $proto_base_descriptor_supplier$() {}\n" - "\n" - " @$Override$\n" - " public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {\n" - " return $proto_class_name$.getDescriptor();\n" - " }\n" - "\n" - " @$Override$\n" - " public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {\n" - " return getFileDescriptor().findServiceByName(\"$service_name$\");\n" - " }\n" - "}\n" - "\n" - "private static final class $proto_file_descriptor_supplier$\n" - " extends $proto_base_descriptor_supplier$ {\n" - " $proto_file_descriptor_supplier$() {}\n" - "}\n" - "\n" - "private static final class $proto_method_descriptor_supplier$\n" - " extends $proto_base_descriptor_supplier$\n" - " implements $ProtoMethodDescriptorSupplier$ {\n" - " private final String methodName;\n" - "\n" - " $proto_method_descriptor_supplier$(String methodName) {\n" - " this.methodName = methodName;\n" - " }\n" - "\n" - " @$Override$\n" - " public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {\n" - " return getServiceDescriptor().findMethodByName(methodName);\n" - " }\n" - "}\n\n"); - } - - p->Print( - *vars, - "private static volatile $ServiceDescriptor$ serviceDescriptor;\n\n"); - - p->Print( - *vars, - "public static $ServiceDescriptor$ getServiceDescriptor() {\n"); - p->Indent(); - p->Print( - *vars, - "$ServiceDescriptor$ result = serviceDescriptor;\n"); - p->Print("if (result == null) {\n"); - p->Indent(); - p->Print( - *vars, - "synchronized ($service_class_name$.class) {\n"); - p->Indent(); - p->Print("result = serviceDescriptor;\n"); - p->Print("if (result == null) {\n"); - p->Indent(); - - p->Print( - *vars, - "serviceDescriptor = result = $ServiceDescriptor$.newBuilder(SERVICE_NAME)"); - p->Indent(); - p->Indent(); - if (flavor == ProtoFlavor::NORMAL) { - p->Print( - *vars, - "\n.setSchemaDescriptor(new $proto_file_descriptor_supplier$())"); - } - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - p->Print(*vars, "\n.addMethod($method_method_name$())"); - } - p->Print("\n.build();\n"); - p->Outdent(); - p->Outdent(); - - p->Outdent(); - p->Print("}\n"); - p->Outdent(); - p->Print("}\n"); - p->Outdent(); - p->Print("}\n"); - p->Print("return result;\n"); - p->Outdent(); - p->Print("}\n"); - } - -static void PrintBindServiceMethodBody(const ServiceDescriptor* service, - std::map* vars, - Printer* p, - bool generate_nano) { - (*vars)["service_name"] = service->name(); - p->Indent(); - p->Print(*vars, - "return " - "$ServerServiceDefinition$.builder(getServiceDescriptor())\n"); - p->Indent(); - p->Indent(); - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* method = service->method(i); - (*vars)["lower_method_name"] = LowerMethodName(method); - (*vars)["method_method_name"] = MethodPropertiesGetterName(method); - (*vars)["input_type"] = MessageFullJavaName(generate_nano, - method->input_type()); - (*vars)["output_type"] = MessageFullJavaName(generate_nano, - method->output_type()); - (*vars)["method_id_name"] = MethodIdFieldName(method); - bool client_streaming = method->client_streaming(); - bool server_streaming = method->server_streaming(); - if (client_streaming) { - if (server_streaming) { - (*vars)["calls_method"] = "asyncBidiStreamingCall"; - } else { - (*vars)["calls_method"] = "asyncClientStreamingCall"; - } - } else { - if (server_streaming) { - (*vars)["calls_method"] = "asyncServerStreamingCall"; - } else { - (*vars)["calls_method"] = "asyncUnaryCall"; - } - } - p->Print(*vars, ".addMethod(\n"); - p->Indent(); - p->Print( - *vars, - "$method_method_name$(),\n" - "$calls_method$(\n"); - p->Indent(); - p->Print( - *vars, - "new MethodHandlers<\n" - " $input_type$,\n" - " $output_type$>(\n" - " $instance$, $method_id_name$)))\n"); - p->Outdent(); - p->Outdent(); - } - p->Print(".build();\n"); - p->Outdent(); - p->Outdent(); - p->Outdent(); -} - -static void PrintService(const ServiceDescriptor* service, - std::map* vars, - Printer* p, - ProtoFlavor flavor, - bool disable_version) { - (*vars)["service_name"] = service->name(); - (*vars)["file_name"] = service->file()->name(); - (*vars)["service_class_name"] = ServiceClassName(service); - (*vars)["grpc_version"] = ""; - #ifdef GRPC_VERSION - if (!disable_version) { - (*vars)["grpc_version"] = " (version " XSTR(GRPC_VERSION) ")"; - } - #endif - // TODO(nmittler): Replace with WriteServiceDocComment once included by protobuf distro. - GrpcWriteServiceDocComment(p, service); - p->Print( - *vars, - "@$Generated$(\n" - " value = \"by gRPC proto compiler$grpc_version$\",\n" - " comments = \"Source: $file_name$\")\n"); - - if (service->options().deprecated()) { - p->Print(*vars, "@$Deprecated$\n"); - } - - p->Print( - *vars, - "public final class $service_class_name$ {\n\n"); - p->Indent(); - p->Print( - *vars, - "private $service_class_name$() {}\n\n"); - - p->Print( - *vars, - "public static final String SERVICE_NAME = " - "\"$Package$$service_name$\";\n\n"); - - PrintMethodFields(service, vars, p, flavor); - - // TODO(nmittler): Replace with WriteDocComment once included by protobuf distro. - GrpcWriteDocComment(p, " Creates a new async stub that supports all call types for the service"); - p->Print( - *vars, - "public static $service_name$Stub newStub($Channel$ channel) {\n"); - p->Indent(); - p->Print( - *vars, - "return new $service_name$Stub(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - - // TODO(nmittler): Replace with WriteDocComment once included by protobuf distro. - GrpcWriteDocComment(p, " Creates a new blocking-style stub that supports unary and streaming " - "output calls on the service"); - p->Print( - *vars, - "public static $service_name$BlockingStub newBlockingStub(\n" - " $Channel$ channel) {\n"); - p->Indent(); - p->Print( - *vars, - "return new $service_name$BlockingStub(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - - // TODO(nmittler): Replace with WriteDocComment once included by protobuf distro. - GrpcWriteDocComment(p, " Creates a new ListenableFuture-style stub that supports unary calls " - "on the service"); - p->Print( - *vars, - "public static $service_name$FutureStub newFutureStub(\n" - " $Channel$ channel) {\n"); - p->Indent(); - p->Print( - *vars, - "return new $service_name$FutureStub(channel);\n"); - p->Outdent(); - p->Print("}\n\n"); - - bool generate_nano = flavor == ProtoFlavor::NANO; -// PrintStub(service, vars, p, ABSTRACT_CLASS, generate_nano); - PrintStub(service, vars, p, ASYNC_CLIENT_IMPL, generate_nano); - PrintStub(service, vars, p, BLOCKING_CLIENT_IMPL, generate_nano); - PrintStub(service, vars, p, FUTURE_CLIENT_IMPL, generate_nano); - - PrintImplBase(service, vars, p, generate_nano); - PrintDubboInterface(service, vars, p, true, generate_nano); - PrintDubboInterface(service, vars, p, false, generate_nano); - - PrintMethodHandlerClass(service, vars, p, generate_nano); - PrintGetServiceDescriptorMethod(service, vars, p, flavor); - p->Outdent(); - p->Print("}\n"); -} - -void PrintImports(Printer* p, bool generate_nano) { - p->Print( - "import static " - "io.grpc.MethodDescriptor.generateFullMethodName;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.asyncUnaryCall;\n" - "import static " - "io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n" - "import static " - "io.grpc.stub.ClientCalls.blockingUnaryCall;\n" - "import static " - "io.grpc.stub.ClientCalls.futureUnaryCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncUnaryCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n" - "import static " - "io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n\n"); - if (generate_nano) { - p->Print("import java.io.IOException;\n\n"); - } -} - -void GenerateService(const ServiceDescriptor* service, - google::protobuf::io::ZeroCopyOutputStream* out, - ProtoFlavor flavor, - bool disable_version) { - // All non-generated classes must be referred by fully qualified names to - // avoid collision with generated classes. - std::map vars; - vars["String"] = "java.lang.String"; - vars["Deprecated"] = "java.lang.Deprecated"; - vars["Override"] = "java.lang.Override"; - vars["Channel"] = "io.grpc.Channel"; - vars["CallOptions"] = "io.grpc.CallOptions"; - vars["MethodType"] = "io.grpc.MethodDescriptor.MethodType"; - vars["ServerMethodDefinition"] = - "io.grpc.ServerMethodDefinition"; - vars["BindableService"] = "io.grpc.BindableService"; - vars["ServerServiceDefinition"] = - "io.grpc.ServerServiceDefinition"; - vars["ServiceDescriptor"] = - "io.grpc.ServiceDescriptor"; - vars["ProtoFileDescriptorSupplier"] = - "io.grpc.protobuf.ProtoFileDescriptorSupplier"; - vars["ProtoServiceDescriptorSupplier"] = - "io.grpc.protobuf.ProtoServiceDescriptorSupplier"; - vars["ProtoMethodDescriptorSupplier"] = - "io.grpc.protobuf.ProtoMethodDescriptorSupplier"; - vars["AbstractStub"] = "io.grpc.stub.AbstractStub"; - vars["RpcMethod"] = "io.grpc.stub.annotations.RpcMethod"; - vars["MethodDescriptor"] = "io.grpc.MethodDescriptor"; - vars["NanoUtils"] = "io.grpc.protobuf.nano.NanoUtils"; - vars["StreamObserver"] = "io.grpc.stub.StreamObserver"; - vars["Iterator"] = "java.util.Iterator"; - vars["Generated"] = "javax.annotation.Generated"; - vars["ListenableFuture"] = "com.google.common.util.concurrent.ListenableFuture"; - vars["default_method_body"] = " throw new UnsupportedOperationException(\"" - "No need to override this method, extend XxxImplBase and override " - "all methods it allows.\");"; - - Printer printer(out, '$'); - string package_name = ServiceJavaPackage(service->file(), - flavor == ProtoFlavor::NANO); - if (!package_name.empty()) { - printer.Print( - "package $package_name$;\n\n", - "package_name", package_name); - } - - PrintImports(&printer, flavor == ProtoFlavor::NANO); - - // Package string is used to fully qualify method names. - vars["Package"] = service->file()->package(); - if (!vars["Package"].empty()) { - vars["Package"].append("."); - } - PrintService(service, &vars, &printer, flavor, disable_version); -} - -string ServiceJavaPackage(const FileDescriptor* file, bool nano) { - string result = google::protobuf::compiler::java::ClassName(file); - size_t last_dot_pos = result.find_last_of('.'); - if (last_dot_pos != string::npos) { - result.resize(last_dot_pos); - } else { - result = ""; - } - if (nano) { - if (!result.empty()) { - result += "."; - } - result += "nano"; - } - return result; -} - -string ServiceClassName(const google::protobuf::ServiceDescriptor* service) { - return service->name() + "Grpc"; -} - -} // namespace java_grpc_generator diff --git a/compiler/src/java_plugin/cpp/java_generator.h b/compiler/src/java_plugin/cpp/java_generator.h deleted file mode 100644 index 7106c54e37..0000000000 --- a/compiler/src/java_plugin/cpp/java_generator.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef NET_GRPC_COMPILER_JAVA_GENERATOR_H_ -#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_ - -#include // for abort() -#include -#include - -#include -#include - -class LogHelper { - std::ostream* os; - - public: - LogHelper(std::ostream* os) : os(os) {} - ~LogHelper() { - *os << std::endl; - ::abort(); - } - std::ostream& get_os() { - return *os; - } -}; - -// Abort the program after logging the mesage if the given condition is not -// true. Otherwise, do nothing. -#define GRPC_CODEGEN_CHECK(x) !(x) && LogHelper(&std::cerr).get_os() \ - << "CHECK FAILED: " << __FILE__ << ":" \ - << __LINE__ << ": " - -// Abort the program after logging the mesage. -#define GRPC_CODEGEN_FAIL GRPC_CODEGEN_CHECK(false) - -using namespace std; - -namespace java_grpc_generator { - -enum ProtoFlavor { - NORMAL, LITE, NANO -}; - -// Returns the package name of the gRPC services defined in the given file. -string ServiceJavaPackage(const google::protobuf::FileDescriptor* file, bool nano); - -// Returns the name of the outer class that wraps in all the generated code for -// the given service. -string ServiceClassName(const google::protobuf::ServiceDescriptor* service); - -// Writes the generated service interface into the given ZeroCopyOutputStream -void GenerateService(const google::protobuf::ServiceDescriptor* service, - google::protobuf::io::ZeroCopyOutputStream* out, - ProtoFlavor flavor, - bool disable_version); - -} // namespace java_grpc_generator - -namespace java_dubbo_generator { - -enum ProtoFlavor { - NORMAL -}; - -// Returns the package name of the Dubbo services defined in the given file. -string ServiceJavaPackage(const google::protobuf::FileDescriptor* file, bool nano); - -// Returns the name of the outer class that wraps in all the generated code for -// the given service. -string ServiceClassName(const google::protobuf::ServiceDescriptor* service); - -// Writes the generated service interface into the given ZeroCopyOutputStream -void GenerateService(const google::protobuf::ServiceDescriptor* service, - google::protobuf::io::ZeroCopyOutputStream* out, - ProtoFlavor flavor, - bool disable_version); - -} // namespace java_dubbo_generator - -#endif // NET_GRPC_COMPILER_JAVA_GENERATOR_H_ diff --git a/compiler/src/java_plugin/cpp/java_plugin.cpp b/compiler/src/java_plugin/cpp/java_plugin.cpp deleted file mode 100644 index c8af98cffa..0000000000 --- a/compiler/src/java_plugin/cpp/java_plugin.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Generates Java gRPC service interface out of Protobuf IDL. -// -// This is a Proto2 compiler plugin. See net/proto2/compiler/proto/plugin.proto -// and net/proto2/compiler/public/plugin.h for more information on plugins. - -#include - -#include "java_generator.h" -#include -#include -#include -#include - -static string JavaPackageToDir(const string& package_name) { - string package_dir = package_name; - for (size_t i = 0; i < package_dir.size(); ++i) { - if (package_dir[i] == '.') { - package_dir[i] = '/'; - } - } - if (!package_dir.empty()) package_dir += "/"; - return package_dir; -} - -class JavaGrpcGenerator : public google::protobuf::compiler::CodeGenerator { - public: - - JavaGrpcGenerator() {} - virtual ~JavaGrpcGenerator() {} - - virtual bool Generate(const google::protobuf::FileDescriptor* file, - const string& parameter, - google::protobuf::compiler::GeneratorContext* context, - string* error) const { - std::vector > options; - google::protobuf::compiler::ParseGeneratorParameter(parameter, &options); - string DUBBO("dubbo"); - - if (DUBBO == parameter) { - string package_name = java_dubbo_generator::ServiceJavaPackage( - file, false); - string package_filename = JavaPackageToDir(package_name); - for (int i = 0; i < file->service_count(); ++i) { - const google::protobuf::ServiceDescriptor* service = file->service(i); - string filename = package_filename - + java_dubbo_generator::ServiceClassName(service) + ".java"; - std::unique_ptr output( - context->Open(filename)); - java_dubbo_generator::GenerateService( - service, output.get(), java_dubbo_generator::ProtoFlavor::NORMAL, false); - } - } else { - java_grpc_generator::ProtoFlavor flavor = - java_grpc_generator::ProtoFlavor::NORMAL; - - bool disable_version = false; - for (size_t i = 0; i < options.size(); i++) { - if (options[i].first == "nano") { - flavor = java_grpc_generator::ProtoFlavor::NANO; - } else if (options[i].first == "lite") { - flavor = java_grpc_generator::ProtoFlavor::LITE; - } else if (options[i].first == "noversion") { - disable_version = true; - } - } - - string package_name = java_grpc_generator::ServiceJavaPackage( - file, flavor == java_grpc_generator::ProtoFlavor::NANO); - string package_filename = JavaPackageToDir(package_name); - for (int i = 0; i < file->service_count(); ++i) { - const google::protobuf::ServiceDescriptor* service = file->service(i); - string filename = package_filename - + java_grpc_generator::ServiceClassName(service) + ".java"; - std::unique_ptr output( - context->Open(filename)); - java_grpc_generator::GenerateService( - service, output.get(), flavor, disable_version); - } - } - return true; - } -}; - -int main(int argc, char* argv[]) { - JavaGrpcGenerator generator; - return google::protobuf::compiler::PluginMain(argc, argv, &generator); -} diff --git a/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java new file mode 100644 index 0000000000..3e8dee10c2 --- /dev/null +++ b/compiler/src/main/java/org/apache/dubbo/gen/AbstractGenerator.java @@ -0,0 +1,293 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.gen; + +import com.google.common.base.Strings; +import com.google.common.html.HtmlEscapers; +import com.google.protobuf.DescriptorProtos.FileDescriptorProto; +import com.google.protobuf.DescriptorProtos.FileOptions; +import com.google.protobuf.DescriptorProtos.MethodDescriptorProto; +import com.google.protobuf.DescriptorProtos.ServiceDescriptorProto; +import com.google.protobuf.DescriptorProtos.SourceCodeInfo.Location; +import com.google.protobuf.compiler.PluginProtos; +import com.salesforce.jprotoc.Generator; +import com.salesforce.jprotoc.GeneratorException; +import com.salesforce.jprotoc.ProtoTypeMap; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public abstract class AbstractGenerator extends Generator { + + private static final int SERVICE_NUMBER_OF_PATHS = 2; + private static final int METHOD_NUMBER_OF_PATHS = 4; + + protected abstract String getClassPrefix(); + + protected abstract String getClassSuffix(); + + private String getServiceJavaDocPrefix() { + return " "; + } + + private String getMethodJavaDocPrefix() { + return " "; + } + + @Override + public List generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException { + final ProtoTypeMap typeMap = ProtoTypeMap.of(request.getProtoFileList()); + + List protosToGenerate = request.getProtoFileList().stream() + .filter(protoFile -> request.getFileToGenerateList().contains(protoFile.getName())) + .collect(Collectors.toList()); + + List services = findServices(protosToGenerate, typeMap); + return generateFiles(services); + } + + private List findServices(List protos, ProtoTypeMap typeMap) { + List contexts = new ArrayList<>(); + + protos.forEach(fileProto -> { + for (int serviceNumber = 0; serviceNumber < fileProto.getServiceCount(); serviceNumber++) { + ServiceContext serviceContext = buildServiceContext( + fileProto.getService(serviceNumber), + typeMap, + fileProto.getSourceCodeInfo().getLocationList(), + serviceNumber + ); + serviceContext.protoName = fileProto.getName(); + serviceContext.packageName = extractPackageName(fileProto); + contexts.add(serviceContext); + } + }); + + return contexts; + } + + private String extractPackageName(FileDescriptorProto proto) { + FileOptions options = proto.getOptions(); + if (options != null) { + String javaPackage = options.getJavaPackage(); + if (!Strings.isNullOrEmpty(javaPackage)) { + return javaPackage; + } + } + + return Strings.nullToEmpty(proto.getPackage()); + } + + private ServiceContext buildServiceContext(ServiceDescriptorProto serviceProto, ProtoTypeMap typeMap, List locations, int serviceNumber) { + ServiceContext serviceContext = new ServiceContext(); + serviceContext.fileName = getClassPrefix() + serviceProto.getName() + getClassSuffix() + ".java"; + serviceContext.className = getClassPrefix() + serviceProto.getName() + getClassSuffix(); + serviceContext.serviceName = serviceProto.getName(); + serviceContext.deprecated = serviceProto.getOptions() != null && serviceProto.getOptions().getDeprecated(); + + List allLocationsForService = locations.stream() + .filter(location -> + location.getPathCount() >= 2 && + location.getPath(0) == FileDescriptorProto.SERVICE_FIELD_NUMBER && + location.getPath(1) == serviceNumber + ) + .collect(Collectors.toList()); + + Location serviceLocation = allLocationsForService.stream() + .filter(location -> location.getPathCount() == SERVICE_NUMBER_OF_PATHS) + .findFirst() + .orElseGet(Location::getDefaultInstance); + serviceContext.javaDoc = getJavaDoc(getComments(serviceLocation), getServiceJavaDocPrefix()); + + for (int methodNumber = 0; methodNumber < serviceProto.getMethodCount(); methodNumber++) { + MethodContext methodContext = buildMethodContext( + serviceProto.getMethod(methodNumber), + typeMap, + locations, + methodNumber + ); + + serviceContext.methods.add(methodContext); + serviceContext.methodTypes.add(methodContext.inputType); + serviceContext.methodTypes.add(methodContext.outputType); + } + return serviceContext; + } + + private MethodContext buildMethodContext(MethodDescriptorProto methodProto, ProtoTypeMap typeMap, List locations, int methodNumber) { + MethodContext methodContext = new MethodContext(); + methodContext.methodName = lowerCaseFirst(methodProto.getName()); + methodContext.inputType = typeMap.toJavaTypeName(methodProto.getInputType()); + methodContext.outputType = typeMap.toJavaTypeName(methodProto.getOutputType()); + methodContext.deprecated = methodProto.getOptions() != null && methodProto.getOptions().getDeprecated(); + methodContext.isManyInput = methodProto.getClientStreaming(); + methodContext.isManyOutput = methodProto.getServerStreaming(); + methodContext.methodNumber = methodNumber; + + Location methodLocation = locations.stream() + .filter(location -> + location.getPathCount() == METHOD_NUMBER_OF_PATHS && + location.getPath(METHOD_NUMBER_OF_PATHS - 1) == methodNumber + ) + .findFirst() + .orElseGet(Location::getDefaultInstance); + methodContext.javaDoc = getJavaDoc(getComments(methodLocation), getMethodJavaDocPrefix()); + + if (!methodProto.getClientStreaming() && !methodProto.getServerStreaming()) { + methodContext.reactiveCallsMethodName = "oneToOne"; + methodContext.grpcCallsMethodName = "asyncUnaryCall"; + } + if (!methodProto.getClientStreaming() && methodProto.getServerStreaming()) { + methodContext.reactiveCallsMethodName = "oneToMany"; + methodContext.grpcCallsMethodName = "asyncServerStreamingCall"; + } + if (methodProto.getClientStreaming() && !methodProto.getServerStreaming()) { + methodContext.reactiveCallsMethodName = "manyToOne"; + methodContext.grpcCallsMethodName = "asyncClientStreamingCall"; + } + if (methodProto.getClientStreaming() && methodProto.getServerStreaming()) { + methodContext.reactiveCallsMethodName = "manyToMany"; + methodContext.grpcCallsMethodName = "asyncBidiStreamingCall"; + } + return methodContext; + } + + private String lowerCaseFirst(String s) { + return Character.toLowerCase(s.charAt(0)) + s.substring(1); + } + + private List generateFiles(List services) { + return services.stream() + .map(this::buildFile) + .collect(Collectors.toList()); + } + + private PluginProtos.CodeGeneratorResponse.File buildFile(ServiceContext context) { + String content = applyTemplate(getClassPrefix() + getClassSuffix() + "Stub.mustache", context); + return PluginProtos.CodeGeneratorResponse.File + .newBuilder() + .setName(absoluteFileName(context)) + .setContent(content) + .build(); + } + + private String absoluteFileName(ServiceContext ctx) { + String dir = ctx.packageName.replace('.', '/'); + if (Strings.isNullOrEmpty(dir)) { + return ctx.fileName; + } else { + return dir + "/" + ctx.fileName; + } + } + + private String getComments(Location location) { + return location.getLeadingComments().isEmpty() ? location.getTrailingComments() : location.getLeadingComments(); + } + + private String getJavaDoc(String comments, String prefix) { + if (!comments.isEmpty()) { + StringBuilder builder = new StringBuilder("/**\n") + .append(prefix).append(" *
\n");
+            Arrays.stream(HtmlEscapers.htmlEscaper().escape(comments).split("\n"))
+                    .map(line -> line.replace("*/", "*/").replace("*", "*"))
+                    .forEach(line -> builder.append(prefix).append(" * ").append(line).append("\n"));
+            builder
+                    .append(prefix).append(" * 
\n") + .append(prefix).append(" */"); + return builder.toString(); + } + return null; + } + + /** + * Template class for proto Service objects. + */ + private class ServiceContext { + // CHECKSTYLE DISABLE VisibilityModifier FOR 8 LINES + public String fileName; + public String protoName; + public String packageName; + public String className; + public String serviceName; + public boolean deprecated; + public String javaDoc; + public List methods = new ArrayList<>(); + + public Set methodTypes = new HashSet<>(); + + public List unaryRequestMethods() { + return methods.stream().filter(m -> !m.isManyInput).collect(Collectors.toList()); + } + + public List unaryMethods() { + return methods.stream().filter(m -> (!m.isManyInput && !m.isManyOutput)).collect(Collectors.toList()); + } + + public List serverStreamingMethods() { + return methods.stream().filter(m -> !m.isManyInput && m.isManyOutput).collect(Collectors.toList()); + } + + public List biStreamingMethods() { + return methods.stream().filter(m -> m.isManyInput).collect(Collectors.toList()); + } + } + + /** + * Template class for proto RPC objects. + */ + private class MethodContext { + // CHECKSTYLE DISABLE VisibilityModifier FOR 10 LINES + public String methodName; + public String inputType; + public String outputType; + public boolean deprecated; + public boolean isManyInput; + public boolean isManyOutput; + public String reactiveCallsMethodName; + public String grpcCallsMethodName; + public int methodNumber; + public String javaDoc; + + // This method mimics the upper-casing method ogf gRPC to ensure compatibility + // See https://github.com/grpc/grpc-java/blob/v1.8.0/compiler/src/java_plugin/cpp/java_generator.cpp#L58 + public String methodNameUpperUnderscore() { + StringBuilder s = new StringBuilder(); + for (int i = 0; i < methodName.length(); i++) { + char c = methodName.charAt(i); + s.append(Character.toUpperCase(c)); + if ((i < methodName.length() - 1) && Character.isLowerCase(c) && Character.isUpperCase(methodName.charAt(i + 1))) { + s.append('_'); + } + } + return s.toString(); + } + + public String methodNamePascalCase() { + String mn = methodName.replace("_", ""); + return String.valueOf(Character.toUpperCase(mn.charAt(0))) + mn.substring(1); + } + + public String methodNameCamelCase() { + String mn = methodName.replace("_", ""); + return String.valueOf(Character.toLowerCase(mn.charAt(0))) + mn.substring(1); + } + } +} diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpService.java b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java similarity index 58% rename from dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpService.java rename to compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java index 5205dc6c67..1c35f0a3ef 100644 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpService.java +++ b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java @@ -1,35 +1,42 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.dubbo.rpc.protocol.httpinvoker; - - -/** - * HttpService - */ -public interface HttpService { - - String sayHello(String name); - - String sayHello(String name, int times); - - void timeOut(int millis); - - String customException(); - - String getRemoteApplicationName(); - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.gen.dubbo; + +import org.apache.dubbo.gen.AbstractGenerator; + +import com.salesforce.jprotoc.ProtocPlugin; + +public class DubboGenerator extends AbstractGenerator { + + public static void main(String[] args) { + if (args.length == 0) { + ProtocPlugin.generate(new DubboGenerator()); + } else { + ProtocPlugin.debug(new DubboGenerator(), args[0]); + } + } + + @Override + protected String getClassPrefix() { + return ""; + } + + @Override + protected String getClassSuffix() { + return "Dubbo"; + } +} \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java similarity index 58% rename from dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java rename to compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java index 2c7415533a..dafdd5a6e6 100644 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java +++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java @@ -14,15 +14,28 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.alibaba.dubbo.rpc.protocol.http; +package org.apache.dubbo.gen.grpc; -import org.aopalliance.intercept.MethodInvocation; +import org.apache.dubbo.gen.AbstractGenerator; -@Deprecated -public class HttpRemoteInvocation extends org.apache.dubbo.rpc.protocol.httpinvoker.HttpRemoteInvocation { - private static final long serialVersionUID = 1L; +import com.salesforce.jprotoc.ProtocPlugin; - public HttpRemoteInvocation(MethodInvocation methodInvocation) { - super(methodInvocation); +public class DubboGrpcGenerator extends AbstractGenerator { + + public static void main(String[] args) { + if (args.length == 0) { + ProtocPlugin.generate(new DubboGrpcGenerator()); + } else { + ProtocPlugin.debug(new DubboGrpcGenerator(), args[0]); + } + } + + @Override + protected String getClassPrefix() { + return "Dubbo"; + } + + protected String getClassSuffix() { + return "Grpc"; } } diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java new file mode 100644 index 0000000000..dd9520b902 --- /dev/null +++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/ReactorDubboGrpcGenerator.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.gen.grpc.reactive; + +import org.apache.dubbo.gen.AbstractGenerator; + +import com.salesforce.jprotoc.ProtocPlugin; + +public class ReactorDubboGrpcGenerator extends AbstractGenerator { + + @Override + protected String getClassPrefix() { + return "ReactorDubbo"; + } + + @Override + protected String getClassSuffix() { + return "Grpc"; + } + + public static void main(String[] args) { + if (args.length == 0) { + ProtocPlugin.generate(new ReactorDubboGrpcGenerator()); + } else { + ProtocPlugin.debug(new ReactorDubboGrpcGenerator(), args[0]); + } + } +} diff --git a/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java new file mode 100644 index 0000000000..028332a27e --- /dev/null +++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/reactive/RxDubboGrpcGenerator.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.gen.grpc.reactive; + +import org.apache.dubbo.gen.AbstractGenerator; + +import com.salesforce.jprotoc.ProtocPlugin; + +public class RxDubboGrpcGenerator extends AbstractGenerator { + @Override + protected String getClassPrefix() { + return "RxDubbo"; + } + + @Override + protected String getClassSuffix() { + return "Grpc"; + } + + public static void main(String[] args) { + if (args.length == 0) { + ProtocPlugin.generate(new RxDubboGrpcGenerator()); + } else { + ProtocPlugin.debug(new RxDubboGrpcGenerator(), args[0]); + } + } +} diff --git a/compiler/src/main/resources/DubboGrpcStub.mustache b/compiler/src/main/resources/DubboGrpcStub.mustache new file mode 100644 index 0000000000..a02d0c434c --- /dev/null +++ b/compiler/src/main/resources/DubboGrpcStub.mustache @@ -0,0 +1,312 @@ +{{#packageName}} + package {{packageName}}; +{{/packageName}} + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.config.ReferenceConfigBase; + +import java.util.concurrent.TimeUnit; + +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; +import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; + +import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; +import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; +import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; +import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; + +{{#deprecated}} + @java.lang.Deprecated +{{/deprecated}} +@javax.annotation.Generated( +value = "by DubboGrpc generator", +comments = "Source: {{protoName}}") +public final class {{className}} { +private {{className}}() {} + +public static class Dubbo{{serviceName}}Stub implements I{{serviceName}} { + +protected URL url; +protected ReferenceConfigBase referenceConfig; + +protected {{serviceName}}Grpc.{{serviceName}}BlockingStub blockingStub; +protected {{serviceName}}Grpc.{{serviceName}}FutureStub futureStub; +protected {{serviceName}}Grpc.{{serviceName}}Stub stub; + +public Dubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase referenceConfig) { +this.url = url; +this.referenceConfig = referenceConfig; + +blockingStub = {{serviceName}}Grpc.newBlockingStub(channel).build(channel, callOptions); +futureStub = {{serviceName}}Grpc.newFutureStub(channel).build(channel, callOptions); +stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions); +} + +{{#unaryMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{outputType}} {{methodName}}({{inputType}} request) { + return blockingStub + .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS) + .{{methodName}}(request); + } + + public com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) { + return futureStub + .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS) + .{{methodName}}(request); + } + + public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver){ + stub + .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS) + .{{methodName}}(request, responseObserver); + } + +{{/unaryMethods}} +{{#serverStreamingMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) { + return blockingStub + .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS) + .{{methodName}}(request); + } + + public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) { + stub + .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS) + .{{methodName}}(request, responseObserver); + } + +{{/serverStreamingMethods}} +{{#biStreamingMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) { + return stub + .withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS) + .{{methodName}}(responseObserver); + } +{{/biStreamingMethods}} +} + +public static Dubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase referenceConfig) { +return new Dubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig); +} + +public interface I{{serviceName}} { +{{#unaryMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + default public {{outputType}} {{methodName}}({{inputType}} request) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + default public com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver); + +{{/unaryMethods}} +{{#serverStreamingMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + default public java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public void {{methodName}}({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> responseObserver); + +{{/serverStreamingMethods}} +{{#biStreamingMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}(io.grpc.stub.StreamObserver<{{outputType}}> responseObserver); + +{{/biStreamingMethods}} +} + +{{#javaDoc}} + {{{javaDoc}}} +{{/javaDoc}} +public static abstract class {{serviceName}}ImplBase implements io.grpc.BindableService, I{{serviceName}} { + +private I{{serviceName}} proxiedImpl; + +public final void setProxiedImpl(I{{serviceName}} proxiedImpl) { +this.proxiedImpl = proxiedImpl; +} + +{{#unaryMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + @java.lang.Override + public final {{outputType}} {{methodName}}({{inputType}} request) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + @java.lang.Override + public final com.google.common.util.concurrent.ListenableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + +{{/unaryMethods}} +{{#serverStreamingMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + @java.lang.Override + public final java.util.Iterator<{{outputType}}> {{methodName}}({{inputType}} request) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + +{{/serverStreamingMethods}} +{{#methods}} + {{#isManyInput}} + public io.grpc.stub.StreamObserver<{{inputType}}> {{methodName}}( + io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) { + return asyncUnimplementedStreamingCall({{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), responseObserver); + } + {{/isManyInput}}{{^isManyInput}} + public void {{methodName}}({{inputType}} request, + io.grpc.stub.StreamObserver<{{outputType}}> responseObserver) { + asyncUnimplementedUnaryCall({{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), responseObserver); + } + {{/isManyInput}} +{{/methods}} + +@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { +return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) +{{#methods}} + .addMethod( + {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), + {{grpcCallsMethodName}}( + new MethodHandlers< + {{inputType}}, + {{outputType}}>( + proxiedImpl, METHODID_{{methodNameUpperUnderscore}}))) +{{/methods}} +.build(); +} +} +{{#methods}} + private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}}; +{{/methods}} + +private static final class MethodHandlers + implements +io.grpc.stub.ServerCalls.UnaryMethod +, +io.grpc.stub.ServerCalls.ServerStreamingMethod +, +io.grpc.stub.ServerCalls.ClientStreamingMethod +, +io.grpc.stub.ServerCalls.BidiStreamingMethod + { +private final I{{serviceName}} serviceImpl; +private final int methodId; + +MethodHandlers(I{{serviceName}} serviceImpl, int methodId) { +this.serviceImpl = serviceImpl; +this.methodId = methodId; +} + +@java.lang.Override +@java.lang.SuppressWarnings("unchecked") +public void invoke(Req request, io.grpc.stub.StreamObserver + responseObserver) { + switch (methodId) { + {{#methods}} + {{^isManyInput}} + case METHODID_{{methodNameUpperUnderscore}}: + serviceImpl.{{methodName}}(({{inputType}}) request, + (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver); + break; + {{/isManyInput}} + {{/methods}} + default: + throw new java.lang.AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver + invoke(io.grpc.stub.StreamObserver + responseObserver) { + switch (methodId) { + {{#methods}} + {{#isManyInput}} + case METHODID_{{methodNameUpperUnderscore}}: + return (io.grpc.stub.StreamObserver + ) serviceImpl.{{methodName}}( + (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver); + {{/isManyInput}} + {{/methods}} + default: + throw new java.lang.AssertionError(); + } + } + } + + } diff --git a/compiler/src/main/resources/DubboStub.mustache b/compiler/src/main/resources/DubboStub.mustache new file mode 100644 index 0000000000..06bd7b4373 --- /dev/null +++ b/compiler/src/main/resources/DubboStub.mustache @@ -0,0 +1,53 @@ +{{#packageName}} + package {{packageName}}; +{{/packageName}} + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; + +{{#deprecated}} + @java.lang.Deprecated +{{/deprecated}} +@javax.annotation.Generated( +value = "by Dubbo generator", +comments = "Source: {{protoName}}") +public final class {{className}} { +private static final AtomicBoolean registered = new AtomicBoolean(); + +private static Class init() { +Class clazz = null; +try { +clazz = Class.forName({{serviceName}}Dubbo.class.getName()); +if (registered.compareAndSet(false, true)) { +{{#methodTypes}} + org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils.marshaller( + {{.}}.getDefaultInstance()); +{{/methodTypes}} +} +} catch (ClassNotFoundException e) { +// ignore +} +return clazz; +} + +private {{serviceName}}Dubbo() {} + +public static final String SERVICE_NAME = "{{packageName}}.{{serviceName}}"; + +/** +* Code generated for Dubbo +*/ +public interface I{{serviceName}} { + +static Class clazz = init(); + +{{#methods}} + {{outputType}} {{methodName}}({{inputType}} request); + + CompletableFuture<{{outputType}}> {{methodName}}Async({{inputType}} request); + +{{/methods}} + +} + +} diff --git a/compiler/src/main/resources/ReactorDubboGrpcStub.mustache b/compiler/src/main/resources/ReactorDubboGrpcStub.mustache new file mode 100644 index 0000000000..2cf1471d6c --- /dev/null +++ b/compiler/src/main/resources/ReactorDubboGrpcStub.mustache @@ -0,0 +1,212 @@ +{{#packageName}} + package {{packageName}}; +{{/packageName}} + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.config.ReferenceConfigBase; + +import java.util.concurrent.TimeUnit; + +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; +import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; + +import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; +import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; +import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; + + +{{#deprecated}} + @java.lang.Deprecated +{{/deprecated}} +@javax.annotation.Generated( +value = "by ReactorDubboGrpc generator", +comments = "Source: {{protoName}}") +public final class {{className}} { +private {{className}}() {} + +public static ReactorDubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase referenceConfig) { +return new ReactorDubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig); +} + +{{#javaDoc}} + {{{javaDoc}}} +{{/javaDoc}} +public static final class ReactorDubbo{{serviceName}}Stub implements IReactor{{serviceName}} { + +protected URL url; +protected ReferenceConfigBase referenceConfig; + +protected {{serviceName}}Grpc.{{serviceName}}Stub stub; + +public ReactorDubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase referenceConfig) { +this.url = url; +this.referenceConfig = referenceConfig; +stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions); +} + +{{#methods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> reactorRequest) { + {{serviceName}}Grpc.{{serviceName}}Stub localStub = stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS); + return com.salesforce.reactorgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(reactorRequest, localStub::{{methodName}}); + } + +{{/methods}} +{{#unaryRequestMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest) { + {{serviceName}}Grpc.{{serviceName}}Stub localStub = stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS); + return com.salesforce.reactorgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(reactor.core.publisher.Mono.just(reactorRequest), localStub::{{methodName}}); + } + +{{/unaryRequestMethods}} +} + +public interface IReactor{{serviceName}} { +{{#methods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> reactorRequest); + +{{/methods}} +{{#unaryRequestMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest); + +{{/unaryRequestMethods}} +} + +{{#javaDoc}} + {{{javaDoc}}} +{{/javaDoc}} +public static abstract class {{serviceName}}ImplBase implements IReactor{{serviceName}}, io.grpc.BindableService { + +private IReactor{{serviceName}} proxiedImpl; + +public final void setProxiedImpl(IReactor{{serviceName}} proxiedImpl) { +this.proxiedImpl = proxiedImpl; +} + +{{#unaryRequestMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public final {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} reactorRequest) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + +{{/unaryRequestMethods}} +{{#methods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}reactor.core.publisher.Flux{{/isManyOutput}}{{^isManyOutput}}reactor.core.publisher.Mono{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}reactor.core.publisher.Flux{{/isManyInput}}{{^isManyInput}}reactor.core.publisher.Mono{{/isManyInput}}<{{inputType}}> request) { + throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED); + } + +{{/methods}} +@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { +return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) +{{#methods}} + .addMethod( + {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), + {{grpcCallsMethodName}}( + new MethodHandlers< + {{inputType}}, + {{outputType}}>( + proxiedImpl, METHODID_{{methodNameUpperUnderscore}}))) +{{/methods}} +.build(); +} +} + +{{#methods}} + private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}}; +{{/methods}} + +private static final class MethodHandlers + implements +io.grpc.stub.ServerCalls.UnaryMethod +, +io.grpc.stub.ServerCalls.ServerStreamingMethod +, +io.grpc.stub.ServerCalls.ClientStreamingMethod +, +io.grpc.stub.ServerCalls.BidiStreamingMethod + { +private final IReactor{{serviceName}} serviceImpl; +private final int methodId; + +MethodHandlers(IReactor{{serviceName}} serviceImpl, int methodId) { +this.serviceImpl = serviceImpl; +this.methodId = methodId; +} + +@java.lang.Override +@java.lang.SuppressWarnings("unchecked") +public void invoke(Req request, io.grpc.stub.StreamObserver + responseObserver) { + switch (methodId) { + {{#methods}} + {{^isManyInput}} + case METHODID_{{methodNameUpperUnderscore}}: + com.salesforce.reactorgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(({{inputType}}) request, + (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver, + serviceImpl::{{methodName}}); + break; + {{/isManyInput}} + {{/methods}} + default: + throw new java.lang.AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver + invoke(io.grpc.stub.StreamObserver + responseObserver) { + switch (methodId) { + {{#methods}} + {{#isManyInput}} + case METHODID_{{methodNameUpperUnderscore}}: + return (io.grpc.stub.StreamObserver + ) com.salesforce.reactorgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}( + (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver, + serviceImpl::{{methodName}}); + {{/isManyInput}} + {{/methods}} + default: + throw new java.lang.AssertionError(); + } + } + } + + } diff --git a/compiler/src/main/resources/RxDubboGrpcStub.mustache b/compiler/src/main/resources/RxDubboGrpcStub.mustache new file mode 100644 index 0000000000..22c06b02cc --- /dev/null +++ b/compiler/src/main/resources/RxDubboGrpcStub.mustache @@ -0,0 +1,246 @@ +{{#packageName}} + package {{packageName}}; +{{/packageName}} + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.config.ReferenceConfigBase; + +import java.util.concurrent.TimeUnit; + +import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; +import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; + +import static {{packageName}}.{{serviceName}}Grpc.getServiceDescriptor; +import static io.grpc.stub.ServerCalls.asyncUnaryCall; +import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; +import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; +import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; + + +{{#deprecated}} + @java.lang.Deprecated +{{/deprecated}} +@javax.annotation.Generated( +value = "by RxDubboGrpc generator", +comments = "Source: {{protoName}}") +public final class {{className}} { +private {{className}}() {} + +public static RxDubbo{{serviceName}}Stub getDubboStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase referenceConfig) { +return new RxDubbo{{serviceName}}Stub(channel, callOptions, url, referenceConfig); +} + +{{#javaDoc}} + {{{javaDoc}}} +{{/javaDoc}} +public static final class RxDubbo{{serviceName}}Stub implements IRx{{serviceName}} { + +protected URL url; +protected ReferenceConfigBase referenceConfig; + +protected {{serviceName}}Grpc.{{serviceName}}Stub stub; + +public RxDubbo{{serviceName}}Stub(io.grpc.Channel channel, io.grpc.CallOptions callOptions, URL url, ReferenceConfigBase referenceConfig) { +this.url = url; +this.referenceConfig = referenceConfig; +stub = {{serviceName}}Grpc.newStub(channel).build(channel, callOptions); +} + +{{#methods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> rxRequest) { + return com.salesforce.rxgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(rxRequest, + {{^isManyInput}} + new com.salesforce.reactivegrpc.common.BiConsumer<{{inputType}}, io.grpc.stub.StreamObserver<{{outputType}}>>() { + @java.lang.Override + public void accept({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> observer) { + stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(request, observer); + } + }); + {{/isManyInput}} + {{#isManyInput}} + new com.salesforce.reactivegrpc.common.Function + , io.grpc.stub.StreamObserver<{{inputType}}>>() { + @java.lang.Override + public io.grpc.stub.StreamObserver<{{inputType}}> apply(io.grpc.stub.StreamObserver<{{outputType}}> observer) { + return stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(observer); + } + }); + {{/isManyInput}} + } + +{{/methods}} +{{#unaryRequestMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest) { + return com.salesforce.rxgrpc.stub.ClientCalls.{{reactiveCallsMethodName}}(io.reactivex.Single.just(rxRequest), + new com.salesforce.reactivegrpc.common.BiConsumer<{{inputType}}, io.grpc.stub.StreamObserver<{{outputType}}>>() { + @java.lang.Override + public void accept({{inputType}} request, io.grpc.stub.StreamObserver<{{outputType}}> observer) { + stub.withDeadlineAfter(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS).{{methodNameCamelCase}}(request, observer); + } + }); + } + +{{/unaryRequestMethods}} +} + +public interface IRx{{serviceName}} { +{{#methods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> rxRequest); + +{{/methods}} +{{#unaryRequestMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest); + +{{/unaryRequestMethods}} +} + + +{{#javaDoc}} + {{{javaDoc}}} +{{/javaDoc}} +public static abstract class {{serviceName}}ImplBase implements IRx{{serviceName}}, io.grpc.BindableService { + +private IRx{{serviceName}} proxiedImpl; + +public final void setProxiedImpl(IRx{{serviceName}} proxiedImpl) { +this.proxiedImpl = proxiedImpl; +} +{{#unaryRequestMethods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public final {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodName}}({{inputType}} rxRequest) { + throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows."); + } + +{{/unaryRequestMethods}} +{{#methods}} + {{#javaDoc}} + {{{javaDoc}}} + {{/javaDoc}} + {{#deprecated}} + @java.lang.Deprecated + {{/deprecated}} + public {{#isManyOutput}}io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}}io.reactivex.Single{{/isManyOutput}}<{{outputType}}> {{methodNameCamelCase}}({{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}}<{{inputType}}> request) { + throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED); + } + +{{/methods}} +@java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { +return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) +{{#methods}} + .addMethod( + {{packageName}}.{{serviceName}}Grpc.get{{methodNamePascalCase}}Method(), + {{grpcCallsMethodName}}( + new MethodHandlers< + {{inputType}}, + {{outputType}}>( + proxiedImpl, METHODID_{{methodNameUpperUnderscore}}))) +{{/methods}} +.build(); +} +} + +{{#methods}} + private static final int METHODID_{{methodNameUpperUnderscore}} = {{methodNumber}}; +{{/methods}} + +private static final class MethodHandlers + implements +io.grpc.stub.ServerCalls.UnaryMethod +, +io.grpc.stub.ServerCalls.ServerStreamingMethod +, +io.grpc.stub.ServerCalls.ClientStreamingMethod +, +io.grpc.stub.ServerCalls.BidiStreamingMethod + { +private final IRx{{serviceName}} serviceImpl; +private final int methodId; + +MethodHandlers(IRx{{serviceName}} serviceImpl, int methodId) { +this.serviceImpl = serviceImpl; +this.methodId = methodId; +} + +@java.lang.Override +@java.lang.SuppressWarnings("unchecked") +public void invoke(Req request, io.grpc.stub.StreamObserver + responseObserver) { + switch (methodId) { + {{#methods}} + {{^isManyInput}} + case METHODID_{{methodNameUpperUnderscore}}: + com.salesforce.rxgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}(({{inputType}}) request, + (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver, + new com.salesforce.reactivegrpc.common.Function + <{{#isManyInput}}io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}}io.reactivex.Single{{/isManyInput}} + <{{inputType}}>, {{#isManyOutput}} + io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}} + io.reactivex.Single{{/isManyOutput}}<{{outputType}}>>() { + @java.lang.Override + public {{#isManyOutput}} + io.reactivex.Flowable{{/isManyOutput}}{{^isManyOutput}} + io.reactivex.Single{{/isManyOutput}}<{{outputType}}> apply({{#isManyInput}} + io.reactivex.Flowable{{/isManyInput}}{{^isManyInput}} + io.reactivex.Single{{/isManyInput}}<{{inputType}}> single) { + return serviceImpl.{{methodNameCamelCase}}(single); + } + }); + break; + {{/isManyInput}} + {{/methods}} + default: + throw new java.lang.AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver + invoke(io.grpc.stub.StreamObserver + responseObserver) { + switch (methodId) { + {{#methods}} + {{#isManyInput}} + case METHODID_{{methodNameUpperUnderscore}}: + return (io.grpc.stub.StreamObserver + ) com.salesforce.rxgrpc.stub.ServerCalls.{{reactiveCallsMethodName}}( + (io.grpc.stub.StreamObserver<{{outputType}}>) responseObserver, + serviceImpl::{{methodNameCamelCase}}); + {{/isManyInput}} + {{/methods}} + default: + throw new java.lang.AssertionError(); + } + } + } + + } diff --git a/dubbo-distribution/src/assembly/source-release.xml b/dubbo-distribution/src/assembly/source-release.xml index 1708f8f7ed..2f265166b7 100644 --- a/dubbo-distribution/src/assembly/source-release.xml +++ b/dubbo-distribution/src/assembly/source-release.xml @@ -51,8 +51,6 @@ **/*.jar **/mvnw* **/.flattened-pom.xml - **/compiler/.gradle/** - **/compiler/gradle/** diff --git a/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java b/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java index c30ce1d3ec..cfc02d71b2 100644 --- a/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java +++ b/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java @@ -26,7 +26,6 @@ import org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerInterceptor; import org.apache.dubbo.rpc.protocol.grpc.interceptors.ServerTransportFilter; import io.grpc.CallOptions; -import io.grpc.Deadline; import io.grpc.ManagedChannel; import io.grpc.ServerBuilder; import io.grpc.netty.GrpcSslContexts; @@ -42,12 +41,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Set; -import java.util.concurrent.TimeUnit; import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE; -import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE; -import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.remoting.Constants.DISPATCHER_KEY; import static org.apache.dubbo.remoting.Constants.SSL_CLIENT_CERT_PATH_KEY; import static org.apache.dubbo.remoting.Constants.SSL_CLIENT_KEY_PASSWORD_KEY; @@ -152,9 +148,10 @@ public class GrpcOptionsUtils { } static CallOptions buildCallOptions(URL url) { - CallOptions callOptions = CallOptions.DEFAULT - .withDeadline(Deadline.after(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)); - + // gRPC Deadline starts counting when it's created, so we need to create and add a new Deadline for each RPC call. +// CallOptions callOptions = CallOptions.DEFAULT +// .withDeadline(Deadline.after(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT), TimeUnit.MILLISECONDS)); + CallOptions callOptions = CallOptions.DEFAULT; return getConfigurator() .map(configurator -> configurator.configureCallOptions(callOptions, url)) .orElse(callOptions); diff --git a/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java b/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java index 8a1188fe68..8381a3f8d5 100644 --- a/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java +++ b/dubbo-rpc/dubbo-rpc-grpc/src/main/java/org/apache/dubbo/rpc/protocol/grpc/GrpcProtocol.java @@ -19,6 +19,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.config.ReferenceConfigBase; import org.apache.dubbo.rpc.Exporter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -116,7 +117,8 @@ public class GrpcProtocol extends AbstractProxyProtocol { final Method dubboStubMethod; try { - dubboStubMethod = enclosingClass.getDeclaredMethod("getDubboStub", Channel.class, CallOptions.class); + dubboStubMethod = enclosingClass.getDeclaredMethod("getDubboStub", Channel.class, CallOptions.class, + URL.class, ReferenceConfigBase.class); } catch (NoSuchMethodException e) { throw new IllegalArgumentException("Does not find getDubboStub in " + enclosingClass.getName() + ", please use the customized protoc-gen-dubbo-java to update the generated classes."); } @@ -128,7 +130,12 @@ public class GrpcProtocol extends AbstractProxyProtocol { // CallOptions try { - @SuppressWarnings("unchecked") final T stub = (T) dubboStubMethod.invoke(null, channel, GrpcOptionsUtils.buildCallOptions(url)); + @SuppressWarnings("unchecked") final T stub = (T) dubboStubMethod.invoke(null, + channel, + GrpcOptionsUtils.buildCallOptions(url), + url, + ApplicationModel.getConsumerModel(url.getServiceKey()).getReferenceConfig() + ); final Invoker target = proxyFactory.getInvoker(stub, type, url); GrpcInvoker grpcInvoker = new GrpcInvoker<>(type, url, target, channel); invokers.add(grpcInvoker); diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/pom.xml b/dubbo-rpc/dubbo-rpc-http-invoker/pom.xml deleted file mode 100644 index f467cc88bb..0000000000 --- a/dubbo-rpc/dubbo-rpc-http-invoker/pom.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - 4.0.0 - - org.apache.dubbo - dubbo-rpc - ${revision} - - dubbo-rpc-http-invoker - jar - ${project.artifactId} - The http rpc module of dubbo project - - false - - - - org.apache.dubbo - dubbo-rpc-api - ${project.parent.version} - - - org.apache.dubbo - dubbo-remoting-http - ${project.parent.version} - - - org.springframework - spring-context - - - org.springframework - spring-web - - - org.apache.dubbo - dubbo-serialization-jdk - ${project.parent.version} - test - - - \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpInvokerProtocol.java b/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpInvokerProtocol.java deleted file mode 100644 index 6657681272..0000000000 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpInvokerProtocol.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.dubbo.rpc.protocol.httpinvoker; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.Version; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.remoting.Constants; -import org.apache.dubbo.remoting.http.HttpBinder; -import org.apache.dubbo.remoting.http.HttpHandler; -import org.apache.dubbo.remoting.http.HttpServer; -import org.apache.dubbo.rpc.RpcContext; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol; -import org.apache.dubbo.rpc.service.GenericService; -import org.apache.dubbo.rpc.support.ProtocolUtils; - -import org.aopalliance.intercept.MethodInvocation; -import org.springframework.remoting.RemoteAccessException; -import org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor; -import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean; -import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter; -import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor; -import org.springframework.remoting.support.RemoteInvocation; -import org.springframework.remoting.support.RemoteInvocationFactory; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.SocketTimeoutException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; -import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; -import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; - -/** - * HttpInvokerProtocol - */ -public class HttpInvokerProtocol extends AbstractProxyProtocol { - - public static final int DEFAULT_PORT = 80; - - private final Map serverMap = new ConcurrentHashMap(); - - private final Map skeletonMap = new ConcurrentHashMap(); - - private HttpBinder httpBinder; - - public HttpInvokerProtocol() { - super(RemoteAccessException.class); - } - - public void setHttpBinder(HttpBinder httpBinder) { - this.httpBinder = httpBinder; - } - - @Override - public int getDefaultPort() { - return DEFAULT_PORT; - } - - @Override - protected Runnable doExport(final T impl, Class type, URL url) throws RpcException { - String addr = getAddr(url); - HttpServer server = serverMap.get(addr); - if (server == null) { - server = httpBinder.bind(url, new InternalHandler()); - serverMap.put(addr, server); - } - final String path = url.getAbsolutePath(); - skeletonMap.put(path, createExporter(impl, type)); - - final String genericPath = path + "/" + GENERIC_KEY; - - skeletonMap.put(genericPath, createExporter(impl, GenericService.class)); - return new Runnable() { - @Override - public void run() { - skeletonMap.remove(path); - skeletonMap.remove(genericPath); - } - }; - } - - private HttpInvokerServiceExporter createExporter(T impl, Class type) { - final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter(); - httpServiceExporter.setServiceInterface(type); - httpServiceExporter.setService(impl); - try { - httpServiceExporter.afterPropertiesSet(); - } catch (Exception e) { - throw new RpcException(e.getMessage(), e); - } - return httpServiceExporter; - } - - @Override - @SuppressWarnings("unchecked") - protected T doRefer(final Class serviceType, final URL url) throws RpcException { - final String generic = url.getParameter(GENERIC_KEY); - final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class); - - final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean(); - httpProxyFactoryBean.setRemoteInvocationFactory(new RemoteInvocationFactory() { - @Override - public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) { - RemoteInvocation invocation; - /* - package was renamed to 'org.apache.dubbo' in v2.7.0, so only provider versions after v2.7.0 can - recognize org.apache.xxx.HttpRemoteInvocation'. - */ - if (Version.isRelease270OrHigher(url.getParameter(RELEASE_KEY))) { - invocation = new HttpRemoteInvocation(methodInvocation); - } else { - /* - The customized 'com.alibaba.dubbo.rpc.protocol.http.HttpRemoteInvocation' was firstly introduced - in v2.6.3. The main purpose is to support transformation of attachments in HttpInvokerProtocol, see - https://github.com/apache/dubbo/pull/1827. To guarantee interoperability with lower - versions, we need to check if the provider is v2.6.3 or higher before sending customized - HttpRemoteInvocation. - */ - if (Version.isRelease263OrHigher(url.getParameter(DUBBO_VERSION_KEY))) { - invocation = new com.alibaba.dubbo.rpc.protocol.http.HttpRemoteInvocation(methodInvocation); - } else { - invocation = new RemoteInvocation(methodInvocation); - } - } - if (isGeneric) { - invocation.addAttribute(GENERIC_KEY, generic); - } - return invocation; - } - }); - - String key = url.toIdentityString(); - if (isGeneric) { - key = key + "/" + GENERIC_KEY; - } - - httpProxyFactoryBean.setServiceUrl(key.replace("http-invoker","http")); - httpProxyFactoryBean.setServiceInterface(serviceType); - String client = url.getParameter(Constants.CLIENT_KEY); - if (StringUtils.isEmpty(client) || "simple".equals(client)) { - SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor = new SimpleHttpInvokerRequestExecutor() { - @Override - protected void prepareConnection(HttpURLConnection con, - int contentLength) throws IOException { - super.prepareConnection(con, contentLength); - con.setReadTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT)); - con.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT)); - } - }; - httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor); - } else if ("commons".equals(client)) { - HttpComponentsHttpInvokerRequestExecutor httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor(); - httpInvokerRequestExecutor.setReadTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT)); - httpInvokerRequestExecutor.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT)); - httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor); - } else { - throw new IllegalStateException("Unsupported http protocol client " + client + ", only supported: simple, commons"); - } - httpProxyFactoryBean.afterPropertiesSet(); - return (T) httpProxyFactoryBean.getObject(); - } - - @Override - protected int getErrorCode(Throwable e) { - if (e instanceof RemoteAccessException) { - e = e.getCause(); - } - if (e != null) { - Class cls = e.getClass(); - if (SocketTimeoutException.class.equals(cls)) { - return RpcException.TIMEOUT_EXCEPTION; - } else if (IOException.class.isAssignableFrom(cls)) { - return RpcException.NETWORK_EXCEPTION; - } else if (ClassNotFoundException.class.isAssignableFrom(cls)) { - return RpcException.SERIALIZATION_EXCEPTION; - } - } - return super.getErrorCode(e); - } - - private class InternalHandler implements HttpHandler { - - @Override - public void handle(HttpServletRequest request, HttpServletResponse response) - throws IOException, ServletException { - String uri = request.getRequestURI(); - HttpInvokerServiceExporter skeleton = skeletonMap.get(uri); - if (!"POST".equalsIgnoreCase(request.getMethod())) { - response.setStatus(500); - } else { - RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort()); - try { - skeleton.handleRequest(request, response); - } catch (Throwable e) { - throw new ServletException(e); - } - } - } - - } - -} diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpRemoteInvocation.java b/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpRemoteInvocation.java deleted file mode 100644 index fca51031c7..0000000000 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpRemoteInvocation.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.dubbo.rpc.protocol.httpinvoker; - -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.rpc.RpcContext; - -import org.aopalliance.intercept.MethodInvocation; -import org.springframework.remoting.support.RemoteInvocation; - -import java.lang.reflect.InvocationTargetException; -import java.util.HashMap; -import java.util.Map; - -import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; - -public class HttpRemoteInvocation extends RemoteInvocation { - - private static final long serialVersionUID = 1L; - private static final String DUBBO_ATTACHMENTS_ATTR_NAME = "dubbo.attachments"; - - public HttpRemoteInvocation(MethodInvocation methodInvocation) { - super(methodInvocation); - addAttribute(DUBBO_ATTACHMENTS_ATTR_NAME, new HashMap(RpcContext.getContext().getAttachments())); - } - - @Override - public Object invoke(Object targetObject) throws NoSuchMethodException, IllegalAccessException, - InvocationTargetException { - RpcContext context = RpcContext.getContext(); - context.setAttachments((Map) getAttribute(DUBBO_ATTACHMENTS_ATTR_NAME)); - - String generic = (String) getAttribute(GENERIC_KEY); - if (StringUtils.isNotEmpty(generic)) { - context.setAttachment(GENERIC_KEY, generic); - } - try { - return super.invoke(targetObject); - } finally { - context.setAttachments(null); - - } - } -} diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol b/dubbo-rpc/dubbo-rpc-http-invoker/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol deleted file mode 100644 index 90763763f6..0000000000 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol +++ /dev/null @@ -1 +0,0 @@ -http-invoker=org.apache.dubbo.rpc.protocol.httpinvoker.HttpInvokerProtocol \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpInvokerProtocolTest.java b/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpInvokerProtocolTest.java deleted file mode 100644 index 046c3b7694..0000000000 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpInvokerProtocolTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.dubbo.rpc.protocol.httpinvoker; - -import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.beanutil.JavaBeanDescriptor; -import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil; -import org.apache.dubbo.common.extension.ExtensionLoader; -import org.apache.dubbo.common.serialize.ObjectInput; -import org.apache.dubbo.common.serialize.ObjectOutput; -import org.apache.dubbo.common.serialize.Serialization; -import org.apache.dubbo.common.serialize.nativejava.NativeJavaSerialization; -import org.apache.dubbo.rpc.Exporter; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.Protocol; -import org.apache.dubbo.rpc.ProxyFactory; -import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.service.GenericService; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.fail; - -/** - * HttpInvokerProtocolTest - */ -public class HttpInvokerProtocolTest { - - @Test - public void testHttpProtocol() { - HttpServiceImpl server = new HttpServiceImpl(); - Assertions.assertFalse(server.isCalled()); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(HttpService.class, url); - HttpService client = proxyFactory.getProxy(invoker); - String result = client.sayHello("haha"); - Assertions.assertTrue(server.isCalled()); - Assertions.assertEquals("Hello, haha", result); - invoker.destroy(); - exporter.unexport(); - } - - @Test - public void testGenericInvoke() { - HttpServiceImpl server = new HttpServiceImpl(); - Assertions.assertFalse(server.isCalled()); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(GenericService.class, url); - GenericService client = proxyFactory.getProxy(invoker, true); - String result = (String) client.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"haha"}); - Assertions.assertTrue(server.isCalled()); - Assertions.assertEquals("Hello, haha", result); - invoker.destroy(); - exporter.unexport(); - } - - @Test - public void testGenericInvokeWithNativeJava() throws IOException, ClassNotFoundException { - HttpServiceImpl server = new HttpServiceImpl(); - Assertions.assertFalse(server.isCalled()); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0&generic=nativejava"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(GenericService.class, url); - GenericService client = proxyFactory.getProxy(invoker); - - Serialization serialization = new NativeJavaSerialization(); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - - ObjectOutput objectOutput = serialization.serialize(url, byteArrayOutputStream); - objectOutput.writeObject("haha"); - objectOutput.flushBuffer(); - - Object result = client.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{byteArrayOutputStream.toByteArray()}); - ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream((byte[]) result); - ObjectInput objectInput = serialization.deserialize(url, byteArrayInputStream); - Assertions.assertTrue(server.isCalled()); - Assertions.assertEquals("Hello, haha", objectInput.readObject()); - invoker.destroy(); - exporter.unexport(); - } - - @Test - public void testGenericInvokeWithBean() { - HttpServiceImpl server = new HttpServiceImpl(); - Assertions.assertFalse(server.isCalled()); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0&generic=bean"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(GenericService.class, url); - GenericService client = proxyFactory.getProxy(invoker); - - JavaBeanDescriptor javaBeanDescriptor = JavaBeanSerializeUtil.serialize("haha"); - - Object result = client.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{javaBeanDescriptor}); - Assertions.assertTrue(server.isCalled()); - Assertions.assertEquals("Hello, haha", JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) result)); - invoker.destroy(); - exporter.unexport(); - } - - @Test - public void testOverload() { - HttpServiceImpl server = new HttpServiceImpl(); - Assertions.assertFalse(server.isCalled()); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0&hessian.overload.method=true&hessian2.request=false"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(HttpService.class, url); - HttpService client = proxyFactory.getProxy(invoker); - String result = client.sayHello("haha"); - Assertions.assertEquals("Hello, haha", result); - result = client.sayHello("haha", 1); - Assertions.assertEquals("Hello, haha. ", result); - invoker.destroy(); - exporter.unexport(); - } - - @Test - public void testSimpleClient() { - HttpServiceImpl server = new HttpServiceImpl(); - Assertions.assertFalse(server.isCalled()); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0&client=simple"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(HttpService.class, url); - HttpService client = proxyFactory.getProxy(invoker); - String result = client.sayHello("haha"); - Assertions.assertTrue(server.isCalled()); - Assertions.assertEquals("Hello, haha", result); - invoker.destroy(); - exporter.unexport(); - } - - @Test - public void testTimeOut() { - HttpServiceImpl server = new HttpServiceImpl(); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0&timeout=10"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(HttpService.class, url); - HttpService client = proxyFactory.getProxy(invoker); - try { - client.timeOut(6000); - fail(); - } catch (RpcException expected) { - Assertions.assertTrue(expected.isTimeout()); - } finally { - invoker.destroy(); - exporter.unexport(); - } - - } - - @Test - public void testCustomException() { - HttpServiceImpl server = new HttpServiceImpl(); - ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension(); - Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension(); - URL url = URL.valueOf("http-invoker://127.0.0.1:5342/" + HttpService.class.getName() + "?release=2.7.0"); - Exporter exporter = protocol.export(proxyFactory.getInvoker(server, HttpService.class, url)); - Invoker invoker = protocol.refer(HttpService.class, url); - HttpService client = proxyFactory.getProxy(invoker); - try { - client.customException(); - fail(); - } catch (HttpServiceImpl.MyException expected) { - } - invoker.destroy(); - exporter.unexport(); - } - -} diff --git a/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpServiceImpl.java b/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpServiceImpl.java deleted file mode 100644 index d47e8134d1..0000000000 --- a/dubbo-rpc/dubbo-rpc-http-invoker/src/test/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpServiceImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.dubbo.rpc.protocol.httpinvoker; - -import org.apache.dubbo.rpc.RpcContext; - -/** - * HttpServiceImpl - */ -public class HttpServiceImpl implements HttpService { - - private boolean called; - - public String sayHello(String name) { - called = true; - return "Hello, " + name; - } - - public String sayHello(String name, int times) { - called = true; - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < times; i++) { - sb.append("Hello, " + name + ". "); - } - return sb.toString(); - } - - public boolean isCalled() { - return called; - } - - public void timeOut(int millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - @Override - public String getRemoteApplicationName() { - return RpcContext.getContext().getRemoteApplicationName(); - } - - public String customException() { - throw new MyException("custom exception"); - } - - static class MyException extends RuntimeException { - - private static final long serialVersionUID = -3051041116483629056L; - - public MyException(String message) { - super(message); - } - } -} diff --git a/dubbo-rpc/dubbo-rpc-jsonrpc/pom.xml b/dubbo-rpc/dubbo-rpc-jsonrpc/pom.xml deleted file mode 100644 index 0963763dd3..0000000000 --- a/dubbo-rpc/dubbo-rpc-jsonrpc/pom.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - dubbo-rpc - org.apache.dubbo - ${revision} - ../pom.xml - - 4.0.0 - - dubbo-rpc-jsonrpc - - The JSON-RPC module of dubbo project - - - false - - - - - org.apache.dubbo - dubbo-rpc-api - ${project.parent.version} - - - org.apache.dubbo - dubbo-remoting-http - ${project.parent.version} - - - org.springframework - spring-context - - - com.github.briandilley.jsonrpc4j - jsonrpc4j - - - javax.portlet - portlet-api - - - - - \ No newline at end of file diff --git a/dubbo-serialization/dubbo-serialization-protobuf/pom.xml b/dubbo-serialization/dubbo-serialization-protobuf/pom.xml index 4c81312e57..65eb7b7a96 100644 --- a/dubbo-serialization/dubbo-serialization-protobuf/pom.xml +++ b/dubbo-serialization/dubbo-serialization-protobuf/pom.xml @@ -29,8 +29,7 @@ limitations under the License. The protobuf serialization module of dubbo project false - - 1.19.0-SNAPSHOT + 0.0.1-SNAPSHOT @@ -61,24 +60,17 @@ limitations under the License. org.xolstice.maven.plugins protobuf-maven-plugin 0.5.1 + true com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier} - grpc-java - - org.apache.dubbo:protoc-gen-dubbo-java:${proto_dubbo_plugin_version}:exe:${os.detected.classifier} - build/generated/source/proto/main/java false - - dubbo compile - compile-custom test-compile - test-compile-custom