/*
 * 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
 */

/*
 * JDOQLCodeGeneration.g
 *
 * Created on Decemember 10, 2001
 */

header
{
    package com.sun.jdo.spi.persistence.support.ejb.ejbqlc;
    
    import java.util.ResourceBundle;
    import org.glassfish.persistence.common.I18NHelper;
    import com.sun.jdo.spi.persistence.utility.StringHelper;
}

/**
 * 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 JDOQLCodeGeneration extends TreeParser;

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

{
    /** Type helper. */
    protected TypeSupport typeSupport;
    
    /** Parameter helper. */
    protected ParameterSupport paramSupport;
    
    /** I18N support. */
    protected final static ResourceBundle msgs = 
        I18NHelper.loadBundle(JDOQLCodeGeneration.class);
    
    /** The identification variable used for the candidate class. */
    private String candidateClassIdentificationVar;

    /** The name of the candidate class. */
    private String candidateClassName;

    /** The parameter declarations. */
    private StringBuffer parameterDecls;

    /** The variable declarations. */
    private StringBuffer variableDecls;

    /** The filter expression. */
    private StringBuffer filter;

    /** The ordering expression. */
    private StringBuffer ordering;

    /** The result expression. */
    private StringBuffer result;

    /** The result type. */
    private String resultType;

    /** Flag indicating whether the result element is a pc class. */
    private boolean isPCResult;

    /**
     *  Flag indicating whether the result element is associated to an
     *  aggregate function.
     */
    private boolean isAggregate = false;

    /** Counter for variables defined during codegen. */
    private int tmpVarCount = 0;

    /** 
     * Counter indicating how many parenthesis need to be closed 
     * at the end of the filter expr. 
     */
    private int parenCount = 0;
    
    /** Flag indicates whether the select clause has DISTINCT. */
    private boolean isDistinct = false;

    /**
     *
     */
    public void init(TypeSupport typeSupport, ParameterSupport paramSupport)
    {
        this.typeSupport = typeSupport;
        this.paramSupport = paramSupport;
    }

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

    /** */
    public void reportError(String s) {
        ErrorMsg.fatal(I18NHelper.getMessage(msgs, 
                "ERR_JDOQLCodeGenerationError") + s); //NOI18N
    }

    /** 
     * Returns the result of an EJBQL compile process. 
     * A JDOQLElements instances represents all the necessary information to 
     * create a JDOQL query instance that corresponds to the EJBQL query.
     * @return JDOQLElements instance representing the JDOQL query.
     */
    public JDOQLElements getJDOQLElements()
    {

        return new JDOQLElements(candidateClassName, parameterDecls.toString(),
            variableDecls.toString(), filter.toString(), ordering.toString(),
            result.toString(), resultType, isPCResult, isAggregate,
            paramSupport.getParameterEjbNames());
    }

    //========= Internal helper methods ==========

    /**
     * Extracts the name of the candidate class of the JDOQL query from the 
     * select- and from-clause of the EJBQL query.
     */
    private void handleCandidateClass(EJBQLAST query)
        throws RecognitionException
    {
        EJBQLAST from = (EJBQLAST)query.getFirstChild();
        EJBQLAST select = (EJBQLAST)from.getNextSibling();
        EJBQLAST var = null;
        var = extractIdentificationVariable(select);
        var = getIdentificationVarDecl(from, var.getText());
        candidateClassIdentificationVar = var.getText();
        candidateClassName = 
            typeSupport.getPCForTypeInfo(var.getTypeInfo());
    }

    /** 
     * Calculates the parameter declarations of the JDOQL query from the 
     * signature of the EJB finsder or selector method.
     */
    private void initParameterDeclarations()
    {
        parameterDecls = new StringBuffer();
        for (int i = 1; i <= paramSupport.getParameterCount(); i++) {
            String name = paramSupport.getParameterName(i);
            Object type = typeSupport.getTypeInfo(paramSupport.getParameterType(i));
            String ejbName = paramSupport.getParameterEjbName(i);
            String pcClassName = null;
            if (ejbName != null) {
                pcClassName = typeSupport.getPCForTypeInfo(ejbName);
            } else if (typeSupport.isLocalInterface(type) ||
                    typeSupport.isRemoteInterface(type)) {
                // This parameter corresponds to an EJB but the ejbName 
                // cannot be determined from query.
                // Since different EJBs may have the same interfaces,
                // the explicit pcClassName cannot be determined.
                pcClassName = "java.lang.Object";
            } else {
                pcClassName = typeSupport.getPCForTypeInfo(type);
            }

            parameterDecls.append(pcClassName);
            parameterDecls.append(" "); //NOI18N
            parameterDecls.append(name);
            parameterDecls.append(", "); //NOI18N
        }
    }

    /** 
     * EJBQL string literals escape a single quote using two single quotes. 
     * In JDOQL string literals single quotes need not to be escaped => 
     * replace '' by '.
     */
    private String convertStringLiteral(String ejbqlStringLiteral)
    {
        // first replace '' by '
        String ret = StringHelper.replace(ejbqlStringLiteral, "''", "'"); //NOI18N
        // Add a hack for a backslash at the end of the literal
        // Note, we might need to escape backslashes in the entire string 
        // literal, if the character following the backslash is an "escaped" 
        // char such as \n, \n, etc. Needs some further investigation.
        if (ret.endsWith("\\")) {
            ret = ret + "\\";
        }
        return ret;
    }
    
    /** */
    private EJBQLAST getIdentificationVarDecl(EJBQLAST from, String varName)
        throws RecognitionException
    {
        // iterate all identification var declarations
        for (EJBQLAST varDecl = (EJBQLAST)from.getFirstChild();
            varDecl != null;
            varDecl = (EJBQLAST)varDecl.getNextSibling()) {
            // domain of the current variable declaration
            EJBQLAST domain = (EJBQLAST)varDecl.getFirstChild();
            // identification variable node
            EJBQLAST varNode = (EJBQLAST)domain.getNextSibling();
            if (varNode.getText().equalsIgnoreCase(varName)) {
                // found the declaration node of the variable we are looking for
                if (domain.getType() == ABSTRACT_SCHEMA_NAME)
                    // the domain is a abstract schema type => found the var decl
                    return varNode;
                else
                    // domain is a collectionMemberDecl => use its var decl
                    return getIdentificationVarDecl(from, 
                        extractIdentificationVariable(domain).getText());
            }
        }
        return null;
    }

    /** 
     * Returns the name of a new variable of the JDOQL query.
     */
    private String getTmpVarName()
    {
        // TBD: The name must not conflict with a defined identification variable
        int no = tmpVarCount++;
        return "_jdoVar" + no; //NOI18N
    }
    
    /**
     * Returns the typeInfo of the element type of a collection valued CMR field.
     */
    private Object getElementTypeOfCollectionValuedCMR(EJBQLAST cmrFieldAccess)
    {
        EJBQLAST classExpr = (EJBQLAST)cmrFieldAccess.getFirstChild();
        EJBQLAST cmrField = (EJBQLAST)classExpr.getNextSibling();
        Object fieldInfo = typeSupport.getFieldInfo(
            classExpr.getTypeInfo(), cmrField.getText());
        return typeSupport.getElementType(fieldInfo);
    }
    
}

// rules

query
    :   #(  q:QUERY 
            {
                initParameterDeclarations();
                variableDecls = new StringBuffer();
                filter = new StringBuffer();
                ordering = new StringBuffer();
                result = new StringBuffer();
                handleCandidateClass(q);
            }
            fromClause 
            selectClause 
            whereClause
            orderbyClause
        )
    ;

extractIdentificationVariable returns [EJBQLAST var]
    :   #( SELECT ( DISTINCT )? var = extractIdentificationVariable )
    |   #( CMP_FIELD_ACCESS var = extractIdentificationVariable . )
    |   #( SINGLE_CMR_FIELD_ACCESS var = extractIdentificationVariable . )
    |   #( COLLECTION_CMR_FIELD_ACCESS var = extractIdentificationVariable . )
    |   #( OBJECT var = extractIdentificationVariable )
    |   #( AVG ( DISTINCT )? var = extractIdentificationVariable )
    |   #( MAX ( DISTINCT )? var = extractIdentificationVariable )
    |   #( MIN ( DISTINCT )? var = extractIdentificationVariable )
    |   #( SUM ( DISTINCT )? var = extractIdentificationVariable )
    |   #( COUNT ( DISTINCT )? var = extractIdentificationVariable )
    |   i:IDENTIFICATION_VAR { var = i; }
    ;

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

fromClause
    :   #( FROM ( identificationVarDecl )+ )
    ;

identificationVarDecl
    :   collectionMemberDecl
    |   rangeVarDecl
    ;

collectionMemberDecl
    :   #(  IN 
            {
                if (filter.length() > 0) {
                    // Please note, the FROM clause is processed prior to the 
                    // WHERE clause, so a filter of length == 0 means we are 
                    // processing the first IN clause of the FROM clause.
                    // We need to add an & operator and an open parenthesis for 
                    // all IN clauses but the first one. The parenthesis ensure 
                    // the resulting filter is portable, meaning the contains 
                    // clause must be the left expression of an AND-expression 
                    // where the variable is used in the right expression. 
                    filter.append(" & ("); //NOI18N
                    parenCount++;
                }
            }
            pathExpr[filter]
            v:IDENTIFICATION_VAR_DECL
            {
                // generate varibale declaration
                variableDecls.append(typeSupport.getPCForTypeInfo(
                        v.getTypeInfo()));
                variableDecls.append(' ');
                variableDecls.append(v.getText());
                variableDecls.append("; "); //NOI18N
                // now generate the contains clause
                filter.append(".contains("); //NOI18N
                filter.append(v.getText()); 
                filter.append(')');
            }
        )
    ;

rangeVarDecl
    :   #(  RANGE 
            ABSTRACT_SCHEMA_NAME 
            v:IDENTIFICATION_VAR_DECL
        )
        {
            // Do not generate variable decl for identification variable 
            // that represents the candidate class
            if (!v.getText().equalsIgnoreCase(candidateClassIdentificationVar)) {
                variableDecls.append(typeSupport.getPCForTypeInfo(
                        v.getTypeInfo()));
                variableDecls.append(' ');
                variableDecls.append(v.getText());
                variableDecls.append("; "); //NOI18N
            }
        }
    ;

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

selectClause
    :   #(  SELECT distinct[result] p:projection[result] )
        {
            isPCResult = typeSupport.isEjbName(p.getTypeInfo());
            resultType = isPCResult ? 
                typeSupport.getPCForTypeInfo(p.getTypeInfo()) :
                typeSupport.getTypeName(p.getTypeInfo());
        }
    ;

distinct[StringBuffer buf]
    :   // the code generation of this distinct is postponed until projection
        // checking as there is no need to generate distinct outside
        // aggregate functions
        DISTINCT { isDistinct = true; }
    |   // empty rule
    ;

aggregateDistinct[StringBuffer buf]
    :   DISTINCT { buf.append("distinct "); } //NOI18N
    |   // empty rule
    ;

projection[StringBuffer buf]
    :   #( AVG
            {
                isAggregate = true;
                buf.append("avg(");
            }
            aggregateDistinct[buf] pathExpr[buf]
            { buf.append(")"); }
        )
    |   #( MAX
            {
                isAggregate = true;
                buf.append("max(");
            }
            aggregateDistinct[buf] p:pathExpr[buf]
            { buf.append(")"); }
        )
    |   #( MIN
            {
                isAggregate = true;
                buf.append("min(");
            }
            aggregateDistinct[buf] pathExpr[buf]
            { buf.append(")"); }
        )
    |   #( SUM
            {
                isAggregate = true;
                buf.append("sum(");
            }
            aggregateDistinct[buf] pathExpr[buf]
            { buf.append(")"); }
        )
    |   #( COUNT
            {
                isAggregate = true;
                buf.append("count(");
            }
            aggregateDistinct[buf] pathExpr[buf]
            { buf.append(")"); }
        )
    |   {
            if (isDistinct) {
                buf.append("distinct "); //NOI18N
            }
        }
        pathExpr[buf]
    |   {
            if (isDistinct) {
                buf.append("distinct "); //NOI18N
            }
        }
        #( o:OBJECT pathExpr[buf] ) 
    ;

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

whereClause
    :   #(  WHERE 
            {
                if (filter.length() > 0) {
                    filter.append(" & ("); //NOI18N
                    // filter.length() > 0 means there are one or more contains 
                    // clauses generated from parsing the from clause => 
                    // enclose the where clause expression into parenthesis.
                    parenCount++;
                }
            }
            expression[filter]
            {
                while (parenCount > 0) {
                    filter.append(")"); //NOI18N
                    parenCount--;
                }
            }
        )
    ;

// ----------------------------------
// rules: orderby clause
// ----------------------------------

orderbyClause
    :   #(  ORDER
                (
                    {
                        if (ordering.length() > 0) {
                            ordering.append(", ");  
                        }
                    }
                    pathExpr[ordering]
                    ( 
                        ASC { ordering.append(" ascending"); } //NOI18N
                        |
                        DESC { ordering.append(" descending"); } //NOI18N
                    )
                )+
        )
    |
    ;

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

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

conditionalExpr[StringBuffer buf]
    :   #(  AND             { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" & "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  OR              { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" | "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    ;

relationalExpr[StringBuffer buf]
    :   #(  EQUAL           { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" == "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  NOT_EQUAL       { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" != "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  LT              { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" < "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  LE              { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" <= "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  GT              { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" > "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  GE              { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" >= "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    ;

binaryArithmeticExpr[StringBuffer buf]
    :   #(  PLUS            { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" + "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  MINUS           { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" - "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  STAR            { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" * "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  DIV             { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" / "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    ;

unaryExpr[StringBuffer buf]
    :   #(  UNARY_PLUS
            expression[buf]
        )
    |   #(  UNARY_MINUS     { buf.append(" -("); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    |   #(  NOT             { buf.append(" !("); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N
        )
    ;

betweenExpr[StringBuffer buf]
{
    StringBuffer tmp = new StringBuffer();
}
    :   #(  BETWEEN
            expression[tmp]
            {   
                buf.append('('); 
                buf.append(tmp.toString()); 
                buf.append(" >= "); // NOI18N
            }
            expression[buf]
            { 
                buf.append(" & "); // NOI18N
                buf.append(tmp.toString());  
                buf.append(" <= "); // NOI18N
            }
            expression[buf]
            {   buf.append(')'); }
        )
    |   #(  NOT_BETWEEN
            expression[tmp]
            {   
                buf.append('('); 
                buf.append(tmp.toString()); 
                buf.append(" < "); // NOI18N
            }
            expression[buf]
            { 
                buf.append(" | "); // NOI18N
                buf.append(tmp.toString());  
                buf.append(" > "); // NOI18N
            }
            expression[buf]
            {   buf.append(')'); }
        )
    ;

likeExpr[StringBuffer buf]
    :   #(  LIKE 
            expression[buf]     { buf.append(".like("); } //NOI18N
            ( stringLiteral[buf] | parameter[buf] )
            escape[buf]         { buf.append(')'); }
        )
    |   #(  NOT_LIKE            { buf.append('!'); }
            expression[buf]     { buf.append(".like("); } //NOI18N
            ( stringLiteral[buf] | parameter[buf] )
            escape[buf]         { buf.append(')'); }
        )
    ;

escape[StringBuffer buf]
    :   #(  ESCAPE { buf.append (", "); } //NOI18N
            ( singleCharStringLiteral[buf] | parameter[buf] ) )
    |   // empty rule
    ;

singleCharStringLiteral[StringBuffer buf]
    :   s:STRING_LITERAL  
        {
            buf.append('\'');
            buf.append(convertStringLiteral(s.getText())); 
            buf.append('\'');
        }
    ;

inExpr[StringBuffer buf]
{
    StringBuffer expr = new StringBuffer();
    StringBuffer elementExpr = new StringBuffer();
}
    :   #(  IN 
            expression[expr]  
            { buf.append('('); } 
            primary[elementExpr]
            { 
                buf.append('(');
                buf.append(expr.toString());
                buf.append(" == "); //NOI18N
                buf.append(elementExpr.toString());
                buf.append(')');
            }
            (   
                {   
                    // create a new StringBuffer for the new elementExpr
                    elementExpr = new StringBuffer(); 
                }
                primary[elementExpr] 
                {
                    buf.append(" | "); //NOI18N
                    buf.append('(');
                    buf.append(expr.toString());
                    buf.append(" == "); //NOI18N
                    buf.append(elementExpr.toString());
                    buf.append(')');
                }
            )*
            {
                buf.append(')'); 
            }
        )
    |   #(  NOT_IN 
            expression[expr]
            { buf.append('('); } 
            primary[elementExpr]
            { 
                buf.append('(');
                buf.append(expr.toString());
                buf.append(" != "); //NOI18N
                buf.append(elementExpr.toString());
                buf.append(')');
            }
            (               
                {   
                    // create a new StringBuffer for the new elementExpr
                    elementExpr = new StringBuffer(); 
                }
                primary[elementExpr] 
                {
                    buf.append(" & "); //NOI18N
                    buf.append('(');
                    buf.append(expr.toString());
                    buf.append(" != "); //NOI18N
                    buf.append(elementExpr.toString());
                    buf.append(')');
                }
            )*
            {
                buf.append(')'); 
            }
        )
    ;

nullComparisonExpr[StringBuffer buf]
    :   #(  NULL 
            expression[buf] { buf.append(" == null"); } //NOI18N
        )
    |   #(  NOT_NULL 
            expression[buf] { buf.append(" != null"); } //NOI18N
        )
    ;

emptyCollectionComparisonExpr[StringBuffer buf]
    :   #(  EMPTY 
            expression[buf] { buf.append(".isEmpty()"); } //NOI18N
        )
    |   #(  NOT_EMPTY       { buf.append("!"); } //NOI18N
            expression[buf] { buf.append(".isEmpty()"); } //NOI18N
        )
    ;

collectionMemberExpr[StringBuffer buf]
{
    StringBuffer member = new StringBuffer();
    StringBuffer col = new StringBuffer();
}
    :   #(  MEMBER 
            expression[member]
            cmrAccess1:expression[col]
            { 
                String varName = getTmpVarName();
                // Use the element type as variable type. The value might be 
                // an input parameter of a local/remote interface which we 
                // cannot uniquely map to a PC class during deployment.
                Object varType = getElementTypeOfCollectionValuedCMR(cmrAccess1);
                // generate varibale declaration
                variableDecls.append(typeSupport.getPCForTypeInfo(varType));
                variableDecls.append(' ');
                variableDecls.append(varName);
                variableDecls.append("; "); //NOI18N
                buf.append("("); //NOI18N
                buf.append(col.toString());
                buf.append(".contains(");  //NOI18N
                buf.append(varName);
                buf.append(") & "); //NOI18N
                buf.append(varName);
                buf.append(" == "); //NOI18N
                buf.append(member.toString());
                buf.append(")"); //NOI18N
            }
        )
    |   #(  NOT_MEMBER 
            expression[member]
            cmrAccess2:expression[col]
            { 
                String varName = getTmpVarName();
                // Use the element type as variable type. The value might be 
                // an input parameter of a local/remote interface which we 
                // cannot uniquely map to a PC class during deployment.
                Object varType = getElementTypeOfCollectionValuedCMR(cmrAccess2);
                // generate varibale declaration
                variableDecls.append(typeSupport.getPCForTypeInfo(varType));
                variableDecls.append(' ');
                variableDecls.append(varName);
                variableDecls.append("; "); //NOI18N
                buf.append("("); //NOI18N
                buf.append(col.toString());
                buf.append(".isEmpty() | (!(");  //NOI18N
                buf.append(col.toString());
                buf.append(".contains(");  //NOI18N
                buf.append(varName);
                buf.append(") & "); //NOI18N
                buf.append(varName);
                buf.append(" == "); //NOI18N
                buf.append(member.toString());
                buf.append(")))"); //NOI18N
            }
        )
    ;

function[StringBuffer buf]
    :   concat[buf]
    |   substring[buf]
    |   length[buf]
    |   locate[buf]
    |   abs[buf]
    |   sqrt[buf]
    |   mod[buf]
    ;

concat[StringBuffer buf]
    :   #(  CONCAT          { buf.append("("); } //NOI18N
            expression[buf] { buf.append(" + "); } //NOI18N
            expression[buf] { buf.append(")"); } //NOI18N 
        )
    ;

substring[StringBuffer buf]
    :   // EJBQL: SUBSTRING(string, start, length) ->
        // JDOQL: string.substring(start-1, start+length-1)
        #(  SUBSTRING 
            expression[buf]   
            { buf.append(".substring("); } //NOI18N
            start:.
            length:.
        )
        {
            if ((start.getType() == INT_LITERAL) && 
                (length.getType() == INT_LITERAL)) {
                // Optimization: start and length are constant values =>
                // calulate beginIndex and endIndex of the JDOQL substring 
                // call at compile time.
                int startValue = Integer.parseInt(start.getText());
                int lengthValue = Integer.parseInt(length.getText());
                buf.append(startValue - 1);
                buf.append(", "); //NOI18N
                buf.append(startValue - 1 + lengthValue);
            }
            else {
                StringBuffer startBuf = new StringBuffer();
                expression(start, startBuf);
                buf.append(startBuf.toString()); 
                buf.append(" - 1, "); //NOI18N
                buf.append(startBuf.toString());
                buf.append(" - 1 + "); //NOI18N
                expression(length, buf);
            }
            buf.append(")"); //NOI18N
        }
    ;

length[StringBuffer buf]
    :   #(  LENGTH 
            expression[buf] { buf.append(".length()"); } //NOI18N
        )
    ;

locate[StringBuffer buf]
{
    StringBuffer pattern = new StringBuffer();
}
    :   // EJBQL: LOCATE(pattern, string) ->
        // JDOQL: (string.indexOf(pattern) + 1)
        // EJBQL: LOCATE(pattern, string, start) ->
        // JDOQL: (string.indexOf(pattern, start - 1) + 1)
        #(  LOCATE              { buf.append("("); } //NOI18N
            expression[pattern] 
            expression[buf]     { buf.append(".indexOf(");  //NOI18N
                                  buf.append(pattern.toString()); }
            locateStartPos[buf] { buf.append(") + 1)"); } //NOI18N
        )
    ;

locateStartPos[StringBuffer buf]
    :   start:.
        {
            buf.append(", ");  //NOI18N 
            if (start.getType() == INT_LITERAL) {
                // Optimization: start is a constant value =>
                // calulate startIndex of JDOQL indexOf call at compile time.
                buf.append(Integer.parseInt(start.getText()) - 1);
            }
            else {
                expression(start, buf);
                { buf.append(" - 1"); } //NOI18N
            }
        }
    |   // empty rule
    ;

abs[StringBuffer buf]
    :   #(  ABS  
            { buf.append ("java.lang.Math.abs("); } //NOI18N
            expression[buf]
            { buf.append (")"); } //NOI18N
        )
    ;

sqrt[StringBuffer buf]
    :   #(  SQRT 
            { buf.append ("java.lang.Math.sqrt("); } //NOI18N
            expression[buf]
            { buf.append (")"); } //NOI18N
        )
    ;

mod[StringBuffer buf]
    :   #(  MOD
            { buf.append("("); } //NOI18N
            expression[buf]
            { buf.append(" % "); } //NOI18N
            expression[buf]
            { buf.append(")"); } //NOI18N
        )
    ;   

primary[StringBuffer buf]
    :   literal[buf]
    |   pathExpr[buf]
    |   parameter[buf]
    ;

literal[StringBuffer buf]
    :   TRUE           
        { buf.append("true"); } // NOI18N
    |   FALSE          
        { buf.append("false"); } // NOI18N
    |   stringLiteral[buf]
    |   i:INT_LITERAL  
        { 
            buf.append(i.getText()); 
        }  
    |   l:LONG_LITERAL   
        { 
            buf.append(l.getText()); 
        }  
    |   f:FLOAT_LITERAL  
        { 
            buf.append(f.getText()); 
        }
    |   d:DOUBLE_LITERAL 
        { 
            buf.append(d.getText()); 
        }
    ;


stringLiteral[StringBuffer buf]
    :   s:STRING_LITERAL  
        {
            buf.append('"'); // NOI18N
            buf.append(convertStringLiteral(s.getText())); 
            buf.append('"'); // NOI18N
        }
    ;

pathExpr[StringBuffer buf]
    :   #(  CMP_FIELD_ACCESS
            pathExpr[buf]
            { buf.append('.'); }
            f1:field
            { buf.append(f1.getText()); }
        )
    |   #(  SINGLE_CMR_FIELD_ACCESS
            pathExpr[buf]
            { buf.append('.'); }
            f2:field
            { buf.append(f2.getText()); }
        )
    |   #(  COLLECTION_CMR_FIELD_ACCESS
            pathExpr[buf]
            { buf.append('.'); }
            f3:field
            { buf.append(f3.getText()); }
        )
    |   v:IDENTIFICATION_VAR
        {
            String name = v.getText();
            if (name.equalsIgnoreCase(candidateClassIdentificationVar))
               name = "this"; //NOI18N
            buf.append(name);
        }
    |   #( dot:DOT expression[buf]expression[buf])
        {
            ErrorMsg.fatal(I18NHelper.getMessage(msgs, "ERR_UnexpectedNode", //NOI18N
                    dot.getText(), String.valueOf(dot.getType())));
        }
    |   i:IDENT
        {
            ErrorMsg.fatal(I18NHelper.getMessage(msgs, "ERR_UnexpectedNode", //NOI18N
                    i.getText(), String.valueOf(i.getType())));
        }
    ;

field
    :   CMP_FIELD
    |   COLLECTION_CMR_FIELD
    |   SINGLE_CMR_FIELD
    ;

parameter [StringBuffer buf]
    :   param:INPUT_PARAMETER
        {
            buf.append(paramSupport.getParameterName(param.getText()));
        }
    ;
