/*
// $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/RngParser.jj#24 $
// Farrago is an extensible data management system.
// Copyright (C) 2005-2009 The Eigenbase Project
// Copyright (C) 2005-2009 SQLstream, Inc.
// Copyright (C) 2005-2009 LucidEra, Inc.
// Portions Copyright (C) 2004-2009 John V. Sichi
//
// This program is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License, or (at your option)
// any later version approved by The Eigenbase Project.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

options {
    STATIC = false;
    UNICODE_INPUT = true;
    IGNORE_CASE = true;
}

PARSER_BEGIN(RngParser)

package net.sf.farrago.rng.parserimpl;

import net.sf.farrago.catalog.*;
import net.sf.farrago.ddl.*;
import net.sf.farrago.session.*;
import net.sf.farrago.parser.*;
import net.sf.farrago.util.*;
import org.eigenbase.util.*;
import org.eigenbase.util14.DateTimeUtil;
import java.math.*;
import java.util.*;
import javax.jmi.reflect.*;
import java.sql.*;

import net.sf.farrago.cwm.core.*;
import net.sf.farrago.rngmodel.*;
import net.sf.farrago.rngmodel.rngschema.*;

import org.eigenbase.reltype.*;
import org.eigenbase.sql.*;
import org.eigenbase.sql.fun.*;
import org.eigenbase.sql.parser.*;
import org.eigenbase.sql.type.*;
import org.eigenbase.resource.*;
import net.sf.farrago.resource.*;
import net.sf.farrago.query.*;
import net.sf.farrago.cwm.*;
import net.sf.farrago.cwm.datatypes.*;
import net.sf.farrago.cwm.relational.*;
import net.sf.farrago.cwm.relational.enumerations.*;
import net.sf.farrago.cwm.keysindexes.*;
import net.sf.farrago.cwm.behavioral.*;
import net.sf.farrago.fem.med.*;
import net.sf.farrago.fem.security.*;
import net.sf.farrago.fem.sql2003.*;

import net.sf.farrago.rng.*;

/**
 * Farrago parser implementation extended with RNG syntax.
 *
 * @author John V. Sichi
 * @version $Id: //open/dev/farrago/examples/rng/src/net/sf/farrago/rng/RngParser.jj#24 $
 */
public class RngParser extends FarragoAbstractParserImpl
{
    private static Metadata metadata;

    public SqlParserPos getCurrentPosition()
    {
        return new SqlParserPos(
            token.beginLine,
            token.beginColumn);
    }

    public SqlParseException normalizeException(Throwable ex)
    {
        try {
            if (ex instanceof ParseException) {
                ex = cleanupParseException((ParseException) ex);
            }
            return convertException(ex);
        } catch (ParseException e) {
            throw new AssertionError(e);
        }
    }

    public Metadata getMetadata()
    {
        synchronized (RngParser.class) {
            if (metadata == null) {
                metadata = new MetadataImpl(
                    new RngParser(new java.io.StringReader("")));
            }
            return metadata;
        }
    }

    // implement SqlAbstractParserImpl
    public void setTabSize(int tabSize)
    {
        jj_input_stream.setTabSize(tabSize);
    }

    RngmodelPackage getRngModelPackage()
    {
        return FarragoRngUDR.getRngModelPackage(getRepos());
    }
}

PARSER_END(RngParser)


/*****************************************
 * Syntactical Descriptions              *
 *****************************************/

/**
 * Allows parser to be extended with new types of table references.  The
 * default implementation of this production is empty.
 */
SqlNode ExtendedTableRef() :
{
}
{
    UnusedExtension()
    {
        return null;
    }
}

/**
 * Allows an OVER clause following a table expression as an extension to
 * standard SQL syntax. The default implementation of this production is empty.
 */
SqlNode TableOverOpt() :
{
}
{
    { return null; }
}

/*
 * Parses dialect-specific keywords immediately following the SELECT keyword.
 */
void SqlSelectKeywords(List keywords) :
{}
{
    E()
}

/*
 * Parses dialect-specific keywords immediately following the INSERT keyword.
 */
void SqlInsertKeywords(List keywords) :
{}
{
    E()
}

String NonReservedKeyWord() :
{
    String kw;
}
{
    (
        kw = CommonNonReservedKeyWord()
        {
            return kw;
        }
        |
        kw = DdlNonReservedKeyWord()
        {
            return kw;
        }
        |
        kw = RngNonReservedKeyWord()
        {
            return kw;
        }
    )
}

String RngNonReservedKeyWord() :
{
}
{
    (
        <RNG> | <SEED>
    )
    {
        return getToken(0).image.toUpperCase();
    }
}

CwmModelElement ExtensionModelSchemaObjDefinition() :
{
    RngRandomNumberGenerator rng;
    SqlIdentifier qualifiedName;
    String externalLocation;
    long seed;
}
{
    <RNG>
    {
        rng = getRngModelPackage().getRngschema()
        .getRngRandomNumberGenerator().createRngRandomNumberGenerator();
    }
    qualifiedName = CompoundIdentifier3()
    {
        farragoParser.getDdlValidator().setSchemaObjectName(
            rng, qualifiedName);
    }
    <EXTERNAL> externalLocation = QuotedString()
    {
        rng.setSerializedFile(externalLocation);
    }
    [ <SEED> seed = UnsignedValue() { rng.setInitialSeed(new Long(seed)); } ]
    {
        return rng;
    }
}

long UnsignedValue() :
{
    Token t;
}
{
    t = <UNSIGNED_INTEGER_LITERAL>
    {
        try {
            return Long.parseLong(t.image);
        } catch (NumberFormatException ex) {
            throw generateParseException();
        }
    }
}

CwmModelElement ExtensionModelDefinition() :
{
}
{
    (
        LOOKAHEAD({false}) <NULL>
    )
    {
        return null;
    }
}

CwmModelElement ExtensionModelDrop() :
{
    SqlIdentifier qualifiedName;
    RngRandomNumberGenerator rng;
}
{
    <RNG> qualifiedName = CompoundIdentifier3()
    {
        rng = farragoParser.getStmtValidator().findSchemaObject(
            qualifiedName,
            RngRandomNumberGenerator.class);
    }
    CascadeOption()
    {
        return rng;
    }
}

DdlStmt ExtensionModelAlter() :
{
}
{
    (
        LOOKAHEAD({false}) <NULL>
    )
    {
        return null;
    }
}

SqlNode ExtendedBuiltinFunctionCall() :
{
    SqlIdentifier id;
    long longCeiling;
    int ceiling = -1;
    RngRandomNumberGenerator rng;
}
{
    <NEXT_RANDOM_INT>
    <LPAREN>
    (
        <CEILING> longCeiling = UnsignedValue()
        {
            ceiling = (int) longCeiling;
        }
        | <UNBOUNDED>
    )
    <FROM>
    id = CompoundIdentifier3()
    <RPAREN>
    {
        rng = farragoParser.getStmtValidator().findSchemaObject(
            id,
            RngRandomNumberGenerator.class);
        return
        FarragoRngOperatorTable.rngInstance().nextRandomInt.createCall(
            getPos(),
            SqlLiteral.createExactNumeric(
                Integer.toString(ceiling),
                getPos()),
            SqlLiteral.createCharString(
                FarragoCatalogUtil.getQualifiedName(rng).toString(),
                getPos()),
            SqlLiteral.createCharString(
                FarragoProperties.instance().expandProperties(
                    rng.getSerializedFile()),
                getPos()));
    }
}

TOKEN :
{
    < NEXT_RANDOM_INT: "NEXT_RANDOM_INT" >
    | < RNG: "RNG" >
    | < SEED: "SEED" >
}

/*
* Parse Floor/Ceil function parameters
*/
SqlNode FloorCeilOptions( SqlParserPos pos, boolean floorFlag) :
{
    SqlNode node;
}
{
    node = StandardFloorCeilOptions( pos, floorFlag)
    {
        return node;
    }
}

// End RngParser.jj
