/*
 * 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.resolver;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.persistence.jpa.jpql.Assert;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.parser.AbsExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractPathExpression;
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.BadExpression;
import org.eclipse.persistence.jpa.jpql.parser.BetweenExpression;
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.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
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.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EmptyCollectionComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.EntityTypeLiteral;
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.ExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.parser.GroupByClause;
import org.eclipse.persistence.jpa.jpql.parser.HavingClause;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.InExpression;
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.Join;
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.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.ObjectExpression;
import org.eclipse.persistence.jpa.jpql.parser.OnClause;
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.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
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.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.TreatExpression;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.TypeExpression;
import org.eclipse.persistence.jpa.jpql.parser.UnknownExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateItem;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;
import org.eclipse.persistence.jpa.jpql.parser.UpperExpression;
import org.eclipse.persistence.jpa.jpql.parser.ValueExpression;
import org.eclipse.persistence.jpa.jpql.parser.WhenClause;
import org.eclipse.persistence.jpa.jpql.parser.WhereClause;
import org.eclipse.persistence.jpa.jpql.tools.JPQLQueryContext;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;

/**
 * This visitor creates a {@link Resolver} that gives information about the visited {@link Expression}.
 * The actual {@link Resolver} will calculate the proper {@link IType} as well.
 * <p>
 * The type of an {@link Expression} follows the following rules:
 * <ul>
 * <li>The type of the query result specified by the <b>SELECT</b> clause of a query is an entity
 * abstract schema type, a state field type, the result of a scalar expression, the result of an
 * aggregate function, the result of a construction operation, or some sequence of these.</li>
 *
 * <li>The result type of the <b>SELECT</b> clause is defined by the result types of the select
 * expressions contained in it. When multiple select expressions are used in the <b>SELECT</b>
 * clause, the elements in this result correspond in order to the order of their specification in
 * the <b>SELECT</b> clause and in type to the result types of each of the select expressions.</li>
 *
 * <li>The result type of an <code>identification_variable</code> is the type of the entity object
 * or embeddable object to which the identification variable corresponds. The type of an
 * <code>identification_variable</code> that refers to an entity abstract schema type is the type of
 * the entity to which that identification variable corresponds or a subtype as determined by the
 * object/relational mapping.</li>
 *
 * <li>The result type of a <code>single_valued_path_expression</code> that is a
 * <code>state_field_path_expression</code> is the same type as the corresponding state field of the
 * entity or embeddable class. If the state field of the entity is a primitive type, the result type
 * is the corresponding object type.</li>
 *
 * <li>The result type of a <code>single_valued_path_expression</code> that is a
 * <code>single_valued_object_path_expression</code> is the type of the entity object or embeddable
 * object to which the path expression corresponds. A
 * <code>single_valued_object_path_expression</code> that results in an entity object will result in
 * an entity of the type of the relationship field or the subtype of the relationship field of the
 * entity object as determined by the object/relational mapping.</li>
 *
 * <li>The result type of a <code>single_valued_path_expression</code> that is an
 * identification_variable to which the <code>KEY</code> or <code>VALUE</code> function has been
 * applied is determined by the type of the map key or value respectively, as defined by the above
 * rules.</li>
 *
 * <li>The result type of a <code>single_valued_path_expression</code> that is an
 * identification_variable to which the <code>ENTRY</code> function has been applied is
 * {@link java.util.Map.Entry Map.Entry}, where the key and value types of the map entry are
 * determined by the above rules as applied to the map key and map value respectively.</li>
 *
 * <li>The result type of a <code>scalar_expression</code> is the type of the scalar value to which
 * the expression evaluates.</li>
 *
 * <li>The result type of an <code>entity_type_expression</code> scalar expression is the Java class
 * to which the resulting abstract schema type corresponds.</li>
 *
 * <li>The result type of a <code>constructor_expression</code> is the type of the class for which
 * the constructor is defined. The types of the arguments to the constructor are defined by the
 * above rules.</li>
 * </ul>
 * <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.
 *
 * @version 2.5.1
 * @since 2.3
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
public abstract class ResolverBuilder implements ExpressionVisitor {

    /**
     * This visitor is responsible to retrieve the {@link CollectionExpression} if it is visited.
     */
    private CollectionExpressionVisitor collectionExpressionVisitor;

    /**
     * The context used to query information about the JPQL query.
     */
    private final JPQLQueryContext queryContext;

    /**
     * The {@link Resolver} for the {@link Expression} that was visited.
     */
    protected Resolver resolver;

    /**
     * Creates a new <code>ResolverBuilder</code>.
     *
     * @param queryContext The context used to query information about the JPQL query
     * @exception NullPointerException The {@link JPQLQueryContext} cannot be <code>null</code>
     */
    public ResolverBuilder(JPQLQueryContext queryContext) {
        super();
        Assert.isNotNull(queryContext, "The JPQLQueryContext cannot be null");
        this.queryContext = queryContext;
    }

    /**
     * Creates a new {link Resolver} that simply wraps the already determined type by using its
     * fully qualified class name.
     *
     * @param typeName The fully qualified class name of the Java type to wrap with a {@link Resolver}
     * @return A new {@link Resolver}
     */
    protected Resolver buildClassNameResolver(String typeName) {
        return new ClassNameResolver(getDeclarationResolver(), typeName);
    }

    /**
     * Creates a new {link Resolver} that simply wraps the already determined type.
     *
     * @param type The Java type to wrap with a {@link Resolver}
     * @return A new {@link Resolver}
     */
    protected Resolver buildClassResolver(Class<?> type) {
        return new ClassResolver(getDeclarationResolver(), type);
    }

    /**
     * Creates a visitor that collects the {@link CollectionExpression} if it's been visited.
     *
     * @return A new {@link CollectionExpressionVisitor}
     */
    protected CollectionExpressionVisitor buildCollectionExpressionVisitor() {
        return new CollectionExpressionVisitor();
    }

    /**
     * Creates a new {@link Resolver} for the given collection-valued path expression.
     *
     * @param variableName The last segment of the collection-valued path expression
     * @return A new {@link Resolver} that can get the information for a collection-valued path
     */
    protected Resolver buildCollectionValuedFieldResolver(String variableName) {

        Resolver resolver = this.resolver.getChild(variableName);

        if (resolver == null) {
            resolver = new CollectionValuedFieldResolver(this.resolver, variableName);
        }

        return resolver;
    }

    /**
     * Creates a new {@link Resolver} that will resolve the given enum literal.
     *
     * @param expression The {@link Expression} that represents the enum literal
     * @param type The {@link IType} representing the {@link Enum} type
     * @param enumLiteral The fully qualified enum constant
     * @return The {@link Resolver} for an enum literal
     */
    protected Resolver buildEnumResolver(AbstractPathExpression expression,
                                         IType type,
                                         String enumLiteral) {

        DeclarationResolver parent = getDeclarationResolver(expression);
        return new EnumLiteralResolver(parent, type, enumLiteral);
    }

    /**
     * Creates a new {@link Resolver} that is used when nothing can be resolved.
     *
     * @return A "<code>null</code>" version of a {@link Resolver}
     */
    protected Resolver buildNullResolver() {
        return new NullResolver(getDeclarationResolver());
    }

    /**
     * Creates a new {@link Resolver} for the given state field path expression.
     *
     * @param variableName The last segment of the state field path expression
     * @return A new {@link Resolver} that can get the information for a state field path
     */
    protected Resolver buildStateFieldResolver(String variableName) {

        Resolver resolver = this.resolver.getChild(variableName);

        if (resolver == null) {
            resolver = new StateFieldResolver(this.resolver, variableName);
        }

        return resolver;
    }

    /**
     * Disposes the internal data of this resolver.
     */
    public void dispose() {
        resolver = null;
    }

    /**
     * Casts the given {@link Expression} to a {@link CollectionExpression} if it is actually an
     * object of that type.
     *
     * @param expression The {@link Expression} to cast
     * @return The given {@link Expression} if it is a {@link CollectionExpression} or <code>null</code>
     * if it is any other object
     */
    protected CollectionExpression getCollectionExpression(Expression expression) {
        CollectionExpressionVisitor visitor = getCollectionExpressionVisitor();
        try {
            expression.accept(visitor);
            return visitor.expression;
        }
        finally {
            visitor.expression = null;
        }
    }

    /**
     * Returns the visitor that collects the {@link CollectionExpression} if it's been visited.
     *
     * @return The {@link CollectionExpressionVisitor}
     * @see #buildCollectionExpressionVisitor()
     */
    protected CollectionExpressionVisitor getCollectionExpressionVisitor() {
        if (collectionExpressionVisitor == null) {
            collectionExpressionVisitor = buildCollectionExpressionVisitor();
        }
        return collectionExpressionVisitor;
    }

    /**
     * Returns the {@link DeclarationResolver} of the current query's declaration. For a
     * <b>SELECT</b> query, it contains the information defined in the <b>FROM</b> clause. For
     * <b>DELETE</b> and <b>UPDATE</b> queries, it contains a single range declaration variable. If
     * the current query is a subquery, then it contains the information defined in the
     * <code>FROM</code> clause.
     *
     * @return The {@link DeclarationResolver} for the current query being visited
     */
    protected DeclarationResolver getDeclarationResolver() {
        return queryContext.getDeclarationResolver();
    }

    /**
     * Returns the {@link DeclarationResolver} of the current query's declaration. For a
     * <b>SELECT</b> query, it contains the information defined in the <b>FROM</b> clause. For
     * <b>DELETE</b> and <b>UPDATE</b> queries, it contains a single range variable declaration. If
     * the current query is a subquery, then it contains the information defined in the subquery
     * <code>FROM</code> clause.
     *
     * @param expression The {@link Expression} that will be used to retrieve its query expression,
     * i.e. either {@link JPQLExpression} or {@link SimpleSelectStatement}
     * @return The {@link DeclarationResolver} for the current query being visited
     */
    protected DeclarationResolver getDeclarationResolver(Expression expression) {
        return queryContext.getDeclarationResolver(expression);
    }

    /**
     * Returns the {@link JPQLQueryContext} that contains information related to the JPQL query.
     *
     * @return The {@link JPQLQueryContext}, which is never <code>null</code>
     */
    protected JPQLQueryContext getQueryContext() {
        return queryContext;
    }

    /**
     * Returns the current {@link Resolver} used to resolve an {@link Expression}.
     *
     * @return The current {@link Resolver}, which should never be <code>null</code>
     */
    public Resolver getResolver() {
        return resolver;
    }

    @Override
    public void visit(AbsExpression expression) {

        // Visit the child expression in order to create the resolver
        expression.getExpression().accept(this);

        // Wrap the Resolver used to determine the type of the state field
        // path expression so we can return the actual type
        resolver = new AbsFunctionResolver(resolver);
    }

    @Override
    public void visit(AbstractSchemaName expression) {

        String abstractSchemaName = expression.getText();

        if (ExpressionTools.stringIsNotEmpty(abstractSchemaName)) {

            DeclarationResolver parent = getDeclarationResolver(expression);

            if (queryContext.isSubquery()) {
                resolver = new SubqueryEntityResolver(parent, queryContext.getCurrentContext(), expression);
            }
            else {
                resolver = new EntityResolver(parent, abstractSchemaName);
            }
        }
        else {
            resolver = buildNullResolver();
        }
    }

    @Override
    public void visit(AdditionExpression expression) {
        visitArithmeticExpression(expression);
    }

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

    @Override
    public void visit(AndExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(ArithmeticFactor expression) {

        // First traverse the expression
        expression.getExpression().accept(this);

        // Make sure the type is a numeric type
        DeclarationResolver parent = getDeclarationResolver(expression);
        resolver = new NumericResolver(parent, resolver);
    }

    @Override
    public void visit(AvgFunction expression) {
        resolver = buildClassResolver(Double.class);
    }

    @Override
    public void visit(BadExpression expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(BetweenExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(CaseExpression expression) {
        visitCollectionEquivalentExpression(
            expression.getWhenClauses(),
            expression.getElseExpression()
        );
    }

    @Override
    public void visit(CoalesceExpression expression) {
        visitCollectionEquivalentExpression(expression.getExpression(), null);
    }

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

    @Override
    public void visit(CollectionMemberDeclaration expression) {
        expression.getCollectionValuedPathExpression().accept(this);
    }

    @Override
    public void visit(CollectionMemberExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(CollectionValuedPathExpression expression) {

        // If the path ends with '.', then the path is incomplete
        // so we can't resolve the type
        if (!expression.endsWithDot()) {

            // Check first to see if it's an enum type
            String path = expression.toActualText();
            IType type = queryContext.getTypeRepository().getEnumType(path);

            if (type != null) {
                resolver = buildEnumResolver(expression, type, path);
            }
            else {
                expression.getIdentificationVariable().accept(this);

                for (int index = expression.hasVirtualIdentificationVariable() ? 0 : 1, count = expression.pathSize(); index < count; index++) {
                    path = expression.getPath(index);
                    if (index + 1 < count) {
                        resolver = buildStateFieldResolver(path);
                    }
                    else {
                        resolver = buildCollectionValuedFieldResolver(path);
                    }
                }
            }
        }
        else {
            resolver = buildNullResolver();
        }
    }

    @Override
    public void visit(ComparisonExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(ConcatExpression expression) {
        resolver = buildClassResolver(String.class);
    }

    @Override
    public void visit(ConstructorExpression expression) {

        String className = expression.getClassName();

        if (ExpressionTools.stringIsNotEmpty(className)) {
            resolver = buildClassNameResolver(className);
        }
        else {
            resolver = buildNullResolver();
        }
    }

    @Override
    public void visit(CountFunction expression) {
        resolver = buildClassResolver(Long.class);
    }

    @Override
    public void visit(DateTime expression) {

        if (expression.isCurrentDate()) {
            resolver = buildClassResolver(Date.class);
        }
        else if (expression.isCurrentTime()) {
            resolver = buildClassResolver(Time.class);
        }
        else if (expression.isCurrentTimestamp()) {
            resolver = buildClassResolver(Timestamp.class);
        }
        else {
            String text = expression.getText();

            if (text.startsWith("{d")) {
                resolver = buildClassResolver(Date.class);
            }
            else if (text.startsWith("{ts")) {
                resolver = buildClassResolver(Timestamp.class);
            }
            else if (text.startsWith("{t")) {
                resolver = buildClassResolver(Time.class);
            }
            else {
                resolver = buildNullResolver();
            }
        }
    }

    @Override
    public void visit(DeleteClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(DeleteStatement expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(DivisionExpression expression) {
        visitArithmeticExpression(expression);
    }

    @Override
    public void visit(EmptyCollectionComparisonExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(EntityTypeLiteral expression) {

        String entityTypeName = expression.getEntityTypeName();

        if (ExpressionTools.stringIsNotEmpty(entityTypeName)) {
            DeclarationResolver parent = getDeclarationResolver(expression);
            resolver = new EntityResolver(parent, entityTypeName);
        }
        else {
            resolver = buildNullResolver();
        }
    }

    @Override
    public void visit(EntryExpression expression) {
        resolver = buildClassResolver(Map.Entry.class);
    }

    @Override
    public void visit(ExistsExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(FromClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(FunctionExpression expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(GroupByClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(HavingClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(IdentificationVariable expression) {
        DeclarationResolver parent = getDeclarationResolver(expression);
        resolver = parent.getResolver(expression.getVariableName());
    }

    @Override
    public void visit(IdentificationVariableDeclaration expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(IndexExpression expression) {
        resolver = buildClassResolver(Integer.class);
    }

    @Override
    public void visit(InExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(InputParameter expression) {
        resolver = buildClassNameResolver(IType.UNRESOLVABLE_TYPE);
    }

    @Override
    public void visit(Join expression) {
        expression.getJoinAssociationPath().accept(this);
        resolver.setNullAllowed(expression.isLeftJoin());
    }

    @Override
    public void visit(JPQLExpression expression) {
        expression.getQueryStatement().accept(this);
    }

    @Override
    public void visit(KeyExpression expression) {

        // Visit the identification variable in order to create the resolver
        expression.getExpression().accept(this);

        // Wrap the Resolver used to determine the type of the identification
        // variable so we can return the actual type
        resolver = new KeyResolver(resolver);
    }

    @Override
    public void visit(KeywordExpression expression) {

        String text = expression.getText();

        if (text == KeywordExpression.FALSE ||
            text == KeywordExpression.TRUE) {

            resolver = buildClassResolver(Boolean.class);
        }
        else {
            resolver = buildClassResolver(Object.class);
        }
    }

    @Override
    public void visit(LengthExpression expression) {
        resolver = buildClassResolver(Integer.class);
    }

    @Override
    public void visit(LikeExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(LocateExpression expression) {
        resolver = buildClassResolver(Integer.class);
    }

    @Override
    public void visit(LowerExpression expression) {
        resolver = buildClassResolver(String.class);
    }

    @Override
    public void visit(MaxFunction expression) {
        // Visit the state field path expression in order to create the resolver
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(MinFunction expression) {
        // Visit the state field path expression in order to create the resolver
        expression.getExpression().accept(this);
    }

    @Override
    public void visit(ModExpression expression) {
        resolver = buildClassResolver(Integer.class);
    }

    @Override
    public void visit(MultiplicationExpression expression) {
        visitArithmeticExpression(expression);
    }

    @Override
    public void visit(NotExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(NullComparisonExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(NullExpression expression) {
        resolver = buildClassNameResolver(IType.UNRESOLVABLE_TYPE);
    }

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

    @Override
    public void visit(NumericLiteral expression) {

        try {
            String text = expression.getText();

            // Long value
            // Integer value
            if (ExpressionTools.LONG_REGEXP   .matcher(text).matches() ||
                ExpressionTools.INTEGER_REGEXP.matcher(text).matches()) {

                Long value = Long.parseLong(text);

                if (value <= Integer.MAX_VALUE) {
                    resolver = buildClassResolver(Integer.class);
                }
                else {
                    resolver = buildClassResolver(Long.class);
                }
            }
            // Float
            else if (ExpressionTools.FLOAT_REGEXP.matcher(text).matches()) {
                resolver = buildClassResolver(Float.class);
            }
            // Decimal
            else if (ExpressionTools.DOUBLE_REGEXP.matcher(text).matches()) {
                resolver = buildClassResolver(Double.class);
            }
        }
        catch (Exception e) {
            resolver = buildClassResolver(Object.class);
        }
    }

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

    @Override
    public void visit(OnClause expression) {
        expression.getConditionalExpression().accept(this);
    }

    @Override
    public void visit(OrderByClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(OrderByItem expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(OrExpression expression) {
        resolver = buildClassResolver(Boolean.class);
    }

    @Override
    public void visit(RangeVariableDeclaration expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(ResultVariable expression) {
        expression.getSelectExpression().accept(this);
    }

    @Override
    public void visit(SelectClause expression) {

        Expression selectExpression = expression.getSelectExpression();

        // visit(CollectionExpression) iterates through the children but for a
        // SELECT clause, a CollectionExpression means the result type is Object[]
        CollectionExpression collectionExpression = getCollectionExpression(selectExpression);

        if (collectionExpression != null) {
            resolver = buildClassResolver(Object[].class);
        }
        else {
            selectExpression.accept(this);
        }
    }

    @Override
    public void visit(SelectStatement expression) {
        expression.getSelectClause().accept(this);
    }

    @Override
    public void visit(SimpleFromClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(SimpleSelectClause expression) {
        expression.getSelectExpression().accept(this);
    }

    @Override
    public void visit(SimpleSelectStatement expression) {
        queryContext.newSubqueryContext(expression);
        try {
            expression.getSelectClause().accept(this);
        }
        finally {
            queryContext.disposeSubqueryContext();
        }
    }

    @Override
    public void visit(SizeExpression expression) {
        resolver = buildClassResolver(Integer.class);
    }

    @Override
    public void visit(SqrtExpression expression) {
        resolver = buildClassResolver(Double.class);
    }

    @Override
    public void visit(StateFieldPathExpression expression) {

        // If the path ends with '.', then the path is incomplete
        // so we can't resolve the type
        if (!expression.endsWithDot()) {

            // Check first to see if it's an enum type
            String path = expression.toActualText();
            IType type = queryContext.getTypeRepository().getEnumType(path);

            if (type != null) {
                resolver = buildEnumResolver(expression, type, path);
            }
            else {
                expression.getIdentificationVariable().accept(this);

                for (int index = expression.hasVirtualIdentificationVariable() ? 0 : 1, count = expression.pathSize(); index < count; index++) {
                    path = expression.getPath(index);
                    resolver = buildStateFieldResolver(expression.getPath(index));
                }
            }
        }
        else {
            resolver = buildNullResolver();
        }
    }

    @Override
    public void visit(StringLiteral expression) {
        resolver = buildClassResolver(String.class);
    }

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

    @Override
    public void visit(SubstringExpression expression) {
        resolver = buildClassResolver(String.class);
    }

    @Override
    public void visit(SubtractionExpression expression) {
        visitArithmeticExpression(expression);
    }

    @Override
    public void visit(SumFunction expression) {

        // Visit the state field path expression in order to create the resolver
        expression.getExpression().accept(this);

        // Wrap the Resolver used to determine the type of the state field
        // path expression so we can return the actual type
        resolver = new SumFunctionResolver(resolver);
    }

    @Override
    public void visit(TreatExpression expression) {

        // Visit the identification variable in order to create the resolver
        expression.getCollectionValuedPathExpression().accept(this);

        // Retrieve the entity type name
        String entityTypeName = getQueryContext().literal(
            expression.getEntityType(),
            LiteralType.ENTITY_TYPE
        );

        // Wrap the Resolver for down casting
        resolver = new TreatResolver(resolver, entityTypeName);
    }

    @Override
    public void visit(TrimExpression expression) {
        resolver = buildClassResolver(String.class);
    }

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

    @Override
    public void visit(UnknownExpression expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(UpdateClause expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(UpdateItem expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(UpdateStatement expression) {
        resolver = buildClassResolver(Object.class);
    }

    @Override
    public void visit(UpperExpression expression) {
        resolver = buildClassResolver(String.class);
    }

    @Override
    public void visit(ValueExpression expression) {

        // Visit the identification variable in order to create the resolver
        expression.getExpression().accept(this);

        // Wrap the Resolver used to determine the type of the identification
        // variable so we can return the actual type
        resolver = new ValueResolver(resolver);
    }

    @Override
    public void visit(WhenClause expression) {
        expression.getThenExpression().accept(this);
    }

    @Override
    public void visit(WhereClause expression) {
        expression.getConditionalExpression().accept(this);
    }

    /**
     * Visits the given {@link ArithmeticExpression} and create the appropriate {@link Resolver}.
     *
     * @param expression The {@link ArithmeticExpression} to visit
     */
    protected void visitArithmeticExpression(ArithmeticExpression expression) {

        List<Resolver> resolvers = new ArrayList<Resolver>(2);

        // Visit the first expression
        expression.getLeftExpression().accept(this);
        resolvers.add(resolver);

        // Visit the second expression
        expression.getRightExpression().accept(this);
        resolvers.add(resolver);

        // This will resolve the correct numeric type
        DeclarationResolver parent = getDeclarationResolver(expression);
        resolver = new NumericResolver(parent, resolvers);
    }

    /**
     * Visits the given {@link Expression} and creates a {@link Resolver} that will check the type
     * for each of its children. If the type is the same, then it's the {@link Expression}'s type;
     * otherwise the type will be {@link Object}.
     *
     * @param expression The {@link Expression} to calculate the type of its children
     * @param extraExpression This {@link Expression} will be resolved, if it's not <code>null</code>
     * and its type will be added to the collection of types
     */
    protected void visitCollectionEquivalentExpression(Expression expression,
                                                       Expression extraExpression) {

        List<Resolver> resolvers = new ArrayList<Resolver>();
        CollectionExpression collectionExpression = getCollectionExpression(expression);

        // Gather the resolver for all children
        if (collectionExpression != null) {
            for (Expression child : collectionExpression.children()) {
                child.accept(this);
                resolvers.add(resolver);
            }
        }
        // Otherwise visit the actual expression
        else {
            expression.accept(this);
            resolvers.add(resolver);
        }

        // Add the resolver for the other expression
        if (extraExpression != null) {
            extraExpression.accept(this);
            resolvers.add(resolver);
        }

        DeclarationResolver parent = getDeclarationResolver(expression);
        resolver = new CollectionEquivalentResolver(parent, resolvers);
    }

    /**
     * This visitor is used to check if the expression visited is a {@link CollectionExpression}.
     */
    protected static final class CollectionExpressionVisitor extends AbstractExpressionVisitor {

        /**
         * The {@link CollectionExpression} that was visited, otherwise <code>null</code>.
         */
        protected CollectionExpression expression;

        /**
         * Creates a new <code>CollectionExpressionVisitor</code>.
         */
        public CollectionExpressionVisitor() {
            super();
        }

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