/*
 * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.jpa.jpql.tools;

import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.AbsExpression_InvalidNumericExpression;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.AvgFunction_InvalidNumericExpression;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.BetweenExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CollectionMemberExpression_Embeddable;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.ComparisonExpression_WrongComparisonType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.ConcatExpression_Expression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.ConstructorExpression_UndefinedConstructor;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.ConstructorExpression_UnknownType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CountFunction_DistinctEmbeddable;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.EncapsulatedIdentificationVariableExpression_NotMapValued;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.IdentificationVariable_EntityName;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.LengthExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.LocateExpression_FirstExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.LocateExpression_SecondExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.LocateExpression_ThirdExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.LowerExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.ModExpression_FirstExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.ModExpression_SecondExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.NotExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.NullComparisonExpression_InvalidType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.SqrtExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.SubstringExpression_FirstExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.SubstringExpression_SecondExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.SubstringExpression_ThirdExpression_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.SumFunction_WrongType;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.UpdateItem_NotAssignable;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.UpdateItem_NotResolvable;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.UpdateItem_NullNotAssignableToPrimitive;
import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.UpperExpression_WrongType;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.jpa.jpql.AbstractSemanticValidator;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.ITypeHelper;
import org.eclipse.persistence.jpa.jpql.JPAVersion;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.LiteralVisitor;
import org.eclipse.persistence.jpa.jpql.SemanticValidatorHelper;
import org.eclipse.persistence.jpa.jpql.parser.AbsExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSchemaName;
import org.eclipse.persistence.jpa.jpql.parser.AdditionExpression;
import org.eclipse.persistence.jpa.jpql.parser.AllOrAnyExpression;
import org.eclipse.persistence.jpa.jpql.parser.AndExpression;
import org.eclipse.persistence.jpa.jpql.parser.ArithmeticExpression;
import org.eclipse.persistence.jpa.jpql.parser.ArithmeticFactor;
import org.eclipse.persistence.jpa.jpql.parser.AvgFunction;
import org.eclipse.persistence.jpa.jpql.parser.BetweenExpression;
import org.eclipse.persistence.jpa.jpql.parser.BooleanPrimaryBNF;
import org.eclipse.persistence.jpa.jpql.parser.CaseExpression;
import org.eclipse.persistence.jpa.jpql.parser.CoalesceExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberExpression;
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EmptyCollectionComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.EncapsulatedIdentificationVariableExpression;
import org.eclipse.persistence.jpa.jpql.parser.EntryExpression;
import org.eclipse.persistence.jpa.jpql.parser.ExistsExpression;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLQueryBNF;
import org.eclipse.persistence.jpa.jpql.parser.KeyExpression;
import org.eclipse.persistence.jpa.jpql.parser.KeywordExpression;
import org.eclipse.persistence.jpa.jpql.parser.LengthExpression;
import org.eclipse.persistence.jpa.jpql.parser.LikeExpression;
import org.eclipse.persistence.jpa.jpql.parser.LiteralBNF;
import org.eclipse.persistence.jpa.jpql.parser.LocateExpression;
import org.eclipse.persistence.jpa.jpql.parser.LowerExpression;
import org.eclipse.persistence.jpa.jpql.parser.MaxFunction;
import org.eclipse.persistence.jpa.jpql.parser.MinFunction;
import org.eclipse.persistence.jpa.jpql.parser.ModExpression;
import org.eclipse.persistence.jpa.jpql.parser.MultiplicationExpression;
import org.eclipse.persistence.jpa.jpql.parser.NotExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullIfExpression;
import org.eclipse.persistence.jpa.jpql.parser.NumericLiteral;
import org.eclipse.persistence.jpa.jpql.parser.OrExpression;
import org.eclipse.persistence.jpa.jpql.parser.OrderByClause;
import org.eclipse.persistence.jpa.jpql.parser.OrderByItem;
import org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.SimpleArithmeticExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.SizeExpression;
import org.eclipse.persistence.jpa.jpql.parser.SqrtExpression;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.StringLiteral;
import org.eclipse.persistence.jpa.jpql.parser.StringPrimaryBNF;
import org.eclipse.persistence.jpa.jpql.parser.SubExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubstringExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubtractionExpression;
import org.eclipse.persistence.jpa.jpql.parser.SumFunction;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateItem;
import org.eclipse.persistence.jpa.jpql.parser.UpperExpression;
import org.eclipse.persistence.jpa.jpql.parser.ValueExpression;

/**
 * This validator is responsible to gather the problems found in a JPQL query by validating the
 * content to make sure it is semantically valid. The grammar is not validated by this visitor.
 * <p>
 * For instance, the function <b>AVG</b> accepts a state field path. The property it represents has
 * to be of numeric type. <b>AVG(e.name)</b> is parsable but is not semantically valid because the
 * type of name is a string (the property signature is: "<code>private String name</code>").
 * <p>
 * Provisional API: This interface is part of an interim API that is still under development and
 * expected to change significantly before reaching stability. It is available at this early stage
 * to solicit feedback from pioneering adopters on the understanding that any code that uses this
 * API will almost certainly be broken (repeatedly) as the API evolves.
 *
 * @see DefaultGrammarValidator
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public class DefaultSemanticValidator extends AbstractSemanticValidator {

    /**
     * This validator determines whether the {@link Expression} visited represents
     * {@link Expression#NULL}.
     */
    protected NullValueVisitor nullValueVisitor;

    /**
     * This finder is responsible to retrieve the abstract schema name from the <b>UPDATE</b> range
     * declaration expression.
     */
    protected UpdateClauseAbstractSchemaNameFinder updateClauseAbstractSchemaNameFinder;

    /**
     * The {@link TypeValidator TypeVlidators} mapped to their Java class. Those validators validate
     * any {@link Expression} by making sure its type matches the desired type.
     */
    protected Map<Class<? extends TypeValidator>, TypeValidator> validators;

    /**
     * Creates a new <code>DefaultSemanticValidator</code>.
     *
     * @param queryContext The context used to query information about the JPQL query
     * @exception NullPointerException The given {@link JPQLQueryContext} cannot be <code>null</code>
     */
    public DefaultSemanticValidator(JPQLQueryContext queryContext) {
        super(new GenericSemanticValidatorHelper(queryContext));
    }

    /**
     * Creates a new <code>DefaultSemanticValidator</code>.
     *
     * @param helper The given helper allows the validator to access the JPA artifacts without using
     * Hermes SPI directly
     * @exception NullPointerException The given {@link SemanticValidatorHelper} cannot be <code>null</code>
     * @since 2.4
     */
    public DefaultSemanticValidator(SemanticValidatorHelper helper) {
        super(helper);
    }

    protected boolean areTypesEquivalent(Object[] typeDeclarations1, Object[] typeDeclarations2) {

        // Empty array
        if ((typeDeclarations1.length == 0) && (typeDeclarations2.length == 0)) {
            return true;
        }

        // Different array length, always not equivalent
        if (typeDeclarations1.length != typeDeclarations2.length) {
            return false;
        }

        // Compare each element of the array together
        for (int index = typeDeclarations1.length; --index >= 0; ) {
            if (!helper.isTypeDeclarationAssignableTo(typeDeclarations1[index], typeDeclarations2[index])) {
                return false;
            }
        }

        return true;
    }

    @Override
    protected LiteralVisitor buildLiteralVisitor() {
        return new DefaultLiteralVisitor();
    }

    @Override
    protected OwningClauseVisitor buildOwningClauseVisitor() {
        return new OwningClauseVisitor();
    }

    protected ResultVariableInOrderByVisitor buildResultVariableInOrderByVisitor() {
        return new ResultVariableInOrderByVisitor();
    }

    protected AbstractSchemaName findAbstractSchemaName(UpdateItem expression) {
        UpdateClauseAbstractSchemaNameFinder visitor = getUpdateClauseAbstractSchemaNameFinder();
        try {
            expression.accept(visitor);
            return visitor.expression;
        }
        finally {
            visitor.expression = null;
        }
    }

    protected NullValueVisitor getNullValueVisitor() {
        if (nullValueVisitor == null) {
            nullValueVisitor = new NullValueVisitor();
        }
        return nullValueVisitor;
    }

    protected Object getType(Expression expression) {
        return helper.getType(expression);
    }

    protected ITypeHelper getTypeHelper() {
        return helper.getTypeHelper();
    }

    protected UpdateClauseAbstractSchemaNameFinder getUpdateClauseAbstractSchemaNameFinder() {
        if (updateClauseAbstractSchemaNameFinder == null) {
            updateClauseAbstractSchemaNameFinder = new UpdateClauseAbstractSchemaNameFinder();
        }
        return updateClauseAbstractSchemaNameFinder;
    }

    protected TypeValidator getValidator(Class<? extends TypeValidator> validatorClass) {
        TypeValidator validator = validators.get(validatorClass);
        if (validator == null) {
            try {
                Constructor<? extends TypeValidator> constructor = validatorClass.getDeclaredConstructor(DefaultSemanticValidator.class);
                constructor.setAccessible(true);
                validator = constructor.newInstance(this);
                validators.put(validatorClass, validator);
            }
            catch (ReflectiveOperationException e) { /* Never happens */ }
        }
        return validator;
    }

    @Override
    protected void initialize() {
        super.initialize();
        validators = new HashMap<Class<? extends TypeValidator>, TypeValidator>();
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression} returns a boolean value;</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @return <code>true</code> if the given {@link Expression} passes the checks; <code>false</code>
     * otherwise
     */
    protected boolean isBooleanType(Expression expression) {
        return isValid(expression, BooleanTypeValidator.class);
    }

    protected boolean isComparisonEquivalentType(Expression expression1, Expression expression2) {

        Object type1 = helper.getType(expression1);
        Object type2 = helper.getType(expression2);

        // 1. The types are the same
        // 2. The type cannot be determined, pretend they are equivalent,
        //    another rule will validate it
        // 3. One is assignable to the other one
        ITypeHelper typeHelper = getTypeHelper();

        return (type1 == type2) ||
               !helper.isTypeResolvable(type1) ||
               !helper.isTypeResolvable(type2) ||
                typeHelper.isNumericType(type1) && typeHelper.isNumericType(type2) ||
                typeHelper.isDateType(type1)    && typeHelper.isDateType(type2)    ||
                helper.isAssignableTo(type1, type2) ||
                helper.isAssignableTo(type2, type1);
    }

    protected boolean isEquivalentBetweenType(Expression expression1, Expression expression2) {

        Object type1 = helper.getType(expression1);
        Object type2 = helper.getType(expression2);

        // The type cannot be determined, pretend they are equivalent,
        // another rule will validate it
        if (!helper.isTypeResolvable(type1) ||
            !helper.isTypeResolvable(type2)) {

            return true;
        }

        ITypeHelper typeHelper = getTypeHelper();

        if (type1 == type2) {
            return typeHelper.isNumericType(type1) ||
            typeHelper.isStringType(type1)  ||
            typeHelper.isDateType(type1);
        }
        else {
            return typeHelper.isNumericType(type1) && typeHelper.isNumericType(type2) ||
                   typeHelper.isStringType(type1)  && typeHelper.isStringType(type2)  ||
                   typeHelper.isDateType(type1)    && typeHelper.isDateType(type2);
        }
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression}'s type is an integral type (long or integer).</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @return <code>true</code> if the given {@link Expression} passes the checks; <code>false</code>
     * otherwise
     */
    protected boolean isIntegralType(Expression expression) {

        if (isNumericType(expression)) {

            ITypeHelper typeHelper = getTypeHelper();
            Object type = helper.getType(expression);

            return type == typeHelper.unknownType() ||
                   typeHelper.isIntegralType(type);
        }

        return false;
    }

    protected boolean isNullValue(Expression expression) {
        NullValueVisitor visitor = getNullValueVisitor();
        try {
            expression.accept(visitor);
            return visitor.valid;
        }
        finally {
            visitor.valid = false;
        }
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression} returns a numeric value;</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @return <code>true</code> if the given {@link Expression} passes the checks; <code>false</code>
     * otherwise
     */
    protected boolean isNumericType(Expression expression) {
        return isValid(expression, NumericTypeValidator.class);
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression}'s type is a string type.</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @return <code>true</code> if the given {@link Expression} passes the checks; <code>false</code>
     * otherwise
     */
    protected boolean isStringType(Expression expression) {
        return isValid(expression, StringTypeValidator.class);
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type by using the
     * {@link TypeValidator}.
     *
     * @param expression The {@link Expression} to validate
     * @param validatorClass The Java class of the {@link TypeValidator} that will determine if the
     * given {@link Expression} has the right type
     * @return <code>true</code> if the given {@link Expression} passes the checks; <code>false</code>
     * otherwise
     */
    protected boolean isValid(Expression expression, Class<? extends TypeValidator> validatorClass) {
        TypeValidator validator = getValidator(validatorClass);
        try {
            expression.accept(validator);
            return validator.valid;
        }
        finally {
            validator.valid = false;
        }
    }

    protected boolean isValidWithFindQueryBNF(AbstractExpression expression, String queryBNF) {
        JPQLQueryBNFValidator validator = getExpressionValidator(queryBNF);
        try {
            JPQLQueryBNF childQueryBNF = expression.getParent().findQueryBNF(expression);
            validator.validate(childQueryBNF);
            return validator.isValid();
        }
        finally {
            validator.dispose();
        }
    }

    @Override
    protected PathType selectClausePathExpressionPathType() {
        return PathType.ANY_FIELD;
    }

    @Override
    protected boolean validateAbsExpression(AbsExpression expression) {

        boolean valid = super.validateAbsExpression(expression);

        if (valid) {
            // The ABS function takes a numeric argument
            valid = validateNumericType(expression.getExpression(), AbsExpression_InvalidNumericExpression);
        }

        return valid;
    }

    @Override
    protected int validateArithmeticExpression(ArithmeticExpression expression,
                                               String leftExpressionWrongTypeMessageKey,
                                               String rightExpressionWrongTypeMessageKey) {

        int result = super.validateArithmeticExpression(
            expression,
            leftExpressionWrongTypeMessageKey,
            rightExpressionWrongTypeMessageKey
        );

        // Only validate the left expression if it's still valid
        if (isValid(result, 0)) {
            boolean valid = validateNumericType(expression.getLeftExpression(), leftExpressionWrongTypeMessageKey);
            updateStatus(result, 0, valid);
        }

        // Validate the right expression
        boolean valid = validateNumericType(expression.getRightExpression(), rightExpressionWrongTypeMessageKey);
        updateStatus(result, 1, valid);

        return result;
    }

    @Override
    protected boolean validateAvgFunction(AvgFunction expression) {

        // Arguments to the functions AVG must be numeric
        boolean valid = super.validateAvgFunction(expression);

        if (valid) {
            valid = validateNumericType(expression.getExpression(), AvgFunction_InvalidNumericExpression);
        }

        return valid;
    }

    @Override
    protected int validateBetweenExpression(BetweenExpression expression) {

        int result = super.validateBetweenExpression(expression);

        // Only add extra validation if the lower and upper expressions are still valid
        if (isValid(result, 1) &&
            isValid(result, 2) &&
            !isEquivalentBetweenType(expression.getExpression(), expression.getLowerBoundExpression()) ||
            !isEquivalentBetweenType(expression.getExpression(), expression.getUpperBoundExpression())) {

            addProblem(expression, BetweenExpression_WrongType);
            updateStatus(result, 1, false);
            updateStatus(result, 2, false);
        }

        return result;
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression} returns a boolean value;</li>
     * <li>The {@link Expression}'s type is a boolean type.</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @param messageKey The key used to retrieve the localized message describing the problem
     */
    protected boolean validateBooleanType(Expression expression, String messageKey) {

        if (isValid(expression, BooleanPrimaryBNF.ID) && !isBooleanType(expression)) {
            addProblem(expression, messageKey);
            return false;
        }

        return true;
    }

    @Override
    protected int validateCollectionMemberExpression(CollectionMemberExpression expression) {

        int result = super.validateCollectionMemberExpression(expression);

        if (isValid(result, 0) && expression.hasEntityExpression()) {
            Expression entityExpression = expression.getEntityExpression();

            // Check for embeddable type
            Object type = helper.getType(entityExpression);

            if (helper.getEmbeddable(type) != null) {
                addProblem(entityExpression, CollectionMemberExpression_Embeddable);
                updateStatus(result, 0, false);
            }
        }

        return result;
    }

    @Override
    protected boolean validateComparisonExpression(ComparisonExpression expression) {

        boolean valid = super.validateComparisonExpression(expression);

        // Only validate the left and right if they are still valid
        if (valid && expression.hasLeftExpression() && expression.hasRightExpression()) {

            // The result of the two expressions must be like that of the other argument
            // Comparisons over instances of embeddable class or map entry types are not supported
            if (!isComparisonEquivalentType(expression.getLeftExpression(),
                                            expression.getRightExpression())) {

                addProblem(expression, ComparisonExpression_WrongComparisonType);
                valid = false;
            }
        }

        return valid;
    }

    @Override
    protected boolean validateConcatExpression(ConcatExpression expression) {

        boolean result = super.validateConcatExpression(expression);

        // The CONCAT function returns a string that is a concatenation of its arguments
        if (expression.hasExpression()) {
            int index = 0;
            for (Expression child : getChildren(expression.getExpression())) {
                // Don't validate the first expression if it is not valid
                if (index != 0 || result) {
                    result &= validateStringType(child, ConcatExpression_Expression_WrongType);
                }
                index++;
            }
        }

        return result;
    }

    @Override
    protected void validateConstructorExpression(ConstructorExpression expression) {

        super.validateConstructorExpression(expression);
        String className = expression.getClassName();

        // Only test the constructor if it has been specified
        if (ExpressionTools.stringIsNotEmpty(className)) {
            Object type = helper.getType(className);

            // Unknown type
            if (!helper.isTypeResolvable(type)) {
                int startPosition = position(expression) + 4 /* NEW + whitespace */;
                int endPosition = startPosition + className.length();
                addProblem(expression, startPosition, endPosition, ConstructorExpression_UnknownType, className);
            }
            // Test the arguments' types with the constructors' types
            else if (expression.hasLeftParenthesis() &&
                     expression.hasConstructorItems()) {

                Expression constructorItems = expression.getConstructorItems();

                // Retrieve the constructor's arguments so their type can be calculated
                List<Expression> children = getChildren(constructorItems);
                Object[] typeDeclarations = null;
                boolean constructorFound = false;

                for (Object constructor : helper.getConstructors(type)) {
                    Object[] parameterTypeDeclarations = helper.getMethodParameterTypeDeclarations(constructor);

                    // The number of items match, check their types are equivalent
                    if (children.size() == parameterTypeDeclarations.length) {

                        // The constructor is the default constructor and both have no parameters
                        if (parameterTypeDeclarations.length == 0) {
                            constructor = true;
                        }
                        else {

                            // Populate the type declaration array
                            if (typeDeclarations == null) {
                                typeDeclarations = new Object[children.size()];

                                for (int index = children.size(); --index >= 0; ) {
                                    typeDeclarations[index] = helper.getTypeDeclaration(children.get(index));
                                }
                            }

                            constructorFound = areTypesEquivalent(parameterTypeDeclarations, typeDeclarations);

                            if (constructorFound) {
                                break;
                            }
                        }
                    }
                }

                // No constructor was found matching the argument list
                if (!constructorFound) {
                    int startPosition = position(expression) + 4 /* NEW + whitespace */;
                    int endPosition = startPosition + className.length();
                    addProblem(expression, startPosition, endPosition, ConstructorExpression_UndefinedConstructor);
                }
            }
        }
    }

    @Override
    protected void validateCountFunction(CountFunction expression) {

        super.validateCountFunction(expression);

        // The use of DISTINCT with COUNT is not supported for arguments of
        // embeddable types or map entry types (weird because map entry is not
        // allowed in a COUNT expression)
        if (expression.hasExpression() &&
            expression.hasDistinct()) {

            Expression childExpression = expression.getExpression();

            // Check for embeddable type
            Object type = helper.getType(childExpression);

            if (helper.getEmbeddable(type) != null) {
                int distinctLength = Expression.DISTINCT.length() + 1; // +1 = space
                int startIndex  = position(childExpression) - distinctLength;
                int endIndex    = startIndex + length(childExpression) + distinctLength;
                addProblem(expression, startIndex, endIndex, CountFunction_DistinctEmbeddable);
            }
        }
    }

    @Override
    protected void validateEntryExpression(EntryExpression expression) {
        validateMapIdentificationVariable(expression);
        super.validateEntryExpression(expression);
    }

    @Override
    protected boolean validateIdentificationVariable(IdentificationVariable expression, String variable) {

        boolean valid = super.validateIdentificationVariable(expression, variable);

        for (String entityName : helper.entityNames()) {

            // An identification variable must not have the same name as any entity in the same
            // persistence unit, unless it's representing an entity literal
            if (variable.equalsIgnoreCase(entityName)) {

                // An identification variable could represent an entity type literal,
                // validate the parent to make sure it allows it
                if (!isValidWithFindQueryBNF(expression, LiteralBNF.ID)) {
                    int startIndex = position(expression);
                    int endIndex   = startIndex + variable.length();
                    addProblem(expression, startIndex, endIndex, IdentificationVariable_EntityName);
                    valid = false;
                    break;
                }
            }
        }

        return valid;
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression} returns a integral value;</li>
     * <li>The {@link Expression}'s type is an integral type (long or integer).</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @param queryBNF The unique identifier of the query BNF used to validate the type
     * @param messageKey The key used to retrieve the localized message describing the problem
     * @return <code>false</code> if the given expression was validated and is invalid;
     * <code>true</code> otherwise
     */
    protected boolean validateIntegralType(Expression expression, String queryBNF, String messageKey) {

        if (isValid(expression, queryBNF) && !isIntegralType(expression)) {
            addProblem(expression, messageKey);
            return false;
        }

        return true;
    }

    @Override
    protected void validateKeyExpression(KeyExpression expression) {
        validateMapIdentificationVariable(expression);
        super.validateKeyExpression(expression);
    }

    @Override
    protected boolean validateLengthExpression(LengthExpression expression) {

        boolean valid = super.validateLengthExpression(expression);

        if (valid) {
            valid = validateStringType(expression.getExpression(), LengthExpression_WrongType);
        }

        return valid;
    }

    @Override
    protected int validateLocateExpression(LocateExpression expression) {

        int result = super.validateLocateExpression(expression);

        // The first argument is the string to be located; the second argument is the string to be
        // searched; the optional third argument is an integer that represents the string position at
        // which the search is started (by default, the beginning of the string to be searched)
        if (isValid(result, 0)) {
            boolean valid = validateStringType(expression.getFirstExpression(), LocateExpression_FirstExpression_WrongType);
            updateStatus(result, 0, valid);
        }

        if (isValid(result, 1)) {
            boolean valid = validateStringType (expression.getSecondExpression(), LocateExpression_SecondExpression_WrongType);
            updateStatus(result, 1, valid);
        }

        if (isValid(result, 2)) {
            boolean valid = validateNumericType(expression.getThirdExpression(),  LocateExpression_ThirdExpression_WrongType);
            updateStatus(result, 2, valid);
        }

        return result;
    }

    @Override
    protected boolean validateLowerExpression(LowerExpression expression) {

        boolean valid = super.validateLowerExpression(expression);

        if (valid) {
            valid = validateStringType(expression.getExpression(), LowerExpression_WrongType);
        }

        return valid;
    }

    protected void validateMapIdentificationVariable(EncapsulatedIdentificationVariableExpression expression) {

        // The KEY, VALUE, and ENTRY operators may only be applied to
        // identification variables that correspond to map-valued associations
        // or map-valued element collections
        if (expression.hasExpression()) {

            Expression childExpression = expression.getExpression();
            String variableName = literal(childExpression, LiteralType.IDENTIFICATION_VARIABLE);

            // Retrieve the identification variable's type without traversing the type parameters
            if (ExpressionTools.stringIsNotEmpty(variableName)) {
                Object typeDeclaration = helper.getTypeDeclaration(childExpression);
                Object type = helper.getType(typeDeclaration);

                if (!getTypeHelper().isMapType(type)) {
                    addProblem(
                        childExpression,
                        EncapsulatedIdentificationVariableExpression_NotMapValued,
                        expression.getIdentifier()
                    );
                }
            }
        }
    }

    @Override
    protected int validateModExpression(ModExpression expression) {

        int result = super.validateModExpression(expression);

        // Don't validate the first expression if it's not valid
        if (isValid(result, 0)) {

            boolean valid = validateIntegralType(
                expression.getFirstExpression(),
                expression.parameterExpressionBNF(0),
                ModExpression_FirstExpression_WrongType
            );

            updateStatus(result, 0, valid);
        }

        // Don't validate the second expression if it's not valid
        if (isValid(result, 1)) {

            boolean valid = validateIntegralType(
                expression.getSecondExpression(),
                expression.parameterExpressionBNF(1),
                ModExpression_SecondExpression_WrongType
            );

            updateStatus(result, 1, valid);
        }

        return result;
    }

    @Override
    protected void validateNotExpression(NotExpression expression) {
        super.validateNotExpression(expression);
        validateBooleanType(expression.getExpression(), NotExpression_WrongType);
    }

    @Override
    protected void validateNullComparisonExpression(NullComparisonExpression expression) {

        super.validateNullComparisonExpression(expression);

        // Null comparisons over instances of embeddable class types are not supported
        StateFieldPathExpression pathExpression = getStateFieldPathExpression(expression.getExpression());

        if (pathExpression != null) {
            Object type = helper.getType(pathExpression);

            if (helper.getEmbeddable(type) != null) {
                addProblem(pathExpression, NullComparisonExpression_InvalidType, pathExpression.toParsedText());
            }
        }
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression} returns a numeric value;</li>
     * <li>The {@link Expression}'s type is an numeric type.</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @param messageKey The key used to retrieve the localized message describing the problem
     * @return <code>false</code> if the given expression was validated and is invalid;
     * <code>true</code> otherwise
     */
    protected boolean validateNumericType(Expression expression, String messageKey) {

        if (isValid(expression, SimpleArithmeticExpressionBNF.ID) && !isNumericType(expression)) {
            addProblem(expression, messageKey);
            return false;
        }

        return true;
    }

    @Override
    protected boolean validateSqrtExpression(SqrtExpression expression) {

        boolean valid = super.validateSqrtExpression(expression);

        if (valid) {
            // The SQRT function takes a numeric argument
            valid = validateNumericType(expression.getExpression(), SqrtExpression_WrongType);
        }

        return valid;
    }

    /**
     * Determines whether the given {@link Expression} is of the correct type based on these rules:
     * <ul>
     * <li>The {@link Expression} returns a String value;</li>
     * <li>The {@link Expression}'s type is a String type.</li>
     * </ul>
     *
     * @param expression The {@link Expression} to validate
     * @param messageKey The key used to retrieve the localized message describing the problem
     * @return <code>false</code> if the given expression was validated and is invalid;
     * <code>true</code> otherwise
     */
    protected boolean validateStringType(Expression expression, String messageKey) {

        if (isValid(expression, StringPrimaryBNF.ID) && !isStringType(expression)) {
            addProblem(expression, messageKey, expression.toParsedText());
            return false;
        }

        return true;
    }

    @Override
    protected int validateSubstringExpression(SubstringExpression expression) {

        int result = super.validateSubstringExpression(expression);

        if (isValid(result, 0)) {
            boolean valid = validateStringType(
                expression.getFirstExpression(),
                SubstringExpression_FirstExpression_WrongType
            );
            updateStatus(result, 0, valid);
        }

        // The second and third arguments of the SUBSTRING function denote the starting position and
        // length of the substring to be returned. These arguments are integers
        if (isValid(result, 1)) {

            boolean valid = validateIntegralType(
                expression.getSecondExpression(),
                expression.getParameterQueryBNFId(1),
                SubstringExpression_SecondExpression_WrongType
            );

            updateStatus(result, 1, valid);
        }

        // The third argument is optional for JPA 2.0
        if (isValid(result, 2) && getJPAVersion().isNewerThanOrEqual(JPAVersion.VERSION_2_0)) {

            boolean valid = validateIntegralType(
                expression.getThirdExpression(),
                expression.getParameterQueryBNFId(2),
                SubstringExpression_ThirdExpression_WrongType
            );

            updateStatus(result, 2, valid);
        }

        return result;
    }

    @Override
    protected boolean validateSumFunction(SumFunction expression) {

        boolean valid = super.validateSumFunction(expression);

        if (valid) {
            // Arguments to the functions SUM must be numeric
            valid = validateNumericType(expression.getExpression(), SumFunction_WrongType);
        }

        return valid;
    }

    @Override
    @SuppressWarnings("null")
    protected boolean validateUpdateItem(UpdateItem expression) {

        // First validate the path expression
        boolean valid = super.validateUpdateItem(expression);

        if (valid) {

            // Retrieve the entity to make sure the state field is part of it
            AbstractSchemaName abstractSchemaName = findAbstractSchemaName(expression);
            String entityName = (abstractSchemaName != null) ? abstractSchemaName.getText() : null;

             if (ExpressionTools.stringIsNotEmpty(entityName)) {
                 Object entity = helper.getEntityNamed(entityName);

                // Check the existence of the state field on the entity
                if ((entity != null) && expression.hasSpaceAfterStateFieldPathExpression()) {
                    StateFieldPathExpression pathExpression = getStateFieldPathExpression(expression.getStateFieldPathExpression());
                    String stateFieldValue = (pathExpression != null) ? pathExpression.toParsedText() : null;

                    if (ExpressionTools.stringIsNotEmpty(stateFieldValue)) {

                        // State field without a dot
                        if (stateFieldValue.indexOf('.') == -1) {
                            Object mapping = helper.getMappingNamed(entity, stateFieldValue);

                             if (mapping == null) {
                                 addProblem(pathExpression, UpdateItem_NotResolvable, stateFieldValue);
                             }
                             else {
                                 validateUpdateItemTypes(expression, helper.getMappingType(mapping));
                             }
                        }
                        else {
                            Object type = helper.getType(pathExpression);

                            if (!helper.isTypeResolvable(type)) {
                                 addProblem(pathExpression, UpdateItem_NotResolvable, stateFieldValue);
                            }
                            else {
                                 validateUpdateItemTypes(expression, type);
                            }
                        }
                    }
                 }
             }
        }

        return valid;
    }

    protected void validateUpdateItemTypes(UpdateItem expression, Object type) {

        if (expression.hasNewValue()) {

            Expression newValue = expression.getNewValue();
            ITypeHelper typeHelper = getTypeHelper();
            boolean nullValue = isNullValue(newValue);

            // A NULL value is ignored, except if the type is a primitive, null cannot be
            // assigned to a mapping of primitive type
            if (nullValue) {
                if (typeHelper.isPrimitiveType(type)) {
                    addProblem(expression, UpdateItem_NullNotAssignableToPrimitive);
                }
                return;
            }

            Object newValueType = getType(newValue);

            // Do a quick check for known JDK types:
            // 1) Date/Time/Timestamp
            // 2) Any classes related to a number, eg long/Long etc
            if (!helper.isTypeResolvable(newValueType) ||
                typeHelper.isDateType(type) && typeHelper.isDateType(newValueType) ||
                (typeHelper.isNumericType(type)         || typeHelper.isPrimitiveType(type)) &&
                (typeHelper.isNumericType(newValueType) || typeHelper.isPrimitiveType(newValueType))) {

                return;
            }

            // The new value's type can't be assigned to the item's type
            if (!helper.isAssignableTo(newValueType, type)) {
                addProblem(
                    expression,
                    UpdateItem_NotAssignable,
                    helper.getTypeName(newValueType),
                    helper.getTypeName(type)
                );
            }
        }
    }

    @Override
    protected boolean validateUpperExpression(UpperExpression expression) {

        boolean valid = super.validateUpperExpression(expression);

        if (valid) {
            // The UPPER function convert a string to upper case,
            // with regard to the locale of the database
            valid = validateStringType(expression.getExpression(), UpperExpression_WrongType);
        }

        return valid;
    }

    @Override
    protected void validateValueExpression(ValueExpression expression) {
        validateMapIdentificationVariable(expression);
        super.validateValueExpression(expression);
    }

    /**
     * This visitor validates expression that is a boolean literal to make sure the type is a
     * <b>Boolean</b>.
     */
    protected class BooleanTypeValidator extends TypeValidator {

        @Override
        protected boolean isRightType(Object type) {
            return getTypeHelper().isBooleanType(type);
        }

        @Override
        public void visit(AllOrAnyExpression expression) {
            // ALL|ANY|SOME always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(AndExpression expression) {
            // AND always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(BetweenExpression expression) {
            // BETWEEN always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(ComparisonExpression expression) {
            // A comparison always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(EmptyCollectionComparisonExpression expression) {
            // IS EMPTY always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(ExistsExpression expression) {
            // EXISTS always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(KeywordExpression expression) {
            valid = true;
        }

        @Override
        public void visit(LikeExpression expression) {
            // LIKE always returns a boolean value
            valid = true;
        }

         @Override
        public void visit(NotExpression expression) {
            // NOT always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(NullComparisonExpression expression) {
            // IS NULL always returns a boolean value
            valid = true;
        }

        @Override
        public void visit(OrExpression expression) {
            // OR always returns a boolean value
            valid = true;
        }
    }

    protected static class NullValueVisitor extends AbstractExpressionVisitor {

        /**
         * Determines whether the {@link Expression} visited represents {@link Expression#NULL}.
         */
        protected boolean valid;

        @Override
        public void visit(KeywordExpression expression) {
            valid = expression.getText() == Expression.NULL;
        }
    }

    /**
     * This visitor validates expression that is a numeric literal to make sure the type is an
     * instance of <b>Number</b>.
     */
    protected class NumericTypeValidator extends TypeValidator {

        @Override
        protected boolean isRightType(Object type) {
            return getTypeHelper().isNumericType(type);
        }

        @Override
        public void visit(AbsExpression expression) {
            // ABS always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(AdditionExpression expression) {
            // An addition expression always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(ArithmeticFactor expression) {
            // +/- is always numeric value
            valid = true;
        }

        @Override
        public void visit(AvgFunction expression) {
            // AVG always returns a double
            valid = true;
        }

        @Override
        public void visit(CountFunction expression) {
            // COUNT always returns a long
            valid = true;
        }

        @Override
        public void visit(DivisionExpression expression) {
            // A division expression always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(IndexExpression expression) {
            // INDEX always returns an integer
            valid = true;
        }

        @Override
        public void visit(LengthExpression expression) {
            // LENGTH always returns an integer
            valid = true;
        }

        @Override
        public void visit(LocateExpression expression) {
            // LOCATE always returns an integer
            valid = true;
        }

        @Override
        public void visit(MaxFunction expression) {
            // SUM always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(MinFunction expression) {
            // SUM always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(ModExpression expression) {
            // MOD always returns an integer
            valid = true;
        }

        @Override
        public void visit(MultiplicationExpression expression) {
            // A multiplication expression always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(NumericLiteral expression) {
            // A numeric literal is by definition valid
            valid = true;
        }

        @Override
        public void visit(SizeExpression expression) {
            // SIZE always returns an integer
            valid = true;
        }

        @Override
        public void visit(SqrtExpression expression) {
            // SQRT always returns a double
            valid = true;
        }

        @Override
        public void visit(SubtractionExpression expression) {
            // A subtraction expression always returns a numeric value
            valid = true;
        }

        @Override
        public void visit(SumFunction expression) {
            // SUM always returns a long
            valid = true;
        }
    }

    protected static class ResultVariableInOrderByVisitor extends AbstractExpressionVisitor {

        public boolean result;

        @Override
        public void visit(IdentificationVariable expression) {
            expression.getParent().accept(this);
        }

        @Override
        public void visit(OrderByClause expression) {
            result = true;
        }

        @Override
        public void visit(OrderByItem expression) {
            expression.getParent().accept(this);
        }
    }

    /**
     * This visitor validates that the {@link Expression} is a string primary and to make sure the
     * type is String.
     */
    protected class StringTypeValidator extends TypeValidator {

        @Override
        protected boolean isRightType(Object type) {
            return getTypeHelper().isStringType(type);
        }

        @Override
        public void visit(ConcatExpression expression) {
            // CONCAT always returns a string
            valid = true;
        }

        @Override
        public void visit(LowerExpression expression) {
            // LOWER always returns a string
            valid = true;
        }

        @Override
        public void visit(StringLiteral expression) {
            // A string literal is by definition valid
            valid = true;
        }

        @Override
        public void visit(SubstringExpression expression) {
            // SUBSTRING always returns a string
            valid = true;
        }

        @Override
        public void visit(TrimExpression expression) {
            // TRIM always returns a string
            valid = true;
        }

        @Override
        public void visit(UpperExpression expression) {
            // UPPER always returns a string
            valid = true;
        }
    }

    /**
     * The basic validator for validating the type of an {@link Expression}.
     */
    protected abstract class TypeValidator extends AbstractExpressionVisitor {

        /**
         * Determines whether the expression that was visited returns a number.
         */
        protected boolean valid;

        /**
         * Determines whether the given type is the expected type.
         *
         * @param type The type to validate
         * @return <code>true</code> if the given type is of the expected type; <code>false</code> if
         * it's not the right type
         */
        protected abstract boolean isRightType(Object type);

        @Override
        public final void visit(CaseExpression expression) {
            Object type = getType(expression);
            valid = isRightType(type);
        }

        @Override
        public final void visit(CoalesceExpression expression) {
            Object type = getType(expression);
            valid = isRightType(type);
        }

        @Override
        public final void visit(InputParameter expression) {
            // An input parameter can't be validated until the query
            // is executed so it is assumed to be valid
            valid = true;
        }

        @Override
        public void visit(NullExpression expression) {
            // The missing expression is validated by GrammarValidator
            valid = true;
        }

        @Override
        public final void visit(NullIfExpression expression) {
            expression.getFirstExpression().accept(this);
        }

        @Override
        public final void visit(StateFieldPathExpression expression) {
            Object type = getType(expression);
            valid = isRightType(type);
        }

        @Override
        public final void visit(SubExpression expression) {
            expression.getExpression().accept(this);
        }
    }

    protected static class UpdateClauseAbstractSchemaNameFinder extends AbstractExpressionVisitor {

        protected AbstractSchemaName expression;

        @Override
        public void visit(AbstractSchemaName expression) {
            this.expression = expression;
        }

        @Override
        public void visit(CollectionExpression expression) {
            expression.getParent().accept(this);
        }

        @Override
        public void visit(RangeVariableDeclaration expression) {
            expression.getRootObject().accept(this);
        }

        @Override
        public void visit(UpdateClause expression) {
            expression.getRangeVariableDeclaration().accept(this);
        }

        @Override
        public void visit(UpdateItem expression) {
            expression.getParent().accept(this);
        }
    }
}
