/*
 * 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
//
//     09/02/2019-3.0 Alexandre Jacob
//        - 527415: Fix code when locale is tr, az or lt
package org.eclipse.persistence.jpa.jpql.tools.resolver;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSchemaName;
import org.eclipse.persistence.jpa.jpql.parser.AnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SubExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;
import org.eclipse.persistence.jpa.jpql.tools.JPQLQueryContext;
import org.eclipse.persistence.jpa.jpql.tools.spi.IMapping;
import org.eclipse.persistence.jpa.jpql.tools.spi.IQuery;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;
import org.eclipse.persistence.jpa.jpql.tools.spi.ITypeDeclaration;

/**
 * This {@link Resolver} is responsible to visit the current query (which is either the top-level
 * query or a subquery) and gathers the information from the declaration clause. For a <b>SELECT</b>
 * or <b>DELETE</b> clause, the information will be retrieved from the <b>FROM</b> clause. For an
 * <code>UDPATE</code> clause, it will be retrieved from the unique identification range variable
 * declaration.
 *
 * @version 2.5
 * @since 2.3
 * @author Pascal Filion
 */
public class DeclarationResolver extends Resolver {

    /**
     * The {@link Declaration Declarations} of the current query that was parsed.
     */
    private List<Declaration> declarations;

    /**
     * This visitor is responsible to visit the current query's declaration and populate this
     * resolver with the list of declarations.
     */
    private DeclarationVisitor declarationVisitor;

    /**
     * This visitor is responsible to convert the abstract schema name into a path expression.
     */
    private QualifyRangeDeclarationVisitor qualifyRangeDeclarationVisitor;

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

    /**
     * The identification variable names mapped to their resolvers.
     */
    private Map<String, Resolver> resolvers;

    /**
     * The variables identifying the select expressions, if any was defined or an empty set if none
     * were defined.
     */
    private Map<IdentificationVariable, String> resultVariables;

    /**
     * This visitor resolves the "root" object represented by the given {@link Expression}. This will
     * also handle using a subquery in the <code><b>FROM</b></code> clause. This is only supported by
     * EclipseLink.
     */
    private RootObjectExpressionVisitor rootObjectExpressionVisitor;

    /**
     * Creates a new <code>DeclarationResolver</code>.
     *
     * @param parent The parent resolver if this is used for a subquery or null if it's used for the
     * top-level query
     * @param queryContext The context used to query information about the query
     */
    public DeclarationResolver(DeclarationResolver parent, JPQLQueryContext queryContext) {
        super(parent);
        initialize(queryContext);
    }

    /**
     * Adds the given {@link Declaration} at the end of the list.
     *
     * @param declaration The {@link Declaration} representing a single variable declaration
     */
    protected final void addDeclaration(Declaration declaration) {
        declarations.add(declaration);
    }

    /**
     * Registers a 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
     */
    public void addRangeVariableDeclaration(String entityName, String variableName) {

        // Always make the identification variable be upper case since it's
        // case insensitive, the get will also use upper case
        String internalVariableName = variableName.toUpperCase(Locale.ROOT);

        // Make sure the identification variable was not declared more than once,
        // this could cause issues when trying to resolve it
        if (!resolvers.containsKey(internalVariableName)) {

            // Resolve the expression and map it with the identification variable
            Resolver resolver = new EntityResolver(this, entityName);
            resolver = new IdentificationVariableResolver(resolver, variableName);
            resolvers.put(internalVariableName, resolver);

            RangeDeclaration declaration = new RangeDeclaration();
            declaration.rootPath               = entityName;
            declaration.identificationVariable = new IdentificationVariable(null, variableName);
            declarations.add(declaration);
        }
    }

    protected DeclarationVisitor buildDeclarationVisitor() {
        return new DeclarationVisitor();
    }

    protected RootObjectExpressionVisitor buildRootObjectExpressionVisitor() {
        return new RootObjectExpressionVisitor();
    }

    @Override
    protected IType buildType() {
        return getTypeHelper().unknownType();
    }

    @Override
    protected ITypeDeclaration buildTypeDeclaration() {
        return getTypeHelper().unknownTypeDeclaration();
    }

    @Override
    protected void checkParent(Resolver parent) {
        // Don't do anything, this is the root
    }

    /**
     * Converts the given {@link Declaration} from being set as a range variable declaration to
     * a path expression declaration.
     * <p>
     * In this query "<code>UPDATE Employee SET firstName = 'MODIFIED' WHERE (SELECT COUNT(m) FROM
     * managedEmployees m) {@literal >} 0</code>" <em>managedEmployees</em> is an unqualified
     * collection-valued path expression (<code>employee.managedEmployees</code>).
     *
     * @param declaration The {@link Declaration} that was parsed to range over an abstract schema
     * name but is actually ranging over a path expression
     * @param outerVariableName The identification variable coming from the parent identification
     * variable declaration
     */
    public void convertUnqualifiedDeclaration(Declaration declaration, String outerVariableName) {

        QualifyRangeDeclarationVisitor visitor = qualifyRangeDeclarationVisitor();

        try {
            visitor.oldDeclaration    = declaration;
            visitor.outerVariableName = outerVariableName;

            declaration.declarationExpression.accept(visitor);
        }
        finally {
            visitor.oldDeclaration    = null;
            visitor.newDeclaration    = null;
            visitor.outerVariableName = null;
        }
    }

    /**
     * Disposes the internal data.
     */
    public void dispose() {
        resolvers      .clear();
        declarations   .clear();
        resultVariables.clear();
    }

    /**
     * Retrieves the {@link Declaration} for which the given variable name is used to navigate to the
     * "root" object.
     *
     * @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
     * @since 2.5
     */
    public Declaration getDeclaration(String variableName) {

        for (Declaration declaration : declarations) {
            if (declaration.getVariableName().equalsIgnoreCase(variableName)) {
                return declaration;
            }
        }

        return null;
    }

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

    protected DeclarationVisitor getDeclarationVisitor() {
        if (declarationVisitor == null) {
            declarationVisitor = buildDeclarationVisitor();
        }
        return declarationVisitor;
    }

    @Override
    public DeclarationResolver getParent() {
        return (DeclarationResolver) super.getParent();
    }

    @Override
    public IQuery getQuery() {
        return queryContext.getQuery();
    }

    /**
     * Returns the {@link JPQLQueryContext} that is used by this visitor.
     *
     * @return The {@link JPQLQueryContext} holding onto the JPQL query and the cached information
     */
    protected JPQLQueryContext getQueryContext() {
        return queryContext;
    }

    /**
     * Retrieves the {@link Resolver} mapped with the given identification variable. If the
     * identification is not defined in the declaration traversed by this resolver, than the search
     * will traverse the parent hierarchy.
     *
     * @param variableName The identification variable that maps a {@link Resolver}
     * @return The {@link Resolver} mapped with the given identification variable
     */
    public Resolver getResolver(String variableName) {

        variableName = variableName.toUpperCase(Locale.ROOT);
        Resolver resolver = getResolverImp(variableName);

        if ((resolver == null) && (getParent() != null)) {
            resolver = getParent().getResolver(variableName);
        }

        if (resolver == null) {
            resolver = new NullResolver(this);
            resolvers.put(variableName, resolver);
        }

        return resolver;
    }

    /**
     * Retrieves the {@link Resolver} mapped with the given identification variable. The search does
     * not traverse the parent hierarchy.
     *
     * @param variableName The identification variable that maps a {@link Resolver}
     * @return The {@link Resolver} mapped with the given identification variable
     */
    protected Resolver getResolverImp(String variableName) {
        return resolvers.get(variableName);
    }

    /**
     * Returns the variables that got defined in the select expression. This only applies to JPQL
     * queries built for JPA 2.0 or later.
     *
     * @return The variables identifying the select expressions, if any was defined or an empty set
     * if none were defined
     */
    public Set<String> getResultVariables() {
        return new HashSet<String>(resultVariables.values());
    }

    /**
     * Returns the map of result variables that got used to define a select expression. This only
     * applies to JPQL queries built for JPA 2.0.
     *
     * @return The variables identifying the select expressions, if any was defined or an empty map
     * if none were defined
     */
    public Map<IdentificationVariable, String> getResultVariablesMap() {
        return resultVariables;
    }

    protected RootObjectExpressionVisitor getRootObjectExpressionVisitor() {
        if (rootObjectExpressionVisitor == null) {
            rootObjectExpressionVisitor = buildRootObjectExpressionVisitor();
        }
        return rootObjectExpressionVisitor;
    }

    /**
     * Determines whether the JPQL expression has <b>JOIN</b> expressions.
     *
     * @return <code>true</code> if the query or subquery being traversed contains <b>JOIN</b>
     * expressions; <code>false</code> otherwise
     */
    public boolean hasJoins() {

        for (Declaration declaration : declarations) {
            if (declaration.hasJoins()) {
                return true;
            }
        }

        return false;
    }

    /**
     * Initializes this <code>DeclarationResolver</code>.
     *
     * @param queryContext The context used to query information about the query
     */
    protected void initialize(JPQLQueryContext queryContext) {
        this.queryContext    = queryContext;
        this.resolvers       = new HashMap<String, Resolver>();
        this.declarations    = new LinkedList<Declaration>();
        this.resultVariables = new HashMap<IdentificationVariable, String>();
    }

    /**
     * Determines whether the given identification variable is defining a <b>JOIN</b> expression or
     * in a <code>IN</code> expressions for a collection-valued field. If the search didn't find the
     * identification in this resolver, then it will traverse the parent hierarchy.
     *
     * @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> otherwise
     */
    public boolean isCollectionIdentificationVariable(String variableName) {

        boolean result = isCollectionIdentificationVariableImp(variableName);

        if (!result && (getParent() != null)) {
            result = getParent().isCollectionIdentificationVariableImp(variableName);
        }

        return result;
    }

    /**
     * Determines whether the given identification variable is defining a <b>JOIN</b> expression or
     * in a <code>IN</code> expressions for a collection-valued field. The search does not traverse
     * the parent hierarchy.
     *
     * @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> otherwise
     */
    protected boolean isCollectionIdentificationVariableImp(String variableName) {

        for (Declaration declaration : declarations) {

            switch (declaration.getType()) {

                case COLLECTION: {
                    if (declaration.getVariableName().equalsIgnoreCase(variableName)) {
                        return true;
                    }
                    return false;
                }

                case RANGE:
                case DERIVED: {

                    AbstractRangeDeclaration rangeDeclaration = (AbstractRangeDeclaration) declaration;

                    // Check the JOIN expressions
                    for (Join join : rangeDeclaration.getJoins()) {

                        String joinVariableName = queryContext.literal(
                            join.getIdentificationVariable(),
                            LiteralType.IDENTIFICATION_VARIABLE
                        );

                        if (joinVariableName.equalsIgnoreCase(variableName)) {
                            // Make sure the JOIN expression maps a collection mapping
                            Resolver resolver = getResolver(variableName);
                            IMapping mapping = (resolver != null) ? resolver.getMapping() : null;
                            return (mapping != null) && mapping.isCollection();
                        }
                    }
                }

                default:
                    continue;
            }
        }

        return false;
    }

    /**
     * Determines whether the given variable name is an identification variable name mapping an
     * entity. The search traverses the parent resolver if it is not found in this resolver, which
     * represents the current JPQL query.
     *
     * @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
     */
    public boolean isRangeIdentificationVariable(String variableName) {

        boolean result = isRangeIdentificationVariableImp(variableName);

        if (!result && (getParent() != null)) {
            result = getParent().isRangeIdentificationVariableImp(variableName);
        }

        return result;
    }

    /**
     * Determines whether the given variable name is an identification variable name mapping an
     * entity. The search only searches in this resolver, which represents the current JPQL query.
     *
     * @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
     */
    protected boolean isRangeIdentificationVariableImp(String variableName) {

        for (Declaration declaration : declarations) {

            if (declaration.getType().isRange() &&
                declaration.getVariableName().equalsIgnoreCase(variableName)) {

                return true;
            }
        }

        return false;
    }

    /**
     * Determines if the given variable is a result variable.
     *
     * @param variable 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
     */
    public boolean isResultVariable(String variable) {
        return resultVariables.containsValue(variable.toUpperCase(Locale.ROOT));
    }

    /**
     * Visits the current query (which is either the top-level query or a subquery) and gathers the
     * information from the declaration clause.
     *
     * @param expression The {@link Expression} to visit in order to retrieve the information
     * contained in the given query's declaration
     */
    public void populate(Expression expression) {
        DeclarationVisitor visitor = getDeclarationVisitor();
        try {
            expression.accept(visitor);
        }
        finally {
            visitor.currentDeclaration = null;
        }
    }

    protected QualifyRangeDeclarationVisitor qualifyRangeDeclarationVisitor() {
        if (qualifyRangeDeclarationVisitor == null) {
            qualifyRangeDeclarationVisitor = new QualifyRangeDeclarationVisitor();
        }
        return qualifyRangeDeclarationVisitor;
    }

    /**
     * Resolves the "root" object represented by the given {@link Expression}. This will also handle
     * using a subquery in the <code><b>FROM</b></code> clause. This is only supported by EclipseLink.
     *
     * @param expression The {@link Expression} to visit, which represents the "root" object of a
     * declaration
     * @return The {@link Resolver} for the given {@link Expression}
     */
    protected Resolver resolveRootObject(Expression expression) {
        RootObjectExpressionVisitor visitor = getRootObjectExpressionVisitor();
        try {
            expression.accept(visitor);
            return visitor.resolver;
        }
        finally {
            visitor.resolver = null;
        }
    }

    protected String visitDeclaration(Expression expression, Expression identificationVariable) {

        // Visit the identification variable expression and retrieve the identification variable name
        String variableName = queryContext.literal(
            identificationVariable,
            LiteralType.IDENTIFICATION_VARIABLE
        );

        // If it's not empty, then we can create a Resolver
        if (variableName != ExpressionTools.EMPTY_STRING) {

            // Always make the identification variable be upper case since it's
            // case insensitive, the get will also use upper case
            String internalVariableName = variableName.toUpperCase(Locale.ROOT);

            // Make sure the identification variable was not declared more than once,
            // this could cause issues when trying to resolve it
            if (!resolvers.containsKey(internalVariableName)) {

                // Resolve the expression and map it with the identification variable
                Resolver resolver = resolveRootObject(expression);
                resolver = new IdentificationVariableResolver(resolver, variableName);
                resolvers.put(internalVariableName, resolver);
            }

            return variableName;
        }

        return ExpressionTools.EMPTY_STRING;
    }

    protected class DeclarationVisitor extends AbstractExpressionVisitor {

        /**
         * This flag is used to determine what to do in {@link #visit(SimpleSelectStatement)}.
         */
        protected boolean buildingDeclaration;

        /**
         * Flag used to determine if the {@link IdentificationVariable} to visit is a result variable.
         */
        protected boolean collectResultVariable;

        /**
         * The {@link Declaration} being populated.
         */
        protected Declaration currentDeclaration;

        @Override
        public void visit(AbstractSchemaName expression) {
            currentDeclaration = new RangeDeclaration();
            currentDeclaration.rootPath = expression.getText();
            declarations.add(currentDeclaration);
        }

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

        @Override
        public void visit(CollectionMemberDeclaration expression) {

            CollectionDeclaration declaration = new CollectionDeclaration();
            declaration.declarationExpression = expression;
            declaration.baseExpression        = expression.getCollectionValuedPathExpression();
            declaration.rootPath              = declaration.baseExpression.toActualText();
            declarations.add(declaration);

            // Retrieve the IdentificationVariable
            Expression identificationVariable = expression.getIdentificationVariable();
            String variableName = visitDeclaration(expression, identificationVariable);

            if (variableName != ExpressionTools.EMPTY_STRING) {
                declaration.identificationVariable = (IdentificationVariable) identificationVariable;
            }
        }

        @Override
        public void visit(CollectionValuedPathExpression expression) {
            currentDeclaration = new DerivedDeclaration();
            currentDeclaration.rootPath = expression.toActualText();
            declarations.add(currentDeclaration);
        }

        @Override
        public void visit(DeleteClause expression) {

            try {
                buildingDeclaration = true;
                expression.getRangeVariableDeclaration().accept(this);
                buildingDeclaration = false;

                currentDeclaration.declarationExpression = expression;
            }
            finally {
                currentDeclaration = null;
            }
        }

        @Override
        public void visit(DeleteStatement expression) {
            expression.getDeleteClause().accept(this);
        }

        @Override
        public void visit(FromClause expression) {
            expression.getDeclaration().accept(this);
        }

        @Override
        public void visit(IdentificationVariable expression) {
            if (collectResultVariable) {
                resultVariables.put(expression, expression.getText().toUpperCase(Locale.ROOT));
            }
        }

        @Override
        public void visit(IdentificationVariableDeclaration expression) {

            try {
                expression.getRangeVariableDeclaration().accept(this);
                expression.getJoins().accept(this);
                currentDeclaration.declarationExpression = expression;
            }
            finally {
                currentDeclaration = null;
            }
        }

        @Override
        public void visit(Join expression) {

            AbstractRangeDeclaration rangeDeclaration = (AbstractRangeDeclaration) currentDeclaration;
            Expression identificationVariable = expression.getIdentificationVariable();
            visitDeclaration(expression, identificationVariable);
            rangeDeclaration.addJoin(expression);
        }

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

        @Override
        public void visit(NullExpression expression) {
            if (buildingDeclaration) {
                currentDeclaration = new UnknownDeclaration();
                currentDeclaration.baseExpression = expression;
                currentDeclaration.rootPath       = ExpressionTools.EMPTY_STRING;
                declarations.add(currentDeclaration);
            }
        }

        @Override
        public void visit(RangeVariableDeclaration expression) {

            // Visit the "root" object, which will create the right Declaration
            Expression rootObject = expression.getRootObject();
            buildingDeclaration = true;
            rootObject.accept(this);
            buildingDeclaration = false;

            // Set the base expression
            currentDeclaration.baseExpression = expression;

            // Set the identification variable
            Expression identificationVariable = expression.getIdentificationVariable();
            String variableName = visitDeclaration(rootObject, identificationVariable);

            if (variableName != ExpressionTools.EMPTY_STRING) {
                currentDeclaration.identificationVariable = (IdentificationVariable) identificationVariable;
            }
        }

        @Override
        public void visit(ResultVariable expression) {
            collectResultVariable = true;
            expression.getResultVariable().accept(this);
            collectResultVariable = false;
        }

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

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

        @Override
        public void visit(SimpleFromClause expression) {
            expression.getDeclaration().accept(this);
        }

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

        @Override
        public void visit(SimpleSelectStatement expression) {
            expression.getFromClause().accept(this);
        }

        @Override
        public void visit(UpdateClause expression) {

            try {
                buildingDeclaration = true;
                expression.getRangeVariableDeclaration().accept(this);
                buildingDeclaration = false;

                currentDeclaration.declarationExpression = expression;
            }
            finally {
                currentDeclaration = null;
            }
        }

        @Override
        public void visit(UpdateStatement expression) {
            expression.getUpdateClause().accept(this);
        }
    }

    protected static class QualifyRangeDeclarationVisitor extends AbstractExpressionVisitor {

        /**
         * The new {@link Declaration}.
         */
        protected Declaration newDeclaration;

        /**
         * The {@link Declaration} being modified.
         */
        protected Declaration oldDeclaration;

        /**
         * The identification variable coming from the parent identification variable declaration.
         */
        protected String outerVariableName;

        @Override
        public void visit(CollectionValuedPathExpression expression) {
            newDeclaration.rootPath       = expression.toActualText();
            newDeclaration.baseExpression = expression;
        }

        @Override
        public void visit(IdentificationVariableDeclaration expression) {
            expression.getRangeVariableDeclaration().accept(this);
        }

        @Override
        public void visit(RangeVariableDeclaration expression) {

            newDeclaration = new DerivedDeclaration();

            expression.setVirtualIdentificationVariable(outerVariableName, newDeclaration.rootPath);
            expression.getRootObject().accept(this);
        }
    }

    /**
     * This visitor takes care to support a subquery defined as a "root" object.
     */
    protected class RootObjectExpressionVisitor extends AnonymousExpressionVisitor {

        /**
         * The {@link Resolver} of the "root" object.
         */
        protected Resolver resolver;

        @Override
        protected void visit(Expression expression) {
            resolver = queryContext.getResolver(expression);
        }

        @Override
        public void visit(SimpleSelectStatement expression) {
            resolver = new FromSubqueryResolver(
                DeclarationResolver.this,
                DeclarationResolver.this.queryContext,
                expression
            );
        }

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