/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.dynamic.data.mapping.expression.internal;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionBaseVisitor;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.AdditionExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.AndExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.BooleanParenthesisContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.DivisionExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.EqualsExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.ExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.FloatingPointLiteralContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.FunctionCallExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.FunctionParametersContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.GreaterThanExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.GreaterThanOrEqualsExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.IntegerLiteralContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.LessThanExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.LessThanOrEqualsExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.LogicalConstantContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.LogicalVariableContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.MinusExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.MultiplicationExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.NotEqualsExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.NotExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.NumericParenthesisContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.NumericVariableContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.OrExpressionContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.StringLiteralContext;
import com.liferay.dynamic.data.mapping.expression.internal.parser.DDMExpressionParser.SubtractionExpressionContext;
import com.liferay.dynamic.data.mapping.expression.model.AndExpression;
import com.liferay.dynamic.data.mapping.expression.model.ArithmeticExpression;
import com.liferay.dynamic.data.mapping.expression.model.ComparisonExpression;
import com.liferay.dynamic.data.mapping.expression.model.Expression;
import com.liferay.dynamic.data.mapping.expression.model.FunctionCallExpression;
import com.liferay.dynamic.data.mapping.expression.model.MinusExpression;
import com.liferay.dynamic.data.mapping.expression.model.NotExpression;
import com.liferay.dynamic.data.mapping.expression.model.OrExpression;
import com.liferay.dynamic.data.mapping.expression.model.Parenthesis;
import com.liferay.dynamic.data.mapping.expression.model.StringTerm;
import com.liferay.dynamic.data.mapping.expression.model.Term;
import com.liferay.portal.kernel.util.StringUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.ParseTree;
/**
* @author Marcellus Tavares
*/
public class DDMExpressionModelVisitor
extends DDMExpressionBaseVisitor<Expression> {
@Override
public Expression visitAdditionExpression(
@NotNull AdditionExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ArithmeticExpression("+", l, r);
}
@Override
public Expression visitAndExpression(
@NotNull AndExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new AndExpression(l, r);
}
@Override
public Expression visitBooleanParenthesis(
@NotNull BooleanParenthesisContext context) {
return visitChild(context, 1);
}
@Override
public Expression visitDivisionExpression(
@NotNull DivisionExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ArithmeticExpression("/", l, r);
}
@Override
public Expression visitEqualsExpression(
@NotNull EqualsExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ComparisonExpression("=", l, r);
}
@Override
public Expression visitExpression(@NotNull ExpressionContext context) {
DDMExpressionParser.LogicalOrExpressionContext
logicalOrExpressionContext = context.logicalOrExpression();
return logicalOrExpressionContext.accept(this);
}
@Override
public Expression visitFloatingPointLiteral(
@NotNull FloatingPointLiteralContext context) {
return new Term(context.getText());
}
@Override
public Expression visitFunctionCallExpression(
@NotNull FunctionCallExpressionContext context) {
String functionName = getFunctionName(context.functionName);
List<Expression> parameters = getFunctionParameters(
context.functionParameters());
return new FunctionCallExpression(functionName, parameters);
}
@Override
public Expression visitGreaterThanExpression(
@NotNull GreaterThanExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ComparisonExpression(">", l, r);
}
@Override
public Expression visitGreaterThanOrEqualsExpression(
@NotNull GreaterThanOrEqualsExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ComparisonExpression(">=", l, r);
}
@Override
public Expression visitIntegerLiteral(
@NotNull IntegerLiteralContext context) {
return new Term(context.getText());
}
@Override
public Expression visitLessThanExpression(
@NotNull LessThanExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ComparisonExpression("<", l, r);
}
@Override
public Expression visitLessThanOrEqualsExpression(
@NotNull LessThanOrEqualsExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ComparisonExpression("<=", l, r);
}
@Override
public Expression visitLogicalConstant(
@NotNull LogicalConstantContext context) {
return new Term(context.getText());
}
@Override
public Expression visitLogicalVariable(
@NotNull LogicalVariableContext context) {
return new Term(context.getText());
}
@Override
public Expression visitMinusExpression(
@NotNull MinusExpressionContext context) {
Expression expression = visitChild(context, 1);
return new MinusExpression(expression);
}
@Override
public Expression visitMultiplicationExpression(
@NotNull MultiplicationExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ArithmeticExpression("*", l, r);
}
@Override
public Expression visitNotEqualsExpression(
@NotNull NotEqualsExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ComparisonExpression("!=", l, r);
}
@Override
public Expression visitNotExpression(
@NotNull NotExpressionContext context) {
Expression expression = visitChild(context, 1);
if (expression instanceof Parenthesis) {
Parenthesis parenthesis = (Parenthesis)expression;
expression = parenthesis.getOperandExpression();
}
return new NotExpression(expression);
}
@Override
public Expression visitNumericParenthesis(
@NotNull NumericParenthesisContext context) {
return new Parenthesis(visitChild(context, 1));
}
@Override
public Expression visitNumericVariable(
@NotNull NumericVariableContext context) {
return new Term(context.getText());
}
@Override
public Expression visitOrExpression(@NotNull OrExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new OrExpression(l, r);
}
@Override
public Expression visitStringLiteral(
@NotNull StringLiteralContext context) {
return new StringTerm(StringUtil.unquote(context.getText()));
}
@Override
public Expression visitSubtractionExpression(
@NotNull SubtractionExpressionContext context) {
Expression l = visitChild(context, 0);
Expression r = visitChild(context, 2);
return new ArithmeticExpression("-", l, r);
}
protected String getFunctionName(Token functionNameToken) {
return functionNameToken.getText();
}
protected List<Expression> getFunctionParameters(
FunctionParametersContext context) {
if (context == null) {
return Collections.emptyList();
}
List<Expression> parameters = new ArrayList<>();
for (int i = 0; i < context.getChildCount(); i += 2) {
Expression parameter = visitChild(context, i);
parameters.add(parameter);
}
return parameters;
}
protected <T> T visitChild(
ParserRuleContext parserRuleContext, int childIndex) {
ParseTree parseTree = parserRuleContext.getChild(childIndex);
return (T)parseTree.accept(this);
}
}