/*
 * Copyright (c) 1997, 2018 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.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

/*
 * Semantic.g
 *
 * Created on November 19, 2001
 */

header
{
    package com.sun.jdo.spi.persistence.support.ejb.ejbqlc;
    
    import java.util.ResourceBundle;
    import java.lang.reflect.Method;
    import org.glassfish.persistence.common.I18NHelper;
    import com.sun.jdo.spi.persistence.support.ejb.ejbc.MethodHelper;
}

/**
 * This class defines the semantic analysis of the EJBQL compiler.
 * Input of this pass is the AST as produced by the parser,
 * that consists of EJBQLAST nodes.
 * The result is a typed EJBQLAST tree.
 *
 * @author  Michael Bouschen
 * @author  Shing Wai Chan
 */
class Semantic extends TreeParser;

options
{
    importVocab = EJBQL;
    buildAST = true;
    defaultErrorHandler = false;
    ASTLabelType = "EJBQLAST"; //NOI18N
}

{
    /** Name of the property to disable order by validation. */
    public static final String DISABLE_ORDERBY_VALIDATION_PROPERTY =
        "com.sun.jdo.spi.persistence.support.ejb.ejbqlc.DISABLE_ORDERBY_VALIDATION"; // NOI18N

    /**
     * Property to disable order by validation. 
     * Note, the default is false, meaning the compiler checks that select 
     * clause and orderby clause are compatible.
     */
    private static final boolean DISABLE_ORDERBY_VALIDATION = 
        Boolean.getBoolean(DISABLE_ORDERBY_VALIDATION_PROPERTY);

    /** Symbol table handling names of variables and parameters. */
    protected SymbolTable symtab;

    /** Type info access helper. */
    protected TypeSupport typeSupport;
    
    /** Parameter info helper. */
    protected ParameterSupport paramSupport;
    
    /** The Method instance of the finder/selector method. */
    protected Method method;

    /** result-type-mapping element from the DD. */
    protected int resultTypeMapping;

    /** Flag indicating finder or selector. */
    protected boolean finderNotSelector;

    /** Flag indicating have aggregate function or not. */
    protected boolean isAggregate = false;

    /** The ejb-name. */
    protected String ejbName;

    /** I18N support. */
    protected final static ResourceBundle msgs = I18NHelper.loadBundle(
        Semantic.class);
    
    /**
     * Initializes the semantic analysis.
     * @param typeSupport type info access helper.
     * @param paramSupport parameter info helper.
     * @param method method instance of the finder/selector method.
     * @param resultTypeMapping result-type-mapping element from the DD
     * @param finderNotSelector <code>true</code> for finder; 
     * <code>false</code> for selector
     * @param ejbName the ejb name of the finder/selector method.
     */
    public void init(TypeSupport typeSupport, ParameterSupport paramSupport,
                     Method method, int resultTypeMapping,  
                     boolean finderNotSelector, String ejbName)
    {
        this.symtab = new SymbolTable();
        this.typeSupport = typeSupport;
        this.paramSupport = paramSupport;
        this.method = method;
        this.resultTypeMapping = resultTypeMapping;
        this.finderNotSelector = finderNotSelector;
        this.ejbName = ejbName;
    }

    /** */
    public void reportError(RecognitionException ex) {
        ErrorMsg.fatal(I18NHelper.getMessage(msgs, "ERR_SemanticError"), ex); //NOI18N
    }

    /** */
    public void reportError(String s) {
        ErrorMsg.fatal(I18NHelper.getMessage(msgs, "ERR_SemanticError") + s); //NOI18N
    }
    
    //========= Internal helper methods ==========

    /**
     * Checks the return type and the type of the select clause expression 
     * of a finder method.
     * <p>
     * The return type of a finder must be one of the following: 
     * <ul>
     * <li>java.util.Collection (multi-object finder)
     * <li>java.util.Enumeration (EJB 1.1 multi-object finder)
     * <li>the entity bean's remote interface (single-object finder)
     * <li>the entity bean's local interface (single-object finder)
     * </ul>
     * The type of the select clause expression of a finder must be 
     * the entity bean's local or remote interface.
     * @param returnType the return type of the finder/selector method object
     * @param selectClauseTypeInfo the type info of the select clause 
     * expression. 
     */
    private void checkFinderReturnType(
        Class returnType, Object selectClauseTypeInfo)
    {
        String selectClauseTypeName = typeSupport.getTypeName(selectClauseTypeInfo);
        Object returnTypeInfo = typeSupport.getTypeInfo(returnType);
        // The return type of a finder must be Collection or Enumeration or
        // the entity bean's remote or local interface 
        if ((returnType != java.util.Collection.class) &&
            (returnType != java.util.Enumeration.class) &&
            (!typeSupport.isRemoteInterfaceOfEjb(returnTypeInfo, ejbName)) &&
            (!typeSupport.isLocalInterfaceOfEjb(returnTypeInfo, ejbName))) {
            ErrorMsg.error(I18NHelper.getMessage(msgs, 
                "EXC_InvalidFinderReturnType", returnType.getName())); //NOI18N
                    
        }
        
        // The type of the select clause expression must be the ejb name 
        // of this bean.
        if (!selectClauseTypeName.equals(this.ejbName)) {
            ErrorMsg.error(I18NHelper.getMessage(msgs, 
                "EXC_InvalidFinderSelectClauseType", selectClauseTypeName)); //NOI18N
        }
    }

    /**
     * Implements type compatibility for selector. The method returns
     * <code>true</code> if returnTypeInfo is compatible with 
     * selectClauseTypeInfo.
     */
    private boolean isCompatibleSelectorSelectorReturnType(
            Object returnTypeInfo, Object selectClauseTypeInfo)
    {
        if (isAggregate) {
            return getCommonOperandType(selectClauseTypeInfo, returnTypeInfo) != TypeSupport.errorType;   
        } else {
            return typeSupport.isCompatibleWith(selectClauseTypeInfo, returnTypeInfo);
        }
    }
    

    /**
     * Checks the return type and the type of the select clause expression 
     * of a selector method.
     * <p>
     * The return type of a selector must be one of the following: 
     * <ul>
     * <li>java.util.Collection (multi-object selector)
     * <li>java.util.Set (multi-object selector)
     * <li>assignable from the type of the select clause expression 
     * (single-object selector)
     * </ul>
     * @param returnType the return type of the finder/selector method object
     * @param selectClauseTypeInfo the type info of the select clause 
     * expression. 
     */
    private void checkSelectorReturnType(
        Class returnType, Object selectClauseTypeInfo)
    {
        String selectClauseTypeName = typeSupport.getTypeName(selectClauseTypeInfo);
        Object returnTypeInfo = typeSupport.getTypeInfo(returnType);
        // The return type of a selector must be Collection or Set or 
        // assingable from the type of the select clause expression
        if ((returnType != java.util.Collection.class) &&
            (returnType != java.util.Set.class) &&
            !isCompatibleSelectorSelectorReturnType(returnTypeInfo,
                selectClauseTypeInfo)) {
            ErrorMsg.error(I18NHelper.getMessage(msgs,
                "EXC_InvalidSelectorReturnType", //NOI18N
                typeSupport.getTypeName(returnTypeInfo), selectClauseTypeName)); 
        }
    }

    /**
     * Checks the result-type-mapping element setting in the case of a finder 
     * method. Finder must not specify result-type-mapping.
     */
    private void checkFinderResultTypeMapping()
    {
        if (resultTypeMapping != MethodHelper.NO_RETURN) {
            ErrorMsg.error(I18NHelper.getMessage(msgs, 
                "EXC_InvalidResultTypeMappingForFinder")); //NOI18N
        }
    }

    /**
     * Checks the setting of the result-type-mapping element for a 
     * selector. Only selectors returning a entity object may 
     * specify this.
     * <p>
     * The method checks the following error cases:
     * <ul>
     * <li>result-type-mapping is specified as Remote, 
     * but bean does not have remote interface
     * <li>result-type-mapping is specified as Local, 
     * but bean does not have local interface
     * <li>single-object selector returns remote interface,
     * but result-type-mapping is not specified as Remote
     * <li>single-object selector returns local interface,
     * but result-type-mapping is specified as Remote
     * <li>result-type-mapping is specified for a selector returning 
     * non-entity objects.
     * </ul>
     * @param returnType the return type of the finder/selector method object
     * @param selectClauseTypeInfo the type info of the select clause.
     */
    private void checkSelectorResultTypeMapping(
        Class returnType, Object selectClauseTypeInfo)
    {
        Object returnTypeInfo = typeSupport.getTypeInfo(returnType);

        // case: multi-object selector returning entity objects
        if (typeSupport.isCollectionType(returnTypeInfo) && 
            typeSupport.isEjbName(selectClauseTypeInfo)) {
            if (resultTypeMapping == MethodHelper.REMOTE_RETURN) {
                // result-type-mapping is Remote => 
                // bean must have remote interface
                if (!typeSupport.hasRemoteInterface(selectClauseTypeInfo)) {
                    ErrorMsg.error(I18NHelper.getMessage(msgs, 
                        "EXC_InvalidRemoteResultTypeMappingForMultiSelector", //NOI18N
                        selectClauseTypeInfo)); 
                }
            }
            else {
                // result-type-mapping is Local or not specified => 
                // bean must have local interface
                if (!typeSupport.hasLocalInterface(selectClauseTypeInfo)) {
                    ErrorMsg.error(I18NHelper.getMessage(msgs,
                        "EXC_InvalidLocalResultTypeMappingForMultiSelector", //NOI18N
                        selectClauseTypeInfo)); 
                }
            }
        }
        // case: single-object selector returning remote interface
        else if (typeSupport.isRemoteInterface(returnTypeInfo)) {
            // result-type-mapping must be Remote
            if (resultTypeMapping != MethodHelper.REMOTE_RETURN) {
                ErrorMsg.error(I18NHelper.getMessage(msgs,
                    "EXC_InvalidLocalResultTypeMappingForSingleSelector")); //NOI18N     
            }
        }
        // case: single-object selector returning local interface
        else if (typeSupport.isLocalInterface(returnTypeInfo)) {
            // result-type-mapping must be Local or not specified
            if (resultTypeMapping == MethodHelper.REMOTE_RETURN) {
                ErrorMsg.error(I18NHelper.getMessage(msgs,
                    "EXC_InvalidRemoteResultTypeMappingForSingleSelector")); //NOI18N     
            }
        }
        // cases: single-object and multi-object selector 
        // returning non-enity object(s)
        else if (resultTypeMapping != MethodHelper.NO_RETURN) {
            // result-type-mapping must not be specified
            ErrorMsg.error(I18NHelper.getMessage(msgs, 
                "EXC_InvalidResultTypeMappingForSelector", //NOI18N
                selectClauseTypeInfo)); 
        }
    }

    /**
     * Checks that select clause and orderby clause are compatible.
     * <p>
     * The method checks the following error cases:
     * <ul>
     * <li>if the select clause is an identification variable or
     * a single valued cmr path expression, then the orderby item
     * must be a cmp field of the entity bean abstract schema
     * type value returned by the SELECT clause
     * <li>if the select clause is a cmp field, then
     * orderby item must be empty or the same cmp field.
     * </ul>
     * @param select the select clause of the query
     * @param orderby the orderby clause of the query
     */
    private void checkSelectOrderbyClause(EJBQLAST select, EJBQLAST orderby)
    {
        // nothing to check if no orderby clause or 
        // if orderby validation is disabled
        if ((orderby == null) || DISABLE_ORDERBY_VALIDATION) {
            return;
        }

        AST selectReturnAST = select.getFirstChild();
        // skip DISTINCT node, so selectReturnAST should be one of the following:
        //     Object(x), cmr-field, cmp-field
        // it is illegal to be an aggregate function node
        if (selectReturnAST.getType() == DISTINCT) {
            selectReturnAST = selectReturnAST.getNextSibling();
        }

        if (selectReturnAST.getType() == CMP_FIELD_ACCESS) {
            StringBuffer buf = new StringBuffer();
            genPathExpression(selectReturnAST, buf);
            String selectReturnPathExpr = buf.toString();
            for (AST sibling = orderby.getFirstChild();
                    sibling != null;
                    sibling = sibling.getNextSibling().getNextSibling()) {

                // share buf
                buf.setLength(0);
                genPathExpression(sibling, buf);
                String siblingPathExpr = buf.toString();
                if (!selectReturnPathExpr.equals(siblingPathExpr)) {
                    ErrorMsg.error(I18NHelper.getMessage(msgs, 
                    "EXC_InvalidOrderbyItemForCMPSelect", //NOI18N
                    siblingPathExpr)); 
                }
            }
        } else {
            AST abstractSchemaAST = null;
            if (selectReturnAST.getType() == SINGLE_CMR_FIELD_ACCESS) {
                abstractSchemaAST = selectReturnAST;
            } else if (selectReturnAST.getType() == OBJECT) {
                abstractSchemaAST = selectReturnAST.getFirstChild();
            } else { // it must be an aggregate function node
                ErrorMsg.error(I18NHelper.getMessage(msgs,
                "EXC_InvalidAggregateOrderby" //NOI18N
                ));
            }

            StringBuffer buf = new StringBuffer();
            genPathExpression(abstractSchemaAST, buf);
            String abstractSchemaExpr = buf.toString();
            for (AST sibling = orderby.getFirstChild();
                    sibling != null;
                    sibling = sibling.getNextSibling().getNextSibling()) {

                // share  buf
                buf.setLength(0);
                genPathExpression(sibling.getFirstChild(), buf);
                String siblingRootExpr = buf.toString();
                if (!abstractSchemaExpr.equals(siblingRootExpr)) {
                    buf.setLength(0);
                    genPathExpression(sibling, buf);
                    ErrorMsg.error(I18NHelper.getMessage(msgs, 
                    "EXC_InvalidOrderbyItem", //NOI18N
                    buf.toString())); 
                }
            }
        } 
    }

    /**
     * Form a string representation of a dot expression and append to given
     * StringBuffer.
     * @param ast the AST node representing the root the of the expression
     * @param buf the StringBuffer that will have result of path expression
     * append
     */
    //SW: We can write this method without recursion. Michael suggests to use
    //recursion for readability.
    private void genPathExpression(AST ast, StringBuffer buf) {
        if (ast == null) {
            return;
        }
        switch (ast.getType()) {
            case CMP_FIELD_ACCESS:
            case COLLECTION_CMR_FIELD_ACCESS:
            case SINGLE_CMR_FIELD_ACCESS:
                AST left = ast.getFirstChild();
                AST right = left.getNextSibling();
                genPathExpression(left, buf);
                buf.append('.');
                genPathExpression(right, buf);
                break;
            default:
                buf.append(ast.getText());
                break;
        }
    }

    /**
     * Analyses a logical operation AND, OR
     * @param op the logical operator
     * @param leftAST left operand 
     * @param rightAST right operand
     * @return the type info of the operator 
     */
    private Object analyseConditionalExpr(EJBQLAST op, EJBQLAST leftAST, EJBQLAST rightAST)
    {
        Object left = leftAST.getTypeInfo();
        Object right = rightAST.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(left) || typeSupport.isErrorType(right))
            return typeSupport.errorType;
        
        if (typeSupport.isBooleanType(left) && typeSupport.isBooleanType(right)) {
            Object common = typeSupport.booleanType;
            return common;
        }

        // if this code is reached a bitwise operator was used with invalid arguments
        ErrorMsg.error(op.getLine(), op.getColumn(), 
            I18NHelper.getMessage(msgs, "EXC_InvalidArguments",  op.getText())); //NOI18N
        return typeSupport.errorType;
    }
    
    /** 
     * Analyses a equality operation (==, <>)
     * @param op the relational operator
     * @param leftAST left operand 
     * @param rightAST right operand
     * @return the type info of the operator
     */
    private Object analyseEqualityExpr(EJBQLAST op, EJBQLAST leftAST, EJBQLAST rightAST)
    {
        Object left = leftAST.getTypeInfo();
        Object right = rightAST.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(left) || typeSupport.isErrorType(right)) {
            return typeSupport.errorType;
        }

        // check left hand side for literals and input params 
        if (isLiteral(leftAST)) {
            ErrorMsg.error(leftAST.getLine(), leftAST.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_InvalidLHSLiteral", //NOI18N 
                    leftAST.getText(), op.getText()));
            return typeSupport.errorType;
        }
        else if (isInputParameter(leftAST)) {
            ErrorMsg.error(leftAST.getLine(), leftAST.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_InvalidLHSParameter", //NOI18N 
                    leftAST.getText(), op.getText()));
            return typeSupport.errorType;
        }
        
        // check operand types 
        if (typeSupport.isNumberType(left) && typeSupport.isNumberType(right)) {
            return typeSupport.booleanType;
        }
        else if (typeSupport.isStringType(left) && typeSupport.isStringType(right)) {
            return typeSupport.booleanType;
        }
        else if (typeSupport.isDateTimeType(left) && typeSupport.isDateTimeType(right)) {
            return typeSupport.booleanType;
        }
        else if (isEntityBeanValue(leftAST) && isEntityBeanValue(rightAST) && 
                 (typeSupport.isCompatibleWith(left, right) ||
                  typeSupport.isCompatibleWith(right, left))) {
            String leftEjbName = (String)leftAST.getTypeInfo();
            // the input parameter must be on right hand side of an equality
            // expression ('?1' = e.department is not supported)
            return analyseParameterEjbName(rightAST, leftEjbName);
        }
        else if (typeSupport.isBooleanType(left) && typeSupport.isBooleanType(right)) {
            return typeSupport.booleanType;
        }

        // if this code is reached a conditional operator was used with invalid arguments
        ErrorMsg.error(op.getLine(), op.getColumn(), 
            I18NHelper.getMessage(msgs, "EXC_InvalidArguments",  op.getText())); //NOI18N 
        return typeSupport.errorType;
    }
    
    /**
     * Analyses a relational operation (<, <=, >, >=)
     * @param op the relational operator
     * @param leftAST left operand 
     * @param rightAST right operand
     * @return the type info of the operator
     */
    private Object analyseRelationalExpr(EJBQLAST op, EJBQLAST leftAST, EJBQLAST rightAST)
    {
        Object left = leftAST.getTypeInfo();
        Object right = rightAST.getTypeInfo();

        // handle error type
        if (typeSupport.isErrorType(left) || typeSupport.isErrorType(right)) {
            return typeSupport.errorType;
        }

        // check left hand side for literals and input params 
        if (isLiteral(leftAST)) {
            ErrorMsg.error(leftAST.getLine(), leftAST.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_InvalidLHSLiteral", //NOI18N 
                    leftAST.getText(), op.getText()));
            return typeSupport.errorType;
        }
        else if (isInputParameter(leftAST)) {
            ErrorMsg.error(leftAST.getLine(), leftAST.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_InvalidLHSParameter", //NOI18N 
                    leftAST.getText(), op.getText()));
            return typeSupport.errorType;
        }
        
        // check operand types
        if ((typeSupport.isNumberType(left) && typeSupport.isNumberType(right)) ||
            (typeSupport.isDateTimeType(left) && typeSupport.isDateTimeType(right)) ||
            (typeSupport.isStringType(left) && typeSupport.isStringType(right))) {
            return typeSupport.booleanType;
        }

        // if this code is reached a conditional operator was used with invalid arguments
        ErrorMsg.error(op.getLine(), op.getColumn(), 
            I18NHelper.getMessage(msgs, "EXC_InvalidArguments",  op.getText())); //NOI18N 
        return typeSupport.errorType;
    }
    
    /**
     * Analyses a binary arithmetic expression +, -, *, /.
     * @param op the  operator
     * @param leftAST left operand 
     * @param rightAST right operand
     * @return the type info of the operator
     */
    private Object analyseBinaryArithmeticExpr(EJBQLAST op, EJBQLAST leftAST, EJBQLAST rightAST)
    {
        Object left = leftAST.getTypeInfo();
        Object right = rightAST.getTypeInfo();

        // handle error type
        if (typeSupport.isErrorType(left) || typeSupport.isErrorType(right)) {
            return typeSupport.errorType;
        }

        if (typeSupport.isNumberType(left) && typeSupport.isNumberType(right)) {
            Object common = getCommonOperandType(left, right);
            if (!typeSupport.isErrorType(common))
                return common;
        }

        // if this code is reached a conditional operator was used with invalid arguments
        ErrorMsg.error(op.getLine(), op.getColumn(), 
            I18NHelper.getMessage(msgs, "EXC_InvalidArguments",  op.getText())); //NOI18N
        return typeSupport.errorType;
    }

    /**
     * Returns the common type info for the specified operand types. 
     * This includes binary numeric promotion as specified in Java.
     * @param left type info of left operand 
     * @param right type info of right operand
     * @return the type info of the operator
     */
    private Object getCommonOperandType(Object left, Object right)
    {
        if (typeSupport.isNumberType(left) && typeSupport.isNumberType(right)) {
            boolean wrapper = false;

            // handle java.math.BigDecimal:
            if (typeSupport.bigDecimalType.equals(left)) {
                return left;
            }
            if (typeSupport.bigDecimalType.equals(right)) {
                return right;
            }
            
            // handle java.math.BigInteger
            if (typeSupport.bigIntegerType.equals(left)) {
                // if right is floating point return BigDecimal, 
                // otherwise return BigInteger
                return typeSupport.isFloatingPointType(right) ? 
                       typeSupport.bigDecimalType : left;
            }
            if (typeSupport.bigIntegerType.equals(right)) {
                // if left is floating point return BigDecimal, 
                // otherwise return BigInteger
                return typeSupport.isFloatingPointType(left) ? 
                       typeSupport.bigDecimalType : right;
            }       

            if (typeSupport.isNumericWrapperType(left)) {
                left = typeSupport.getPrimitiveType(left);
                wrapper = true;
            }
            if (typeSupport.isNumericWrapperType(right)) {
                right = typeSupport.getPrimitiveType(right);
                wrapper = true;
            }
            
            // handle numeric types with arbitrary arithmetic operator
            if (typeSupport.isNumericType(left) && typeSupport.isNumericType(right)) {
                Object promotedType = typeSupport.binaryNumericPromotion(left, right);
                if (wrapper) 
                    promotedType = typeSupport.getWrapperType(promotedType);
                return promotedType;
            }
        }
        else if (typeSupport.isBooleanType(left) && typeSupport.isBooleanType(right)) {
            // check for boolean wrapper class: if one of the operands has the 
            // type Boolean return Boolean, otherwise return boolean.
            if (left.equals(typeSupport.booleanClassType) || 
                right.equals(typeSupport.booleanClassType))
                return typeSupport.booleanClassType;
            else
                return typeSupport.booleanType;
        }
        else if (typeSupport.isCompatibleWith(left, right)) {
            return right;
        }
        else if (typeSupport.isCompatibleWith(right, left)) {
            return left;
        }

        // not compatible types => return errorType
        return typeSupport.errorType;
    }

    /**
     * Analyses a unary expression (+ and -).
     * @param op the operator
     * @param argASTleftAST left operand 
     * @param rightAST right operand
     * @return the type info of the operator 
     */
    private Object analyseUnaryArithmeticExpr(EJBQLAST op, EJBQLAST argAST)
    {
        Object arg = argAST.getTypeInfo();

        // handle error type
        if (typeSupport.isErrorType(arg))
            return arg;
        
        if (typeSupport.isNumberType(arg)) {
            boolean wrapper = false;
            if (typeSupport.isNumericWrapperType(arg)) {
                arg = typeSupport.getPrimitiveType(arg);
                wrapper = true;
            }

            Object promotedType = typeSupport.unaryNumericPromotion(arg);
            if (wrapper)
                promotedType = typeSupport.getWrapperType(promotedType);
            return promotedType;
        }
        
        // if this code is reached a conditional operator was used with invalid arguments
        ErrorMsg.error(op.getLine(), op.getColumn(), 
            I18NHelper.getMessage(msgs, "EXC_InvalidArguments",  op.getText())); //NOI18N
        return typeSupport.errorType;
    }
    
    /** 
     * Analyses a expression node that is expected to access a collection 
     * valued CMR field. It returns the element type of the collection valued 
     * CMR field. 
     * @param fieldAccess the field access node
     * @return the type info of the operator 
     */
    private Object analyseCollectionValuedCMRField(EJBQLAST fieldAccess)
    {
        if (fieldAccess.getType() != COLLECTION_CMR_FIELD_ACCESS) {
            ErrorMsg.fatal(I18NHelper.getMessage(msgs, "ERR_InvalidPathExpr")); //NOI18N
            return typeSupport.errorType;
        }

        EJBQLAST classExpr = (EJBQLAST)fieldAccess.getFirstChild();
        EJBQLAST field = (EJBQLAST)classExpr.getNextSibling();
        Object fieldInfo = 
            typeSupport.getFieldInfo(classExpr.getTypeInfo(), field.getText());
        return typeSupport.getElementType(fieldInfo);
    }

    /**
     * Analyses a MEMBER OF operation. 
     * @param op the MEMBER OF operator
     * @param value node representing the value to be tested
     * @param col the collection
     * @return the type info of the operator
     */
    private Object analyseMemberExpr(EJBQLAST op, EJBQLAST value, EJBQLAST col)
    {
        Object valueTypeInfo = value.getTypeInfo();
        Object elementTypeInfo = analyseCollectionValuedCMRField(col);

        // handle error type
        if (typeSupport.isErrorType(valueTypeInfo) || 
            typeSupport.isErrorType(elementTypeInfo)) {
            return typeSupport.errorType;
        }

        // check compatibility
        if (typeSupport.isCompatibleWith(valueTypeInfo, elementTypeInfo) ||
            typeSupport.isCompatibleWith(elementTypeInfo, valueTypeInfo)) {

            return analyseParameterEjbName(value, (String)elementTypeInfo);
        }
        
        // if this code is reached there is a compatibility problem 
        // with the value and the collection expr
        ErrorMsg.error(op.getLine(), op.getColumn(), 
            I18NHelper.getMessage(msgs, "EXC_CollectionElementTypeMismatch", //NOI18N
                typeSupport.getTypeName(elementTypeInfo), 
                typeSupport.getTypeName(valueTypeInfo)));
        return typeSupport.errorType;
    }

    /**
     * Analyses the type of the element to be compatible with the type of the
     * value expression in the sense that element type can be cast into value
     * type without losing precision.
     * For instance, element type can be a double and value type can be an
     * integer.
     * @param elementAST given element
     * @param valueTypeInfo the type to be check for compatibility
     * @return the type info of the elementAST or typeSupport.errorType
     */
    private Object analyseInCollectionElement(EJBQLAST elementAST,
            Object valueTypeInfo)
    {
        Object elementTypeInfo = elementAST.getTypeInfo();

        // handle error type
        if (typeSupport.isErrorType(valueTypeInfo) || 
            typeSupport.isErrorType(elementTypeInfo)) {
            return typeSupport.errorType;
        }

        Object common = getCommonOperandType(elementTypeInfo, valueTypeInfo);
        if (!typeSupport.isErrorType(common) &&
                elementTypeInfo.equals(common)) {
            return common;
        }

        // if this code is reached there is a compatibility problem
        // with the value and the collection expr
        ErrorMsg.error(elementAST.getLine(), elementAST.getColumn(),
            I18NHelper.getMessage(msgs, "EXC_CollectionElementTypeMismatch", //NOI18N
            typeSupport.getTypeName(valueTypeInfo),
            typeSupport.getTypeName(elementTypeInfo)));
        return typeSupport.errorType;
    }

    /**
     * Analyses whether paramAST can be associated to a ejbName.
     * @param paramAST AST node corresponds to a PARAMETER
     * @param ejbName name to be check with paramAST
     * @return the type info of typeSupport.booleanType or typeSupport.errorType
     */
    private Object analyseParameterEjbName(EJBQLAST paramAST, String ejbName)
    {
        if (isInputParameter(paramAST)) {
            String paramName = paramAST.getText();
            String paramEjbName = paramSupport.getParameterEjbName(paramName);
            if (paramEjbName != null && !paramEjbName.equals(ejbName)) {
                ErrorMsg.error(paramAST.getLine(), paramAST.getColumn(),
                    I18NHelper.getMessage(msgs,
                    "EXC_MultipleEJBNameParameter", // NOI18N
                    paramName, ejbName, paramEjbName));
                return typeSupport.errorType;
            } else {
                paramSupport.setParameterEjbName(paramName, ejbName);
            }
        }
        return typeSupport.booleanType;
    }
    
    /** 
     * Returns <code>true</code> if ast denotes a entity bena value.
     */
    private boolean isEntityBeanValue(EJBQLAST ast)
    {
        switch(ast.getType()) {
        case SINGLE_CMR_FIELD_ACCESS:
        case IDENTIFICATION_VAR:
            return true;
        case INPUT_PARAMETER:
            Object typeInfo = ast.getTypeInfo();
            return typeSupport.isEjbOrInterfaceName(typeInfo);
        }
        return false;
    }

    /** 
     * Returns <code>true</code> if ast denotes a literal.
     */
    private boolean isLiteral(EJBQLAST ast)
    {
        int tokenType = ast.getType();
        return ((tokenType == INT_LITERAL) || 
                (tokenType == LONG_LITERAL) ||
                (tokenType == STRING_LITERAL) || 
                (tokenType == FLOAT_LITERAL) || 
                (tokenType == DOUBLE_LITERAL) ||
                (tokenType == TRUE) || 
                (tokenType == FALSE));
    }

    /** 
     * Returns <code>true</code> if ast denotes a input parameter access.
     */
    private boolean isInputParameter(EJBQLAST ast)
    {
        return ast.getType() == INPUT_PARAMETER;
    }
    
    /**
     * The method checks the specified node being an expression of type String. 
     * @param expr the expression to be checked
     * @return <code>true</code> if the specified expression has the type String.
     */
    private boolean isStringExpr(EJBQLAST expr)
    {
        Object exprType = expr.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(exprType))
            return true;
        
        // expr must have the type String
        if (!typeSupport.isStringType(exprType)) {
            ErrorMsg.error(expr.getLine(), expr.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_StringExprExpected", //NOI18N
                    typeSupport.getTypeName(exprType)));
            return false;
        }
        
        // everything is ok => return true;
        return true;
    }

    /**
     * The method checks the specified node being an expression of 
     * type int or java.lang.Integer.
     * @param expr the expression to be checked
     * @return <code>true</code> if the specified expression has the type 
     * int or java.lang.Integer.
     */
    private boolean isIntExpr(EJBQLAST expr)
    {
        Object exprType = expr.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(exprType))
            return true;
        
        // expr must have the type int or Integer
        if (!typeSupport.isIntType(exprType)) {
            ErrorMsg.error(expr.getLine(), expr.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_IntExprExpected", //NOI18N
                    typeSupport.getTypeName(exprType)));
            return false;
        }
        
        // everything is ok => return true;
        return true;
    }

    /**
     * The method checks the specified node being an expression of 
     * type double or java.lang.Double.
     * @param expr the expression to be checked
     * @return <code>true</code> if the specified expression has the type 
     * double or java.lang.Double.
     */
    private boolean isDoubleExpr(EJBQLAST expr)
    {
        Object exprType = expr.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(exprType))
            return true;
        
        // expr must have the type double or Double
        if (!typeSupport.isDoubleType(exprType)) {
            ErrorMsg.error(expr.getLine(), expr.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_DoubleExprExpected", //NOI18N
                    typeSupport.getTypeName(exprType)));
            return false;
        }
        
        // everything is ok => return true;
        return true;
    }

    /**
     * The method checks the specified node being an expression of a number type
     * (a numeric type or a number wrapper class).
     * @param expr the expression to be checked
     * @return <code>true</code> if the specified expression has a number type.
     */
    private boolean isNumberExpr(EJBQLAST expr)
    {
        Object exprType = expr.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(exprType))
            return true;
        
        // expr must have a number type
        if (!typeSupport.isNumberType(exprType)) {
            ErrorMsg.error(expr.getLine(), expr.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_NumberExprExpected", //NOI18N
                    typeSupport.getTypeName(exprType)));
            return false;
        }
        
        // everything is ok => return true;
        return true;
    }

    /**
     * The method checks the specified node being an expression of a number type
     * (a numeric type or a number wrapper class).
     * @param expr the expression to be checked
     * @return <code>true</code> if the specified expression has a number or
     * String type 
     */
    private boolean isNumberOrStringExpr(EJBQLAST expr)
    {
        Object exprType = expr.getTypeInfo();
        
        // handle error type
        if (typeSupport.isErrorType(exprType))
            return true;
        
        // expr must have a number type
        if (!typeSupport.isNumberType(exprType) &&
                !typeSupport.isStringType(exprType)) {
            ErrorMsg.error(expr.getLine(), expr.getColumn(), 
                I18NHelper.getMessage(msgs,
                    "EXC_NumberOrStringExprExpected", //NOI18N
                    typeSupport.getTypeName(exprType)));
            return false;
        }
        
        // everything is ok => return true;
        return true;
    }

    /** 
     * The method checks whether the specified node denotes a valid abstract 
     * schema type.
     * @param ident the node to be checked
     * @return the type info for the abstract bean class of the specified 
     * abstract schema type.
     */
    private Object checkAbstractSchemaType(EJBQLAST ident)
    {
        String name = ident.getText();
        Object typeInfo = 
            typeSupport.getTypeInfoForAbstractSchema(name);
        if (typeInfo == null) {
            ErrorMsg.error(ident.getLine(), ident.getColumn(), 
                I18NHelper.getMessage(msgs, 
                    "EXC_AbstractSchemNameExpected", name)); //NOI18N
            typeInfo = typeSupport.errorType;
        }
        return typeInfo;
    }

    /**
     * Returns true if the specified text is a string literal consisting of a
     * single char. Escaped chars are counted as a single char such as \ uxxxx.
     */
    private boolean isSingleCharacterStringLiteral(String text)
    {
        int i = 0;
        int length = text.length();
        if (length == 0) {
            // empty string
            return false;
        }
        if (text.charAt(i) == '\\')
        {
            i++;
            if (i == length) {
                // string literal was '\'
                return true;
            }
            // escaped char => check the next char
            if (text.charAt(i) == 'u') {
                // unicode
                i +=5;
            }
            else if (('0' <= text.charAt(i)) && (text.charAt(i) <= '3')) {
                i++;
                if ((i < length) && isOctalDigit(text.charAt(i))) {
                    i++;
                    if ((i < length) && isOctalDigit(text.charAt(i))) {
                        i++;
                    }
                }
            }
            else if (isOctalDigit(text.charAt(i))) {
                i++;
                if ((i < length) && isOctalDigit(text.charAt(i))) {
                    i++;
                }
            }
            else {
                i++;
            }
        }
        else if (text.charAt(i) == '\''){
            // check special EJBQL single quote char
            i++;
            if ((i < length) && (text.charAt(i) == '\'')) {
                i++;
            }
        }
        else {
            i++;
        }
        // reached end of text?
        return (i == length);
    }

    /** Returns true if the specified char is an octal digit */
    private boolean isOctalDigit(char c)
    {
        return ('0' <= c && c <= '7');
    }

}

// rules

query
    :   #(QUERY fromClause s:selectClause whereClause o:orderbyClause)
        {
            checkSelectOrderbyClause(#s, #o);
        }
    ;

// ----------------------------------
// rules: from clause
// ----------------------------------

fromClause
    :   #( FROM ( identificationVarDecl )+ )
    ;

identificationVarDecl
    :   collectionMemberDecl
    |   rangeVarDecl
    ;

collectionMemberDecl
    :   #(IN p:collectionValuedPathExpression var:IDENT)
        {
            Object typeInfo = analyseCollectionValuedCMRField(#p);
            String name = #var.getText();
            Object identVar = new IdentificationVariable(name, typeInfo);
            if (symtab.declare(name, identVar) != null) {
                ErrorMsg.error(#var.getLine(), #var.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_MultipleDeclaration", name)); //NOI18N
            }
            #var.setType(IDENTIFICATION_VAR_DECL);
            #var.setTypeInfo(typeInfo);
        }
    ;

rangeVarDecl
    :   #(RANGE abstractSchemaName:ABSTRACT_SCHEMA_NAME var:IDENT)
        {
            // check abstract schema name
            Object typeInfo = 
                checkAbstractSchemaType(#abstractSchemaName);
            #abstractSchemaName.setTypeInfo(typeInfo);

            // check identification variable
            String name = #var.getText();
            Object identVar = new IdentificationVariable(name, typeInfo);
            if (symtab.declare(name, identVar) != null) {
                ErrorMsg.error(#var.getLine(), #var.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_MultipleDeclaration", name)); //NOI18N
            }
            #var.setType(IDENTIFICATION_VAR_DECL);
            #var.setTypeInfo(typeInfo);
        }
    ;

// ----------------------------------
// rules: select clause
// ----------------------------------

selectClause
    :   #( SELECT distinct p:projection )
        {
            Object selectClauseTypeInfo = #p.getTypeInfo();
            Class returnType = method.getReturnType();
            if (finderNotSelector) {
                checkFinderReturnType(returnType, selectClauseTypeInfo);
                checkFinderResultTypeMapping();
            }
            else {
                checkSelectorReturnType(returnType, selectClauseTypeInfo);
                checkSelectorResultTypeMapping(returnType, 
                                               selectClauseTypeInfo);
            }
        }
    ;

distinct
    :   DISTINCT
    |   // empty rule
        {
            // Insert DISTINCT keyword, in the case of a multi-object selector 
            // having java.util.Set as return type
            if (!finderNotSelector && 
                (method.getReturnType() == java.util.Set.class)) {
                #distinct = #[DISTINCT,"distinct"];
            }
        }
    ; 

projection
    :   singleValuedPathExpression
    |   #( o:OBJECT var:IDENT )
        {
            String name = #var.getText();
            Object decl = symtab.getDeclaration(name);
            Object typeInfo = null;
            if ((decl != null) && 
                (decl instanceof IdentificationVariable)) {
                #var.setType(IDENTIFICATION_VAR);
                typeInfo = ((IdentificationVariable)decl).getTypeInfo();
            }
            else {
                ErrorMsg.error(#var.getLine(), #var.getColumn(), 
                    I18NHelper.getMessage(msgs, 
                        "EXC_IdentificationVariableExcepted", name)); //NOI18N
            }
            #var.setTypeInfo(typeInfo);
            #o.setTypeInfo(typeInfo);
        }
    |   #( sum:SUM ( DISTINCT )? sumExpr:cmpPathExpression )
        {
            // check numeric type
            Object typeInfo = #sumExpr.getTypeInfo();
            if (!typeSupport.isNumberType(typeInfo) ||
                    typeSupport.isCharType(typeInfo)) {
                ErrorMsg.error(#sumExpr.getLine(), #sumExpr.getColumn(),
                    I18NHelper.getMessage(msgs,
                        "EXC_NumberExprExpected", //NO18N
                        typeSupport.getTypeName(typeInfo)));
            }
            #sum.setTypeInfo(typeSupport.getSumReturnType(typeInfo));
            isAggregate = true;
        }
    |   #( avg:AVG ( DISTINCT )? avgExpr:cmpPathExpression )
        {
            // check numeric type
            Object typeInfo = #avgExpr.getTypeInfo();
            if (!typeSupport.isNumberType(typeInfo) ||
                    typeSupport.isCharType(typeInfo)) {
                ErrorMsg.error(#avgExpr.getLine(), #avgExpr.getColumn(),
                    I18NHelper.getMessage(msgs,
                        "EXC_NumberExprExpected", //NO18N
                        typeSupport.getTypeName(typeInfo)));
            }
            #avg.setTypeInfo(typeSupport.getAvgReturnType(typeInfo));
            isAggregate = true;
        }
    |   #( min:MIN ( DISTINCT )? minExpr:cmpPathExpression )
        {
            // check orderable type
            Object typeInfo = #minExpr.getTypeInfo();
            if (!typeSupport.isOrderableType(typeInfo)) {
                ErrorMsg.error(#minExpr.getLine(), #minExpr.getColumn(),
                    I18NHelper.getMessage(msgs,
                        "EXC_OrderableExpected", //NO18N
                        typeSupport.getTypeName(typeInfo)));
            }
            #min.setTypeInfo(typeSupport.getMinMaxReturnType(typeInfo));
            isAggregate = true;
        }
    |   #( max:MAX ( DISTINCT )? maxExpr:cmpPathExpression )
        {
            // check orderable type
            Object typeInfo = #maxExpr.getTypeInfo();
            if (!typeSupport.isOrderableType(typeInfo)) {
                ErrorMsg.error(#maxExpr.getLine(), #maxExpr.getColumn(),
                    I18NHelper.getMessage(msgs,
                        "EXC_OrderableExpected", //NO18N
                        typeSupport.getTypeName(typeInfo)));
            }
            #max.setTypeInfo(typeSupport.getMinMaxReturnType(typeInfo));
            isAggregate = true;
        }
    |   #( c:COUNT ( DISTINCT )? countExpr )
        {
            #c.setTypeInfo(typeSupport.longClassType);
            isAggregate = true;
        }
    ;

countExpr
    :   v:IDENT
        {
            String name = #v.getText();
            Object decl = symtab.getDeclaration(name);
            Object typeInfo = null;
            if ((decl != null) && 
                (decl instanceof IdentificationVariable)) {
                #v.setType(IDENTIFICATION_VAR);
                typeInfo = ((IdentificationVariable)decl).getTypeInfo();
            }
            else {
                ErrorMsg.error(#v.getLine(), #v.getColumn(), 
                    I18NHelper.getMessage(msgs, 
                    "EXC_IdentificationVariableExcepted", name)); //NOI18N
            }
            #v.setTypeInfo(typeInfo);
        }
    |   singleValuedPathExpression
    ;

// ----------------------------------
// rules: where clause
// ----------------------------------

whereClause
    :   #( WHERE e:expression )
        {
            Object typeInfo = #e.getTypeInfo();
            if (!typeSupport.isBooleanType(typeInfo)) {
                ErrorMsg.error(#e.getLine(), #e.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_BooleanWhereClauseExpected",  //NOI18N
                        typeSupport.getTypeName(typeInfo)));
            }
        }
    ;

// ----------------------------------
// rules: order by clause
// ----------------------------------

orderbyClause
    :   #( ORDER ( orderbyItem )+ )
    |   // empty rule
    ;

orderbyItem
    :   expr:cmpPathExpression ( ASC | DESC )
        {
            // check orderable type
            Object typeInfo = #expr.getTypeInfo();
            if (!typeSupport.isOrderableType(typeInfo)) {
                ErrorMsg.error(#expr.getLine(), #expr.getColumn(),
                    I18NHelper.getMessage(msgs,
                        "EXC_OrderableOrderbyClauseExpected", //NO18N
                        typeSupport.getTypeName(typeInfo)));
            }
        }
    ;

// ----------------------------------
// rules: expression
// ----------------------------------

expression
    :   conditionalExpr
    |   relationalExpr
    |   binaryArithmeticExpr
    |   unaryExpr
    |   betweenExpr
    |   likeExpr
    |   inExpr
    |   nullComparisonExpr
    |   emptyCollectionComparisonExpr
    |   collectionMemberExpr
    |   function
    |   primary
    ;

conditionalExpr
    :   #( op1:AND left1:expression right1:expression )
        {
            #op1.setTypeInfo(analyseConditionalExpr(#op1, #left1, #right1));
        }
    |   #( op2:OR  left2:expression right2:expression )
        {
            #op2.setTypeInfo(analyseConditionalExpr(#op2, #left2, #right2));
        }
    ;

relationalExpr
    :   #( op1:EQUAL left1:expression right1:expression )
        {
            #op1.setTypeInfo(analyseEqualityExpr(#op1, #left1, #right1));
        }
    |   #( op2:NOT_EQUAL left2:expression right2:expression )
        {
            #op2.setTypeInfo(analyseEqualityExpr(#op2, #left2, #right2));
        }
    |   #( op3:LT left3:expression right3:expression )
        {
            #op3.setTypeInfo(analyseRelationalExpr(#op3, #left3, #right3));
        }
    |   #( op4:LE left4:expression right4:expression )
        {
            #op4.setTypeInfo(analyseRelationalExpr(#op4, #left4, #right4));
        }
    |   #( op5:GT left5:expression right5:expression )
        {
            #op5.setTypeInfo(analyseRelationalExpr(#op5, #left5, #right5));
        }
    |   #( op6:GE left6:expression right6:expression )
        {
            #op6.setTypeInfo(analyseRelationalExpr(#op6, #left6, #right6));
        }
    ;

binaryArithmeticExpr
    :   #( op1:PLUS left1:expression right1:expression )
        {
            #op1.setTypeInfo(analyseBinaryArithmeticExpr(#op1, #left1, #right1));
        }
    |   #( op2:MINUS left2:expression right2:expression )
        {
            #op2.setTypeInfo(analyseBinaryArithmeticExpr(#op2, #left2, #right2));
        }
    |   #( op3:STAR left3:expression right3:expression )
        {
            #op3.setTypeInfo(analyseBinaryArithmeticExpr(#op3, #left3, #right3));
        }
    |   #( op4:DIV left4:expression right4:expression )
        {
            #op4.setTypeInfo(analyseBinaryArithmeticExpr(#op4, #left4, #right4));
        }
    ;

unaryExpr
    :   #( op1:UNARY_PLUS arg1:expression )
        {
            #op1.setTypeInfo(analyseUnaryArithmeticExpr(#op1, #arg1));
        }
    |   #( op2:UNARY_MINUS arg2:expression )
        {
            #op2.setTypeInfo(analyseUnaryArithmeticExpr(#op2, #arg2));
        }
    |   #( op3:NOT arg3:expression )
        {
            Object typeInfo = typeSupport.errorType;
            Object arg = #arg3.getTypeInfo();
            if (typeSupport.isErrorType(arg))
                typeInfo = typeSupport.errorType;
            else if (typeSupport.isBooleanType(arg))
                typeInfo = arg;
            else {
                ErrorMsg.error(#op3.getLine(), #op3.getColumn(), 
                    I18NHelper.getMessage(msgs, "EXC_InvalidArguments", //NOI18N
                        #op3.getText())); 
            }
            #op3.setTypeInfo(typeInfo);
        }
    ;

betweenExpr 
    :   #( op1:BETWEEN expr1:expression lower1:expression upper1:expression )
        {
            #op1.setTypeInfo((isNumberExpr(#expr1) && isNumberExpr(#lower1) && isNumberExpr(#upper1)) ? 
                typeSupport.booleanType : typeSupport.errorType);
        }
    |   #( op2:NOT_BETWEEN expr2:expression lower2:expression upper2:expression )
        {
            #op2.setTypeInfo((isNumberExpr(#expr2) && isNumberExpr(#lower2) && isNumberExpr(#upper2)) ? 
                typeSupport.booleanType : typeSupport.errorType);
        }
    ;

likeExpr
    :   #( op1:LIKE expr1:cmpPathExpression pattern escape )
        {
            #op1.setTypeInfo(isStringExpr(#expr1) ? 
                typeSupport.booleanType : typeSupport.errorType);
        }
    |   #( op2:NOT_LIKE expr2:cmpPathExpression pattern escape )
        {
            #op2.setTypeInfo(isStringExpr(#expr2) ? 
                typeSupport.booleanType : typeSupport.errorType);
        }
    ;

pattern
    :   STRING_LITERAL 
    |   p:inputParameter
        {
            if (!typeSupport.isStringType(#p.getTypeInfo())) {
                ErrorMsg.error(#p.getLine(), #p.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_InvalidPatternDefinition",
                        #p.getText())); //NOI18N
            }
        }
    ;

escape
    :   #( ESCAPE escapeCharacter )
    |   // empty rule
    ;

escapeCharacter
    :   s:STRING_LITERAL
        {
            String literal = #s.getText();
            // String must be single charater string literal =>
            // either '<char>' or ''''
            if (!isSingleCharacterStringLiteral(#s.getText())) {
                ErrorMsg.error(#s.getLine(), #s.getColumn(),
                    I18NHelper.getMessage(msgs, 
                        "EXC_InvalidEscapeDefinition", #s.getText())); //NOI18N
            }
        }
    |   p:inputParameter
        {
            Object paramType = #p.getTypeInfo();
            if (!typeSupport.isCharType(paramType)) {
                ErrorMsg.error(#p.getLine(), #p.getColumn(),
                    I18NHelper.getMessage(msgs, 
                        "EXC_InvalidEscapeParameterDefinition", #p.getText())); //NOI18N
            }
        }
    ;

inExpr
    :   #( op1:IN expr1:cmpPathExpression inCollection[#expr1.getTypeInfo()] )
        {
            #op1.setTypeInfo(isNumberOrStringExpr(#expr1) ? 
                typeSupport.booleanType : typeSupport.errorType);
        }
    |   #( op2:NOT_IN expr2:cmpPathExpression inCollection[#expr2.getTypeInfo()] )
        {
            #op2.setTypeInfo(isNumberOrStringExpr(#expr2) ? 
                typeSupport.booleanType : typeSupport.errorType);
        }
    ;

nullComparisonExpr
    :   #( op1:NULL ( singleValuedPathExpression | inputParameter ) )
        {
            #op1.setTypeInfo(typeSupport.booleanType);
        }
    |   #( op2:NOT_NULL ( singleValuedPathExpression | inputParameter ) )
        {
            #op2.setTypeInfo(typeSupport.booleanType);
        }
    ;

emptyCollectionComparisonExpr
{ 
    Object elementTypeInfo = null; 
}
    :   #( op1:EMPTY col1:collectionValuedPathExpression )
        {
            elementTypeInfo = analyseCollectionValuedCMRField(#col1);
            #op1.setTypeInfo(typeSupport.isErrorType(elementTypeInfo) ? 
                typeSupport.errorType : typeSupport.booleanType );
        }
    |   #( op2:NOT_EMPTY col2:collectionValuedPathExpression )
        {
            elementTypeInfo = analyseCollectionValuedCMRField(#col2);
            #op2.setTypeInfo(typeSupport.isErrorType(elementTypeInfo) ? 
                typeSupport.errorType : typeSupport.booleanType );
        }
    ;

collectionMemberExpr
    :   #( op1:MEMBER value1:member col1:collectionValuedPathExpression )
        {
            #op1.setTypeInfo(analyseMemberExpr(#op1, #value1, #col1));
        }
    |   #( op2:NOT_MEMBER value2:member col2:collectionValuedPathExpression )
        {
            #op2.setTypeInfo(analyseMemberExpr(#op2, #value2, #col2));
        }
    ;

member
    :   identificationVariable
    |   inputParameter
    |   singleValuedCmrPathExpression
    ;

function
    :   concat
    |   substring
    |   length
    |   locate
    |   abs
    |   sqrt
    |   mod
    ;

concat
    :   #( op:CONCAT arg1:expression arg2:expression )
        {
            #op.setTypeInfo((isStringExpr(#arg1) && isStringExpr(#arg2)) ?
                typeSupport.stringType : typeSupport.errorType);
        }
    ;

substring
    :   #( op:SUBSTRING arg1:expression arg2:expression arg3:expression )
        {
            #op.setTypeInfo((isStringExpr(#arg1) && isIntExpr(#arg2) && isIntExpr(#arg3)) ? 
                typeSupport.stringType : typeSupport.errorType);
        }
    ;

length
    :   #( op:LENGTH arg:expression )
        {
            #op.setTypeInfo(isStringExpr(#arg) ? 
                typeSupport.intType : typeSupport.errorType);
        }
    ;

locate
    :   #( op:LOCATE arg1:expression arg2:expression ( arg3:expression )? )
        {
            #op.setTypeInfo((isStringExpr(#arg1) && isStringExpr(#arg2) && 
                             ((#arg3 == null) || isIntExpr(#arg3))) ?
                typeSupport.intType : typeSupport.errorType);
        }
    ;

abs
    :   #( op:ABS expr:expression )
        {
            #op.setTypeInfo(isNumberExpr(#expr) ? 
                #expr.getTypeInfo() : typeSupport.errorType);
        }
    ;

sqrt
    :   #( op:SQRT expr:expression )
        {
            #op.setTypeInfo(isDoubleExpr(#expr) ? 
                #expr.getTypeInfo() : typeSupport.errorType);
        }
    ;

mod
    :   #( op:MOD arg1:expression arg2:expression )
        {
            #op.setTypeInfo((isIntExpr(#arg1) && isIntExpr(#arg2)) ? 
                typeSupport.intType : typeSupport.errorType);
        }
    ;

primary
    :   literal
    |   singleValuedPathExpression
    |   identificationVariable
    |   inputParameter
    ;

literal
    :   b1:TRUE          { #b1.setTypeInfo(typeSupport.booleanType); }
    |   b2:FALSE         { #b2.setTypeInfo(typeSupport.booleanType); }
    |   s:STRING_LITERAL { #s.setTypeInfo(typeSupport.stringType); }
    |   i:INT_LITERAL    { #i.setTypeInfo(typeSupport.intType); }
    |   l:LONG_LITERAL   { #l.setTypeInfo(typeSupport.longType); }
    |   f:FLOAT_LITERAL  { #f.setTypeInfo(typeSupport.floatType); }
    |   d:DOUBLE_LITERAL { #d.setTypeInfo(typeSupport.doubleType); }
    ;

pathExpression
    :   #(  dot:DOT  o:objectDenoter i:IDENT )
        {
            String fieldName = #i.getText();
            Object typeInfo = #o.getTypeInfo();
            Object fieldTypeInfo = 
                typeSupport.getFieldType(typeInfo, fieldName);
            if (fieldTypeInfo == null) {
                // field is not known
                ErrorMsg.error(#i.getLine(), #i.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_UnknownField", fieldName, //NOI18N
                        typeSupport.getAbstractSchemaForTypeInfo(typeInfo)));
                fieldTypeInfo = typeSupport.errorType;
            }
            else {
                Object fieldInfo = typeSupport.getFieldInfo(typeInfo, fieldName);
                if (fieldInfo == null) {
                    ErrorMsg.fatal(I18NHelper.getMessage(msgs, 
                            "ERR_MissingFieldInfo",  //NOI18N
                            fieldName, typeSupport.getTypeName(typeInfo)));
                }
                if (!typeSupport.isRelationship(fieldInfo)) {
                    // field is not a relationship => cmp field
                    #i.setType(CMP_FIELD);
                    #dot.setType(CMP_FIELD_ACCESS);
                }
                else if (typeSupport.isCollectionType(fieldTypeInfo)) {
                    // field is a relationship of a collection type =>
                    // collection valued cmr field
                    #i.setType(COLLECTION_CMR_FIELD);
                    #dot.setType(COLLECTION_CMR_FIELD_ACCESS);
                }
                else {
                    // field is a relationship of a non collection type =>
                    // single valued cmr field
                    #i.setType(SINGLE_CMR_FIELD);
                    #dot.setType(SINGLE_CMR_FIELD_ACCESS);
                }
            }
            #dot.setTypeInfo(fieldTypeInfo);
            #i.setTypeInfo(fieldTypeInfo);
        }

    ;

objectDenoter
    :   identificationVariable
    |   singleValuedCmrPathExpression
    ;

identificationVariable
    :   i:IDENT 
        {
            String name = #i.getText();
            Object decl = symtab.getDeclaration(name);
            // check for identification variables
            if ((decl != null) && (decl instanceof IdentificationVariable)) {
                #i.setType(IDENTIFICATION_VAR);
                #i.setTypeInfo(((IdentificationVariable)decl).getTypeInfo());
            }
            else {
                #i.setTypeInfo(typeSupport.errorType);
                ErrorMsg.error(#i.getLine(), #i.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_UndefinedIdentifier", name)); //NOI18N
                        
            }
        }
    ;

singleValuedPathExpression
    :   p:pathExpression
        {
            int fieldTokenType = #p.getType();
            if ((fieldTokenType != SINGLE_CMR_FIELD_ACCESS) && 
                (fieldTokenType != CMP_FIELD_ACCESS)) {
                EJBQLAST classExpr = (EJBQLAST)#p.getFirstChild();
                EJBQLAST field = (EJBQLAST)classExpr.getNextSibling();
                ErrorMsg.error(field.getLine(), field.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_SingleValuedCMROrCMPFieldExpected", //NOI18N
                        field.getText(), typeSupport.getTypeName(field.getTypeInfo())));
                #p.setType(SINGLE_CMR_FIELD_ACCESS);
            }
        }
    ;

cmpPathExpression
    :   p:pathExpression
        {
            int fieldTokenType = #p.getType();
            if ((fieldTokenType != CMP_FIELD_ACCESS)) {
                EJBQLAST classExpr = (EJBQLAST)#p.getFirstChild();
                EJBQLAST field = (EJBQLAST)classExpr.getNextSibling();
                ErrorMsg.error(field.getLine(), field.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_CMPFieldExpected", //NOI18N
                        field.getText(), typeSupport.getTypeName(field.getTypeInfo())));
                #p.setType(CMP_FIELD_ACCESS);
            }
        }
    ;

singleValuedCmrPathExpression
    :   p:pathExpression
        {
            int fieldTokenType = #p.getType();
            if (fieldTokenType != SINGLE_CMR_FIELD_ACCESS) {
                EJBQLAST classExpr = (EJBQLAST)#p.getFirstChild();
                EJBQLAST field = (EJBQLAST)classExpr.getNextSibling();
                ErrorMsg.error(field.getLine(), field.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_SingleValuedCMRFieldExpected", //NOI18N
                        field.getText(), typeSupport.getTypeName(field.getTypeInfo())));
                #p.setType(COLLECTION_CMR_FIELD_ACCESS);
            }
        }
    ;

collectionValuedPathExpression
    :   p:pathExpression
        {
            int fieldTokenType = #p.getType();
            if (fieldTokenType != COLLECTION_CMR_FIELD_ACCESS) {
                EJBQLAST classExpr = (EJBQLAST)#p.getFirstChild();
                EJBQLAST field = (EJBQLAST)classExpr.getNextSibling();
                ErrorMsg.error(field.getLine(), field.getColumn(),
                    I18NHelper.getMessage(msgs, "EXC_CollectionValuedCMRFieldExpected", //NOI18N
                        field.getText(), typeSupport.getTypeName(field.getTypeInfo())));
                #p.setType(COLLECTION_CMR_FIELD_ACCESS);
            }
        }
    ;

inCollection [Object valueExprTypeInfo]
    :   ( inCollectionElement[valueExprTypeInfo] )+
    ;

inCollectionElement [Object valueExprTypeInfo]
    :   l:literal
        {
            l.setTypeInfo(analyseInCollectionElement(#l, valueExprTypeInfo));
        }
    |   i:inputParameter
        {
            i.setTypeInfo(analyseInCollectionElement(#i, valueExprTypeInfo));
        }
    ;

inputParameter
    :   param:INPUT_PARAMETER
        {
            Object typeInfo = typeSupport.getTypeInfo(
                paramSupport.getParameterType(#param.getText()));
            #param.setTypeInfo(typeInfo);
        }
    ;

