BlockAst.java
package com.taxonomy.dsl.ast;
import java.util.*;
/**
* A generic block in the DSL AST.
*
* <p>Every top-level construct ({@code element}, {@code relation}, {@code requirement},
* {@code mapping}, {@code view}, {@code evidence}, and future block types) is first
* parsed into a {@code BlockAst}. The {@link #kind} field carries the keyword
* (e.g. {@code "element"}), while {@link #headerTokens} contains the remaining
* tokens on the header line (e.g. {@code ["CP-1023", "type", "Capability"]}).
*
* <p>Unknown block types and unknown properties are preserved so that
* round-trips through parse → serialize are lossless.
*/
public final class BlockAst {
private final String kind;
private final List<String> headerTokens;
private final List<PropertyAst> properties;
private final List<BlockAst> children;
private final Map<String, String> extensions;
private final SourceLocation sourceLocation;
public BlockAst(String kind,
List<String> headerTokens,
List<PropertyAst> properties,
List<BlockAst> children,
Map<String, String> extensions,
SourceLocation sourceLocation) {
this.kind = Objects.requireNonNull(kind);
this.headerTokens = List.copyOf(headerTokens);
this.properties = List.copyOf(properties);
this.children = List.copyOf(children);
this.extensions = Map.copyOf(extensions);
this.sourceLocation = sourceLocation;
}
public String getKind() { return kind; }
public List<String> getHeaderTokens() { return headerTokens; }
public List<PropertyAst> getProperties() { return properties; }
public List<BlockAst> getChildren() { return children; }
public Map<String, String> getExtensions() { return extensions; }
public SourceLocation getSourceLocation() { return sourceLocation; }
/** Convenience: look up a property value by key, or {@code null}. */
public String property(String key) {
return properties.stream()
.filter(p -> p.key().equals(key))
.map(PropertyAst::value)
.findFirst()
.orElse(null);
}
/** Convenience: look up all property values for a given key (for repeated keys like {@code include}). */
public List<String> propertyValues(String key) {
return properties.stream()
.filter(p -> p.key().equals(key))
.map(PropertyAst::value)
.toList();
}
}