use of io.helidon.build.archetype.engine.v2.ast.Input.DeclaredInput in project helidon-build-tools by oracle.
the class InputResolver method onVisitInput.
/**
* Invoked for every named input visit.
*
* @param input input
* @param scope scope
* @param context context
* @return visit result if a value already exists, {@code null} otherwise
*/
protected VisitResult onVisitInput(DeclaredInput input, Context.Scope scope, Context context) {
Step currentStep = currentSteps.peek();
if (currentStep == null) {
throw new IllegalStateException(input.location() + " Input not nested inside a step");
}
boolean global = input.isGlobal();
if (global) {
DeclaredInput parent = parents.peek();
if (parent != null && !parent.isGlobal()) {
throw new IllegalStateException(input.location() + " Parent input is not global");
}
}
parents.push(input);
Value value = context.getValue(scope.id());
if (value == null) {
if (!visitedSteps.contains(currentStep)) {
visitedSteps.add(currentStep);
onVisitStep(currentStep, context);
}
return null;
}
input.validate(value, scope.id());
return input.visitValue(value);
}
use of io.helidon.build.archetype.engine.v2.ast.Input.DeclaredInput in project helidon-build-tools by oracle.
the class ArchetypeValidator method visitInput.
@Override
public VisitResult visitInput(Input input0, Context ctx) {
// process scope
Map<String, DeclaredInput> currentScope = requireNonNull(scopes.peek(), "current scope is null");
scopes.push(new HashMap<>());
if (input0 instanceof DeclaredInput) {
DeclaredInput input = (DeclaredInput) input0;
Context.Scope scope = ctx.newScope(input.id(), input.isGlobal());
inputPath = scope.id();
ctx.pushScope(scope);
allRefs.computeIfAbsent(inputPath, k -> new ArrayList<>());
if (input instanceof Input.Options) {
options.push(new HashSet<>());
}
if (currentScope.containsKey(inputPath)) {
errors.add(String.format("%s %s: '%s'", input.location(), INPUT_ALREADY_DECLARED, inputPath));
} else {
currentScope.put(inputPath, input);
List<Block> duplicates = requireNonNull(allRefs.get(inputPath), "duplicate refs is null");
if (!duplicates.isEmpty()) {
Block duplicate = duplicates.get(0);
if (duplicate.kind() != input.kind()) {
errors.add(String.format("%s %s: '%s'", input.location(), INPUT_TYPE_MISMATCH, inputPath));
}
}
duplicates.add(input);
}
boolean optional = input.isOptional();
if (optional && input.defaultValue().unwrap() == null) {
errors.add(String.format("%s %s: '%s'", input.location(), INPUT_OPTIONAL_NO_DEFAULT, inputPath));
}
StepState stepState = steps.peek();
if (stepState == null) {
errors.add(String.format("%s %s: '%s'", input.location(), INPUT_NOT_IN_STEP, inputPath));
} else {
stepState.optional = stepState.optional && optional;
stepState.inputs++;
}
} else if (input0 instanceof Input.Option) {
Input.Option option = (Input.Option) input0;
String value = option.value();
if (!requireNonNull(options.peek(), "option values is null").add(value)) {
errors.add(String.format("%s %s: '%s'", option.location(), OPTION_VALUE_ALREADY_DECLARED, value));
}
}
return VisitResult.CONTINUE;
}
use of io.helidon.build.archetype.engine.v2.ast.Input.DeclaredInput in project helidon-build-tools by oracle.
the class InputResolver method visitOption.
@Override
public VisitResult visitOption(Option option, Context context) {
if (parents.isEmpty()) {
throw new IllegalStateException("parents is empty");
}
DeclaredInput parent = parents.peek();
Value inputValue = context.lookup("PARENT." + parent.id());
if (inputValue != null) {
return parent.visitOption(inputValue, option);
}
return VisitResult.SKIP_SUBTREE;
}
use of io.helidon.build.archetype.engine.v2.ast.Input.DeclaredInput in project helidon-build-tools by oracle.
the class BatchInputResolver method visit.
private VisitResult visit(DeclaredInput input, Context context) {
Context.Scope scope = context.newScope(input.id(), input.isGlobal());
VisitResult result = onVisitInput(input, scope, context);
if (result == null) {
Value defaultValue = defaultValue(input, context);
if (input.isOptional()) {
if (defaultValue != null) {
context.setValue(scope.id(), defaultValue, ContextValue.ValueKind.DEFAULT);
if (input instanceof Input.Boolean && !defaultValue.asBoolean()) {
result = VisitResult.SKIP_SUBTREE;
} else {
result = VisitResult.CONTINUE;
}
} else {
throw new UnresolvedInputException(scope.id());
}
} else if (input instanceof Input.Enum) {
List<Input.Option> options = ((Input.Enum) input).options(context::filterNode);
int defaultIndex = optionIndex(defaultValue.asString(), options);
// skip prompting if there is only one option with a default value
if (options.size() == 1 && defaultIndex >= 0) {
context.setValue(scope.id(), defaultValue, ContextValue.ValueKind.DEFAULT);
result = VisitResult.CONTINUE;
} else {
throw new UnresolvedInputException(scope.id());
}
}
}
context.pushScope(scope);
return result;
}
Aggregations