summaryrefslogtreecommitdiffstats
path: root/configgen
diff options
context:
space:
mode:
authorHarald Musum <musum@yahooinc.com>2023-09-07 12:25:37 +0200
committerHarald Musum <musum@yahooinc.com>2023-09-07 12:25:37 +0200
commitcac205f35b56d0bd584013b79b88a6635dee5ab4 (patch)
treebcf8461b3091c44ae78e5d9355a2109ba7d6a77a /configgen
parentdaba552c567f1fcb9e300ae65825c1d97cedbb5e (diff)
Support optional 'path' config type
Initial work needed for this to work (config definition and config library)
Diffstat (limited to 'configgen')
-rw-r--r--configgen/src/main/java/com/yahoo/config/codegen/BuilderGenerator.java45
-rw-r--r--configgen/src/main/java/com/yahoo/config/codegen/ConfigGenerator.java11
-rw-r--r--configgen/src/main/java/com/yahoo/config/codegen/DefLine.java14
-rw-r--r--configgen/src/main/java/com/yahoo/config/codegen/LeafCNode.java12
-rw-r--r--configgen/src/test/java/com/yahoo/config/codegen/DefLineParsingTest.java21
-rw-r--r--configgen/src/test/java/com/yahoo/config/codegen/DefParserTest.java4
-rw-r--r--configgen/src/test/java/com/yahoo/config/codegen/JavaClassBuilderTest.java2
-rw-r--r--configgen/src/test/java/com/yahoo/config/codegen/NormalizedDefinitionTest.java2
-rw-r--r--configgen/src/test/resources/allfeatures.reference28
-rw-r--r--configgen/src/test/resources/configgen.allfeatures.def1
10 files changed, 127 insertions, 13 deletions
diff --git a/configgen/src/main/java/com/yahoo/config/codegen/BuilderGenerator.java b/configgen/src/main/java/com/yahoo/config/codegen/BuilderGenerator.java
index 6cd344466e4..12469d7a3ef 100644
--- a/configgen/src/main/java/com/yahoo/config/codegen/BuilderGenerator.java
+++ b/configgen/src/main/java/com/yahoo/config/codegen/BuilderGenerator.java
@@ -4,10 +4,12 @@ package com.yahoo.config.codegen;
import com.yahoo.config.codegen.LeafCNode.FileLeaf;
import com.yahoo.config.codegen.LeafCNode.ModelLeaf;
import com.yahoo.config.codegen.LeafCNode.PathLeaf;
+import com.yahoo.config.codegen.LeafCNode.OptionalPathLeaf;
import com.yahoo.config.codegen.LeafCNode.UrlLeaf;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
import static com.yahoo.config.codegen.ConfigGenerator.boxedDataType;
@@ -89,7 +91,9 @@ public class BuilderGenerator {
private static String getUninitializedScalars(InnerCNode node) {
List<String> scalarsWithoutDefault = new ArrayList<>();
for (CNode child : node.getChildren()) {
- if (child instanceof LeafCNode && (!child.isArray && !child.isMap && ((LeafCNode) child).getDefaultValue() == null)) {
+ if (child instanceof LeafCNode
+ && (!child.isArray && !child.isMap && ((LeafCNode) child).getDefaultValue() == null)
+ && (! (child instanceof OptionalPathLeaf))) {
scalarsWithoutDefault.add("\"" + child.getName() + "\"");
}
}
@@ -109,7 +113,11 @@ public class BuilderGenerator {
} else if (node instanceof InnerCNode) {
return String.format("public %s %s = new %s();", builderType(node), node.getName(), builderType(node));
} else if (node instanceof LeafCNode) {
- return String.format("private %s %s = null;", boxedBuilderType((LeafCNode) node), node.getName());
+ String boxedBuilderType = boxedBuilderType((LeafCNode) node);
+ if (boxedBuilderType.startsWith("Optional<"))
+ return String.format("private %s %s = Optional.empty();", boxedBuilderType, node.getName());
+ else
+ return String.format("private %s %s = null;", boxedBuilderType, node.getName());
} else {
throw new IllegalStateException("Cannot produce builder field definition for node"); // Should not happen
}
@@ -207,6 +215,11 @@ public class BuilderGenerator {
private static String privateLeafNodeSetter(LeafCNode n) {
if ("String".equals(builderType(n)) || "FileReference".equals(builderType(n))) {
return "";
+ } else if ("Optional<FileReference>".equals(builderType(n))) {
+ return "\n\n" + //
+ "private Builder " + n.getName() + "(String " + INTERNAL_PREFIX + "value) {\n" + //
+ " return " + n.getName() + "(" + builderType(n) + ".of(" + INTERNAL_PREFIX + "value));\n" + //
+ "}";
} else {
return "\n\n" + //
"private Builder " + n.getName() + "(String " + INTERNAL_PREFIX + "value) {\n" + //
@@ -270,14 +283,24 @@ public class BuilderGenerator {
: "";
String bType = builderType(n);
- String stringSetter = "";
- if ( ! "String".equals(bType) && ! "FileReference".equals(bType) && ! "ModelReference".equals(bType)) {
+ String privateSetter = "";
+ if ( ! Set.of("String", "FileReference", "ModelReference", "Optional<FileReference>").contains(bType)) {
String type = boxedDataType(n);
if ("UrlReference".equals(bType))
type = bType;
- stringSetter = String.format("\nprivate Builder %s(String %svalue) {\n" +
- " return %s(%s.valueOf(%svalue));\n" + //
- "}", name, INTERNAL_PREFIX, name, type, INTERNAL_PREFIX);
+ //
+ privateSetter = String.format("""
+
+ private Builder %s(String %svalue) {
+ return %s(%s.valueOf(%svalue));
+ }""", name, INTERNAL_PREFIX, name, type, INTERNAL_PREFIX);
+ } else if ("Optional<FileReference>".equals(bType)) {
+ //
+ privateSetter = String.format("""
+
+ private Builder %s(FileReference %svalue) {
+ return %s(Optional.of(%svalue));
+ }""", name, INTERNAL_PREFIX, name, INTERNAL_PREFIX);
}
String getNullGuard = bType.equals(boxedBuilderType(n)) ? String.format(
@@ -286,7 +309,7 @@ public class BuilderGenerator {
return String.format("public Builder %s(%s %svalue) {%s\n" +
" %s = %svalue;\n" + //
"%s", name, bType, INTERNAL_PREFIX, getNullGuard, name, INTERNAL_PREFIX, signalInitialized) +
- " return this;" + "\n}\n" + stringSetter;
+ " return this;" + "\n}\n" + privateSetter;
}
}
@@ -307,6 +330,8 @@ public class BuilderGenerator {
return name + "(" + nodeClass(child) + ".toFileReferenceMap(config." + name + "));";
} else if (child instanceof PathLeaf) {
return name + "(config." + name + ".getFileReference());";
+ } else if (child instanceof OptionalPathLeaf) {
+ return name + "(config." + name + ".getFileReference());";
} else if (child instanceof UrlLeaf && isArray) {
return name + "(" + nodeClass(child) + ".toUrlReferences(config." + name + "));";
} else if (child instanceof UrlLeaf && isMap) {
@@ -408,6 +433,8 @@ public class BuilderGenerator {
return "String";
} else if (node instanceof PathLeaf) {
return "FileReference";
+ } else if (node instanceof OptionalPathLeaf) {
+ return "Optional<FileReference>";
} else if (node instanceof UrlLeaf) {
return "UrlReference";
} else if (node instanceof ModelLeaf) {
@@ -424,6 +451,8 @@ public class BuilderGenerator {
return "String";
} else if (node instanceof PathLeaf) {
return "FileReference";
+ } else if (node instanceof OptionalPathLeaf) {
+ return "Optional<FileReference>";
} else if (node instanceof UrlLeaf) {
return "UrlReference";
} else if (node instanceof ModelLeaf) {
diff --git a/configgen/src/main/java/com/yahoo/config/codegen/ConfigGenerator.java b/configgen/src/main/java/com/yahoo/config/codegen/ConfigGenerator.java
index cb10ffdc2be..903d8dc0865 100644
--- a/configgen/src/main/java/com/yahoo/config/codegen/ConfigGenerator.java
+++ b/configgen/src/main/java/com/yahoo/config/codegen/ConfigGenerator.java
@@ -7,6 +7,7 @@ import com.yahoo.config.codegen.LeafCNode.EnumLeaf;
import com.yahoo.config.codegen.LeafCNode.FileLeaf;
import com.yahoo.config.codegen.LeafCNode.IntegerLeaf;
import com.yahoo.config.codegen.LeafCNode.LongLeaf;
+import com.yahoo.config.codegen.LeafCNode.OptionalPathLeaf;
import com.yahoo.config.codegen.LeafCNode.PathLeaf;
import com.yahoo.config.codegen.LeafCNode.ReferenceLeaf;
import com.yahoo.config.codegen.LeafCNode.StringLeaf;
@@ -165,6 +166,8 @@ public class ConfigGenerator {
return name + " = LeafNodeVector.createFileNodeVector(builder." + name + ");";
} else if (child instanceof PathLeaf && isArray) {
return name + " = LeafNodeVector.createPathNodeVector(builder." + name + ");";
+ } else if (child instanceof OptionalPathLeaf && isArray) {
+ return name + " = LeafNodeVector.createOptionalPathNodeVector(builder." + name + ");";
} else if (child instanceof UrlLeaf && isArray) {
return name + " = LeafNodeVector.createUrlNodeVector(builder." + name + ");";
} else if (child instanceof ModelLeaf && isArray) {
@@ -175,6 +178,8 @@ public class ConfigGenerator {
return name + " = LeafNodeMaps.asFileNodeMap(builder." + name + ");";
} else if (child instanceof PathLeaf && isMap) {
return name + " = LeafNodeMaps.asPathNodeMap(builder." + name + ");";
+ } else if (child instanceof OptionalPathLeaf && isMap) {
+ return name + " = LeafNodeMaps.asOptionalPathNodeMap(builder." + name + ");";
} else if (child instanceof UrlLeaf && isMap) {
return name + " = LeafNodeMaps.asUrlNodeMap(builder." + name + ");";
} else if (child instanceof ModelLeaf && isMap) {
@@ -401,6 +406,8 @@ public class ConfigGenerator {
return "FileNode";
} else if (node instanceof PathLeaf) {
return "PathNode";
+ } else if (node instanceof OptionalPathLeaf) {
+ return "OptionalPathNode";
} else if (node instanceof UrlLeaf) {
return "UrlNode";
} else if (node instanceof ModelLeaf) {
@@ -431,6 +438,8 @@ public class ConfigGenerator {
return "FileReference";
} else if (node instanceof PathLeaf) {
return "Path";
+ } else if (node instanceof OptionalPathLeaf) {
+ return "Optional<Path>";
} else if (node instanceof UrlLeaf) {
return "File";
} else if (node instanceof ModelLeaf) {
@@ -456,6 +465,8 @@ public class ConfigGenerator {
return "Integer";
} else if (rawType.toLowerCase().equals(rawType)) {
return ConfiggenUtil.capitalize(rawType);
+ } else if (rawType.startsWith("Optional<")) {
+ return "Optional";
} else {
return rawType;
}
diff --git a/configgen/src/main/java/com/yahoo/config/codegen/DefLine.java b/configgen/src/main/java/com/yahoo/config/codegen/DefLine.java
index 385c7f1979e..d6bffe349a8 100644
--- a/configgen/src/main/java/com/yahoo/config/codegen/DefLine.java
+++ b/configgen/src/main/java/com/yahoo/config/codegen/DefLine.java
@@ -7,6 +7,7 @@ import java.util.regex.Pattern;
public class DefLine {
private final static Pattern defaultPattern = Pattern.compile("^\\s*default\\s*=\\s*(\\S+)");
+ private final static Pattern optionalPattern = Pattern.compile("^\\s*optional\\s*");
private final static Pattern rangePattern = Pattern.compile("^\\s*range\\s*=\\s*([\\(\\[].*?[\\)\\]])");
private final static Pattern restartPattern = Pattern.compile("^\\s*restart\\s*");
private final static Pattern wordPattern = Pattern.compile("\\S+");
@@ -21,6 +22,7 @@ public class DefLine {
private final Type type = new Type();
private DefaultValue defaultValue = null;
+ private boolean optional = false;
private String range = null;
private boolean restart = false;
@@ -74,6 +76,9 @@ public class DefLine {
}
public Type getType() {
+ if (optional && type.name.equals("path"))
+ type.name = "optionalPath";
+
return type;
}
@@ -89,6 +94,8 @@ public class DefLine {
return enumArray;
}
+ public boolean isOptional() { return optional; }
+
/**
* Special function that searches through s and returns the index
* of the first occurrence of " that is not escaped.
@@ -114,6 +121,7 @@ public class DefLine {
private int parseOptions(CharSequence string) {
Matcher defaultNullMatcher = defaultNullPattern.matcher(string);
Matcher defaultMatcher = defaultPattern.matcher(string);
+ Matcher optionalMatcher = optionalPattern.matcher(string);
Matcher rangeMatcher = rangePattern.matcher(string);
Matcher restartMatcher = restartPattern.matcher(string);
@@ -133,6 +141,12 @@ public class DefLine {
defaultValue = new DefaultValue(deflt, type);
}
return defaultMatcher.end();
+ } else if (optionalMatcher.find()) {
+ if ( ! type.name.equals("path"))
+ throw new IllegalArgumentException("optional can only be used for 'path'");
+ optional = true;
+ type.name = "optionalPath";
+ return optionalMatcher.end();
} else if (rangeMatcher.find()) {
range = rangeMatcher.group(1);
return rangeMatcher.end();
diff --git a/configgen/src/main/java/com/yahoo/config/codegen/LeafCNode.java b/configgen/src/main/java/com/yahoo/config/codegen/LeafCNode.java
index afd6acfbabf..c2470b0c703 100644
--- a/configgen/src/main/java/com/yahoo/config/codegen/LeafCNode.java
+++ b/configgen/src/main/java/com/yahoo/config/codegen/LeafCNode.java
@@ -26,6 +26,7 @@ public abstract class LeafCNode extends CNode {
case "reference" -> new ReferenceLeaf(parent, name);
case "file" -> new FileLeaf(parent, name);
case "path" -> new PathLeaf(parent, name);
+ case "optionalPath" -> new OptionalPathLeaf(parent, name);
case "enum" -> new EnumLeaf(parent, name, type.enumArray);
case "url" -> new UrlLeaf(parent, name);
case "model" -> new ModelLeaf(parent, name);
@@ -217,6 +218,17 @@ public abstract class LeafCNode extends CNode {
}
}
+ public static class OptionalPathLeaf extends NoClassLeafCNode {
+ OptionalPathLeaf(InnerCNode parent, String name) {
+ super(parent, name);
+ }
+
+ @Override
+ public String getType() {
+ return "optionalPath";
+ }
+ }
+
public static class UrlLeaf extends NoClassLeafCNode {
UrlLeaf(InnerCNode parent, String name) {
super(parent, name);
diff --git a/configgen/src/test/java/com/yahoo/config/codegen/DefLineParsingTest.java b/configgen/src/test/java/com/yahoo/config/codegen/DefLineParsingTest.java
index 0e2f6cc4d05..bb6b8eb64b4 100644
--- a/configgen/src/test/java/com/yahoo/config/codegen/DefLineParsingTest.java
+++ b/configgen/src/test/java/com/yahoo/config/codegen/DefLineParsingTest.java
@@ -1,6 +1,7 @@
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.codegen;
+import java.util.Optional;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@@ -246,4 +247,24 @@ public class DefLineParsingTest {
assertTrue(r1.getRestart());
}
+ @Test
+ void testParseOptionalPathWithDefault() {
+ DefLine l = new DefLine("pathWithDef path optional");
+
+ assertEquals("pathWithDef", l.getName());
+ assertNull(l.getDefault());
+ assertTrue(l.isOptional());
+ assertEquals("optionalPath", l.getType().getName());
+ }
+
+ @Test
+ void testParsPathWithDefault() {
+ DefLine l = new DefLine("pathWithDef path");
+
+ assertEquals("pathWithDef", l.getName());
+ assertNull(l.getDefault());
+ assertFalse(l.isOptional());
+ assertEquals("path", l.getType().getName());
+ }
+
}
diff --git a/configgen/src/test/java/com/yahoo/config/codegen/DefParserTest.java b/configgen/src/test/java/com/yahoo/config/codegen/DefParserTest.java
index 45d1f21763c..e5227282c05 100644
--- a/configgen/src/test/java/com/yahoo/config/codegen/DefParserTest.java
+++ b/configgen/src/test/java/com/yahoo/config/codegen/DefParserTest.java
@@ -28,7 +28,7 @@ public class DefParserTest {
CNode root = new DefParser("test", new FileReader(defFile)).getTree();
assertNotNull(root);
CNode[] children = root.getChildren();
- assertEquals(37, children.length);
+ assertEquals(38, children.length);
int numGrandChildren = 0;
int numGreatGrandChildren = 0;
@@ -70,7 +70,7 @@ public class DefParserTest {
void testMd5Sum() throws IOException {
File defFile = new File(DEF_NAME);
CNode root = new DefParser("test", new FileReader(defFile)).getTree();
- assertEquals("0501f9e2c4ecc8c283e100e0b1178ca4", root.defMd5);
+ assertEquals("ee37973499305fde315da46256e64b2e", root.defMd5);
}
@Test
diff --git a/configgen/src/test/java/com/yahoo/config/codegen/JavaClassBuilderTest.java b/configgen/src/test/java/com/yahoo/config/codegen/JavaClassBuilderTest.java
index 428576e340f..c3145c03fff 100644
--- a/configgen/src/test/java/com/yahoo/config/codegen/JavaClassBuilderTest.java
+++ b/configgen/src/test/java/com/yahoo/config/codegen/JavaClassBuilderTest.java
@@ -120,7 +120,7 @@ public class JavaClassBuilderTest {
}
for (int i = 0; i < referenceClassLines.size(); i++) {
if (configClassLines.length <= i)
- fail("Missing lines i generated config class. First missing line:\n" + referenceClassLines.get(i));
+ fail("Missing lines in generated config class. First missing line:\n" + referenceClassLines.get(i));
assertEquals(referenceClassLines.get(i), configClassLines[i], "Line " + i);
}
}
diff --git a/configgen/src/test/java/com/yahoo/config/codegen/NormalizedDefinitionTest.java b/configgen/src/test/java/com/yahoo/config/codegen/NormalizedDefinitionTest.java
index 57b3ed962eb..18608102ffa 100644
--- a/configgen/src/test/java/com/yahoo/config/codegen/NormalizedDefinitionTest.java
+++ b/configgen/src/test/java/com/yahoo/config/codegen/NormalizedDefinitionTest.java
@@ -70,7 +70,7 @@ public class NormalizedDefinitionTest {
}
assertNotNull(out);
- assertEquals(75, out.size());
+ assertEquals(76, out.size());
assertNotNull(fileReader);
fileReader.close();
diff --git a/configgen/src/test/resources/allfeatures.reference b/configgen/src/test/resources/allfeatures.reference
index b7a79f663e7..79508b3a25f 100644
--- a/configgen/src/test/resources/allfeatures.reference
+++ b/configgen/src/test/resources/allfeatures.reference
@@ -35,7 +35,7 @@ import com.yahoo.config.*;
*/
public final class AllfeaturesConfig extends ConfigInstance {
- public final static String CONFIG_DEF_MD5 = "0501f9e2c4ecc8c283e100e0b1178ca4";
+ public final static String CONFIG_DEF_MD5 = "ee37973499305fde315da46256e64b2e";
public final static String CONFIG_DEF_NAME = "allfeatures";
public final static String CONFIG_DEF_NAMESPACE = "configgen";
public final static String[] CONFIG_DEF_SCHEMA = {
@@ -56,6 +56,7 @@ public final class AllfeaturesConfig extends ConfigInstance {
"refwithdef reference default=\":parent:\"",
"fileVal file",
"pathVal path",
+ "optionalPathVal path optional",
"urlVal url",
"modelVal model",
"boolarr[] bool",
@@ -130,6 +131,7 @@ public final class AllfeaturesConfig extends ConfigInstance {
private String refwithdef = null;
private String fileVal = null;
private FileReference pathVal = null;
+ private Optional<FileReference> optionalPathVal = Optional.empty();
private UrlReference urlVal = null;
private ModelReference modelVal = null;
public List<Boolean> boolarr = new ArrayList<>();
@@ -171,6 +173,7 @@ public final class AllfeaturesConfig extends ConfigInstance {
refwithdef(config.refwithdef());
fileVal(config.fileVal().value());
pathVal(config.pathVal.getFileReference());
+ optionalPathVal(config.optionalPathVal.getFileReference());
urlVal(config.urlVal.getUrlReference());
modelVal(config.modelVal.getModelReference());
boolarr(config.boolarr());
@@ -231,6 +234,8 @@ public final class AllfeaturesConfig extends ConfigInstance {
fileVal(__superior.fileVal);
if (__superior.pathVal != null)
pathVal(__superior.pathVal);
+ if (__superior.optionalPathVal != null)
+ optionalPathVal(__superior.optionalPathVal);
if (__superior.urlVal != null)
urlVal(__superior.urlVal);
if (__superior.modelVal != null)
@@ -412,6 +417,17 @@ public final class AllfeaturesConfig extends ConfigInstance {
}
+ public Builder optionalPathVal(Optional<FileReference> __value) {
+ if (__value == null) throw new IllegalArgumentException("Null value is not allowed.");
+ optionalPathVal = __value;
+ __uninitialized.remove("optionalPathVal");
+ return this;
+ }
+
+ private Builder optionalPathVal(FileReference __value) {
+ return optionalPathVal(Optional.of(__value));
+ }
+
public Builder urlVal(UrlReference __value) {
if (__value == null) throw new IllegalArgumentException("Null value is not allowed.");
urlVal = __value;
@@ -759,6 +775,7 @@ public final class AllfeaturesConfig extends ConfigInstance {
private final ReferenceNode refwithdef;
private final FileNode fileVal;
private final PathNode pathVal;
+ private final OptionalPathNode optionalPathVal;
private final UrlNode urlVal;
private final ModelNode modelVal;
private final LeafNodeVector<Boolean, BooleanNode> boolarr;
@@ -822,6 +839,8 @@ public final class AllfeaturesConfig extends ConfigInstance {
new FileNode() : new FileNode(builder.fileVal);
pathVal = (builder.pathVal == null) ?
new PathNode() : new PathNode(builder.pathVal);
+ optionalPathVal = (builder.optionalPathVal == null) ?
+ new OptionalPathNode() : new OptionalPathNode(builder.optionalPathVal);
urlVal = (builder.urlVal == null) ?
new UrlNode() : new UrlNode(builder.urlVal);
modelVal = (builder.modelVal == null) ?
@@ -960,6 +979,13 @@ public final class AllfeaturesConfig extends ConfigInstance {
}
/**
+ * @return allfeatures.optionalPathVal
+ */
+ public Optional<Path> optionalPathVal() {
+ return optionalPathVal.value();
+ }
+
+ /**
* @return allfeatures.urlVal
*/
public File urlVal() {
diff --git a/configgen/src/test/resources/configgen.allfeatures.def b/configgen/src/test/resources/configgen.allfeatures.def
index 1f93e29b73b..eee39dc18f3 100644
--- a/configgen/src/test/resources/configgen.allfeatures.def
+++ b/configgen/src/test/resources/configgen.allfeatures.def
@@ -39,6 +39,7 @@ refVal reference
refwithdef reference default=":parent:"
fileVal file
pathVal path
+optionalPathVal path optional
urlVal url
modelVal model