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