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

/*
 * EJBQL.g
 *
 * Created on November 12, 2001
 */

header
{
    package com.sun.jdo.spi.persistence.support.ejb.ejbqlc;

    import antlr.MismatchedTokenException;
    import antlr.MismatchedCharException;
    import antlr.NoViableAltException;
    import antlr.NoViableAltForCharException;
    import antlr.TokenStreamRecognitionException;
    
    import java.util.ResourceBundle;
    import org.glassfish.persistence.common.I18NHelper;
}

//===== Lexical Analyzer Class Definitions =====

/**
 * This class defines the lexical analysis for the EJBQL compiler.
 *
 * @author  Michael Bouschen
 * @author  Shing Wai Chan
 */
class EJBQLLexer extends Lexer;
options
{
    k = 2;
    exportVocab = EJBQL;
    charVocabulary = '\u0000'..'\uFFFE'; //NOI18N
    caseSensitiveLiterals = false;
}

tokens {

    // keywords 
    SELECT = "select"; //NOI18N
    FROM = "from"; //NOI18N
    WHERE = "where"; //NOI18N
    DISTINCT = "distinct"; //NOI18N
    OBJECT = "object"; //NOI18N
    NULL = "null"; //NOI18N
    TRUE = "true"; //NOI18N
    FALSE = "false"; //NOI18N
    NOT = "not"; //NOI18N
    AND = "and"; //NOI18N
    OR = "or"; //NOI18N
    BETWEEN = "between"; //NOI18N
    LIKE = "like"; //NOI18N
    IN = "in"; //NOI18N
    AS = "as"; //NOI18N
    UNKNOWN = "unknown"; //NOI18N
    EMPTY = "empty"; //NOI18N
    MEMBER = "member"; //NOI18N
    OF = "of"; //NOI18N
    IS = "is"; //NOI18N

    // function/operator names treated as keywords
    ESCAPE = "escape"; //NOI18N
    CONCAT = "concat"; //NOI18N
    SUBSTRING = "substring"; //NOI18N
    LOCATE = "locate"; //NOI18N
    LENGTH = "length"; //NOI18N
    ABS = "abs"; //NOI18N
    SQRT = "sqrt"; //NOI18N
    MOD = "mod"; //NOI18N

    // aggregate functions
    AVG = "avg"; //NOI18N
    MAX = "max"; //NOI18N
    MIN = "min"; //NOI18N
    SUM = "sum"; //NOI18N
    COUNT = "count"; //NOI18N

    // order by
    ORDER = "order"; //NOI18N
    BY = "by"; //NOI18N
    ASC = "asc"; //NOI18N
    DESC = "desc"; //NOI18N

    // relational operators
    EQUAL;
    NOT_EQUAL;
    GE;
    GT;
    LE;
    LT;

    // arithmetic operators
    PLUS;
    MINUS;
    STAR;
    DIV;

    // literals
    STRING_LITERAL;
    INT_LITERAL;
    LONG_LITERAL;
    FLOAT_LITERAL;
    DOUBLE_LITERAL;

    // other token types
    IDENT;
    DOT;
    INPUT_PARAMETER;

    // lexer internal token types
    LPAREN;
    RPAREN;
    COMMA;
    WS;
    HEX_DIGIT;
    EXPONENT;
    FLOAT_SUFFIX;
    UNICODE_DIGIT;
    UNICODE_STR;
}

{
    /**
     * The width of a tab stop.
     * This value is used to calculate the correct column in a line
     * conatining a tab character.
     */
    protected static final int TABSIZE = 4;

    /** */
    protected static final int EOF_CHAR = 65535; // = (char) -1 = EOF

    /** I18N support. */
    protected final static ResourceBundle msgs = 
        I18NHelper.loadBundle(EJBQLLexer.class);
    
    /**
     *
     */
    public void tab() 
    {
        int column = getColumn();
        int newColumn = (((column-1)/TABSIZE)+1)*TABSIZE+1;
        setColumn(newColumn);
    }

    /** */
    public void reportError(int line, int column, String s)
    {
        ErrorMsg.error(line, column, s);
    }

    /** Report lexer exception errors caught in nextToken(). */
    public void reportError(RecognitionException e)
    {
        handleANTLRException(e);
    }

    /** Lexer error-reporting function. */
    public void reportError(String s)
    {
        ErrorMsg.error(0, 0, s);
    }

    /** Lexer warning-reporting function. */
    public void reportWarning(String s)
    {
        throw new EJBQLException(s);
    }

    /**
     *
     */
    public static void handleANTLRException(ANTLRException ex)
    {
        if (ex instanceof MismatchedCharException) {
            MismatchedCharException mismatched = (MismatchedCharException)ex;
            if (mismatched.mismatchType == MismatchedCharException.CHAR) {
                if (mismatched.foundChar == EOF_CHAR) {
                    ErrorMsg.error(mismatched.getLine(), mismatched.getColumn(),
                        //TBD: bundle key
                        I18NHelper.getMessage(msgs, "EXC_UnexpectedEOF")); //NOI18N
                }
                else {
                    ErrorMsg.error(mismatched.getLine(), mismatched.getColumn(), 
                        I18NHelper.getMessage(msgs, "EXC_ExpectedCharFound", //NOI18N
                            String.valueOf((char)mismatched.expecting), 
                            String.valueOf((char)mismatched.foundChar)));
                }
                return;
            }
        }
        else if (ex instanceof MismatchedTokenException) {
            MismatchedTokenException mismatched = (MismatchedTokenException)ex;
            Token token = mismatched.token;
            if ((mismatched.mismatchType == MismatchedTokenException.TOKEN) &&
                (token != null)) {
                if (token.getType() == Token.EOF_TYPE) {
                    ErrorMsg.error(token.getLine(), token.getColumn(),
                        //TBD: bundle key
                        I18NHelper.getMessage(msgs, "EXC_UnexpectedEOF")); //NOI18N
                }
                else {
                    ErrorMsg.error(token.getLine(), token.getColumn(), 
                        I18NHelper.getMessage(msgs, "EXC_SyntaxErrorAt", token.getText())); //NOI18N
                }
                return;
            }
        }
        else if (ex instanceof NoViableAltException) {
            Token token = ((NoViableAltException)ex).token;
            if (token != null) {
                if (token.getType() == Token.EOF_TYPE) {
                    ErrorMsg.error(token.getLine(), token.getColumn(), 
                        //TBD: bundle key
                        I18NHelper.getMessage(msgs, "EXC_UnexpectedEOF")); //NOI18N
                }
                else {
                    ErrorMsg.error(token.getLine(), token.getColumn(), 
                        I18NHelper.getMessage(msgs, "EXC_UnexpectedToken", token.getText())); //NOI18N
                }
                return;
            }
        }
        else if (ex instanceof NoViableAltForCharException) {
            NoViableAltForCharException noViableAlt = (NoViableAltForCharException)ex;
            ErrorMsg.error(noViableAlt.getLine(), noViableAlt.getColumn(), 
                I18NHelper.getMessage(msgs, "EXC_UnexpectedChar", new Character(noViableAlt.foundChar)));//NOI18N
        }
        else if (ex instanceof TokenStreamRecognitionException) {
            handleANTLRException(((TokenStreamRecognitionException)ex).recog);
        }

        // no special handling from aboves matches the exception if this line is reached =>
        // make it a syntax error
        int line = 0;
        int column = 0;
        if (ex instanceof RecognitionException) {
            line = ((RecognitionException)ex).getLine();
            column = ((RecognitionException)ex).getColumn();
        }
        ErrorMsg.error(line, column, I18NHelper.getMessage(msgs, "EXC_SyntaxError")); //NOI18N
    }
}

// OPERATORS

LPAREN          :   '('     ;
RPAREN          :   ')'     ;
COMMA           :   ','     ;
//DOT           :   '.'     ;
EQUAL           :   '='     ; 
NOT_EQUAL       :   "<>"    ; //NOI18N
GE              :   ">="    ; //NOI18N
GT              :   ">"     ; //NOI18N
LE              :   "<="    ; //NOI18N
LT              :   '<'     ;
PLUS            :   '+'     ;
DIV             :   '/'     ;
MINUS           :   '-'     ;
STAR            :   '*'     ;

// Whitespace -- ignored
WS  
    :   (   ' '
        |   '\t'
        |   '\f'
        )
        { _ttype = Token.SKIP; }
    ;

NEWLINE
    :   (   "\r\n"  //NOI18N
        |   '\r'
        |   '\n'
        )
        { 
            newline(); 
            _ttype = Token.SKIP; 
        }
    ;

// input parameter
INPUT_PARAMETER
    :  '?' ('1'..'9') ('0'..'9')*
    ;

// string literals
STRING_LITERAL
    :  '\'' ( "''" | ESC | ~'\'' )* '\'' //NOI18N
    ;

// escape sequence -- note that this is protected; it can only be called
//   from another lexer rule -- it will not ever directly return a token to
//   the parser
// There are various ambiguities hushed in this rule.  The optional
// '0'...'9' digit matches should be matched here rather than letting
// them go back to STRING_LITERAL to be matched.  ANTLR does the
// right thing by matching immediately; hence, it's ok to shut off
// the FOLLOW ambig warnings.
protected
ESC
    :   '\\'
        (   options { warnWhenFollowAmbig = false; }
        :   'n'
        |   'r'
        |   't'
        |   'b'
        |   'f'
        |   '"' //NOI18N
            // Note, EJBQL uses a quote to escape a quote
            // |   '\'' 
        |   '\\'
        |   ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT 
        |   ('0'..'3')
            (
                options {
                    warnWhenFollowAmbig = false;
                }
            :   ('0'..'7')
                (   
                    options {
                        warnWhenFollowAmbig = false;
                    }
                :   '0'..'7'
                )?
            )?
        |   ('4'..'7')
            (
                options {
                    warnWhenFollowAmbig = false;
                }
            :   ('0'..'7')
            )?
        )?
    ;

// hexadecimal digit
protected
HEX_DIGIT
    :   ('0'..'9'|'A'..'F'|'a'..'f')
    ;

// a numeric literal
INT_LITERAL
    {   
        boolean isDecimal=false;
        int tokenType = DOUBLE_LITERAL; 
    }
    :   '.' {_ttype = DOT;}
            (('0'..'9')+ {tokenType = DOUBLE_LITERAL;}
             (EXPONENT)? 
             (tokenType = FLOATINGPOINT_SUFFIX)?
            {_ttype = tokenType;} )?
    |   (   '0' {isDecimal = true;} // special case for just '0'
            (   ('x'|'X')
                (                                           // hex
                    // the 'e'|'E' and float suffix stuff look
                    // like hex digits, hence the (...)+ doesn't
                    // know when to stop: ambig.  ANTLR resolves
                    // it correctly by matching immediately.  It
                    // is therefor ok to hush warning.
                    options {
                        warnWhenFollowAmbig=false;
                    }
                :   HEX_DIGIT
                )+
            |   ('0'..'7')+                                 // octal
            )?
        |   ('1'..'9') ('0'..'9')*  {isDecimal=true;}       // non-zero decimal
        )
        (   ('l'|'L') { _ttype = LONG_LITERAL; }
        
        // only check to see if it's a float if looks like decimal so far
        |   {isDecimal}?
            {tokenType = DOUBLE_LITERAL;} 
            (   '.' ('0'..'9')* (EXPONENT)? 
                ( tokenType = FLOATINGPOINT_SUFFIX)?
            |   EXPONENT ( tokenType = FLOATINGPOINT_SUFFIX)?
            |   tokenType = FLOATINGPOINT_SUFFIX
            )
            { _ttype = tokenType; }
        )?
    ;

// a couple protected methods to assist in matching floating point numbers
protected
EXPONENT
    :   ('e'|'E') ('+'|'-')? ('0'..'9')+
    ;

protected
FLOATINGPOINT_SUFFIX returns [int tokenType]
    : 'f' { tokenType = FLOAT_LITERAL; } 
    | 'F' { tokenType = FLOAT_LITERAL; } 
    | 'd' { tokenType = DOUBLE_LITERAL; } 
    | 'D' { tokenType = DOUBLE_LITERAL; } 
    ;

// an identifier.  Note that testLiterals is set to true!  This means
// that after we match the rule, we look in the literals table to see
// if it's a literal or really an identifer

IDENT
    options {paraphrase = "an identifier"; testLiterals=true;} //NOI18N
    :   (   'a'..'z'
        |   'A'..'Z'
        |   '_'
        |   '$'
        |   UNICODE_ESCAPE
        |   c1:'\u0080'..'\uFFFE'
            { 
                if (!Character.isJavaIdentifierStart(c1)) {
                    ErrorMsg.error(getLine(), getColumn(), 
                        I18NHelper.getMessage(msgs, "EXC_UnexpectedChar", String.valueOf(c1)));//NOI18N
                }
            }
        ) 
        (   'a'..'z'
        |   'A'..'Z'
        |   '_'
        |   '$'
        |   '0'..'9'
        |   UNICODE_ESCAPE
        |   c2:'\u0080'..'\uFFFE'
            {   
                if (!Character.isJavaIdentifierPart(c2)) {
                    ErrorMsg.error(getLine(), getColumn(), 
                        I18NHelper.getMessage(msgs, "EXC_UnexpectedChar", String.valueOf(c2)));//NOI18N
                }
            }
        )*
    ;

protected
UNICODE_ESCAPE
    : '\\' ('u')+ HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
        {
            try {
                String tmp = text.toString();
                char c  = (char)Integer.parseInt(tmp.substring(tmp.length() - 4,
                        tmp.length()), 16);
                // problems using ANTLR feature $setText => use generated code
                text.setLength(_begin); 
                text.append(new Character(c).toString());
            }
            catch (NumberFormatException ex) {
                ErrorMsg.fatal(I18NHelper.getMessage(msgs, 
                        "ERR_UnexpectedExceptionUnicode"), ex); //NOI18N
            }
        }
    ;

//===== Parser Class Definitions =====

/**
 * This class defines the syntax analysis (parser) of the EJBQL compiler.
 *
 * @author  Michael Bouschen
 */
class EJBQLParser extends Parser;

options {
    k = 2;                   // two token lookahead
    exportVocab = EJBQL;
    buildAST = true;
    ASTLabelType = "EJBQLAST"; // NOI18N
}

tokens
{
    // root
    QUERY;

    // special from clause tokenes
    RANGE;

    // special dot expresssion
    CMP_FIELD_ACCESS;
    SINGLE_CMR_FIELD_ACCESS;
    COLLECTION_CMR_FIELD_ACCESS;

    // identifier 
    IDENTIFICATION_VAR;
    IDENTIFICATION_VAR_DECL;
    ABSTRACT_SCHEMA_NAME;
    CMP_FIELD;
    SINGLE_CMR_FIELD;
    COLLECTION_CMR_FIELD;

    // operators
    UNARY_MINUS;
    UNARY_PLUS;
    NOT_BETWEEN;
    NOT_LIKE;
    NOT_IN;
    NOT_NULL;
    NOT_EMPTY;
    NOT_MEMBER;
}

{
    /** I18N support. */
    protected final static ResourceBundle msgs = 
        I18NHelper.loadBundle(EJBQLParser.class);
    
    /** ANTLR method called when an error was detected. */
    public void reportError(RecognitionException ex)
    {
        EJBQLLexer.handleANTLRException(ex);
    }

    /** ANTLR method called when an error was detected. */
    public void reportError(String s)
    {
        ErrorMsg.error(0, 0, s);
    }

    /** */
    public void reportError(int line, int column, String s)
    {
        ErrorMsg.error(line, column, s);
    }

    /** ANTLR method called when a warning was detected. */
    public void reportWarning(String s)
    {
        throw new EJBQLException(s);
    }

    /** 
     * This method wraps the root rule in order to handle 
     * ANTLRExceptions thrown during parsing.
     */
    public void query ()
    {
        try {
            root();
        }
        catch (ANTLRException ex) {
            EJBQLLexer.handleANTLRException(ex);
        }
    }
}

// ----------------------------------
// rules
// ----------------------------------

root!
    :   s:selectClause f:fromClause w:whereClause o:orderbyClause EOF!
        {
            // switch the order of subnodes: the fromClause should come first, 
            // because it declares the identification variables used in the 
            // selectClause and the whereClause
            #root = #(#[QUERY,"QUERY"], #f, #s, #w); //NOI18N
            if (#o != null) {
                #root.addChild(#o);
            }
        }
    ;

selectClause
    :   SELECT^ ( DISTINCT )? projection
    ;

projection
    :   p:pathExpr
        {
            if (#p.getType() != DOT) {
                ErrorMsg.error(#p.getLine(), #p.getColumn(), 
                    I18NHelper.getMessage(msgs, "EXC_SyntaxErrorAt", //NOI18N
                        #p.getText())); 
            }
        }
    |   OBJECT^ LPAREN! IDENT RPAREN!
    |   ( AVG^ | MAX^ | MIN^ | SUM^ | COUNT^ ) LPAREN! (DISTINCT)? pathExpr RPAREN!
    ;

fromClause
    :   FROM^ identificationVarDecl ( COMMA! identificationVarDecl )*
    ;

identificationVarDecl
    :   collectionMemberDecl
    |   rangeVarDecl
    ;

collectionMemberDecl
    :   IN^ LPAREN! pathExpr RPAREN! ( AS! )? IDENT
    ;

rangeVarDecl!
    :   abstractSchemaName:. ( AS! )? i:IDENT
        {
            #abstractSchemaName.setType(ABSTRACT_SCHEMA_NAME);
            #rangeVarDecl = #(#[RANGE,"RANGE"], #abstractSchemaName, #i); //NOI18N
        }
    ;

whereClause
    :   WHERE^ conditionalExpr
    |   // empty rule
        {
            // Add where true in the case the where clause is omitted
            #whereClause = #(#[WHERE,"WHERE"], #[TRUE,"TRUE"]); //NOI18N
        }
    ;

pathExpr
    :   IDENT ( DOT^ IDENT )*
    ;

conditionalExpr
    :   conditionalTerm ( OR^ conditionalTerm )*
    ;

conditionalTerm
    :   conditionalFactor ( AND^ conditionalFactor )*
    ;

conditionalFactor
    :   ( NOT^ )? conditionalPrimary
    ;

conditionalPrimary
    :   ( betweenExpr )=> betweenExpr
    |   ( likeExpr )=> likeExpr
    |   ( inExpr )=> inExpr
    |   ( nullComparisonExpr )=> nullComparisonExpr
    |   ( emptyCollectionComparisonExpr )=> emptyCollectionComparisonExpr
    |   ( collectionMemberExpr )=> collectionMemberExpr 
    |   comparisonExpr
    ;

betweenExpr
    :   arithmeticExpr ( n:NOT! )? BETWEEN^ arithmeticExpr AND! arithmeticExpr
        {
            // map NOT BETWEEN to single operator NOT_BETWEEN
            if (#n != null)
                #BETWEEN.setType(NOT_BETWEEN);
        }
    ;

likeExpr
    :   pathExpr ( n:NOT! )? LIKE^ ( stringLiteral | parameter ) escape
        {
            // map NOT LIKE to single operator NOT_LIKE
            if(#n != null)
                #LIKE.setType(NOT_LIKE);
        }
    ;

escape
    :   ESCAPE^ ( stringLiteral | parameter )
    |   // empty rule
    ;

inExpr
    :   pathExpr ( n:NOT! )? IN^ LPAREN! inCollectionElement ( COMMA! inCollectionElement )* RPAREN!
        {
            // map NOT BETWEEN to single operator NOT_IN
            if (#n != null)
                #IN.setType(NOT_IN);
        }
    ;

nullComparisonExpr
    :   ( pathExpr | parameter ) IS! ( n:NOT! )? NULL^
        {
            // map NOT NULL to single operator NOT_NULL
            if (#n != null)
                #NULL.setType(NOT_NULL);
        }
    ;

emptyCollectionComparisonExpr
    :   pathExpr IS! ( n:NOT! )? EMPTY^
        {
            // map IS NOT EMPTY to single operator NOT_EMPTY
            if (#n != null)
                #EMPTY.setType(NOT_EMPTY);
        }
    ;

collectionMemberExpr
    :   ( pathExpr | parameter ) 
        ( n:NOT! )? MEMBER^ ( OF! )? pathExpr
        {
            // map NOT MEMBER to single operator NOT_MEMBER
            if (#n != null)
                #MEMBER.setType(NOT_MEMBER);
        }
    ;

comparisonExpr
    :   arithmeticExpr ( ( EQUAL^ | NOT_EQUAL^ | LT^ | LE^ | GT^ | GE^ ) arithmeticExpr )*
    ;

arithmeticExpr
    :   arithmeticTerm ( ( PLUS^ | MINUS^ ) arithmeticTerm )*
    ;

arithmeticTerm 
    :   arithmeticFactor ( (STAR^ | DIV^ ) arithmeticFactor )*
    ;

arithmeticFactor
    :   MINUS^ {#MINUS.setType(UNARY_MINUS);} arithmeticFactor
    |   PLUS^  {#PLUS.setType(UNARY_PLUS);} arithmeticFactor
    |   arithmeticPrimary
    ;

arithmeticPrimary
    :   pathExpr 
    |   literal
    |   LPAREN! conditionalExpr RPAREN!
    |   parameter
    |   function
    ;

function
    :   CONCAT^ LPAREN! conditionalExpr COMMA! conditionalExpr RPAREN!
    |   SUBSTRING^ LPAREN! conditionalExpr COMMA! conditionalExpr COMMA! conditionalExpr RPAREN!
    |   LENGTH^ LPAREN! conditionalExpr RPAREN!
    |   LOCATE^ LPAREN! conditionalExpr COMMA! conditionalExpr ( COMMA! conditionalExpr )? RPAREN!
    |   ABS^ LPAREN! conditionalExpr RPAREN! 
    |   SQRT^ LPAREN! conditionalExpr RPAREN!
    |   MOD^ LPAREN! conditionalExpr COMMA! conditionalExpr RPAREN!
    ;

parameter
    :   INPUT_PARAMETER
    ;

orderbyClause
    :   ORDER^ BY! orderbyItem ( COMMA! orderbyItem )*
    |   // empty rule
    ;

orderbyItem
    :   pathExpr direction
    ;

direction
    :   ASC
    |   DESC
    |   // empty rule
        {
            // ASC is added as default
            #direction = #[ASC, "ASC"]; //NOI18N
        }
    ;

inCollectionElement
    :   literal
    |   parameter
    ;

literal
    :   TRUE
    |   FALSE
    |   stringLiteral
    |   INT_LITERAL
    |   LONG_LITERAL
    |   FLOAT_LITERAL
    |   DOUBLE_LITERAL
    ;

stringLiteral
    :   s:STRING_LITERAL
        {
            // strip quotes from the token text
            String text = #s.getText();
            #s.setText(text.substring(1,text.length()-1));
        }
    ;
