#!/usr/bin/env python
# Copyright (c) 2016 Google Inc.

# Licensed 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.
"""Generates various info tables from SPIR-V JSON grammar."""

from __future__ import print_function

import errno
import json
import os.path
import re

# Prefix for all C variables generated by this script.
PYGEN_VARIABLE_PREFIX = 'pygen_variable'

# Extensions to recognize, but which don't necessarily come from the SPIR-V
# core grammar.  Get this list from the SPIR-V registery web page.
EXTENSIONS_FROM_SPIRV_REGISTRY = """
SPV_AMD_shader_explicit_vertex_parameter
SPV_AMD_shader_trinary_minmax
SPV_AMD_gcn_shader
SPV_KHR_shader_ballot
SPV_AMD_shader_ballot
SPV_AMD_gpu_shader_half_float
SPV_KHR_shader_draw_parameters
SPV_KHR_subgroup_vote
SPV_KHR_16bit_storage
SPV_KHR_device_group
SPV_KHR_multiview
SPV_NVX_multiview_per_view_attributes
SPV_NV_viewport_array2
SPV_NV_stereo_view_rendering
SPV_NV_sample_mask_override_coverage
SPV_NV_geometry_shader_passthrough
SPV_AMD_texture_gather_bias_lod
SPV_KHR_storage_buffer_storage_class
SPV_KHR_variable_pointers
SPV_AMD_gpu_shader_int16
SPV_KHR_post_depth_coverage
SPV_KHR_shader_atomic_counter_ops
SPV_EXT_shader_stencil_export
SPV_EXT_shader_viewport_index_layer
SPV_AMD_shader_image_load_store_lod
SPV_AMD_shader_fragment_mask
SPV_EXT_fragment_fully_covered
SPV_AMD_gpu_shader_half_float_fetch
SPV_GOOGLE_decorate_string
SPV_GOOGLE_hlsl_functionality1
"""


def make_path_to_file(f):
    """Makes all ancestor directories to the given file, if they
    don't yet exist.

    Arguments:
        f: The file whose ancestor directories are to be created.
    """
    dir = os.path.dirname(os.path.abspath(f))
    try:
        os.makedirs(dir)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(dir):
            pass
        else:
            raise


def convert_min_required_version(version):
    """Converts the minimal required SPIR-V version encoded in the
    grammar to the symbol in SPIRV-Tools"""
    if version is None:
        return 'SPV_ENV_UNIVERSAL_1_0'
    if version == 'None':
        return '0xffffffffu'
    return 'SPV_ENV_UNIVERSAL_{}'.format(version.replace('.', '_'))


def compose_capability_list(caps):
    """Returns a string containing a braced list of capabilities as enums.

    Arguments:
      - caps: a sequence of capability names

    Returns:
      a string containing the braced list of SpvCapability* enums named by caps.
    """
    return "{" + ", ".join(['SpvCapability{}'.format(c) for c in caps]) + "}"


def get_capability_array_name(caps):
    """Returns the name of the array containing all the given capabilities.

    Args:
      - caps: a sequence of capability names
    """
    if not caps:
        return 'nullptr'
    return '{}_caps_{}'.format(PYGEN_VARIABLE_PREFIX, ''.join(caps))


def generate_capability_arrays(caps):
    """Returns the arrays of capabilities.

    Arguments:
      - caps: a sequence of sequence of capability names
    """
    caps = sorted(set([tuple(c) for c in caps if c]))
    arrays = [
        'static const SpvCapability {}[] = {};'.format(
            get_capability_array_name(c), compose_capability_list(c))
        for c in caps]
    return '\n'.join(arrays)


def compose_extension_list(exts):
    """Returns a string containing a braced list of extensions as enums.

    Arguments:
      - exts: a sequence of extension names

    Returns:
      a string containing the braced list of extensions named by exts.
    """
    return "{" + ", ".join(
        ['libspirv::Extension::k{}'.format(e) for e in exts]) + "}"


def get_extension_array_name(extensions):
    """Returns the name of the array containing all the given extensions.

    Args:
      - extensions: a sequence of extension names
    """
    if not extensions:
        return 'nullptr'
    else:
        return '{}_exts_{}'.format(
            PYGEN_VARIABLE_PREFIX, ''.join(extensions))


def generate_extension_arrays(extensions):
    """Returns the arrays of extensions.

    Arguments:
      - caps: a sequence of sequence of extension names
    """
    extensions = sorted(set([tuple(e) for e in extensions if e]))
    arrays = [
        'static const libspirv::Extension {}[] = {};'.format(
            get_extension_array_name(e), compose_extension_list(e))
        for e in extensions]
    return '\n'.join(arrays)


def convert_operand_kind(operand_tuple):
    """Returns the corresponding operand type used in spirv-tools for
    the given operand kind and quantifier used in the JSON grammar.

    Arguments:
      - operand_tuple: a tuple of two elements:
          - operand kind: used in the JSON grammar
          - quantifier: '', '?', or '*'

    Returns:
      a string of the enumerant name in spv_operand_type_t
    """
    kind, quantifier = operand_tuple
    # The following cases are where we differ between the JSON grammar and
    # spirv-tools.
    if kind == 'IdResultType':
        kind = 'TypeId'
    elif kind == 'IdResult':
        kind = 'ResultId'
    elif kind == 'IdMemorySemantics' or kind == 'MemorySemantics':
        kind = 'MemorySemanticsId'
    elif kind == 'IdScope' or kind == 'Scope':
        kind = 'ScopeId'
    elif kind == 'IdRef':
        kind = 'Id'

    elif kind == 'ImageOperands':
        kind = 'Image'
    elif kind == 'Dim':
        kind = 'Dimensionality'
    elif kind == 'ImageFormat':
        kind = 'SamplerImageFormat'
    elif kind == 'KernelEnqueueFlags':
        kind = 'KernelEnqFlags'

    elif kind == 'LiteralExtInstInteger':
        kind = 'ExtensionInstructionNumber'
    elif kind == 'LiteralSpecConstantOpInteger':
        kind = 'SpecConstantOpNumber'
    elif kind == 'LiteralContextDependentNumber':
        kind = 'TypedLiteralNumber'

    elif kind == 'PairLiteralIntegerIdRef':
        kind = 'LiteralIntegerId'
    elif kind == 'PairIdRefLiteralInteger':
        kind = 'IdLiteralInteger'
    elif kind == 'PairIdRefIdRef':  # Used by OpPhi in the grammar
        kind = 'Id'

    if kind == 'FPRoundingMode':
        kind = 'FpRoundingMode'
    elif kind == 'FPFastMathMode':
        kind = 'FpFastMathMode'

    if quantifier == '?':
        kind = 'Optional{}'.format(kind)
    elif quantifier == '*':
        kind = 'Variable{}'.format(kind)

    return 'SPV_OPERAND_TYPE_{}'.format(
        re.sub(r'([a-z])([A-Z])', r'\1_\2', kind).upper())


class InstInitializer(object):
    """Instances holds a SPIR-V instruction suitable for printing as
    the initializer for spv_opcode_desc_t."""

    def __init__(self, opname, caps, exts, operands, version):
        """Initialization.

        Arguments:
          - opname: opcode name (with the 'Op' prefix)
          - caps: a sequence of capability names required by this opcode
          - exts: a sequence of names of extensions enabling this enumerant
          - operands: a sequence of (operand-kind, operand-quantifier) tuples
          - version: minimal SPIR-V version required for this opcode
        """
        assert opname.startswith('Op')
        self.opname = opname[2:]  # Remove the "Op" prefix.
        self.num_caps = len(caps)
        self.caps_mask = get_capability_array_name(caps)
        self.num_exts = len(exts)
        self.exts = get_extension_array_name(exts)
        self.operands = [convert_operand_kind(o) for o in operands]

        self.fix_syntax()

        operands = [o[0] for o in operands]
        self.ref_type_id = 'IdResultType' in operands
        self.def_result_id = 'IdResult' in operands

        self.version = convert_min_required_version(version)

    def fix_syntax(self):
        """Fix an instruction's syntax, adjusting for differences between
        the officially released grammar and how SPIRV-Tools uses the grammar.

        Fixes:
            - ExtInst should not end with SPV_OPERAND_VARIABLE_ID.
            https://github.com/KhronosGroup/SPIRV-Tools/issues/233
        """
        if (self.opname == 'ExtInst'
                and self.operands[-1] == 'SPV_OPERAND_TYPE_VARIABLE_ID'):
            self.operands.pop()

    def __str__(self):
        template = ['{{"{opname}"', 'SpvOp{opname}',
                    '{num_caps}', '{caps_mask}',
                    '{num_operands}', '{{{operands}}}',
                    '{def_result_id}', '{ref_type_id}',
                    '{num_exts}', '{exts}',
                    '{min_version}}}']
        return ', '.join(template).format(
            opname=self.opname,
            num_caps=self.num_caps,
            caps_mask=self.caps_mask,
            num_operands=len(self.operands),
            operands=', '.join(self.operands),
            def_result_id=(1 if self.def_result_id else 0),
            ref_type_id=(1 if self.ref_type_id else 0),
            num_exts=self.num_exts,
            exts=self.exts,
            min_version=self.version)


class ExtInstInitializer(object):
    """Instances holds a SPIR-V extended instruction suitable for printing as
    the initializer for spv_ext_inst_desc_t."""

    def __init__(self, opname, opcode, caps, operands):
        """Initialization.

        Arguments:
          - opname: opcode name
          - opcode: enumerant value for this opcode
          - caps: a sequence of capability names required by this opcode
          - operands: a sequence of (operand-kind, operand-quantifier) tuples
        """
        self.opname = opname
        self.opcode = opcode
        self.num_caps = len(caps)
        self.caps_mask = get_capability_array_name(caps)
        self.operands = [convert_operand_kind(o) for o in operands]
        self.operands.append('SPV_OPERAND_TYPE_NONE')

    def __str__(self):
        template = ['{{"{opname}"', '{opcode}', '{num_caps}', '{caps_mask}',
                    '{{{operands}}}}}']
        return ', '.join(template).format(
            opname=self.opname,
            opcode=self.opcode,
            num_caps=self.num_caps,
            caps_mask=self.caps_mask,
            operands=', '.join(self.operands))


def generate_instruction(inst, is_ext_inst):
    """Returns the C initializer for the given SPIR-V instruction.

    Arguments:
      - inst: a dict containing information about a SPIR-V instruction
      - is_ext_inst: a bool indicating whether |inst| is an extended
                     instruction.

    Returns:
      a string containing the C initializer for spv_opcode_desc_t or
      spv_ext_inst_desc_t
    """
    opname = inst.get('opname')
    opcode = inst.get('opcode')
    caps = inst.get('capabilities', [])
    exts = inst.get('extensions', [])
    operands = inst.get('operands', {})
    operands = [(o['kind'], o.get('quantifier', '')) for o in operands]
    min_version = inst.get('version', None)

    assert opname is not None

    if is_ext_inst:
        return str(ExtInstInitializer(opname, opcode, caps, operands))
    else:
        return str(InstInitializer(opname, caps, exts, operands, min_version))


def generate_instruction_table(inst_table):
    """Returns the info table containing all SPIR-V instructions,
    sorted by opcode, and prefixed by capability arrays.

    Note:
      - the built-in sorted() function is guaranteed to be stable.
        https://docs.python.org/3/library/functions.html#sorted

    Arguments:
      - inst_table: a list containing all SPIR-V instructions.
    """
    inst_table = sorted(inst_table, key=lambda k: (k['opcode'], k['opname']))

    caps_arrays = generate_capability_arrays(
        [inst.get('capabilities', []) for inst in inst_table])
    exts_arrays = generate_extension_arrays(
        [inst.get('extensions', []) for inst in inst_table])

    insts = [generate_instruction(inst, False) for inst in inst_table]
    insts = ['static const spv_opcode_desc_t kOpcodeTableEntries[] = {{\n'
             '  {}\n}};'.format(',\n  '.join(insts))]

    return '{}\n\n{}\n\n{}'.format(caps_arrays, exts_arrays, '\n'.join(insts))


def generate_extended_instruction_table(inst_table, set_name):
    """Returns the info table containing all SPIR-V extended instructions,
    sorted by opcode, and prefixed by capability arrays.

    Arguments:
      - inst_table: a list containing all SPIR-V instructions.
      - set_name: the name of the extended instruction set.
    """
    inst_table = sorted(inst_table, key=lambda k: k['opcode'])
    caps = [inst.get('capabilities', []) for inst in inst_table]
    caps_arrays = generate_capability_arrays(caps)
    insts = [generate_instruction(inst, True) for inst in inst_table]
    insts = ['static const spv_ext_inst_desc_t {}_entries[] = {{\n'
             '  {}\n}};'.format(set_name, ',\n  '.join(insts))]

    return '{}\n\n{}'.format(caps_arrays, '\n'.join(insts))


class EnumerantInitializer(object):
    """Prints an enumerant as the initializer for spv_operand_desc_t."""

    def __init__(self, enumerant, value, caps, exts, parameters, version):
        """Initialization.

        Arguments:
          - enumerant: enumerant name
          - value: enumerant value
          - caps: a sequence of capability names required by this enumerant
          - exts: a sequence of names of extensions enabling this enumerant
          - parameters: a sequence of (operand-kind, operand-quantifier) tuples
          - version: minimal SPIR-V version required for this opcode
        """
        self.enumerant = enumerant
        self.value = value
        self.num_caps = len(caps)
        self.caps = get_capability_array_name(caps)
        self.num_exts = len(exts)
        self.exts = get_extension_array_name(exts)
        self.parameters = [convert_operand_kind(p) for p in parameters]
        self.version = convert_min_required_version(version)

    def __str__(self):
        template = ['{{"{enumerant}"', '{value}', '{num_caps}',
                    '{caps}', '{num_exts}', '{exts}',
                    '{{{parameters}}}', '{min_version}}}']
        return ', '.join(template).format(
            enumerant=self.enumerant,
            value=self.value,
            num_caps=self.num_caps,
            caps=self.caps,
            num_exts=self.num_exts,
            exts=self.exts,
            parameters=', '.join(self.parameters),
            min_version=self.version)


def generate_enum_operand_kind_entry(entry):
    """Returns the C initializer for the given operand enum entry.

    Arguments:
      - entry: a dict containing information about an enum entry

    Returns:
      a string containing the C initializer for spv_operand_desc_t
    """
    enumerant = entry.get('enumerant')
    value = entry.get('value')
    caps = entry.get('capabilities', [])
    exts = entry.get('extensions', [])
    params = entry.get('parameters', [])
    params = [p.get('kind') for p in params]
    params = zip(params, [''] * len(params))
    version = entry.get('version', None)

    assert enumerant is not None
    assert value is not None

    return str(EnumerantInitializer(
        enumerant, value, caps, exts, params, version))


def generate_enum_operand_kind(enum):
    """Returns the C definition for the given operand kind."""
    kind = enum.get('kind')
    assert kind is not None

    # Sort all enumerants first according to their values and then
    # their names so that the symbols with the same values are
    # grouped together.
    if enum.get('category') == 'ValueEnum':
        functor = lambda k: (k['value'], k['enumerant'])
    else:
        functor = lambda k: (int(k['value'], 16), k['enumerant'])
    entries = sorted(enum.get('enumerants', []), key=functor)

    name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind)
    entries = ['  {}'.format(generate_enum_operand_kind_entry(e))
               for e in entries]

    template = ['static const spv_operand_desc_t {name}[] = {{',
                '{entries}', '}};']
    entries = '\n'.join(template).format(
        name=name,
        entries=',\n'.join(entries))

    return kind, name, entries


def generate_operand_kind_table(enums):
    """Returns the info table containing all SPIR-V operand kinds."""
    # We only need to output info tables for those operand kinds that are enums.
    enums = [e for e in enums if e.get('category') in ['ValueEnum', 'BitEnum']]

    caps = [entry.get('capabilities', [])
            for enum in enums
            for entry in enum.get('enumerants', [])]
    caps_arrays = generate_capability_arrays(caps)

    exts = [entry.get('extensions', [])
            for enum in enums
            for entry in enum.get('enumerants', [])]
    exts_arrays = generate_extension_arrays(exts)

    enums = [generate_enum_operand_kind(e) for e in enums]
    # We have three operand kinds that requires their optional counterpart to
    # exist in the operand info table.
    three_optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess']
    three_optional_enums = [e for e in enums if e[0] in three_optional_enums]
    enums.extend(three_optional_enums)

    enum_kinds, enum_names, enum_entries = zip(*enums)
    # Mark the last three as optional ones.
    enum_quantifiers = [''] * (len(enums) - 3) + ['?'] * 3
    # And we don't want redefinition of them.
    enum_entries = enum_entries[:-3]
    enum_kinds = [convert_operand_kind(e)
                  for e in zip(enum_kinds, enum_quantifiers)]
    table_entries = zip(enum_kinds, enum_names, enum_names)
    table_entries = ['  {{{}, ARRAY_SIZE({}), {}}}'.format(*e)
                     for e in table_entries]

    template = [
        'static const spv_operand_desc_group_t {p}_OperandInfoTable[] = {{',
        '{enums}', '}};']
    table = '\n'.join(template).format(
        p=PYGEN_VARIABLE_PREFIX, enums=',\n'.join(table_entries))

    return '\n\n'.join((caps_arrays,) + (exts_arrays,) + enum_entries + (table,))


def get_extension_list(operands):
    """Returns extensions as an alphabetically sorted list of strings."""
    enumerants = sum([item.get('enumerants', []) for item in operands
                      if item.get('category') in ['ValueEnum']], [])

    extensions = sum([item.get('extensions', []) for item in enumerants
                      if item.get('extensions')], [])

    extensions.extend(EXTENSIONS_FROM_SPIRV_REGISTRY.split())

    # Validator would ignore type declaration unique check. Should only be used
    # for legacy autogenerated test files containing multiple instances of the
    # same type declaration, if fixing the test by other methods is too
    # difficult. Shouldn't be used for any other reasons.
    extensions.append('SPV_VALIDATOR_ignore_type_decl_unique')

    return sorted(set(extensions))


def get_capabilities(operands):
    """Returns capabilities as a list of JSON objects, in order of
    appearance.
    """
    enumerants = sum([item.get('enumerants', []) for item in operands
                      if item.get('kind') in ['Capability']], [])
    return enumerants


def generate_extension_enum(operands):
    """Returns enumeration containing extensions declared in the grammar."""
    extensions = get_extension_list(operands)
    return ',\n'.join(['k' + extension for extension in extensions])


def generate_extension_to_string_table(operands):
    """Returns extension to string mapping table."""
    extensions = get_extension_list(operands)
    entry_template = '  {{Extension::k{extension},\n   "{extension}"}}'
    table_entries = [entry_template.format(extension=extension)
                     for extension in extensions]
    table_template = '{{\n{enums}\n}}'
    return table_template.format(enums=',\n'.join(table_entries))


def generate_string_to_extension_table(operands):
    """Returns string to extension mapping table."""
    extensions = get_extension_list(operands)
    entry_template = '  {{"{extension}",\n   Extension::k{extension}}}'
    table_entries = [entry_template.format(extension=extension)
                     for extension in extensions]
    table_template = '{{\n{enums}\n}}'
    return table_template.format(enums=',\n'.join(table_entries))


def generate_capability_to_string_table(operands):
    """Returns capability to string mapping table."""
    capabilities = [item.get('enumerant')
                    for item in get_capabilities(operands)]
    entry_template = '  {{SpvCapability{capability},\n   "{capability}"}}'
    table_entries = [entry_template.format(capability=capability)
                     for capability in capabilities]
    table_template = '{{\n{enums}\n}}'
    return table_template.format(enums=',\n'.join(table_entries))


def generate_extension_to_string_mapping(operands):
    """Returns mapping function from extensions to corresponding strings."""
    extensions = get_extension_list(operands)
    function = 'const char* ExtensionToString(Extension extension) {\n'
    function += '  switch (extension) {\n'
    template = '    case Extension::k{extension}:\n' \
        '      return "{extension}";\n'
    function += ''.join([template.format(extension=extension)
                         for extension in extensions])
    function += '  };\n\n  return "";\n}'
    return function


def generate_string_to_extension_mapping(operands):
    """Returns mapping function from strings to corresponding extensions."""
    extensions = get_extension_list(operands)  # Already sorted

    function = '''
    bool GetExtensionFromString(const char* str, Extension* extension) {{
        static const char* known_ext_strs[] = {{ {strs} }};
        static const Extension known_ext_ids[] = {{ {ids} }};
        const auto b = std::begin(known_ext_strs);
        const auto e = std::end(known_ext_strs);
        const auto found = std::equal_range(
            b, e, str, [](const char* str1, const char* str2) {{
                return std::strcmp(str1, str2) < 0;
            }});
        if (found.first == e || found.first == found.second) return false;

        *extension = known_ext_ids[found.first - b];
        return true;
    }}
    '''.format(strs=', '.join(['"{}"'.format(e) for e in extensions]),
               ids=', '.join(['Extension::k{}'.format(e) for e in extensions]))

    return function


def generate_capability_to_string_mapping(operands):
    """Returns mapping function from capabilities to corresponding strings.
    We take care to avoid emitting duplicate values.
    """
    function = 'const char* CapabilityToString(SpvCapability capability) {\n'
    function += '  switch (capability) {\n'
    template = '    case SpvCapability{capability}:\n' \
        '      return "{capability}";\n'
    emitted = set()  # The values of capabilities we already have emitted
    for capability in get_capabilities(operands):
        value = capability.get('value')
        if value not in emitted:
            emitted.add(value)
            function += template.format(capability=capability.get('enumerant'))
    function += '    case SpvCapabilityMax:\n' \
        '      assert(0 && "Attempting to convert SpvCapabilityMax to string");\n' \
        '      return "";\n'
    function += '  };\n\n  return "";\n}'
    return function


def generate_all_string_enum_mappings(operands):
    """Returns all string-to-enum / enum-to-string mapping tables."""
    tables = []
    tables.append(generate_extension_to_string_mapping(operands))
    tables.append(generate_string_to_extension_mapping(operands))
    tables.append(generate_capability_to_string_mapping(operands))
    return '\n\n'.join(tables)


def main():
    import argparse
    parser = argparse.ArgumentParser(description='Generate SPIR-V info tables')

    parser.add_argument('--spirv-core-grammar', metavar='<path>',
                        type=str, required=False,
                        help='input JSON grammar file for core SPIR-V '
                        'instructions')
    parser.add_argument('--extinst-debuginfo-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for DebugInfo extended '
                        'instruction set')
    parser.add_argument('--extinst-glsl-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for GLSL extended '
                        'instruction set')
    parser.add_argument('--extinst-opencl-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for OpenCL extended '
                        'instruction set')

    parser.add_argument('--core-insts-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for core SPIR-V instructions')
    parser.add_argument('--glsl-insts-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for GLSL extended instruction set')
    parser.add_argument('--opencl-insts-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for OpenCL extended instruction set')
    parser.add_argument('--operand-kinds-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for operand kinds')
    parser.add_argument('--extension-enum-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for extension enumeration')
    parser.add_argument('--enum-string-mapping-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for enum-string mappings')
    parser.add_argument('--extinst-vendor-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for vendor extended '
                        'instruction set'),
    parser.add_argument('--vendor-insts-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for vendor extended instruction set')
    args = parser.parse_args()

    if (args.core_insts_output is None) != \
            (args.operand_kinds_output is None):
        print('error: --core-insts-output and --operand-kinds-output '
              'should be specified together.')
        exit(1)
    if args.operand_kinds_output and not (args.spirv_core_grammar and args.extinst_debuginfo_grammar):
        print('error: --operand-kinds-output requires --spirv-core-grammar '
              'and --exinst-debuginfo-grammar')
        exit(1)
    if (args.glsl_insts_output is None) != \
            (args.extinst_glsl_grammar is None):
        print('error: --glsl-insts-output and --extinst-glsl-grammar '
              'should be specified together.')
        exit(1)
    if (args.opencl_insts_output is None) != \
            (args.extinst_opencl_grammar is None):
        print('error: --opencl-insts-output and --extinst-opencl-grammar '
              'should be specified together.')
        exit(1)
    if (args.vendor_insts_output is None) != \
            (args.extinst_vendor_grammar is None):
        print('error: --vendor-insts-output and '
              '--extinst-vendor-grammar should be specified together.')
        exit(1)
    if all([args.core_insts_output is None,
            args.glsl_insts_output is None,
            args.opencl_insts_output is None,
            args.vendor_insts_output is None,
            args.extension_enum_output is None,
            args.enum_string_mapping_output is None]):
        print('error: at least one output should be specified.')
        exit(1)

    if args.spirv_core_grammar is not None:
        with open(args.spirv_core_grammar) as json_file:
            grammar = json.loads(json_file.read())
            with open(args.extinst_debuginfo_grammar) as debuginfo_json_file:
                debuginfo_grammar = json.loads(debuginfo_json_file.read())
                operand_kinds = grammar['operand_kinds']
                operand_kinds.extend(debuginfo_grammar['operand_kinds'])
        if args.core_insts_output is not None:
            make_path_to_file(args.core_insts_output)
            make_path_to_file(args.operand_kinds_output)
            print(generate_instruction_table(grammar['instructions']),
              file=open(args.core_insts_output, 'w'))
            print(generate_operand_kind_table(operand_kinds),
              file=open(args.operand_kinds_output, 'w'))
        if args.extension_enum_output is not None:
            make_path_to_file(args.extension_enum_output)
            print(generate_extension_enum(grammar['operand_kinds']),
              file=open(args.extension_enum_output, 'w'))
        if args.enum_string_mapping_output is not None:
            make_path_to_file(args.enum_string_mapping_output)
            print(generate_all_string_enum_mappings(operand_kinds),
              file=open(args.enum_string_mapping_output, 'w'))

    if args.extinst_glsl_grammar is not None:
        with open(args.extinst_glsl_grammar) as json_file:
            grammar = json.loads(json_file.read())
            make_path_to_file(args.glsl_insts_output)
            print(generate_extended_instruction_table(
                    grammar['instructions'], "glsl"),
                  file=open(args.glsl_insts_output, 'w'))

    if args.extinst_opencl_grammar is not None:
        with open(args.extinst_opencl_grammar) as json_file:
            grammar = json.loads(json_file.read())
            make_path_to_file(args.opencl_insts_output)
            print(generate_extended_instruction_table(
                    grammar['instructions'], "opencl"),
                  file=open(args.opencl_insts_output, 'w'))

    if args.extinst_vendor_grammar is not None:
        with open(args.extinst_vendor_grammar) as json_file:
            grammar = json.loads(json_file.read())
            make_path_to_file(args.vendor_insts_output)
            name = args.extinst_vendor_grammar
            start = name.find("extinst.") + len("extinst.")
            name = name[start:-len(".grammar.json")].replace("-", "_")
            print(generate_extended_instruction_table(
                    grammar['instructions'], name),
                  file=open(args.vendor_insts_output, 'w'))


if __name__ == '__main__':
    main()
