/*
 * 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.lang.reflect.InvocationTargetException;
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
 */
@SuppressWarnings("nls")
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.query.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 parameterName The name of the input parameter
     * @param type The calculated type based on its surrounding, which is never <code>null</code>
     */
    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
     */
    @SuppressWarnings("unchecked")
    private Class<?> 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
     */
    @SuppressWarnings("unchecked")
    <T> Constructor<T> getConstructor(Class<?> 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.length()));
        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
     */
    @SuppressWarnings("unchecked")
    <T> T newInstance(Class<?> 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<?> 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
     */
    @SuppressWarnings("unchecked")
    <T> T newInstance(Constructor<T> constructor, Object[] parameters) {

        try {

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

            return (T) PrivilegedAccessHelper.invokeConstructor(constructor, parameters);
        }
        catch (InstantiationException e) {
            return null;
        }
        catch (InvocationTargetException e) {
            return null;
        }
        catch (IllegalAccessException 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;
    }
}
