in tools/linter/src/main/java/com/google/cloud/verticals/foundations/dataharmonization/tools/linter/ast/AntlrToTree.java [117:171]
public Void visitChildren(RuleNode node) {
int start;
int end;
// if visiting the root node, ensure the start and end include all tokens
if (node.getParent() == null) {
start = 0;
end = tokens.length - 1;
} else {
start = node.getSourceInterval().a;
end = node.getSourceInterval().b;
}
BaseTreeNode currentNode = ruleToTree.get(node);
// the intervals where nodes are found, not including spaces or comments
IntervalSet childrenIntervals =
new IntervalSet(
IntStream.range(0, node.getChildCount())
.mapToObj(node::getChild)
.map(ParseTree::getSourceInterval)
.filter(Objects::nonNull)
.collect(toImmutableList()));
int lastChildIndex = -1;
for (int i = start; i <= end; i++) {
// the indices in the gaps between nodes contain either whitespaces or comments
if (!childrenIntervals.contains(i)) {
TerminalNode spaceNode;
if (tokens[i].getText().strip().startsWith("//")) {
spaceNode = new TerminalNode(tokens[i].getText(), currentNode, false, COMMENT);
} else {
spaceNode = new TerminalNode(tokens[i].getText(), currentNode, false, SPACE);
}
currentNode.asInternal().children.add(spaceNode);
continue;
}
lastChildIndex++;
ParseTree child = node.getChild(lastChildIndex);
BaseTreeNode childNode;
// Check if the child node is newline, terminal, or internal.
if (child.getChildCount() == 0 && child.getText().equals("\n")) {
childNode = new TerminalNode(child.getText(), currentNode, false, NEWLINE);
} else if (child.getChildCount() == 0) {
childNode = new TerminalNode(child.getText(), currentNode, false, TEXT);
} else {
childNode =
ruleToTree.computeIfAbsent(
child, pt -> new InternalNode(pt.getClass(), currentNode, false));
}
currentNode.asInternal().getChildren().add(childNode);
child.accept(this);
i = child.getSourceInterval().b;
}
return null;
}