# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Parser for Blink IDL.

The parser uses the PLY (Python Lex-Yacc) library to build a set of parsing
rules which understand the Blink dialect of Web IDL.
It derives from a standard Web IDL parser, overriding rules where Blink IDL
differs syntactically or semantically from the base parser, or where the base
parser diverges from the Web IDL standard.

Web IDL:
    http://www.w3.org/TR/WebIDL/
Web IDL Grammar:
    http://www.w3.org/TR/WebIDL/#idl-grammar
PLY:
    http://www.dabeaz.com/ply/

Design doc:
http://www.chromium.org/developers/design-documents/idl-compiler#TOC-Front-end
"""

# Disable check for line length and Member as Function due to how grammar rules
# are defined with PLY
#
# pylint: disable=R0201
# pylint: disable=C0301
#
# Disable attribute validation, as lint can't import parent class to check
# pylint: disable=E1101
#

import os.path
import sys

# PLY is in Chromium src/third_party/ply
module_path, module_name = os.path.split(__file__)
third_party = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir)
# Insert at front to override system libraries, and after path[0] == script dir
sys.path.insert(1, third_party)
from ply import yacc

# Base parser is in Chromium src/tools/idl_parser
tools_dir = os.path.join(module_path, os.pardir, os.pardir, os.pardir, os.pardir, os.pardir, 'tools')
sys.path.append(tools_dir)
from idl_parser.idl_parser import IDLParser  # pylint: disable=import-error
from idl_parser.idl_parser import ParseFile as parse_file

from .blink_idl_lexer import BlinkIDLLexer
from . import blink_idl_lexer


class BlinkIDLParser(IDLParser):
    def __init__(self,
                 # common parameters
                 debug=False,
                 # local parameters
                 rewrite_tables=False,
                 # idl_parser parameters
                 lexer=None, verbose=False, mute_error=False,
                 # yacc parameters
                 outputdir='', optimize=True, write_tables=False,
                 picklefile=None):
        if debug:
            # Turn off optimization and caching, and write out tables,
            # to help debugging
            optimize = False
            outputdir = None
            picklefile = None
            write_tables = True
        if outputdir:
            picklefile = picklefile or os.path.join(outputdir, 'parsetab.pickle')
            if rewrite_tables:
                try:
                    os.unlink(picklefile)
                except OSError:
                    pass

        lexer = lexer or BlinkIDLLexer(debug=debug,
                                       outputdir=outputdir,
                                       optimize=optimize)
        self.lexer = lexer
        self.tokens = lexer.KnownTokens()
        # Optimized mode substantially decreases startup time (by disabling
        # error checking), and also allows use of Python's optimized mode.
        # See: Using Python's Optimized Mode
        # http://www.dabeaz.com/ply/ply.html#ply_nn38
        #
        # |picklefile| allows simpler importing than |tabmodule| (parsetab.py),
        # as we don't need to modify sys.path; virtually identical speed.
        # See: CHANGES, Version 3.2
        # http://ply.googlecode.com/svn/trunk/CHANGES
        self.yaccobj = yacc.yacc(module=self,
                                 debug=debug,
                                 optimize=optimize,
                                 write_tables=write_tables,
                                 picklefile=picklefile)
        self.parse_debug = debug
        self.verbose = verbose
        self.mute_error = mute_error
        self._parse_errors = 0
        self._parse_warnings = 0
        self._last_error_msg = None
        self._last_error_lineno = 0
        self._last_error_pos = 0


################################################################################

def main(argv):
    # If file itself executed, cache lex/parse tables
    try:
        outputdir = argv[1]
    except IndexError as err:
        print('Usage: %s OUTPUT_DIR' % argv[0])
        return 1
    blink_idl_lexer.main(argv)
    # Important: rewrite_tables=True causes the cache file to be deleted if it
    # exists, thus making sure that PLY doesn't load it instead of regenerating
    # the parse table.
    parser = BlinkIDLParser(outputdir=outputdir, rewrite_tables=True)


if __name__ == '__main__':
    sys.exit(main(sys.argv))
