You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/11/28 07:29:36 UTC
[dubbo] branch 2.7.5-release updated: Refactor protobuf compiler
support (gRPC and Dubbo), add Reactive gRPC support.
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 2.7.5-release
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/2.7.5-release by this push:
new 9eaf949 Refactor protobuf compiler support (gRPC and Dubbo), add Reactive gRPC support.
9eaf949 is described below
commit 9eaf949998949a459352bd02d53de2e241d87968
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Nov 28 15:28:36 2019 +0800
Refactor protobuf compiler support (gRPC and Dubbo), add Reactive gRPC support.
---
LICENSE | 6 +-
NOTICE | 9 -
compiler/.gradle/4.3/fileChanges/last-build.bin | Bin 1 -> 0 bytes
.../4.3/fileContent/annotation-processors.bin | Bin 19793 -> 0 bytes
compiler/.gradle/4.3/fileContent/fileContent.lock | Bin 17 -> 0 bytes
compiler/.gradle/4.3/fileHashes/fileHashes.bin | Bin 523091 -> 0 bytes
compiler/.gradle/4.3/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes
.../.gradle/4.3/fileHashes/resourceHashesCache.bin | Bin 193707 -> 0 bytes
.../.gradle/4.3/nativeCompile/nativeCompile.bin | Bin 18497 -> 0 bytes
.../.gradle/4.3/nativeCompile/nativeCompile.lock | Bin 17 -> 0 bytes
compiler/.gradle/4.3/taskHistory/taskHistory.bin | Bin 5498488 -> 0 bytes
compiler/.gradle/4.3/taskHistory/taskHistory.lock | Bin 17 -> 0 bytes
compiler/.gradle/4.9/fileChanges/last-build.bin | Bin 1 -> 0 bytes
.../4.9/fileContent/annotation-processors.bin | Bin 19064 -> 0 bytes
compiler/.gradle/4.9/fileContent/fileContent.lock | Bin 17 -> 0 bytes
compiler/.gradle/4.9/fileContent/parsedCSource.bin | Bin 4544877 -> 0 bytes
compiler/.gradle/4.9/fileHashes/fileHashes.bin | Bin 883135 -> 0 bytes
compiler/.gradle/4.9/fileHashes/fileHashes.lock | Bin 17 -> 0 bytes
.../.gradle/4.9/fileHashes/resourceHashesCache.bin | Bin 397477 -> 0 bytes
.../.gradle/4.9/nativeCompile/nativeCompile.bin | Bin 62218 -> 0 bytes
.../.gradle/4.9/nativeCompile/nativeCompile.lock | Bin 17 -> 0 bytes
compiler/.gradle/4.9/taskHistory/taskHistory.bin | Bin 12084605 -> 0 bytes
compiler/.gradle/4.9/taskHistory/taskHistory.lock | Bin 17 -> 0 bytes
.../buildOutputCleanup/buildOutputCleanup.lock | Bin 17 -> 0 bytes
.../.gradle/buildOutputCleanup/cache.properties | 2 -
.../.gradle/buildOutputCleanup/outputFiles.bin | Bin 57857 -> 0 bytes
compiler/.gradle/vcsWorkingDirs/gc.properties | 0
compiler/BUILD.bazel | 12 -
compiler/README.md | 202 ---
compiler/build.gradle | 406 -----
compiler/check-artifact.sh | 131 --
compiler/gradle/wrapper/gradle-wrapper.jar | Bin 54413 -> 0 bytes
compiler/gradle/wrapper/gradle-wrapper.properties | 5 -
compiler/gradlew | 172 ---
compiler/gradlew.bat | 84 --
compiler/pom.xml | 178 +++
.../src/java_plugin/cpp/java_dubbo_generator.cpp | 580 --------
compiler/src/java_plugin/cpp/java_generator.cpp | 1558 --------------------
compiler/src/java_plugin/cpp/java_generator.h | 78 -
compiler/src/java_plugin/cpp/java_plugin.cpp | 87 --
.../org/apache/dubbo/gen/AbstractGenerator.java | 293 ++++
.../org/apache/dubbo/gen/dubbo/DubboGenerator.java | 42 +
.../apache/dubbo/gen/grpc/DubboGrpcGenerator.java | 41 +
.../grpc/reactive/ReactorDubboGrpcGenerator.java | 42 +
.../gen/grpc/reactive/RxDubboGrpcGenerator.java | 41 +
compiler/src/main/resources/DubboGrpcStub.mustache | 312 ++++
compiler/src/main/resources/DubboStub.mustache | 53 +
.../main/resources/ReactorDubboGrpcStub.mustache | 212 +++
.../src/main/resources/RxDubboGrpcStub.mustache | 246 ++++
.../dubbo/rpc/protocol/grpc/GrpcOptionsUtils.java | 11 +-
.../dubbo/rpc/protocol/grpc/GrpcProtocol.java | 11 +-
.../dubbo-serialization-protobuf/pom.xml | 12 +-
52 files changed, 1476 insertions(+), 3350 deletions(-)
diff --git a/LICENSE b/LICENSE
index 02ae1cd..03d3e19 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 8d33f86..83785ff 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 f76dd23..0000000
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 aa6e57c..0000000
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 f0536e6..0000000
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 d219abd..0000000
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 067763a..0000000
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 827d8b9..0000000
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 7c2e6cd..0000000
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 91ced25..0000000
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 70d6d25..0000000
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 a68d1b7..0000000
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 f76dd23..0000000
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 ea3f5e8..0000000
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 6766d56..0000000
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 d63153f..0000000
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 656cb52..0000000
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 4c4991c..0000000
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 fa0f984..0000000
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 f68f4d2..0000000
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 7e2f718..0000000
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 6467c7d..0000000
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 bfdcb35..0000000
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 287f9ed..0000000
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 0a57826..0000000
--- 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 8bd6f36..0000000
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 e69de29..0000000
diff --git a/compiler/BUILD.bazel b/compiler/BUILD.bazel
deleted file mode 100644
index 1a2f2f3..0000000
--- 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 6a8a643..0000000
--- 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
- <build>
- <extensions>
- <extension>
- <groupId>kr.motd.maven</groupId>
- <artifactId>os-maven-plugin</artifactId>
- <version>1.6.1</version>
- </extension>
- </extensions>
- <plugins>
- <plugin>
- <groupId>org.xolstice.maven.plugins</groupId>
- <artifactId>protobuf-maven-plugin</artifactId>
- <version>0.5.1</version>
- <configuration>
- <protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
- <pluginId>grpc-java</pluginId>
- <pluginArtifact>org.apache.dubbo:protoc-gen-dubbo-java:${proto_dubbo_plugin_version}:exe:${os.detected.classifier}</pluginArtifact>
- <outputDirectory>build/generated/source/proto/main/java</outputDirectory>
- <clearOutputDirectory>false</clearOutputDirectory>
- <!-- supports 'dubbo' and 'grpc' -->
- <pluginParameter>dubbo</pluginParameter>
- </configuration>
- <executions>
- <execution>
- <goals>
- <goal>compile</goal>
- <goal>compile-custom</goal>
- <goal>test-compile</goal>
- <goal>test-compile-custom</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- </goals>
- <configuration>
- <sources>
- <source>build/generated/source/proto/main/java</source>
- </sources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-```
-
-2. Decide which protocol to use: Dubbo or gRPC
- * Dubbo, ` <pluginParameter>dubbo</pluginParameter>`
- * gRPC, ` <pluginParameter>grpc</pluginParameter>`
-
-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<io.grpc.examples.helloworld.HelloReply> 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<io.grpc.examples.helloworld.HelloReply> 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<io.grpc.examples.helloworld.HelloReply> 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<io.grpc.examples.helloworld.HelloReply> 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<io.grpc.examples.helloworld.HelloReply> 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<io.grpc.examples.helloworld.HelloReply> 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 f94fef7..0000000
--- 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 05b57a1..0000000
--- 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 <OS> <ARCH>
-# <OS> and <ARCH> 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 <path-to-protoc>
-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 <path-to-protoc>
-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 0d4a951..0000000
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 a95009c..0000000
--- 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 cccdd3d..0000000
--- 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 f955316..0000000
--- 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 0000000..d0df460
--- /dev/null
+++ b/compiler/pom.xml
@@ -0,0 +1,178 @@
+<!--
+ 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.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>21</version>
+ </parent>
+
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-compiler</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
+
+ <packaging>jar</packaging>
+
+ <properties>
+ <maven_compiler_version>3.6.0</maven_compiler_version>
+ <maven_jar_version>3.0.2</maven_jar_version>
+ <java_source_version>1.8</java_source_version>
+ <java_target_version>1.8</java_target_version>
+ <file_encoding>UTF-8</file_encoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.salesforce.servicelibs</groupId>
+ <artifactId>grpc-contrib</artifactId>
+ <version>0.8.1</version>
+ </dependency>
+ <dependency>
+ <groupId>com.salesforce.servicelibs</groupId>
+ <artifactId>jprotoc</artifactId>
+ <version>0.9.1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>${maven_compiler_version}</version>
+ <configuration>
+ <compilerArgument>-proc:none</compilerArgument>
+ <fork>true</fork>
+ <source>${java_source_version}</source>
+ <target>${java_target_version}</target>
+ <encoding>${file_encoding}</encoding>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>${maven_jar_version}</version>
+ <configuration>
+ <archive>
+ <manifest>
+ <!-- <addClasspath>true</addClasspath>-->
+ <mainClass>org.apache.dubbo.gen.grpc.DubboGrpcGenerator</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+
+ <!-- Optional, used to build directly executable packages (without using 'java -jar'),
+ for example 'artifactId-1.0.0-osx-x86_64.exe', 'artifactId-1.0.0-osx-x86_64.exe' -->
+ <plugin>
+ <groupId>com.salesforce.servicelibs</groupId>
+ <artifactId>canteen-maven-plugin</artifactId>
+ <version>1.0.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>bootstrap</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>release</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+ <name>dubbo-compiler</name>
+ <description>Dubbo customized RPC stub compiler.</description>
+ <url>https://github.com/apache/dubbo</url>
+ <inceptionYear>2011</inceptionYear>
+ <licenses>
+ <license>
+ <name>Apache License, Version 2.0</name>
+ <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+ <distribution>repo</distribution>
+ </license>
+ </licenses>
+
+ <scm>
+ <url>https://github.com/apache/dubbo</url>
+ <connection>scm:git:https://github.com/apache/dubbo.git</connection>
+ <developerConnection>scm:git:https://github.com/apache/dubbo.git</developerConnection>
+ <tag>HEAD</tag>
+ </scm>
+ <mailingLists>
+ <mailingList>
+ <name>Development List</name>
+ <subscribe>dev-subscribe@dubbo.apache.org</subscribe>
+ <unsubscribe>dev-unsubscribe@dubbo.apache.org</unsubscribe>
+ <post>dev@dubbo.apache.org</post>
+ </mailingList>
+ <mailingList>
+ <name>Commits List</name>
+ <subscribe>commits-subscribe@dubbo.apache.org</subscribe>
+ <unsubscribe>commits-unsubscribe@dubbo.apache.org</unsubscribe>
+ <post>commits@dubbo.apache.org</post>
+ </mailingList>
+ <mailingList>
+ <name>Issues List</name>
+ <subscribe>issues-subscribe@dubbo.apache.org</subscribe>
+ <unsubscribe>issues-unsubscribe@dubbo.apache.org</unsubscribe>
+ <post>issues@dubbo.apache.org</post>
+ </mailingList>
+ </mailingLists>
+ <developers>
+ <developer>
+ <id>dubbo.io</id>
+ <name>The Dubbo Project Contributors</name>
+ <email>dev-subscribe@dubbo.apache.org</email>
+ <url>http://dubbo.apache.org/</url>
+ </developer>
+ </developers>
+
+ <organization>
+ <name>The Apache Software Foundation</name>
+ <url>http://www.apache.org/</url>
+ </organization>
+
+ <issueManagement>
+ <system>Github Issues</system>
+ <url>https://github.com/apache/dubbo/issues</url>
+ </issueManagement>
+</project>
\ 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 8e7d7b1..0000000
--- a/compiler/src/java_plugin/cpp/java_dubbo_generator.cpp
+++ /dev/null
@@ -1,580 +0,0 @@
-#include "java_generator.h"
-
-#include <algorithm>
-#include <iostream>
-#include <iterator>
-#include <map>
-#include <set>
-#include <vector>
-#include <google/protobuf/compiler/java/java_names.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-
-// 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<string> 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 <typename ITR>
-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<string>* result) {
- std::back_insert_iterator< std::vector<string> > it(*result);
- GrpcSplitStringToIteratorUsing(full, delim, it);
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-static std::vector<string> GrpcSplit(const string& full, const char* delim) {
- std::vector<string> 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 <typename DescriptorType>
-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<string> 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 <pre> 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<string> lines = GrpcSplit(escapedComments, "\n");
- while (!lines.empty() && lines.back().empty()) {
- lines.pop_back();
- }
- return lines;
- }
- return std::vector<string>();
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-template <typename DescriptorType>
-static std::vector<string> 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<string>& lines,
- bool surroundWithPreTag) {
- if (!lines.empty()) {
- if (surroundWithPreTag) {
- printer->Print(" * <pre>\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(" * </pre>\n");
- }
- }
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-static void GrpcWriteDocComment(Printer* printer, const string& comments) {
- printer->Print("/**\n");
- std::vector<string> 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<string> 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<string> 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<string, string>* 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<string, string>* 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<string, string>* 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<string, string> 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 98093ca..0000000
--- a/compiler/src/java_plugin/cpp/java_generator.cpp
+++ /dev/null
@@ -1,1558 +0,0 @@
-#include "java_generator.h"
-
-#include <algorithm>
-#include <iostream>
-#include <iterator>
-#include <map>
-#include <set>
-#include <vector>
-#include <google/protobuf/compiler/java/java_names.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-
-// 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<string> 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 <typename ITR>
-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<string>* result) {
- std::back_insert_iterator< std::vector<string> > it(*result);
- GrpcSplitStringToIteratorUsing(full, delim, it);
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-static std::vector<string> GrpcSplit(const string& full, const char* delim) {
- std::vector<string> 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 <typename DescriptorType>
-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<string> 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 <pre> 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<string> lines = GrpcSplit(escapedComments, "\n");
- while (!lines.empty() && lines.back().empty()) {
- lines.pop_back();
- }
- return lines;
- }
- return std::vector<string>();
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-template <typename DescriptorType>
-static std::vector<string> 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<string>& lines,
- bool surroundWithPreTag) {
- if (!lines.empty()) {
- if (surroundWithPreTag) {
- printer->Print(" * <pre>\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(" * </pre>\n");
- }
- }
-}
-
-// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
-static void GrpcWriteDocComment(Printer* printer, const string& comments) {
- printer->Print("/**\n");
- std::vector<string> 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<string> 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<string> lines = GrpcGetDocLinesForDescriptor(method);
- GrpcWriteDocCommentBody(printer, lines, true);
- printer->Print(" */\n");
-}
-
-static void PrintMethodFields(
- const ServiceDescriptor* service, std::map<string, string>* 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<T extends com.google.protobuf.nano.MessageNano>\n"
- " implements io.grpc.protobuf.nano.MessageNanoFactory<T> {\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<string, string>* 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<string, string>* 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<string, string>* 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<string, string>* 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<string, string>* vars,
- Printer* p,
- bool generate_nano) {
- // Sort method ids based on client_streaming() so switch tables are compact.
- std::vector<const MethodDescriptor*> 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<Req, Resp> implements\n"
- " io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,\n"
- " io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,\n"
- " io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,\n"
- " io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {\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$<Resp> 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$<Req> invoke(\n"
- " $StreamObserver$<Resp> 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$<Req>) 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<string, string>* 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<string, string>* 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<string, string>* 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<string, string> 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 7106c54..0000000
--- 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 <stdlib.h> // for abort()
-#include <iostream>
-#include <string>
-
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/descriptor.h>
-
-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 c8af98c..0000000
--- 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 <memory>
-
-#include "java_generator.h"
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/compiler/plugin.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-
-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<std::pair<string, string> > 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<google::protobuf::io::ZeroCopyOutputStream> 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<google::protobuf::io::ZeroCopyOutputStream> 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 0000000..3e8dee1
--- /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<PluginProtos.CodeGeneratorResponse.File> generateFiles(PluginProtos.CodeGeneratorRequest request) throws GeneratorException {
+ final ProtoTypeMap typeMap = ProtoTypeMap.of(request.getProtoFileList());
+
+ List<FileDescriptorProto> protosToGenerate = request.getProtoFileList().stream()
+ .filter(protoFile -> request.getFileToGenerateList().contains(protoFile.getName()))
+ .collect(Collectors.toList());
+
+ List<ServiceContext> services = findServices(protosToGenerate, typeMap);
+ return generateFiles(services);
+ }
+
+ private List<ServiceContext> findServices(List<FileDescriptorProto> protos, ProtoTypeMap typeMap) {
+ List<ServiceContext> 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<Location> 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<Location> 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<Location> 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<PluginProtos.CodeGeneratorResponse.File> generateFiles(List<ServiceContext> 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(" * <pre>\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(" * </pre>\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<MethodContext> methods = new ArrayList<>();
+
+ public Set<String> methodTypes = new HashSet<>();
+
+ public List<MethodContext> unaryRequestMethods() {
+ return methods.stream().filter(m -> !m.isManyInput).collect(Collectors.toList());
+ }
+
+ public List<MethodContext> unaryMethods() {
+ return methods.stream().filter(m -> (!m.isManyInput && !m.isManyOutput)).collect(Collectors.toList());
+ }
+
+ public List<MethodContext> serverStreamingMethods() {
+ return methods.stream().filter(m -> !m.isManyInput && m.isManyOutput).collect(Collectors.toList());
+ }
+
+ public List<MethodContext> 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/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.java
new file mode 100644
index 0000000..1c35f0a
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/dubbo/DubboGenerator.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.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/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.java
new file mode 100644
index 0000000..dafdd5a
--- /dev/null
+++ b/compiler/src/main/java/org/apache/dubbo/gen/grpc/DubboGrpcGenerator.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;
+
+import org.apache.dubbo.gen.AbstractGenerator;
+
+import com.salesforce.jprotoc.ProtocPlugin;
+
+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 0000000..dd9520b
--- /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 0000000..028332a
--- /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 0000000..a02d0c4
--- /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
+<Req, Resp> implements
+io.grpc.stub.ServerCalls.UnaryMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ServerStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ClientStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.BidiStreamingMethod
+<Req, Resp> {
+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
+<Resp> 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
+ <Req> invoke(io.grpc.stub.StreamObserver
+ <Resp> responseObserver) {
+ switch (methodId) {
+ {{#methods}}
+ {{#isManyInput}}
+ case METHODID_{{methodNameUpperUnderscore}}:
+ return (io.grpc.stub.StreamObserver
+ <Req>) 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 0000000..06bd7b4
--- /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 0000000..919f62e
--- /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.ChatStub 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.ChatStub 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
+<Req, Resp> implements
+io.grpc.stub.ServerCalls.UnaryMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ServerStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ClientStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.BidiStreamingMethod
+<Req, Resp> {
+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
+<Resp> 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
+ <Req> invoke(io.grpc.stub.StreamObserver
+ <Resp> responseObserver) {
+ switch (methodId) {
+ {{#methods}}
+ {{#isManyInput}}
+ case METHODID_{{methodNameUpperUnderscore}}:
+ return (io.grpc.stub.StreamObserver
+ <Req>) 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 0000000..22c06b0
--- /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<{{outputType}}>, 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
+<Req, Resp> implements
+io.grpc.stub.ServerCalls.UnaryMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ServerStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.ClientStreamingMethod
+<Req, Resp>,
+io.grpc.stub.ServerCalls.BidiStreamingMethod
+<Req, Resp> {
+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
+<Resp> 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
+ <Req> invoke(io.grpc.stub.StreamObserver
+ <Resp> responseObserver) {
+ switch (methodId) {
+ {{#methods}}
+ {{#isManyInput}}
+ case METHODID_{{methodNameUpperUnderscore}}:
+ return (io.grpc.stub.StreamObserver
+ <Req>) 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-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 c30ce1d..cfc02d7 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 8a1188f..8381a3f 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<T> target = proxyFactory.getInvoker(stub, type, url);
GrpcInvoker<T> grpcInvoker = new GrpcInvoker<>(type, url, target, channel);
invokers.add(grpcInvoker);
diff --git a/dubbo-serialization/dubbo-serialization-protobuf/pom.xml b/dubbo-serialization/dubbo-serialization-protobuf/pom.xml
index 4c81312..65eb7b7 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.
<description>The protobuf serialization module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
- <!-- /compiler/build.gradle -->
- <proto_dubbo_plugin_version>1.19.0-SNAPSHOT</proto_dubbo_plugin_version>
+ <dubbo.compiler.version>0.0.1-SNAPSHOT</dubbo.compiler.version>
</properties>
<dependencies>
<dependency>
@@ -61,24 +60,17 @@ limitations under the License.
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
+ <extensions>true</extensions>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
- <pluginId>grpc-java</pluginId>
- <pluginArtifact>
- org.apache.dubbo:protoc-gen-dubbo-java:${proto_dubbo_plugin_version}:exe:${os.detected.classifier}
- </pluginArtifact>
<outputDirectory>build/generated/source/proto/main/java</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
- <!-- supports 'dubbo' and 'grpc' -->
- <pluginParameter>dubbo</pluginParameter>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
- <goal>compile-custom</goal>
<goal>test-compile</goal>
- <goal>test-compile-custom</goal>
</goals>
</execution>
</executions>