Skip to content

Commit

Permalink
Config Doc - Allow to override the top level prefix
Browse files Browse the repository at this point in the history
This is useful in extreme cases such as with ConfigConfig.

Fixes #42372
  • Loading branch information
gsmet committed Aug 9, 2024
1 parent cf7f9aa commit 3509ad8
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
public final class DiscoveryConfigRoot extends DiscoveryRootElement {

private final String prefix;
private final String overriddenDocPrefix;
private final ConfigPhase phase;
private final String overriddenDocFileName;

public DiscoveryConfigRoot(Extension extension, String prefix, String binaryName, String qualifiedName,
public DiscoveryConfigRoot(Extension extension, String prefix, String overriddenDocPrefix,
String binaryName, String qualifiedName,
ConfigPhase configPhase, String overriddenDocFileName, boolean configMapping) {
super(extension, binaryName, qualifiedName, configMapping);

this.prefix = prefix;
this.overriddenDocPrefix = overriddenDocPrefix;
this.phase = configPhase;
this.overriddenDocFileName = overriddenDocFileName;
}
Expand All @@ -27,6 +30,10 @@ public String getPrefix() {
return prefix;
}

public String getOverriddenDocPrefix() {
return overriddenDocPrefix;
}

public ConfigPhase getPhase() {
return phase;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import io.quarkus.annotation.processor.documentation.config.util.Markers;

/**
* At this stage, a config root is actually a prefix: we merged all the config roots with the same prefix.
Expand All @@ -17,14 +20,19 @@ public class ConfigRoot implements ConfigItemCollection {

private final Extension extension;
private final String prefix;
// used by the doc generation to classify config roots
private final String topLevelPrefix;

private String overriddenDocFileName;
private final String overriddenDocFileName;
private final List<AbstractConfigItem> items = new ArrayList<>();
private final Set<String> qualifiedNames = new HashSet<>();

public ConfigRoot(Extension extension, String prefix) {
public ConfigRoot(Extension extension, String prefix, String overriddenDocPrefix, String overriddenDocFileName) {
this.extension = extension;
this.prefix = prefix;
this.overriddenDocFileName = overriddenDocFileName;
this.topLevelPrefix = overriddenDocPrefix != null ? buildTopLevelPrefix(overriddenDocPrefix)
: buildTopLevelPrefix(prefix);
}

public Extension getExtension() {
Expand All @@ -39,13 +47,6 @@ public String getOverriddenDocFileName() {
return overriddenDocFileName;
}

public void setOverriddenDocFileName(String overriddenDocFileName) {
if (this.overriddenDocFileName != null) {
return;
}
this.overriddenDocFileName = overriddenDocFileName;
}

public void addQualifiedName(String qualifiedName) {
qualifiedNames.add(qualifiedName);
}
Expand All @@ -64,6 +65,10 @@ public List<AbstractConfigItem> getItems() {
return Collections.unmodifiableList(items);
}

public String getTopLevelPrefix() {
return topLevelPrefix;
}

public void merge(ConfigRoot other) {
this.qualifiedNames.addAll(other.getQualifiedNames());

Expand Down Expand Up @@ -116,4 +121,14 @@ public boolean hasMemorySizeType() {
}
return false;
}

private static String buildTopLevelPrefix(String prefix) {
String[] prefixSegments = prefix.split(Pattern.quote(Markers.DOT));

if (prefixSegments.length == 1) {
return prefixSegments[0];
}

return prefixSegments[0] + Markers.DOT + prefixSegments[1];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ public ResolvedModel resolveModel() {
List<ConfigRoot> configRoots = new ArrayList<>();

for (DiscoveryConfigRoot discoveryConfigRoot : configCollector.getConfigRoots()) {
ConfigRoot configRoot = new ConfigRoot(discoveryConfigRoot.getExtension(), discoveryConfigRoot.getPrefix());
ConfigRoot configRoot = new ConfigRoot(discoveryConfigRoot.getExtension(), discoveryConfigRoot.getPrefix(),
discoveryConfigRoot.getOverriddenDocPrefix(), discoveryConfigRoot.getOverriddenDocFileName());
Map<String, ConfigSection> existingRootConfigSections = new HashMap<>();

configRoot.setOverriddenDocFileName(discoveryConfigRoot.getOverriddenDocFileName());
configRoot.addQualifiedName(discoveryConfigRoot.getQualifiedName());

ResolutionContext context = new ResolutionContext(configRoot.getPrefix(), new ArrayList<>(), discoveryConfigRoot,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public void scanConfigMappingsWithoutConfigRoot(RoundEnvironment roundEnv, TypeE
try {
// we need to forge a dummy DiscoveryConfigRoot
// it's mostly ignored in the listeners, except for checking if it's a config mapping (for mixed modules)
DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(), "dummy",
DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(), "dummy", "dummy",
utils.element().getBinaryName(configMappingWithoutConfigRoot),
configMappingWithoutConfigRoot.getQualifiedName().toString(),
ConfigPhase.BUILD_TIME, null, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {

AnnotationMirror configRootAnnotation = null;
AnnotationMirror configMappingAnnotion = null;
AnnotationMirror configDocPrefixAnnotation = null;
AnnotationMirror configDocFileNameAnnotation = null;

for (AnnotationMirror annotationMirror : configRoot.getAnnotationMirrors()) {
Expand All @@ -51,6 +52,10 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
configMappingAnnotion = annotationMirror;
continue;
}
if (annotationName.equals(Types.ANNOTATION_CONFIG_DOC_PREFIX)) {
configDocPrefixAnnotation = annotationMirror;
continue;
}
if (annotationName.equals(Types.ANNOTATION_CONFIG_DOC_FILE_NAME)) {
configDocFileNameAnnotation = annotationMirror;
continue;
Expand All @@ -76,6 +81,18 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
}
}

String overriddenDocPrefix = null;
if (configDocPrefixAnnotation != null) {
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : configDocPrefixAnnotation
.getElementValues()
.entrySet()) {
if ("value()".equals(entry.getKey().toString())) {
overriddenDocPrefix = entry.getValue().getValue().toString();
break;
}
}
}

String overriddenDocFileName = null;
if (configDocFileNameAnnotation != null) {
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : configDocFileNameAnnotation
Expand All @@ -91,7 +108,8 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
String rootPrefix = ConfigNamingUtil.getRootPrefix(prefix, "", configRoot.getSimpleName().toString(), configPhase);
String binaryName = utils.element().getBinaryName(configRoot);

DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(), rootPrefix,
DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(),
rootPrefix, overriddenDocPrefix,
binaryName, configRoot.getQualifiedName().toString(), configPhase, overriddenDocFileName, true);
configCollector.addConfigRoot(discoveryConfigRoot);
return Optional.of(discoveryConfigRoot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
ConfigPhase configPhase = ConfigPhase.BUILD_TIME;

AnnotationMirror configRootAnnotation = null;
AnnotationMirror configDocPrefixAnnotation = null;
AnnotationMirror configDocFileNameAnnotation = null;

for (AnnotationMirror annotationMirror : configRoot.getAnnotationMirrors()) {
Expand All @@ -48,6 +49,10 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
configRootAnnotation = annotationMirror;
continue;
}
if (annotationName.equals(Types.ANNOTATION_CONFIG_DOC_PREFIX)) {
configDocPrefixAnnotation = annotationMirror;
continue;
}
if (annotationName.equals(Types.ANNOTATION_CONFIG_DOC_FILE_NAME)) {
configDocFileNameAnnotation = annotationMirror;
continue;
Expand All @@ -73,6 +78,18 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
}
}

String overriddenDocPrefix = null;
if (configDocPrefixAnnotation != null) {
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : configDocPrefixAnnotation
.getElementValues()
.entrySet()) {
if ("value()".equals(entry.getKey().toString())) {
overriddenDocPrefix = entry.getValue().getValue().toString();
break;
}
}
}

String overriddenDocFileName = null;
if (configDocFileNameAnnotation != null) {
for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : configDocFileNameAnnotation
Expand All @@ -88,7 +105,8 @@ public Optional<DiscoveryConfigRoot> onConfigRoot(TypeElement configRoot) {
String rootPrefix = ConfigNamingUtil.getRootPrefix(prefix, name, configRoot.getSimpleName().toString(), configPhase);
String binaryName = utils.element().getBinaryName(configRoot);

DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(), rootPrefix,
DiscoveryConfigRoot discoveryConfigRoot = new DiscoveryConfigRoot(config.getExtension(),
rootPrefix, overriddenDocPrefix,
binaryName, configRoot.getQualifiedName().toString(),
configPhase, overriddenDocFileName, false);
configCollector.addConfigRoot(discoveryConfigRoot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private Types() {
public static final String ANNOTATION_CONFIG_DOC_ENUM_VALUE = "io.quarkus.runtime.annotations.ConfigDocEnumValue";
public static final String ANNOTATION_CONFIG_DOC_DEFAULT = "io.quarkus.runtime.annotations.ConfigDocDefault";
public static final String ANNOTATION_CONFIG_DOC_FILE_NAME = "io.quarkus.runtime.annotations.ConfigDocFilename";
public static final String ANNOTATION_CONFIG_DOC_PREFIX = "io.quarkus.runtime.annotations.ConfigDocPrefix";

public static final String ANNOTATION_CONFIG_WITH_CONVERTER = "io.smallrye.config.WithConverter";
public static final String ANNOTATION_CONFIG_WITH_NAME = "io.smallrye.config.WithName";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.List;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigDocFilename;
import io.quarkus.runtime.annotations.ConfigDocPrefix;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
import io.smallrye.config.ConfigMapping;
Expand All @@ -19,7 +19,7 @@
*/
@ConfigMapping(prefix = "quarkus")
@ConfigRoot(phase = ConfigPhase.RUN_TIME)
@ConfigDocFilename("quarkus-core_quarkus-config.adoc")
@ConfigDocPrefix("quarkus.config")
public interface ConfigConfig {
/**
* A comma separated list of profiles that will be active when Quarkus launches.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.runtime.annotations;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
* This annotation can be used when you want to override the top level prefix from the ConfigRoot/ConfigMapping for doc
* generation.
* <p>
* This is for instance useful for {@code ConfigConfig}, which is an odd beast.
* <p>
* Should be considered very last resort.
*/
@Documented
@Retention(RUNTIME)
@Target({ ElementType.TYPE })
public @interface ConfigDocPrefix {

String value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.maven.execution.MavenSession;
Expand All @@ -44,7 +43,6 @@
import io.quarkus.annotation.processor.documentation.config.model.JavadocElements;
import io.quarkus.annotation.processor.documentation.config.model.JavadocElements.JavadocElement;
import io.quarkus.annotation.processor.documentation.config.model.ResolvedModel;
import io.quarkus.annotation.processor.documentation.config.util.Markers;
import io.quarkus.qute.Engine;
import io.quarkus.qute.ReflectionValueResolver;
import io.quarkus.qute.UserTagSectionHelper;
Expand Down Expand Up @@ -293,15 +291,13 @@ private static MergedModel mergeModel(List<Path> targetDirectories) throws MojoE
continue;
}

String topLevelPrefix = getTopLevelPrefix(configRoot.getPrefix());

Map<String, ConfigRoot> extensionConfigRoots = configRoots.computeIfAbsent(configRoot.getExtension(),
e -> new HashMap<>());

ConfigRoot existingConfigRoot = extensionConfigRoots.get(topLevelPrefix);
ConfigRoot existingConfigRoot = extensionConfigRoots.get(configRoot.getTopLevelPrefix());

if (existingConfigRoot == null) {
extensionConfigRoots.put(topLevelPrefix, configRoot);
extensionConfigRoots.put(configRoot.getTopLevelPrefix(), configRoot);
} else {
existingConfigRoot.merge(configRoot);
}
Expand Down Expand Up @@ -360,16 +356,6 @@ private static void collectGeneratedConfigSections(List<ConfigSection> extension
}
}

private static String getTopLevelPrefix(String prefix) {
String[] prefixSegments = prefix.split(Pattern.quote(Markers.DOT));

if (prefixSegments.length == 1) {
return prefixSegments[0];
}

return prefixSegments[0] + Markers.DOT + prefixSegments[1];
}

private static List<Path> findTargetDirectories(Path scanDirectory) throws MojoExecutionException {
try {
List<Path> targets = new ArrayList<>();
Expand Down
2 changes: 1 addition & 1 deletion docs/src/main/asciidoc/config-reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -847,4 +847,4 @@ link:https://smallrye.io/smallrye-config/Main[SmallRye Config documentation].

== Configuration Reference

include::{generated-dir}/config/quarkus-core_quarkus-config.adoc[opts=optional, leveloffset=+1]
include::{generated-dir}/config/quarkus-core_quarkus.config.adoc[opts=optional, leveloffset=+1]

0 comments on commit 3509ad8

Please sign in to comment.