package org.batfish.grammar.flatjuniper;
import java.util.ArrayList;
import java.util.List;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.batfish.grammar.flatjuniper.FlatJuniperParser.*;
import org.batfish.grammar.flatjuniper.Hierarchy.HierarchyTree.HierarchyPath;
import org.batfish.common.BatfishException;
import org.batfish.main.PartialGroupMatchException;
import org.batfish.main.UndefinedGroupBatfishException;
import org.batfish.common.Warnings;
public class ApplyGroupsApplicator extends FlatJuniperParserBaseListener {
private boolean _changed;
private Flat_juniper_configurationContext _configurationContext;
private HierarchyPath _currentPath;
private Set_lineContext _currentSetLine;
private boolean _enablePathRecording;
private final Hierarchy _hierarchy;
private boolean _inGroup;
private List<ParseTree> _newConfigurationLines;
private boolean _reenablePathRecording;
private final Warnings _w;
public ApplyGroupsApplicator(FlatJuniperCombinedParser combinedParser,
Hierarchy hierarchy, Warnings warnings) {
_hierarchy = hierarchy;
_w = warnings;
}
@Override
public void enterApply_groups(Apply_groupsContext ctx) {
if (_inGroup) {
return;
}
String groupName = ctx.name.getText();
try {
List<ParseTree> applyGroupsLines = _hierarchy.getApplyGroupsLines(
groupName, _currentPath, _configurationContext);
int insertionIndex = _newConfigurationLines.indexOf(_currentSetLine);
_newConfigurationLines.addAll(insertionIndex, applyGroupsLines);
}
catch (PartialGroupMatchException e) {
String message = "Exception processing apply-groups statement at path: \""
+ _currentPath.pathString() + "\" with group \"" + groupName
+ "\": " + e.getMessage() + ": caused by: "
+ ExceptionUtils.getFullStackTrace(e);
_w.pedantic(message);
}
catch (UndefinedGroupBatfishException e) {
String message = "apply-groups statement at path: \""
+ _currentPath.pathString()
+ "\" refers to non-existent group \"" + groupName + "\n";
_w.redFlag(message);
}
catch (BatfishException e) {
String message = "Exception processing apply-groups statement at path: \""
+ _currentPath.pathString() + "\" with group \"" + groupName
+ "\": " + e.getMessage() + ": caused by: "
+ ExceptionUtils.getFullStackTrace(e);
_w.redFlag(message);
}
_newConfigurationLines.remove(_currentSetLine);
_changed = true;
}
@Override
public void enterApply_groups_except(Apply_groups_exceptContext ctx) {
if (_inGroup) {
_w.redFlag(
"Do not know how to handle apply-groups-except occcurring within group statement");
}
_newConfigurationLines.remove(_currentSetLine);
}
@Override
public void enterFlat_juniper_configuration(
Flat_juniper_configurationContext ctx) {
_configurationContext = ctx;
_newConfigurationLines = new ArrayList<>();
_newConfigurationLines.addAll(ctx.children);
}
@Override
public void enterInterface_id(Interface_idContext ctx) {
if (_enablePathRecording
&& (ctx.unit != null || ctx.suffix != null || ctx.node != null)) {
_enablePathRecording = false;
_reenablePathRecording = true;
String text = ctx.getText();
_currentPath.addNode(text);
}
}
@Override
public void enterS_groups_named(S_groups_namedContext ctx) {
_inGroup = true;
}
@Override
public void enterSet_line(Set_lineContext ctx) {
_currentSetLine = ctx;
}
@Override
public void enterSet_line_tail(Set_line_tailContext ctx) {
_enablePathRecording = true;
_currentPath = new HierarchyPath();
}
@Override
public void exitFlat_juniper_configuration(
Flat_juniper_configurationContext ctx) {
_configurationContext.children = _newConfigurationLines;
}
@Override
public void exitInterface_id(Interface_idContext ctx) {
if (_reenablePathRecording) {
_enablePathRecording = true;
_reenablePathRecording = false;
}
}
@Override
public void exitS_groups_named(S_groups_namedContext ctx) {
_inGroup = false;
}
@Override
public void exitSet_line(Set_lineContext ctx) {
_currentSetLine = null;
_currentPath = null;
}
@Override
public void exitSet_line_tail(Set_line_tailContext ctx) {
_enablePathRecording = false;
}
public boolean getChanged() {
return _changed;
}
@Override
public void visitTerminal(TerminalNode node) {
if (_enablePathRecording) {
String text = node.getText();
if (node.getSymbol().getType() == FlatJuniperLexer.WILDCARD) {
_currentPath.addWildcardNode(text);
}
else {
_currentPath.addNode(text);
}
}
}
}