Happy path transform document, duplicate detection should be added.

This commit is contained in:
Johan Maasing 2025-03-29 15:08:24 +01:00
parent d4b6714229
commit ea99135dab
3 changed files with 61 additions and 9 deletions

View file

@ -2,8 +2,10 @@ package nu.zoom.dsl.ast;
import nu.zoom.dsl.parser.EndpointsBaseVisitor; import nu.zoom.dsl.parser.EndpointsBaseVisitor;
import nu.zoom.dsl.parser.EndpointsParser; import nu.zoom.dsl.parser.EndpointsParser;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class EndpointsVisitorTransformer extends EndpointsBaseVisitor<EndpointsParser.DocumentContext> { public class EndpointsVisitorTransformer extends EndpointsBaseVisitor<EndpointsParser.DocumentContext> {
private ArrayList<EndpointNode> endpoints = new ArrayList<>(); private ArrayList<EndpointNode> endpoints = new ArrayList<>();
@ -12,27 +14,74 @@ public class EndpointsVisitorTransformer extends EndpointsBaseVisitor<EndpointsP
public EndpointsVisitorTransformer() { public EndpointsVisitorTransformer() {
} }
public List<EndpointNode> getEndpoints() {
return List.copyOf(endpoints);
}
public List<ConfigItemNode> getConfig() {
return List.copyOf(config);
}
public List<CompoundTypeNode> getDataTypes() {
return List.copyOf(dataTypes);
}
@Override @Override
public EndpointsParser.DocumentContext visitConfigitem(EndpointsParser.ConfigitemContext ctx) { public EndpointsParser.DocumentContext visitConfigitem(EndpointsParser.ConfigitemContext ctx) {
String configKey = ctx.configkey().IDENTIFIER().getText() ; String configKey = ctx.configkey().IDENTIFIER().getText() ;
String configValue = getText(ctx.configvalue()) ; String configValue = getText(ctx.configvalue().IDENTIFIER(), ctx.configvalue().VALUE()) ;
this.config.add(new ConfigItemNode(configKey, configValue)); this.config.add(new ConfigItemNode(configKey, configValue));
return super.visitConfigitem(ctx) ; return super.visitConfigitem(ctx) ;
} }
@Override @Override
public EndpointsParser.DocumentContext visitCompoundType(EndpointsParser.CompoundTypeContext ctx) { public EndpointsParser.DocumentContext visitCompoundType(EndpointsParser.CompoundTypeContext ctx) {
this.dataTypes.add(extractCompoundTypeNode(ctx));
return super.visitCompoundType(ctx); return super.visitCompoundType(ctx);
} }
@Override @Override
public EndpointsParser.DocumentContext visitEndpoint(EndpointsParser.EndpointContext ctx) { public EndpointsParser.DocumentContext visitEndpoint(EndpointsParser.EndpointContext ctx) {
List<String> segments = ctx
.path()
.pathSegment()
.stream()
.map(
segment -> getText(segment.IDENTIFIER(), segment.VALUE())
).toList() ;
TerminalNode typeReference = ctx.IDENTIFIER() ;
if (typeReference != null) {
var endpoint = new EndpointNode(new PathsNode(segments), typeReference.getText());
this.endpoints.add(endpoint);
} else {
var compoundTypeNode = extractCompoundTypeNode(ctx.compoundType()) ;
var endpoint = new EndpointNode(new PathsNode(segments), compoundTypeNode.name());
this.dataTypes.add(compoundTypeNode);
this.endpoints.add(endpoint);
}
return super.visitEndpoint(ctx); return super.visitEndpoint(ctx);
} }
private String getText(EndpointsParser.ConfigvalueContext ctx) { private CompoundTypeNode extractCompoundTypeNode(EndpointsParser.CompoundTypeContext ctx) {
String identifierText = (ctx.IDENTIFIER() != null) ? ctx.IDENTIFIER().getText() : "" ; String typeName = ctx.compoundTypeName().getText() ;
String valueText = (ctx.VALUE() != null) ? ctx.VALUE().getText() : "" ; List<FieldNode> fields = extractTypeFields(ctx.compoundFields().compoundField()) ;
return identifierText + valueText; return new CompoundTypeNode(typeName, fields) ;
}
private List<FieldNode> extractTypeFields(List<EndpointsParser.CompoundFieldContext> compoundFieldContexts) {
return compoundFieldContexts.stream().map(
ctx -> new FieldNode(
ctx.fieldName().getText(),
ctx.fieldType().getText()
)
).toList() ;
}
// Concatenate the text from to terminal nodes. Useful for contexts that are either an identifier or a value,
// and you just want the text from whichever is not null.
private String getText(TerminalNode identifier, TerminalNode value) {
return
identifier != null ? identifier.getText() : ""
+ value != null ? value.getText() : "" ;
} }
} }

View file

@ -11,12 +11,13 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
public class ParserWrapper { public class ParserWrapper {
public DocumentNode parse(Path sourcePath) throws IOException { public static DocumentNode parse(Path sourcePath) throws IOException {
var ins = CharStreams.fromPath(sourcePath, StandardCharsets.UTF_8); var ins = CharStreams.fromPath(sourcePath, StandardCharsets.UTF_8);
EndpointsLexer lexer = new EndpointsLexer(ins); EndpointsLexer lexer = new EndpointsLexer(ins);
EndpointsParser parser = new EndpointsParser(new CommonTokenStream(lexer)); EndpointsParser parser = new EndpointsParser(new CommonTokenStream(lexer));
var document= parser.document() ; var document= parser.document() ;
new EndpointsVisitorTransformer().visit(document); var astTransformer = new EndpointsVisitorTransformer();
return null ; astTransformer.visit(document);
return new DocumentNode(astTransformer.getConfig(), astTransformer.getDataTypes(), astTransformer.getEndpoints());
} }
} }

View file

@ -1,5 +1,6 @@
package nu.zoom.dsl.cli; package nu.zoom.dsl.cli;
import nu.zoom.dsl.ast.DocumentNode;
import nu.zoom.dsl.ast.ParserWrapper; import nu.zoom.dsl.ast.ParserWrapper;
import picocli.CommandLine; import picocli.CommandLine;
import picocli.CommandLine.Command; import picocli.CommandLine.Command;
@ -41,7 +42,8 @@ public class EndpointsCLI implements Callable<Integer> {
validateTemplateDirectory(); validateTemplateDirectory();
validateInputFile(); validateInputFile();
validateOutputDirectory(); validateOutputDirectory();
new ParserWrapper().parse(file); DocumentNode rootNode = ParserWrapper.parse(file);
System.out.println(rootNode);
return 0; return 0;
} catch (Exception e) { } catch (Exception e) {
System.err.println(e.getMessage()); System.err.println(e.getMessage());