/*
 * Copyright (c) 2011, 2019 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.internal.jpa.jpql;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.parser.*;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectMapMapping;
import org.eclipse.persistence.mappings.querykeys.DirectQueryKey;
import org.eclipse.persistence.mappings.querykeys.ForeignReferenceQueryKey;
import org.eclipse.persistence.mappings.querykeys.QueryKey;

/**
 * This visitor resolves the type of any given {@link Expression}.
 *
 * @version 2.6
 * @since 2.4
 * @author Pascal Filion
 */
@SuppressWarnings("nls")
final class TypeResolver implements EclipseLinkExpressionVisitor {

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

    /**
     * This {@link Comparator} compares numeric types and sorts them based on precedence.
     */
    private Comparator<Class<?>> numericTypeComparator;

    /**
     * This visitor resolves a path expression by retrieving the mapping and descriptor of the last segment.
     */
    private PathResolver pathResolver;

    /**
     * The context used to query information about the application metadata and cached information.
     */
    private final JPQLQueryContext queryContext;

    /**
     * The well defined type, which does not have to be calculated.
     */
    private Class<?> type;

    /**
     * A constant representing an unresolvable type.
     */
    private static final Class<?> UNRESOLVABLE_TYPE = TypeResolver.class;

    /**
     * Creates a new <code>TypeResolver</code>.
     *
     * @param queryContext The context used to query information about the application metadata and
     * cached information
     */
    TypeResolver(JPQLQueryContext queryContext) {
        super();
        this.queryContext = queryContext;
    }

    /**
     * Returns the type of the given {@link DatabaseMapping}, which is the persistent field type.
     *
     * @param mapping The {@link DatabaseMapping} to retrieve its persistent field type
     * @return The persistent field type
     */
    @SuppressWarnings("null")
    Class<?> calculateMappingType(DatabaseMapping mapping) {

        // For aggregate mappings (@Embedded and @EmbeddedId), we need to use the descriptor
        // because its mappings have to be retrieve from this one and not from the descriptor
        // returned when querying it with a Java type
        if (mapping.isAggregateMapping()) {
            ClassDescriptor descriptor = mapping.getReferenceDescriptor();
            if (descriptor != null) {
                return descriptor.getJavaClass();
            }
        }

        // Relationship mapping
        if (mapping.isForeignReferenceMapping()) {
            ClassDescriptor descriptor = mapping.getReferenceDescriptor();
            if (descriptor != null) {
                return descriptor.getJavaClass();
            }
        }
        // Collection mapping
        else if (mapping.isCollectionMapping()) {
            return mapping.getContainerPolicy().getContainerClass();
        }

        // Property mapping
        AttributeAccessor accessor = mapping.getAttributeAccessor();

        // Attribute
        if (accessor.isInstanceVariableAttributeAccessor()) {
            InstanceVariableAttributeAccessor attributeAccessor = (InstanceVariableAttributeAccessor) accessor;
            Field field = attributeAccessor.getAttributeField();

            if (field == null) {
                try {
                    field = mapping.getDescriptor().getJavaClass().getDeclaredField(attributeAccessor.getAttributeName());
                }
                catch (Exception e) {}
            }

            return field.getType();
        }

        // Property
        if (accessor.isMethodAttributeAccessor()) {
            MethodAttributeAccessor methodAccessor = (MethodAttributeAccessor) accessor;
            Method method = methodAccessor.getGetMethod();

            if (method == null) {
                try {
                    method = mapping.getDescriptor().getJavaClass().getDeclaredMethod(methodAccessor.getGetMethodName());
                }
                catch (Exception e) {}
            }

            return method.getReturnType();
        }

        // Anything else
        return accessor.getAttributeClass();
    }

    /**
     * Returns the type of the given {@link QueryKey}, which is the persistent field type.
     *
     * @param queryKey The {@link QueryKey} to retrieve its persistent field type
     * @return The persistent field type
     */
    Class<?> calculateQueryKeyType(QueryKey queryKey) {

        // ForeignReferenceQueryKey
        if (queryKey.isForeignReferenceQueryKey()) {
            ForeignReferenceQueryKey foreignReferenceQueryKey = (ForeignReferenceQueryKey) queryKey;
            return foreignReferenceQueryKey.getReferenceClass();
        }

        // DirectQueryKey
        DirectQueryKey key = (DirectQueryKey) queryKey;
        Class<?> type = key.getField().getType();
        return (type != null) ? type : Object.class;
    }

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

    Class<?> compareCollectionEquivalentTypes(List<Class<?>> types) {

        Class<?> localType = null;

        for (Class<?> anotherType : types) {

            if (anotherType == UNRESOLVABLE_TYPE) {
                continue;
            }

            if (localType == null) {
                localType = anotherType;
            }
            // Two types are not the same, then the type is Object
            else if (localType != anotherType) {
                return Object.class;
            }
        }

        if (localType == null) {
            localType = UNRESOLVABLE_TYPE;
        }

        return localType;
    }

    Class<?> convertSumFunctionType(Class<?> type) {

        // Integral types
        if ((type == Integer.TYPE)   ||
            (type == Integer.class)  ||
            (type == Long.TYPE)      ||
            (type == Long.class)     ||
            (type == Byte.TYPE)      ||
            (type == Byte.class)     ||
            (type == Short.TYPE)     ||
            (type == Short.class)    ||
            (type == Character.TYPE) ||
            (type == Character.class)) {

            type = Long.class;
        }

        // Floating types
        else if ((type == Float.TYPE)  ||
                 (type == Float.class) ||
                 (type == Double.TYPE) ||
                 (type == Double.class)) {

            type = Double.class;
        }

        // Anything else, use Object
        else if ((type != BigDecimal.class) &&
                 (type != BigInteger.class)) {

            type = Object.class;
        }

        return type;
    }

    /**
     * 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
     */
    private CollectionExpression getCollectionExpression(Expression expression) {
        CollectionExpressionVisitor visitor = collectionExpressionVisitor();
        try {
            expression.accept(visitor);
            return visitor.expression;
        }
        finally {
            visitor.expression = null;
        }
    }

    private boolean isNumericType() {
        return type == Integer.TYPE     || type == Integer.class ||
               type == Long.TYPE        || type == Long.class    ||
               type == Float.TYPE       || type == Float.class   ||
               type == Double.TYPE      || type == Double.class  ||
               type == BigInteger.class || type == BigDecimal.class;
    }

    private PathResolver pathResolver() {
        if (pathResolver == null) {
            pathResolver = new PathResolver();
        }
        return pathResolver;
    }

    /**
     * Returns the type of the given {@link Expression}.
     *
     * @param expression The {@link Expression} to resolve its type
     * @return Either the closest type or {@link Object} if it could not be determined
     */
    Class<?> resolve(Expression expression) {
        Class<?> oldType = type;
        try {
            expression.accept(this);
            return (type == UNRESOLVABLE_TYPE) ? Object.class : type;
        }
        finally {
            type = oldType;
        }
    }

    ClassDescriptor resolveDescriptor(Expression expression) {

        PathResolver resolver = pathResolver();

        DatabaseMapping oldMapping    = resolver.mapping;
        ClassDescriptor oldDescriptor = resolver.descriptor;

        try {
            resolver.mapping    = null;
            resolver.descriptor = null;

            expression.accept(resolver);

            return resolver.descriptor;
        }
        finally {
            resolver.mapping    = oldMapping;
            resolver.descriptor = oldDescriptor;
        }
    }

    DatabaseMapping resolveMapping(Expression expression) {

        PathResolver resolver = pathResolver();

        QueryKey oldQueryKey          = resolver.queryKey;
        DatabaseMapping oldMapping    = resolver.mapping;
        ClassDescriptor oldDescriptor = resolver.descriptor;

        try {
            resolver.mapping    = null;
            resolver.descriptor = null;
            resolver.queryKey   = null;

            expression.accept(resolver);

            return resolver.mapping;
        }
        finally {
            resolver.mapping    = oldMapping;
            resolver.queryKey   = oldQueryKey;
            resolver.descriptor = oldDescriptor;
        }
    }

    /**
     * Resolves the given {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} and
     * either returns the {@link DatabaseMapping} or the {@link QueryKey} object.
     *
     * @param expression The {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} to
     * resolve by traversing its path expression
     * @return Either the {@link DatabaseMapping} or the {@link QueryKey} that is representing the
     * last path or <code>null</code> if the path expression could not be resolved
     */
    Object resolveMappingObject(Expression expression) {

        PathResolver resolver = pathResolver();

        QueryKey oldQueryKey          = resolver.queryKey;
        DatabaseMapping oldMapping    = resolver.mapping;
        ClassDescriptor oldDescriptor = resolver.descriptor;

        try {
            resolver.mapping    = null;
            resolver.descriptor = null;
            resolver.queryKey   = null;

            expression.accept(resolver);
            return (resolver.mapping != null) ? resolver.mapping : resolver.queryKey;
        }
        finally {
            resolver.mapping    = oldMapping;
            resolver.queryKey   = oldQueryKey;
            resolver.descriptor = oldDescriptor;
        }
    }

    private Class<?> resolveMappingType(AbstractPathExpression expression) {

        PathResolver resolver = pathResolver();

        QueryKey oldQueryKey          = resolver.queryKey;
        DatabaseMapping oldMapping    = resolver.mapping;
        ClassDescriptor oldDescriptor = resolver.descriptor;

        try {
            resolver.mapping    = null;
            resolver.descriptor = null;
            resolver.queryKey   = null;

            expression.accept(resolver);

            if (resolver.mapping != null) {
                return calculateMappingType(resolver.mapping);
            }
            else if (resolver.queryKey != null) {
                return calculateQueryKeyType(resolver.queryKey);
            }
            else {
                return queryContext.getEnumType(expression.toParsedText());
            }
        }
        finally {
            resolver.mapping    = oldMapping;
            resolver.queryKey   = oldQueryKey;
            resolver.descriptor = oldDescriptor;
        }
    }

    QueryKey resolveQueryKey(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {

        PathResolver resolver = pathResolver();

        QueryKey oldQueryKey          = resolver.queryKey;
        DatabaseMapping oldMapping    = resolver.mapping;
        ClassDescriptor oldDescriptor = resolver.descriptor;

        try {
            resolver.mapping    = null;
            resolver.descriptor = null;
            resolver.queryKey   = null;

            expression.accept(resolver);
            return resolver.queryKey;
        }
        finally {
            resolver.mapping    = oldMapping;
            resolver.queryKey   = oldQueryKey;
            resolver.descriptor = oldDescriptor;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AbsExpression expression) {
        // Visit the child expression in order to create the resolver
        expression.getExpression().accept(this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AbstractSchemaName expression) {
        ClassDescriptor descriptor = queryContext.getDescriptor(expression.getText());
        type = descriptor.getJavaClass();
    }

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

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AndExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ArithmeticFactor expression) {

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

        // Make sure the type is a numeric type
        if (!isNumericType()) {
            type = Object.class;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AsOfClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(AvgFunction expression) {
        type = Double.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(BadExpression expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(BetweenExpression expression) {
        type = Boolean.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CastExpression expression) {
        type = Object.class;
    }

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

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

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CollectionMemberExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CollectionValuedPathExpression expression) {
        type = resolveMappingType(expression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ComparisonExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ConcatExpression expression) {
        type = String.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ConnectByClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ConstructorExpression expression) {
        type = queryContext.getType(expression.getClassName());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CountFunction expression) {
        type = Long.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DatabaseType expression) {
        // Nothing to do
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DateTime expression) {

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

            if (text.startsWith("{d")) {
                type = Date.class;
            }
            else if (text.startsWith("{ts")) {
                type = Timestamp.class;
            }
            else if (text.startsWith("{t")) {
                type = Time.class;
            }
            else {
                type = Object.class;
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DeleteClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DeleteStatement expression) {
        type = Object.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(EmptyCollectionComparisonExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(EntityTypeLiteral expression) {
        String entityTypeName = expression.getEntityTypeName();
        ClassDescriptor descriptor = queryContext.getDescriptor(entityTypeName);
        type = descriptor.getJavaClass();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(EntryExpression expression) {
        type = Map.Entry.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ExistsExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ExtractExpression expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(FromClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(FunctionExpression expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(GroupByClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(HavingClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(HierarchicalQueryClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(IdentificationVariable expression) {

        PathResolver resolver = pathResolver();

        DatabaseMapping oldMapping    = resolver.mapping;
        ClassDescriptor oldDescriptor = resolver.descriptor;

        try {
            resolver.mapping    = null;
            resolver.descriptor = null;

            expression.accept(resolver);

            if (resolver.mapping != null) {
                type = calculateMappingType(resolver.mapping);
            }
            else if (resolver.descriptor != null) {
                type = resolver.descriptor.getJavaClass();
            }
            else {
                type = Object.class;
            }
        }
        finally {
            resolver.mapping    = oldMapping;
            resolver.descriptor = oldDescriptor;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(IdentificationVariableDeclaration expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(IndexExpression expression) {
        type = Integer.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(InExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(InputParameter expression) {
        type = UNRESOLVABLE_TYPE;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(Join expression) {
        expression.getJoinAssociationPath().accept(this);
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(KeyExpression expression) {
        IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
        Declaration declaration = queryContext.findDeclaration(identificationVariable.getVariableName());
        DatabaseMapping mapping = declaration.getMapping();
        MappedKeyMapContainerPolicy mapContainerPolicy = (MappedKeyMapContainerPolicy) mapping.getContainerPolicy();
        type = (Class<?>) mapContainerPolicy.getKeyType();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(KeywordExpression expression) {

        String text = expression.getText();

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

            type = Boolean.class;
        }
        else {
            type = Object.class;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LengthExpression expression) {
        type = Integer.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LikeExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LocateExpression expression) {
        type = Integer.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(LowerExpression expression) {
        type = String.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(MaxFunction 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
        if (!isNumericType()) {
            type = Object.class;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(MinFunction 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
        if (!isNumericType()) {
            type = Object.class;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ModExpression expression) {
        type = Integer.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NotExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NullComparisonExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NullExpression expression) {
        type = UNRESOLVABLE_TYPE;
    }

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

    /**
     * {@inheritDoc}
     */
    @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()) {

                // Special case for a long number, Long.parseLong() does not handle 'l|L'
                if (text.endsWith("L") || text.endsWith("l")) {
                    type = Long.class;
                }
                else {
                    Long value = Long.parseLong(text);

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

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

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(OrderByClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(OrderByItem expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(OrderSiblingsByClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(OrExpression expression) {
        type = Boolean.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(RangeVariableDeclaration expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(RegexpExpression expression) {
        type = Boolean.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @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) {
            type = Object[].class;
        }
        else {
            selectExpression.accept(this);
        }
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SimpleFromClause expression) {
        type = Object.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SimpleSelectStatement expression) {
        queryContext.newSubQueryContext(expression, null);
        try {
            expression.getSelectClause().accept(this);
        }
        finally {
            queryContext.disposeSubqueryContext();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SizeExpression expression) {
        type = Integer.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SqrtExpression expression) {
        type = Double.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(StartWithClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(StateFieldPathExpression expression) {
        type = resolveMappingType(expression);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(StringLiteral expression) {
        type = String.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SubstringExpression expression) {
        type = String.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @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
        type = convertSumFunctionType(type);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TableExpression expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TableVariableDeclaration expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TreatExpression expression) {
        expression.getEntityType().accept(this);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(TrimExpression expression) {
        type = String.class;
    }

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

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UnionClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UnknownExpression expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UpdateClause expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UpdateItem expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UpdateStatement expression) {
        type = Object.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UpperExpression expression) {
        type = String.class;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(ValueExpression expression) {

        IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
        Declaration declaration = queryContext.findDeclaration(identificationVariable.getVariableName());
        DatabaseMapping mapping = declaration.getMapping();

        if (mapping.isDirectMapMapping()) {

            DirectMapMapping mapMapping = (DirectMapMapping) mapping;
            type = mapMapping.getValueClass();

            if (type == null) {
                type = mapMapping.getDirectField().getType();
            }
        }
        else {
            type = calculateMappingType(declaration.getMapping());
        }
    }

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

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

    /**
     * Visits the given {@link ArithmeticExpression} and creates the appropriate {@link org.eclipse.
     * persistence.expressions.Expression Expression}.
     *
     * @param expression The {@link ArithmeticExpression} to visit
     */
    private void visitArithmeticExpression(ArithmeticExpression expression) {

        List<Class<?>> types = new ArrayList<>(2);

        // Visit the first expression
        expression.getLeftExpression().accept(this);
        if (isNumericType()) {
            types.add(type);
        }

        // Visit the second expression
        expression.getRightExpression().accept(this);
        if (isNumericType()) {
            types.add(type);
        }

        if (types.size() == 2) {
            Collections.sort(types, NumericTypeComparator.instance());
            type = types.get(0);
        }
        else {
            type = Object.class;
        }
    }

    /**
     * Visits the given {@link Expression} and creates the appropriate {@link org.eclipse.persistence.
     * expressions.Expression Expression} 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
     */
    private void visitCollectionEquivalentExpression(Expression expression,
                                                     Expression extraExpression) {

        List<Class<?>> types = new ArrayList<>();
        CollectionExpression collectionExpression = getCollectionExpression(expression);

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

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

        // Now compare the types
        type = compareCollectionEquivalentTypes(types);
    }

    /**
     * This visitor is used to check if the expression visited is a {@link CollectionExpression}.
     */
    private static 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();
        }

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

    private class PathResolver extends AbstractEclipseLinkExpressionVisitor {

        ClassDescriptor descriptor;
        DatabaseMapping mapping;
        QueryKey queryKey;

        /**
         * {@inheritDoc}
         */
        @Override
        public void visit(AbstractSchemaName expression) {
            descriptor = queryContext.getDescriptor(expression.getText());
        }

        /**
         * {@link InputParameter}
         */
        @Override
        public void visit(CollectionValuedPathExpression expression) {
            visitPathExpression(expression);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void visit(EntityTypeLiteral expression) {
            descriptor = queryContext.getDescriptor(expression.getEntityTypeName());
        }

        /**
         * {@link InputParameter}
         */
        @Override
        public void visit(IdentificationVariable expression) {

            // Check to see if the identification variable is "virtual" and internally
            // changed to a state field path expression. If so, it means it's an unqualified
            // path found in an UPDATE or DELETE query
            StateFieldPathExpression pathExpression = expression.isVirtual() ? expression.getStateFieldPathExpression() : null;

            if (pathExpression != null) {
                pathExpression.accept(this);
            }
            else {
                Declaration declaration = queryContext.findDeclaration(expression.getVariableName());

                // A null declaration Expression would mean it's the first package of an enum type
                if (declaration != null) {
                    descriptor = declaration.getDescriptor();
                }
            }
        }

        /**
         * {@link InputParameter}
         */
        @Override
        public void visit(Join expression) {
            expression.getJoinAssociationPath().accept(this);
        }

        /**
         * {@link InputParameter}
         */
        @Override
        public void visit(KeyExpression expression) {

            IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
            Declaration declaration = queryContext.getDeclaration(identificationVariable.getVariableName());
            DatabaseMapping mapping = declaration.getMapping();

            ContainerPolicy containerPolicy = mapping.getContainerPolicy();
            MappedKeyMapContainerPolicy mapPolicy = (MappedKeyMapContainerPolicy) containerPolicy;
            descriptor = mapPolicy.getKeyMapping().getReferenceDescriptor();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void visit(RangeVariableDeclaration expression) {
            expression.getIdentificationVariable().accept(this);
        }

        @Override
        public void visit(StateFieldPathExpression expression) {
            visitPathExpression(expression);
        }

        /**
         * {@link InputParameter}
         */
        @Override
        public void visit(TreatExpression expression) {
            expression.getEntityType().accept(this);
        }

        /**
         * {@link InputParameter}
         */
        @Override
        public void visit(ValueExpression expression) {
            IdentificationVariable identificationVariable = (IdentificationVariable) expression.getExpression();
            Declaration declaration = queryContext.getDeclaration(identificationVariable.getVariableName());
            descriptor = declaration.getDescriptor();
        }

        private void visitPathExpression(AbstractPathExpression expression) {

            expression.getIdentificationVariable().accept(this);

            if (descriptor == null) {
                return;
            }

            // Now traverse the rest of the path
            for (int index = expression.hasVirtualIdentificationVariable() ? 0 : 1, count = expression.pathSize(); index < count; index++) {

                String path = expression.getPath(index);
                mapping = descriptor.getObjectBuilder().getMappingForAttributeName(path);

                if (mapping == null) {
                    queryKey = descriptor.getQueryKeyNamed(path);

                    if ((queryKey != null) && queryKey.isForeignReferenceQueryKey()) {
                        ForeignReferenceQueryKey referenceQueryKey = (ForeignReferenceQueryKey) queryKey;
                        descriptor = queryContext.getDescriptor(referenceQueryKey.getReferenceClass());
                    }
                    else {
                        if (index + 1 < count) {
                            mapping = null;
                        }
                        descriptor = null;
                    }
                }
                // A collection mapping cannot be used in a path (if it's not the last path)
                else if (mapping.isCollectionMapping() && (index + 1 < count)) {
                    mapping    = null;
                    descriptor = null;
                }
                else {
                    descriptor = mapping.getReferenceDescriptor();
                }

                if (descriptor == null) {
                    if (index + 1 < count) {
                        mapping = null;
                    }
                    break;
                }
            }
        }
    }
}
