Skip to content

Commit

Permalink
Add post-processing to the grpc-stubs project
Browse files Browse the repository at this point in the history
This project contains gRPC definitions (.proto) and generates the stubs and skeletons using the regular gRPC tooling (so not the Quarkus one). Thus, it didn't apply the post-processing steps fixing the @generated annotation (to avoid `javax`) and removing the "final" modifiers.

This commit calls the post-processor so the generated files using the maven exec plugin.
  • Loading branch information
cescoffier committed Feb 13, 2023
1 parent ffb4f3f commit 34b4a4d
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -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);
}

Expand All @@ -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())
Expand All @@ -87,7 +109,7 @@ public com.github.javaparser.utils.SourceRoot.Callback.Result process(Path local
}
});

changedFiles.entrySet().stream().forEach(new Consumer<Entry<Path, Path>>() {
changedFiles.entrySet().forEach(new Consumer<Entry<Path, Path>>() {
@Override
public void accept(Entry<Path, Path> entry) {
try {
Expand All @@ -103,26 +125,27 @@ public void accept(Entry<Path, Path> 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<Entry<Path, Path>>() {
changedFiles.entrySet().forEach(new Consumer<Entry<Path, Path>>() {
@Override
public void accept(Entry<Path, Path> 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<Void>() {

@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);
}
Expand All @@ -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);
}
Expand All @@ -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);
Expand Down
31 changes: 29 additions & 2 deletions extensions/grpc/stubs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc-api</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc-common</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-grpc-codegen</artifactId>
Expand Down Expand Up @@ -82,9 +86,11 @@
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}</protocArtifact>
<protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
</pluginArtifact>
<protocPlugins>
<protocPlugin>
<id>quarkus-grpc-protoc-plugin</id>
Expand All @@ -105,6 +111,27 @@
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>post-process</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<includeProjectDependencies>true</includeProjectDependencies>
<arguments>
<argument>${project.build.directory}/generated-sources/protobuf/grpc-java</argument>
</arguments>
<mainClass>io.quarkus.grpc.deployment.GrpcPostProcessing</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 34b4a4d

Please sign in to comment.