package org.jtwig.parser.parboiled.node;
import org.jtwig.model.expression.VariableExpression;
import org.jtwig.model.tree.OverrideBlockNode;
import org.jtwig.parser.parboiled.ParserContext;
import org.jtwig.parser.parboiled.base.LexicParser;
import org.jtwig.parser.parboiled.base.LimitsParser;
import org.jtwig.parser.parboiled.base.PositionTrackerParser;
import org.jtwig.parser.parboiled.base.SpacingParser;
import org.jtwig.parser.parboiled.expression.VariableExpressionParser;
import org.jtwig.parser.parboiled.model.Keyword;
import org.parboiled.Rule;
public class OverrideBlockNodeParser extends NodeParser<OverrideBlockNode> {
public OverrideBlockNodeParser(ParserContext context) {
super(OverrideBlockNodeParser.class, context);
}
@Override
public Rule NodeRule() {
LimitsParser limitsParser = parserContext().parser(LimitsParser.class);
PositionTrackerParser positionTrackerParser = parserContext().parser(PositionTrackerParser.class);
LexicParser lexicParser = parserContext().parser(LexicParser.class);
SpacingParser spacingParser = parserContext().parser(SpacingParser.class);
VariableExpressionParser variableExpressionParser = parserContext().parser(VariableExpressionParser.class);
CompositeNodeParser compositeNodeParser = parserContext().parser(CompositeNodeParser.class);
return Sequence(
positionTrackerParser.PushPosition(),
Sequence(
limitsParser.startCode(), spacingParser.Spacing(),
lexicParser.Keyword(Keyword.BLOCK),
spacingParser.Mandatory(),
Mandatory(variableExpressionParser.ExpressionRule(), "Block identifier not specified"),
spacingParser.Spacing(),
Mandatory(limitsParser.endCode(), "Missing end of code island")
),
compositeNodeParser.NodeRule(),
Mandatory(Sequence(
limitsParser.startCode(),
spacingParser.Spacing(),
lexicParser.Keyword(Keyword.END_BLOCK),
Optional(
spacingParser.Mandatory(),
variableExpressionParser.ExpressionRule(),
throwExceptionIfNonSameVariableName()
),
spacingParser.Spacing(),
Mandatory(limitsParser.endCode(), "Missing end of code island")
), "Missing endblock tag"),
push(new OverrideBlockNode(
positionTrackerParser.pop(2),
variableExpressionParser.pop(1),
compositeNodeParser.pop()
))
);
}
boolean throwExceptionIfNonSameVariableName() {
VariableExpressionParser variableExpressionParser = parserContext().parser(VariableExpressionParser.class);
VariableExpression expression = variableExpressionParser.pop();
VariableExpression original = variableExpressionParser.peek(1);
if (!expression.getIdentifier().equals(original.getIdentifier())) {
addError(String.format("Expecting block '%s' to end with the same identifier but found '%s' instead", original.getIdentifier(), expression.getIdentifier()));
}
return true;
}
}