diff --git a/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcPostProcessing.java b/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcPostProcessing.java index f6f9dcd2a2491..ca1131b81efaa 100644 --- a/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcPostProcessing.java +++ b/extensions/grpc/codegen/src/main/java/io/quarkus/grpc/deployment/GrpcPostProcessing.java @@ -1,5 +1,6 @@ package io.quarkus.grpc.deployment; +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -9,7 +10,6 @@ import java.util.Map.Entry; import java.util.function.Consumer; -import org.eclipse.microprofile.config.Config; import org.jboss.logging.Logger; import com.github.javaparser.ast.CompilationUnit; @@ -36,15 +36,37 @@ public class GrpcPostProcessing { public static final String STUB = "Stub"; public static final String BIND_METHOD = "bindService"; - private final CodeGenContext context; private final Path root; + private final boolean replaceGeneratedAnnotation; + private final boolean removeFinal; public GrpcPostProcessing(CodeGenContext context, Path root) { - this.context = context; this.root = root; + this.replaceGeneratedAnnotation = isEnabled(context, POST_PROCESS_QUARKUS_GENERATED_ANNOTATION, true); + this.removeFinal = isEnabled(context, POST_PROCESS_NO_FINAL, true); } - private boolean isEnabled(String name, boolean def) { + public GrpcPostProcessing(Path root) { + this.root = root; + this.replaceGeneratedAnnotation = true; + this.removeFinal = true; + } + + /** + * Methods used for the quarkus-grpc-stub project post-processing (as it's not a quarkus app) + * + * @param args expects the path to the source root of the files to post-process. + */ + public static void main(String[] args) { + for (String arg : args) { + Path path = new File(arg).toPath(); + var postprocessing = new GrpcPostProcessing(path); + postprocessing.postprocess(); + } + + } + + private boolean isEnabled(CodeGenContext context, String name, boolean def) { return Boolean.getBoolean(name) || context.config().getOptionalValue(name, Boolean.class).orElse(def); } @@ -61,9 +83,9 @@ public com.github.javaparser.utils.SourceRoot.Callback.Result process(Path local if (unit.getPrimaryType().isPresent()) { TypeDeclaration type = unit.getPrimaryType().get(); - postprocess(unit, type, context.config()); + postprocess(unit, type); - // save to a tempory file first, then move all temporary unit files at the same time + // save to a temporary file first, then move all temporary unit files at the same time try { unit.setStorage(Files.createTempFile(null, null), sr.getParserConfiguration().getCharacterEncoding()) @@ -87,7 +109,7 @@ public com.github.javaparser.utils.SourceRoot.Callback.Result process(Path local } }); - changedFiles.entrySet().stream().forEach(new Consumer>() { + changedFiles.entrySet().forEach(new Consumer>() { @Override public void accept(Entry entry) { try { @@ -103,26 +125,27 @@ public void accept(Entry entry) { // read issue, report and exit log.error("Unable to parse the classes generated using protoc - skipping gRPC post processing", e); } finally { - changedFiles.entrySet().stream().forEach(new Consumer>() { + changedFiles.entrySet().forEach(new Consumer>() { @Override public void accept(Entry e) { try { Files.deleteIfExists(e.getKey()); } catch (IOException discard) { + // Ignore it. } } }); } } - private void postprocess(CompilationUnit unit, TypeDeclaration primary, Config config) { + private void postprocess(CompilationUnit unit, TypeDeclaration primary) { log.debugf("Post-processing %s", primary.getFullyQualifiedName().orElse(primary.getNameAsString())); unit.accept(new ModifierVisitor() { @Override public Visitable visit(NormalAnnotationExpr n, Void arg) { - if (isEnabled(POST_PROCESS_QUARKUS_GENERATED_ANNOTATION, true)) { + if (replaceGeneratedAnnotation) { if (n.getNameAsString().equals(JAVAX_GENERATED)) { n.setName(QUARKUS_GENERATED); } @@ -132,7 +155,7 @@ public Visitable visit(NormalAnnotationExpr n, Void arg) { @Override public Visitable visit(ClassOrInterfaceDeclaration n, Void arg) { - if (isEnabled(POST_PROCESS_NO_FINAL, true)) { + if (removeFinal) { if (n.hasModifier(Modifier.Keyword.FINAL) && n.getNameAsString().endsWith(STUB)) { n.removeModifier(Modifier.Keyword.FINAL); } @@ -142,7 +165,7 @@ public Visitable visit(ClassOrInterfaceDeclaration n, Void arg) { @Override public Visitable visit(MethodDeclaration n, Void arg) { - if (isEnabled(POST_PROCESS_NO_FINAL, true)) { + if (removeFinal) { if (n.hasModifier(Modifier.Keyword.FINAL) && n.getNameAsString().equalsIgnoreCase(BIND_METHOD)) { n.removeModifier(Modifier.Keyword.FINAL); diff --git a/extensions/grpc/stubs/pom.xml b/extensions/grpc/stubs/pom.xml index 8e1ec7c3ed1bd..d3a387d227220 100644 --- a/extensions/grpc/stubs/pom.xml +++ b/extensions/grpc/stubs/pom.xml @@ -17,6 +17,10 @@ io.quarkus quarkus-grpc-api + + io.quarkus + quarkus-grpc-common + io.quarkus quarkus-grpc-codegen @@ -82,9 +86,11 @@ protobuf-maven-plugin 0.6.1 - com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} + com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier} + grpc-java - io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + quarkus-grpc-protoc-plugin @@ -105,6 +111,27 @@ + + + org.codehaus.mojo + exec-maven-plugin + + + post-process + compile + + java + + + true + + ${project.build.directory}/generated-sources/protobuf/grpc-java + + io.quarkus.grpc.deployment.GrpcPostProcessing + + + + diff --git a/extensions/grpc/stubs/src/main/proto/reflection/v1alpha/reflection.proto b/extensions/grpc/stubs/src/main/proto/reflection/v1alpha/reflection.proto index 8057ad5598c88..87030dc30d896 100644 --- a/extensions/grpc/stubs/src/main/proto/reflection/v1alpha/reflection.proto +++ b/extensions/grpc/stubs/src/main/proto/reflection/v1alpha/reflection.proto @@ -11,7 +11,7 @@ service ServerReflection { // The reflection service is structured as a bidirectional stream, ensuring // all related requests go to a single server. rpc ServerReflectionInfo(stream ServerReflectionRequest) - returns (stream ServerReflectionResponse); + returns (stream ServerReflectionResponse); } // The message sent by the client when calling ServerReflectionInfo method.