/*
 * 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
     */
    @SuppressWarnings("fallthrough")
    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);
        }
    }
}
