Skip to content

Commit

Permalink
Document gRPC code generation
Browse files Browse the repository at this point in the history
Also:

- Allows configuring the `proto` directory (quarkusio#12802)
- Provides Gradle snippets (quarkusio#33854)
  • Loading branch information
cescoffier authored and holly-cummins committed Feb 8, 2024
1 parent a37d162 commit 4cb5dbf
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 163 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

import org.eclipse.microprofile.config.Config;
import org.wildfly.common.annotation.NotNull;

import io.quarkus.bootstrap.model.ApplicationModel;
import io.quarkus.bootstrap.prebuild.CodeGenException;

/**
* Service providers for this interface are triggered during generate-sources phase of build of Quarkus applications
*/
public interface CodeGenProvider {
/**
*
* @return unique name of the code gen provider, will correspond to the directory in <code>generated-sources</code>
*/
@NotNull
Expand All @@ -38,6 +39,32 @@ public interface CodeGenProvider {
@NotNull
String inputDirectory();

/**
* Provides the possibility for the provider to override the default input directory.
* This method is called after {@link #init(ApplicationModel, Map)}.
* Returning {@code null} will result in the {@code inputDirectory} method being called to retrieve the default input
* directory.
* <p>
* The returned path must be an absolute path. However, pointing to a directory outside of the project structure should
* be avoided for security purposes.
*
* @return the input directory, must be an absolute path. {@code null} would result in the default input directory being
* used.
*/
default Path getInputDirectory() {
return null;
}

/**
* Provides the possibility for the provider to initialize itself using the application model and properties.
*
* @param model the application model
* @param properties the build time properties defined in the application build file (pom.xml or gradle.build)
*/
default void init(ApplicationModel model, Map<String, String> properties) {
// No-op
}

/**
* Trigger code generation
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ public static void initAndRun(QuarkusClassLoader classLoader,
PathCollection sourceParentDirs, Path generatedSourcesDir, Path buildDir,
Consumer<Path> sourceRegistrar, ApplicationModel appModel, Properties properties,
String launchMode, boolean test) throws CodeGenException {
final List<CodeGenData> generators = init(classLoader, sourceParentDirs, generatedSourcesDir, buildDir,
Map<String, String> props = new HashMap<>();
properties.entrySet().stream().forEach(e -> props.put((String) e.getKey(), (String) e.getValue()));
final List<CodeGenData> generators = init(appModel, props, classLoader, sourceParentDirs, generatedSourcesDir, buildDir,
sourceRegistrar);
if (generators.isEmpty()) {
return;
Expand All @@ -77,7 +79,10 @@ public static void initAndRun(QuarkusClassLoader classLoader,
}
}

private static List<CodeGenData> init(ClassLoader deploymentClassLoader,
private static List<CodeGenData> init(
ApplicationModel model,
Map<String, String> properties,
ClassLoader deploymentClassLoader,
PathCollection sourceParentDirs,
Path generatedSourcesDir,
Path buildDir,
Expand All @@ -89,24 +94,29 @@ private static List<CodeGenData> init(ClassLoader deploymentClassLoader,
}
final List<CodeGenData> result = new ArrayList<>(codeGenProviders.size());
for (CodeGenProvider provider : codeGenProviders) {
provider.init(model, properties);
Path outputDir = codeGenOutDir(generatedSourcesDir, provider, sourceRegistrar);
for (Path sourceParentDir : sourceParentDirs) {
Path in = provider.getInputDirectory();
if (in == null) {
in = sourceParentDir.resolve(provider.inputDirectory());
}
result.add(
new CodeGenData(provider, outputDir, sourceParentDir.resolve(provider.inputDirectory()), buildDir));
new CodeGenData(provider, outputDir, in, buildDir));
}
}
return result;
});
}

public static List<CodeGenData> init(ClassLoader deploymentClassLoader, Collection<ModuleInfo> modules)
public static List<CodeGenData> init(ApplicationModel model, Map<String, String> properties,
ClassLoader deploymentClassLoader, Collection<ModuleInfo> modules)
throws CodeGenException {
return callWithClassloader(deploymentClassLoader, () -> {
List<CodeGenProvider> codeGenProviders = null;
List<CodeGenData> codeGens = List.of();
for (DevModeContext.ModuleInfo module : modules) {
if (!module.getSourceParents().isEmpty() && module.getPreBuildOutputDir() != null) { // it's null for remote dev

if (codeGenProviders == null) {
codeGenProviders = loadCodeGenProviders(deploymentClassLoader);
if (codeGenProviders.isEmpty()) {
Expand All @@ -115,14 +125,19 @@ public static List<CodeGenData> init(ClassLoader deploymentClassLoader, Collecti
}

for (CodeGenProvider provider : codeGenProviders) {
provider.init(model, properties);
Path outputDir = codeGenOutDir(Path.of(module.getPreBuildOutputDir()), provider,
sourcePath -> module.addSourcePathFirst(sourcePath.toAbsolutePath().toString()));
for (Path sourceParentDir : module.getSourceParents()) {
if (codeGens.isEmpty()) {
codeGens = new ArrayList<>();
}
Path in = provider.getInputDirectory();
if (in == null) {
in = sourceParentDir.resolve(provider.inputDirectory());
}
codeGens.add(
new CodeGenData(provider, outputDir, sourceParentDir.resolve(provider.inputDirectory()),
new CodeGenData(provider, outputDir, in,
Path.of(module.getTargetDir())));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class CodeGenWatcher {

CodeGenWatcher(CuratedApplication curatedApplication, DevModeContext context) throws CodeGenException {
final QuarkusClassLoader deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
final List<CodeGenData> codeGens = CodeGenerator.init(deploymentClassLoader, context.getAllModules());
final List<CodeGenData> codeGens = CodeGenerator.init(curatedApplication.getApplicationModel(),
context.getBuildSystemProperties(),
deploymentClassLoader, context.getAllModules());
if (codeGens.isEmpty()) {
fsWatchUtil = null;
this.deploymentClassLoader = null;
Expand Down
Loading

0 comments on commit 4cb5dbf

Please sign in to comment.