/*
 * 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.internal.jpa.jpql;

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.jpql.EclipseLinkLiteralVisitor;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.LiteralVisitor;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.queries.DatabaseQuery;
import org.eclipse.persistence.queries.ReportQuery;

/**
 * This context is used when creating and populating a {@link DatabaseQuery} when traversing the
 * parsed representation of a JPQL query.
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 * @author John Bracken
 */
final class JPQLQueryContext {

    /**
     * The current {@link JPQLQueryContext} is the context used for the current query or subquery.
     * If the current context is not the global context, then its parent is non <code>null</code>.
     */
    private JPQLQueryContext currentContext;

    /**
     * The parsed {@link Expression JPQL Expression} currently visited.
     */
    private org.eclipse.persistence.jpa.jpql.parser.Expression currentQuery;

    /**
     * The resolver 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.
     */
    private DeclarationResolver declarationResolver;

    /**
     * The builder that can convert a {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL
     * Expression} into an {@link Expression EclipseLink Expression}.
     */
    private ExpressionBuilderVisitor expressionBuilder;

    /**
     * The cached {@link Expression Expressions} mapped by a variable name.
     */
    private Map<String, Expression> expressions;

    /**
     * The input parameter name mapped to its type. The input parameter name starts with the
     * positional parameter ('?' or ':').
     */
    Map<InputParameter, Expression> inputParameters;

    /**
     * The parsed representation of the JPQL query.
     */
    private JPQLExpression jpqlExpression;

    /**
     * The JPQL grammar that defines how to parse a JPQL query.
     */
    private JPQLGrammar jpqlGrammar;

    /**
     * The JPQL query to convert into an EclipseLink {@link Expression}.
     */
    private CharSequence jpqlQuery;

    /**
     * This visitor is used to retrieve a variable name from various type of
     * {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression}.
     */
    private EclipseLinkLiteralVisitor literalVisitor;

    /**
     * This visitor is responsible to calculate the closest type of any input parameter.
     */
    private ParameterTypeVisitor parameterTypeVisitor;

    /**
     * When this context is a sub-context used for a subquery, then this is the context for the
     * parent query.
     */
    private JPQLQueryContext parent;

    /**
     * The {@link DatabaseQuery} being populated by visiting the parsed tree representation of the
     * JPQL query.
     */
    private DatabaseQuery query;

    /**
     * The EclipseLink {@link AbstractSession} this context will use.
     */
    private AbstractSession session;

    /**
     * This resolver is used to calculate the type of any
     * {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression}.
     */
    private TypeResolver typeResolver;

    /**
     * The types that have been cached for faster access.
     */
    private Map<String, Class<?>> types;

    /**
     * The identification variables that were used in the current query.
     */
    private Set<String> usedIdentificationVariables;

    /**
     * An empty array used when the type of an
     * {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression} is not required.
     */
    private static final Class<?>[] EMPTY_TYPE = new Class<?>[1];

    /**
     * Creates a new <code>JPQLQueryContext</code>.
     *
     * @param query The {@link DatabaseQuery} from which information will be queries
     * @param jpqlGrammar The JPQL grammar that defines how the JPQL query was parsed
     * @since 2.5
     */
    JPQLQueryContext(DatabaseQuery query, JPQLGrammar jpqlGrammar) {
        this(jpqlGrammar);
        String jpqlQuery = query.getJPQLString();
        cache(query.getSession(), query, parse(jpqlQuery), jpqlQuery);
    }

    /**
     * Creates a new <code>JPQLQueryContext</code>.
     *
     * @param jpqlGrammar The JPQL grammar that defines how the JPQL query was parsed
     */
    JPQLQueryContext(JPQLGrammar jpqlGrammar) {
        super();
        this.jpqlGrammar    = jpqlGrammar;
        this.currentContext = this;
    }

    /**
     * Creates a new <code>JPQLQueryContext</code>.
     *
     * @param parent The parent of this context, which is never <code>null</code>
     * @param currentQuery The parsed tree representation of the subquery
     * @param query The {@link ReportQuery} that will be populated by visiting the parsed tree
     * representation of the subquery
     */
    private JPQLQueryContext(JPQLQueryContext parent,
                             org.eclipse.persistence.jpa.jpql.parser.Expression currentQuery,
                             ReportQuery query) {

        this(parent.jpqlGrammar);
        this.query        = query;
        this.parent       = parent;
        this.currentQuery = currentQuery;
    }

    /**
     * Caches the given input parameter name with its calculated type.
     *
     * @param inputParameter The input parameter
     * @param queryExpression The {@link Expression} that can be reused rather than being recreated
     */
    void addInputParameter(InputParameter inputParameter, Expression queryExpression) {

        if (parent != null) {
            parent.addInputParameter(inputParameter, queryExpression);
        }
        else {
            if (inputParameters == null) {
                inputParameters = new HashMap<>();
            }
            inputParameters.put(inputParameter, queryExpression);
        }
    }

    /**
     * Caches the given query {@link Expression} for future use.
     *
     * @param variableName The identification variable name that is the key to store the given
     * {@link Expression}
     * @param expression The {@link Expression} that can be reused rather than being recreated
     */
    void addQueryExpression(String variableName, Expression expression) {
        currentContext.addQueryExpressionImp(variableName, expression);
    }

    /**
     * Caches the given query {@link Expression} for future use.
     *
     * @param variableName The identification variable name that is the key to store the given
     * {@link Expression}
     * @param expression The {@link Expression} that can be reused rather than being recreated
     */
    void addQueryExpressionImp(String variableName, Expression expression) {
        if (expressions == null) {
            expressions = new HashMap<>();
        }
        expressions.put(variableName, expression);
    }

    /**
     * Adds a virtual range variable declaration that will be used when a JPQL fragment is parsed.
     *
     * @param entityName The name of the entity to be accessible with the given variable name
     * @param variableName The identification variable used to navigate to the entity
     */
    void addRangeVariableDeclaration(String entityName, String variableName) {

        // This method should only be used by HermesParser.buildSelectionCriteria()
        declarationResolver = new DeclarationResolver(this, null);

        declarationResolver.addRangeVariableDeclaration(
            entityName,
            variableName
        );
    }

    /**
     * Adds the given identification variable, which is done when it's used in a clause, except in
     * the declaration portion of the query.
     *
     * @param variableName The identification variable that is used within a clause
     */
    void addUsedIdentificationVariable(String variableName) {
        currentContext.addUsedIdentificationVariableImp(variableName);
    }

    /**
     * Adds the given identification variable, which is done when it's used in a clause, except in
     * the declaration portion of the query.
     *
     * @param variableName The identification variable that is used within a clause
     */
    void addUsedIdentificationVariableImp(String variableName) {
        if (usedIdentificationVariables == null) {
            usedIdentificationVariables = new HashSet<>();
        }
        usedIdentificationVariables.add(variableName);
    }

    /**
     * Retrieves the Java type for the given type name, which has to be the fully qualified type name.
     *
     * @param typeName The fully qualified type name
     * @return The Java type if it could be retrieved; <code>null</code> otherwise
     */
    private <T> Class<T> attemptLoadType(String typeName) {

        try {

            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    return AccessController.doPrivileged(
                        new PrivilegedClassForName<>(typeName, true, getClassLoader())
                    );
                }
                catch (PrivilegedActionException exception) {
                    return null;
                }
            }

            return PrivilegedAccessHelper.getClassForName(typeName, true, getClassLoader());
        }
        catch (ClassNotFoundException e) {
            return null;
        }
    }

    /**
     * Converts the given {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression}
     * into an {@link Expression}.
     *
     * @param expression The {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression}
     * to visit and to convert into an {@link Expression}
     * @return The {@link Expression} representing the given parsed expression
     */
    Expression buildExpression(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
        return expressionBuilder().buildExpression(expression, EMPTY_TYPE);
    }

    /**
     * Converts the given {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression}
     * into an {@link Expression}.
     *
     * @param expression The {@link org.eclipse.persistence.jpa.jpql.parser.Expression JPQL Expression}
     * to visit and to convert into an {@link Expression}
     * @param type The given array will be used to store the type of the given expression
     * @return The {@link Expression} representing the given parsed expression
     */
    Expression buildExpression(org.eclipse.persistence.jpa.jpql.parser.Expression expression,
                               Class<?>[] type) {

        return expressionBuilder().buildExpression(expression, type);
    }

    /**
     * Creates a new EclipseLink {@link Expression} by visiting the given JPQL {@link
     * CollectionValuedPathExpression} that is used in the <code><b>GROUP BY</b></code> clause.
     *
     * @param expression The {@link CollectionValuedPathExpression} to convert into an EclipseLink
     * {@link Expression}
     * @return The EclipseLink {@link Expression} representation of that path expression
     */
    Expression buildGroupByExpression(CollectionValuedPathExpression expression) {
        return expressionBuilder().buildGroupByExpression(expression);
    }

    /**
     * Creates a new EclipseLink {@link Expression} by visiting the given JPQL {@link
     * StateFieldPathExpression}. This method temporarily changes the null allowed flag if the state
     * field is a foreign reference mapping
     *
     * @param expression The {@link StateFieldPathExpression} to convert into an EclipseLink {@link
     * Expression}
     * @return The EclipseLink {@link Expression} representation of that path expression
     */
    Expression buildModifiedPathExpression(StateFieldPathExpression expression) {
        return expressionBuilder().buildModifiedPathExpression(expression);
    }

    /**
     * Creates a new {@link ReportQuery} by visiting the given {@link SimpleSelectStatement}.
     *
     * @param expression The {@link SimpleSelectStatement} to convert into a {@link ReportQuery}
     * @return A fully initialized {@link ReportQuery}
     */
    ReportQuery buildSubquery(SimpleSelectStatement expression) {
        return expressionBuilder().buildSubquery(expression);
    }

    /**
     * Sets the given named query and string representation of the JPQL query.
     *
     * @param session The EclipseLink {@link AbstractSession} this context will use
     * @param query The {@link DatabaseQuery} that may already exist and it will be populated with
     * the information contained in the JPQL query or <code>null</code> if the query will need to be created
     * @param jpqlExpression The parsed tree representation of the JPQL query
     * @param jpqlQuery The JPQL query
     */
    void cache(AbstractSession session,
               DatabaseQuery query,
               JPQLExpression jpqlExpression,
               CharSequence jpqlQuery) {

        this.query          = query;
        this.session        = session;
        this.jpqlQuery      = jpqlQuery;
        this.currentQuery   = jpqlExpression;
        this.jpqlExpression = jpqlExpression;
    }

    /**
     * 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
     */
    Class<?> calculateMappingType(DatabaseMapping mapping) {
        return typeResolver().calculateMappingType(mapping);
    }

    /**
     * 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) {
        return typeResolver().calculateQueryKeyType(queryKey);
    }

    /**
     * Disposes this context, which is the current context being used by a subquery. Once it is
     * disposed, any information retrieved will be for the subquery's parent query.
     */
    void disposeSubqueryContext() {
        currentContext = currentContext.parent;
    }

    private ExpressionBuilderVisitor expressionBuilder() {

        if (parent != null) {
            return parent.expressionBuilder();
        }

        if (expressionBuilder == null) {
            expressionBuilder = new ExpressionBuilderVisitor(this);
        }

        return expressionBuilder;
    }

    /**
     * Retrieves the {@link Declaration} for which the given variable name is used to navigate to the
     * "root" object. This goes up the hierarchy when looking for the {@link Declaration} if it's not
     * defined in the current context.
     *
     * @param variableName The name of the identification variable that is used to navigate a "root" object
     * @return The {@link Declaration} containing the information about the identification variable declaration
     * @see #getDeclaration(String)
     */
    Declaration findDeclaration(String variableName) {
        return currentContext.findDeclarationImp(variableName);
    }

    Declaration findDeclarationImp(String variableName) {
        Declaration declaration = getDeclarationResolverImp().getDeclaration(variableName);
        if ((declaration == null) && (parent != null)) {
            declaration = parent.findDeclarationImp(variableName);
        }
        return declaration;
    }

    /**
     * Retrieves the cached {@link Expression} associated with the given variable name. The scope of
     * the search is the entire query (going from the current query, if it's a subquery, up to the
     * top-level query).
     *
     * @param variableName The variable name for which its associated {@link Expression} is requested
     * @return The cached {@link Expression} associated with the given variable name or <code>null</code>
     * if none was cached.
     */
    Expression findQueryExpression(String variableName) {
        return currentContext.findQueryExpressionImp(variableName);
    }

    Expression findQueryExpressionImp(String variableName) {
        Expression expression = getQueryExpressionImp(variableName);
        if ((expression == null) && (parent != null)) {
            expression = parent.findQueryExpressionImp(variableName);
        }
        return expression;
    }

    /**
     * Returns the parent context if the current context is not the root context.
     *
     * @return The parent context or <code>null</code> if the current context is the root
     */
    JPQLQueryContext getActualParent() {
        return parent;
    }

    /**
     * Returns the root {@link Expression} for which all new {@link Expression expressions} a child.
     *
     * @return The root {@link Expression} of the query or subquery
     */
    Expression getBaseExpression() {
        // Retrieve the first declaration, which is the base declaration (For top-level query, it's
        // always a range over an abstract schema name. For subqueries, it's either a range over an
        // abstract schema name or a derived path expression)
        return getDeclarationResolver().getFirstDeclaration().getQueryExpression();
    }

    /**
     * Returns the {@link ClassLoader} used by EclipseLink to load the application's classes.
     *
     * @return The application's {@link ClassLoader}
     */
    private ClassLoader getClassLoader() {
        return getSession().getDatasourcePlatform().getConversionManager().getLoader();
    }

    /**
     * Returns the {@link Constructor} for the given Java {@link Class}. The constructor to retrieve
     * has the given parameter types.
     *
     * @param type The Java type for which its constructor should be retrieved
     * @param parameterTypes The types of the constructor's parameters
     * @return The {@link Constructor} or <code>null</code> if none exist or the privilege access
     * was denied
     */
    <T> Constructor<T> getConstructor(Class<T> type, Class<?>[] parameterTypes) {
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    return AccessController.doPrivileged(
                        new PrivilegedGetConstructorFor<>(type, parameterTypes, true)
                    );
                }
                catch (PrivilegedActionException exception) {
                    return null;
                }
            }

            return PrivilegedAccessHelper.getConstructorFor(type, parameterTypes, true);
        }
        catch (NoSuchMethodException e) {
            return null;
        }
    }

    /**
     * Returns the current {@link JPQLQueryContext}, i.e. the context of the query being manipulated,
     * which can either be the top-level query or a subquery.
     *
     * @return The active context
     */
    JPQLQueryContext getCurrentContext() {
        return currentContext;
    }

    /**
     * Returns the current {@link Expression} being manipulated, which is either the top-level query
     * or a subquery.
     *
     * @return Either the top-level query or a subquery
     */
    org.eclipse.persistence.jpa.jpql.parser.Expression getCurrentQuery() {
        return currentContext.currentQuery;
    }

    /**
     * Returns the current {@link DatabaseQuery} being populated.
     *
     * @return The {@link DatabaseQuery} being populated, which can be the top-level query or a
     * subquery depending on which query is been visited
     */
    @SuppressWarnings("unchecked")
    <T extends DatabaseQuery> T getDatabaseQuery() {
        return (T) currentContext.query;
    }

    /**
     * Retrieves the {@link Declaration} for which the given variable name is used to navigate to the
     * "root" object. This does not go up the hierarchy when looking for the {@link Declaration}.
     *
     * @param variableName The name of the identification variable that is used to navigate a "root" object
     * @return The {@link Declaration} containing the information about the identification variable declaration
     * @see #findDeclaration(String)
     */
    Declaration getDeclaration(String variableName) {
        return getDeclarationResolver().getDeclaration(variableName);
    }

    /**
     * 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
     */
    DeclarationResolver getDeclarationResolver() {
        return currentContext.getDeclarationResolverImp();
    }

    /**
     * Returns the {@link DeclarationResolver} of the current query's declaration.
     *
     * @return The {@link DeclarationResolver} for the current query being visited
     */
    DeclarationResolver getDeclarationResolverImp() {

        if (declarationResolver == null) {
            DeclarationResolver parentResolver = (parent == null) ? null : parent.getDeclarationResolverImp();
            declarationResolver = new DeclarationResolver(this, parentResolver);
        }

        declarationResolver.populate(currentQuery);
        return declarationResolver;
    }

    /**
     * Returns the ordered list of {@link Declaration Declarations}.
     *
     * @return The {@link Declaration Declarations} of the current query that was parsed
     */
    List<Declaration> getDeclarations() {
        return getDeclarationResolver().getDeclarations();
    }

    /**
     * Retrieves the descriptor associated with the given type.
     *
     * @param type The type associated with the descriptor
     * @return The EclipseLink {@link ClassDescriptor descriptor} representing the managed type
     */
    ClassDescriptor getDescriptor(Class<?> type) {
        return getSession().getClassDescriptor(type);
    }

    /**
     * Retrieves the descriptor associated with the given abstract schema name, which is the
     * descriptor's alias.
     *
     * @param abstractSchemaName The managed type name associated with the managed type
     * @return The EclipseLink {@link ClassDescriptor descriptor} representing the managed type
     */
    ClassDescriptor getDescriptor(String abstractSchemaName) {
        return getSession().getDescriptorForAlias(abstractSchemaName);
    }

    /**
     * Returns the {@link Class} representing the possible given enum constant. If the given value
     * does not represent an enum constant, then <code>null</code> is returned.
     *
     * @param enumTypeName The fully qualified enum type with the constant
     * @return The external form for the given Enum type or <code>null</code> if none exists
     */
    Class<?> getEnumType(String enumTypeName) {

        // Get the position of the last dot so we can remove the constant
        int lastDotIndex = enumTypeName.lastIndexOf('.');

        if (lastDotIndex == -1) {
            return null;
        }

        // Retrieve the fully qualified enum type name
        String typeName = enumTypeName.substring(0, lastDotIndex);

        // Attempt to load the enum type
        Class<?> type = getType(typeName);
        return ((type != null) && type.isEnum()) ? type : null;
    }

    /**
     * Returns the first {@link Declaration} of the current context that was created after visiting
     * the declaration clause.
     *
     * @return The first {@link Declaration} object
     */
    Declaration getFirstDeclaration() {
        return currentContext.getFirstDeclarationImp();
    }

    /**
     * Returns the first {@link Declaration}, from this context, that was created after visiting the
     * declaration clause.
     *
     * @return The first {@link Declaration} object
     */
    Declaration getFirstDeclarationImp() {
        return getDeclarationResolverImp().getFirstDeclaration();
    }

    /**
     * Returns the {@link JPQLGrammar} that defines how the JPQL query was parsed.
     *
     * @return The {@link JPQLGrammar} that was used to parse the JPQL query
     */
    JPQLGrammar getGrammar() {
        return jpqlGrammar;
    }

    /**
     * Returns the parsed representation of a <b>JOIN FETCH</b> that were defined in the same
     * declaration than the given range identification variable name.
     *
     * @param variableName The name of the identification variable that should be used to define an
     * abstract schema name
     * @return The <b>JOIN FETCH</b> expressions used in the same declaration or an empty collection
     * if none was defined
     */
    Collection<Join> getJoinFetches(String variableName) {
        return getDeclarationResolver().getJoinFetches(variableName);
    }

    /**
     * Returns the parsed tree representation of the JPQL query.
     *
     * @return The parsed tree representation of the JPQL query
     */
    JPQLExpression getJPQLExpression() {
        return (parent != null) ? parent.getJPQLExpression() : jpqlExpression;
    }

    /**
     * Returns the string representation of the JPQL query.
     *
     * @return The string representation of the JPQL query
     */
    CharSequence getJPQLQuery() {
        return (parent != null) ? parent.getJPQLQuery() : jpqlQuery;
    }

    /**
     * Retrieves, if it can be determined, the type of the given {@link InputParameter}. The type
     * will be guessed based on its location within expression.
     * <p>
     * Note: Both named and positional input parameter can be used.
     *
     * @param inputParameter The {@link InputParameter} to retrieve its type
     * @return Either the closest type of the input parameter or <code>null</code> if the type could
     * not be determined
     */
    Class<?> getParameterType(InputParameter inputParameter) {
        ParameterTypeVisitor resolver = parameterTypeVisitor();
        try {
            inputParameter.accept(resolver);
            return resolver.getType();
        }
        finally {
            resolver.dispose();
        }
    }

    /**
     * Returns the parent context if the current context is not the root context.
     *
     * @return The parent context or <code>null</code> if the current context is the root
     */
    JPQLQueryContext getParent() {
        return currentContext.parent;
    }

    /**
     * Retrieves the cached {@link Expression} associated with the given variable name. The scope of
     * the search is local to the current query or subquery.
     *
     * @param variableName The variable name for which its associated {@link Expression} is requested
     * @return The cached {@link Expression} associated with the given variable name or <code>null</code>
     * if none was cached.
     */
    Expression getQueryExpression(String variableName) {
        return currentContext.getQueryExpressionImp(variableName);
    }

    /**
     * Retrieves the cached {@link Expression} associated with the given variable name.
     *
     * @param variableName The variable name for which its associated {@link Expression} is requested
     * @return The cached {@link Expression} associated with the given variable name or <code>null</code>
     * if none was cached.
     */
    Expression getQueryExpressionImp(String variableName) {
        return (expressions == null) ? null : expressions.get(variableName);
    }

    /**
     * Returns the EclipseLink {@link AbstractSession} that this query will execute against, which
     * gives access to the JPA artifacts.
     *
     * @return The current EclipseLink session
     */
    AbstractSession getSession() {
        return (parent != null) ? parent.getSession() : session;
    }

    /**
     * Returns the Java class of the given {@link Expression}.
     *
     * @param expression The {@link Expression} for which its type will be calculated
     * @return Either the Java class that was resolved or the <code>null</code> if it could not be resolved
     */
    Class<?> getType(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
        return typeResolver().resolve(expression);
    }

    /**
     * Retrieves the external class for the given fully qualified class name.
     *
     * @param typeName The fully qualified class name of the class to retrieve
     * @return The external form of the class to retrieve
     */
    Class<?> getType(String typeName) {
        return loadTypeImp(typeName);
    }

    private Map<String, Class<?>> getTypes() {

        if (parent != null) {
            return parent.getTypes();
        }

        if (types == null) {
            types = new HashMap<>();
        }

        return types;
    }

    /**
     * Returns the identification variables that was used in the current query.
     *
     * @return The identification variables that were used throughout the current query at the
     * exception of their declaration
     */
    Set<String> getUsedIdentificationVariables() {
        return currentContext.getUsedIdentificationVariablesImp();
    }

    /**
     * Returns the identification variables that are registered in this context.
     *
     * @return The identification variables that were used throughout the current query at the
     * exception of their declaration
     */
    Set<String> getUsedIdentificationVariablesImp() {
        if (usedIdentificationVariables == null) {
            return Collections.emptySet();
        }
        return usedIdentificationVariables;
    }

    /**
     * Determines whether the given identification variable is defining a join or a collection member
     * declaration expressions.
     *
     * @param variableName The identification variable to check for what it maps
     * @return <code>true</code> if the given identification variable maps a collection-valued field
     * defined in a <code>JOIN</code> or <code>IN</code> expression; <code>false</code> if it's not
     * defined or it's mapping an abstract schema name
     */
    boolean isCollectionIdentificationVariable(String variableName) {
        return getDeclarationResolver().isCollectionIdentificationVariable(variableName);
    }

    /**
     * Determines whether the given identification variable is used, at the exception of where it was
     * defined.
     *
     * @param variableName The identification variable to check if it was used in a clause
     * @return <code>true</code> if the identification is used in a clause, at the exception of where
     * it was defined; <code>false</code> otherwise
     */
    boolean isIdentificationVariableUsed(String variableName) {
        return currentContext.isIdentificationVariableUsedImp(variableName);
    }

    private boolean isIdentificationVariableUsedImp(String variableName) {
        boolean result = (usedIdentificationVariables != null) && usedIdentificationVariables.contains(variableName);
        if (!result && (parent != null)) {
            result = parent.isIdentificationVariableUsedImp(variableName);
        }
        return result;
    }

    /**
     * Determines whether the given variable name is an identification variable name used to define
     * an abstract schema name.
     *
     * @param variableName The name of the variable to verify if it's defined in a range variable
     * declaration in the current query or any parent query
     * @return <code>true</code> if the variable name is mapping an abstract schema name; <code>false</code>
     * if it's defined in a collection member declaration
     */
    boolean isRangeIdentificationVariable(String variableName) {
        return getDeclarationResolverImp().isRangeIdentificationVariable(variableName);
    }

    /**
     * Determines if the given variable is a result variable.
     *
     * @param variableName The variable to check if it's a result variable
     * @return <code>true</code> if the given variable is defined as a result variable;
     * <code>false</code> otherwise
     */
    boolean isResultVariable(String variableName) {
        return getDeclarationResolverImp().isResultVariable(variableName);
    }

    /**
     * Retrieves the "literal" from the given {@link Expression}. The literal to retrieve depends on
     * the given {@link LiteralType type}. The literal is basically a string value like an
     * identification variable name, an input parameter, a path expression, an abstract schema name,
     * etc.
     *
     * @param expression The {@link Expression} to visit
     * @param type The {@link LiteralType} helps to determine what to retrieve from the visited
     * {@link Expression}
     * @return A value from the given {@link Expression} or an empty string if the given {@link
     * Expression} and the {@link LiteralType} do not match
     */
    String literal(org.eclipse.persistence.jpa.jpql.parser.Expression expression, LiteralType type) {

        LiteralVisitor visitor = literalVisitor();

        try {
            visitor.setType(type);
            expression.accept(visitor);

            // Make sure the identification variable is capitalized and unique since
            // String.equals() is used rather than String.equalsIgnoreCase()
            if (visitor.literal != ExpressionTools.EMPTY_STRING &&
               (type == LiteralType.IDENTIFICATION_VARIABLE ||
                type == LiteralType.RESULT_VARIABLE||
                type == LiteralType.PATH_EXPRESSION_IDENTIFICATION_VARIABLE)) {

                return visitor.literal.toUpperCase().intern();
            }

            return visitor.literal;
        }
        finally {
            visitor.literal = ExpressionTools.EMPTY_STRING;
        }
    }

    private LiteralVisitor literalVisitor() {

        if (parent != null) {
            return parent.literalVisitor();
        }

        if (literalVisitor == null) {
            literalVisitor = new EclipseLinkLiteralVisitor();
        }

        return literalVisitor;
    }

    private Class<?> loadInnerType(String typeName) {

        int index = typeName.lastIndexOf('.');

        if (index == -1) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        sb.append(typeName.substring(0, index));
        sb.append("$");
        sb.append(typeName.substring(index + 1));
        typeName = sb.toString();

        return loadTypeImp(typeName);
    }

    private Class<?> loadTypeImp(String typeName) {

        Map<String, Class<?>> types = getTypes();
        Class<?> type = types.get(typeName);

        // The type was already cached, simply return it
        if (type != null) {
            return type;
        }

        // Attempt to load the Java type
        Class<?> javaType = attemptLoadType(typeName);

        // A Java type exists, return it
        if (javaType != null) {
            types.put(javaType.getName(), javaType);
            return javaType;
        }

        // Now try with a possible inner enum type
        return loadInnerType(typeName);
    }

    /**
     * Creates a new instance from the given Java type.
     *
     * @param type The Java type for which a new instance will be created
     * @param parameterType The type of the constructor's single parameter
     * @param parameter The object to pass during instantiation
     * @return A new instance or <code>null</code> if a problem was encountered during instantiation
     */
    <T> T newInstance(Class<T> type, Class<?> parameterType, Object parameter) {
        return newInstance(type, new Class<?>[] { parameterType }, new Object[] { parameter });
    }

    /**
     * Creates a new instance from the given Java type.
     *
     * @param type The Java type for which a new instance will be created
     * @param parameterTypes The types of the constructor's parameters
     * @param parameters The objects to pass during instantiation
     * @return A new instance of the given type or <code>null</code> if a problem was encountered
     * during instantiation
     */
    <T> T newInstance(Class<T> type, Class<?>[] parameterTypes, Object[] parameters) {

        Constructor<T> constructor = getConstructor(type, parameterTypes);

        if (constructor != null) {
            return newInstance(constructor, parameters);
        }

        return null;
    }

    /**
     * Creates a new instance by using the given constructor.
     *
     * @param constructor The constructor used to create the new instance
     * @param parameters The objects to pass during instantiation
     * @return A new instance or <code>null</code> if a problem was encountered during instantiation
     */
    <T> T newInstance(Constructor<T> constructor, Object[] parameters) {

        try {

            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    return AccessController.doPrivileged(
                        new PrivilegedInvokeConstructor<>(constructor, parameters)
                    );
                }
                catch (PrivilegedActionException exception) {
                    return null;
                }
            }

            return PrivilegedAccessHelper.invokeConstructor(constructor, parameters);
        }
        catch (ReflectiveOperationException e) {
            return null;
        }
    }

    /**
     * Changes the state of this context to use the given subquery. Once the subquery is created and
     * populated, {@link #disposeSubqueryContext()} has to be called.
     *
     * @param currentQuery The parsed tree representation of the subquery that will become the
     * current {@link DatabaseQuery}
     * @param query The {@link ReportQuery} for the subquery
     * @see #disposeSubqueryContext()
     */
    void newSubQueryContext(org.eclipse.persistence.jpa.jpql.parser.Expression currentQuery,
                            ReportQuery query) {

        currentContext = new JPQLQueryContext(currentContext, currentQuery, query);
    }

    private ParameterTypeVisitor parameterTypeVisitor() {

        if (parent != null) {
            return parent.parameterTypeVisitor();
        }

        if (parameterTypeVisitor == null) {
            parameterTypeVisitor = new ParameterTypeVisitor(this);
        }

        return parameterTypeVisitor;
    }

    private JPQLExpression parse(String jpqlQuery) {
        return new JPQLExpression(jpqlQuery, jpqlGrammar);
    }

    /**
     * Resolves the given {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} and
     * returns the corresponding descriptor. Usually this method is used when retrieving the
     * descriptor for an identification variable or a path expression. In the case of a range
     * variable declaration, the descriptor of the entity is returned. In the case of a path
     * expression, the mapping reference descriptor will be returned.
     *
     * @param expression The {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression}
     */
    ClassDescriptor resolveDescriptor(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
        return typeResolver().resolveDescriptor(expression);
    }

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

    /**
     * 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(org.eclipse.persistence.jpa.jpql.parser.Expression expression) {
        return typeResolver().resolveMappingObject(expression);
    }

    /**
     * Sets the query to populate.
     *
     * @param query The {@link DatabaseQuery} that was created before populating it
     */
    void setDatabasQuery(DatabaseQuery query) {
        this.query = query;
    }

    TypeResolver typeResolver() {

        if (parent != null) {
            return parent.typeResolver();
        }

        if (typeResolver == null) {
            typeResolver = new TypeResolver(this);
        }

        return typeResolver;
    }
}
