package org.apache.commons.ognl;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/* Generated By:JavaCC: Do not edit this line. JJTOgnlParserState.java Version 4.1d1 */

import java.util.ArrayList;
import java.util.List;

/**
 * $Id$
 */
public class JJTOgnlParserState
{
    private final List<Node> nodes;

    private final List<Integer> marks;

    private int numNodesOnStack;

    private int currentMark;

    private boolean nodeCreated;

    public JJTOgnlParserState()
    {
        nodes = new ArrayList<Node>();
        marks = new ArrayList<Integer>();
        numNodesOnStack = 0;
        currentMark = 0;
    }

    /*
     * Determines whether the current node was actually closed and pushed. This should only be called in the final user
     * action of a node scope.
     */
    public boolean nodeCreated()
    {
        return nodeCreated;
    }

    /*
     * Call this to reinitialize the node stack. It is called automatically by the parser's ReInit() method.
     */
    public void reset()
    {
        nodes.clear();
        marks.clear();
        numNodesOnStack = 0;
        currentMark = 0;
    }

    /*
     * Returns the root node of the AST. It only makes sense to call this after a successful parse.
     */
    public Node rootNode()
    {
        return nodes.get( 0 );
    }

    /* Pushes a node on to the stack. */
    public void pushNode( Node node )
    {
        nodes.add( node );
        ++numNodesOnStack;
    }

    /*
     * Returns the node on the top of the stack, and remove it from the stack.
     */
    public Node popNode()
    {
        if ( --numNodesOnStack < currentMark )
        {
            currentMark = marks.remove( marks.size() - 1 );
        }
        return nodes.remove( nodes.size() - 1 );
    }

    /* Returns the node currently on the top of the stack. */
    public Node peekNode()
    {
        return nodes.get( nodes.size() - 1 );
    }

    /*
     * Returns the number of children on the stack in the current node scope.
     */
    public int nodeArity()
    {
        return numNodesOnStack - currentMark;
    }

    public void clearNodeScope( Node unused )
    {
        while ( numNodesOnStack > currentMark )
        {
            popNode();
        }
        currentMark = marks.remove( marks.size() - 1 );
    }

    public void openNodeScope( Node node )
    {
        marks.add( currentMark );
        currentMark = numNodesOnStack;
        node.jjtOpen();
    }

    /*
     * A definite node is constructed from a specified number of children. That number of nodes are popped from the
     * stack and made the children of the definite node. Then the definite node is pushed on to the stack.
     */
    public void closeNodeScope( Node node, int num )
    {
        currentMark = marks.remove( marks.size() - 1 );
        while ( num-- > 0 )
        {
            Node poppedNode = popNode();
            poppedNode.jjtSetParent( node );
            node.jjtAddChild( poppedNode, num );
        }
        node.jjtClose();
        pushNode( node );
        nodeCreated = true;
    }

    /*
     * A conditional node is constructed if its condition is true. All the nodes that have been pushed since the node
     * was opened are made children of the conditional node, which is then pushed on to the stack. If the condition is
     * false the node is not constructed and they are left on the stack.
     */
    public void closeNodeScope( Node node, boolean condition )
    {
        if ( condition )
        {
            int arity = nodeArity();
            currentMark = marks.remove( marks.size() - 1 );
            while ( arity-- > 0 )
            {
                Node poppedNode = popNode();
                poppedNode.jjtSetParent( node );
                node.jjtAddChild( poppedNode, arity );
            }
            node.jjtClose();
            pushNode( node );
            nodeCreated = true;
        }
        else
        {
            currentMark = marks.remove( marks.size() - 1 );
            nodeCreated = false;
        }
    }
}
/* JavaCC - OriginalChecksum=61071c68a05e7c9104307c34a2e37165 (do not edit this line) */
