#!/usr/bin/env python3
# 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."""

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 or KHR grammar files.  Get this list from the SPIR-V registry web page.
# NOTE: Only put things on this list if it is not in those grammar files.
EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS = """
SPV_AMD_gcn_shader
SPV_AMD_gpu_shader_half_float
SPV_AMD_gpu_shader_int16
SPV_AMD_shader_trinary_minmax
SPV_KHR_non_semantic_info
"""

OUTPUT_LANGUAGE = 'c'

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_SPIRV_VERSION_WORD(1, 0)'
    if version == 'None':
        return '0xffffffffu'
    return 'SPV_SPIRV_VERSION_WORD({})'.format(version.replace('.', ','))


def convert_max_required_version(version):
    """Converts the maximum required SPIR-V version encoded in the grammar to
    the symbol in SPIRV-Tools."""
    if version is None:
        return '0xffffffffu'
    return 'SPV_SPIRV_VERSION_WORD({})'.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* or spv::Capability:: enums named by caps.
    """
    base_string = 'SpvCapability'
    global OUTPUT_LANGUAGE
    if OUTPUT_LANGUAGE == 'c++':
        base_string = 'spv::Capability::'

    return '{' + ', '.join([(base_string + '{}').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]))
    cap_str = 'SpvCapability'
    global OUTPUT_LANGUAGE
    if OUTPUT_LANGUAGE == 'c++':
        cap_str = 'spv::Capability'
    arrays = [
        'static const ' + cap_str + ' {}[] = {};'.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(
        ['spvtools::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 spvtools::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, lastVersion):
        """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
          - lastVersion: last version of SPIR-V that includes 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)
        self.lastVersion = convert_max_required_version(lastVersion)

    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):
        global OUTPUT_LANGUAGE
        base_str = 'SpvOp'
        if OUTPUT_LANGUAGE == 'c++':
            base_str = 'spv::Op::Op'

        template = ['{{"{opname}"', base_str + '{opname}',
                    '{num_caps}', '{caps_mask}',
                    '{num_operands}', '{{{operands}}}',
                    '{def_result_id}', '{ref_type_id}',
                    '{num_exts}', '{exts}',
                    '{min_version}', '{max_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,
            max_version=self.lastVersion)


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)
    max_version = inst.get('lastVersion', 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, max_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(json_grammar, set_name, operand_kind_prefix=""):
    """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.
      - operand_kind_prefix: the prefix, if any, to add to the front
        of operand kind names.
    """
    if operand_kind_prefix:
        prefix_operand_kind_names(operand_kind_prefix, json_grammar)

    inst_table = json_grammar["instructions"]
    set_name = set_name.replace(".", "_")

    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, lastVersion):
        """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
          - lastVersion: last SPIR-V version this opode appears
        """
        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)
        self.lastVersion = convert_max_required_version(lastVersion)

    def __str__(self):
        template = ['{{"{enumerant}"', '{value}', '{num_caps}',
                    '{caps}', '{num_exts}', '{exts}',
                    '{{{parameters}}}', '{min_version}',
                    '{max_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,
            max_version=self.lastVersion)


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

    Arguments:
      - entry: a dict containing information about an enum entry
      - extension_map: a dict mapping enum value to list of extensions

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

    assert enumerant is not None
    assert value is not None

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


def generate_enum_operand_kind(enum, synthetic_exts_list):
    """Returns the C definition for the given operand kind.
    It's a static const named array of spv_operand_desc_t.

    Also appends to |synthetic_exts_list| a list of extension lists
    used.
    """
    kind = enum.get('kind')
    assert kind is not None

    # Sort all enumerants according to their values, but otherwise
    # preserve their order so the first name listed in the grammar
    # as the preferred name for disassembly.
    if enum.get('category') == 'ValueEnum':
        def functor(k): return (k['value'])
    else:
        def functor(k): return (int(k['value'], 16))
    entries = sorted(enum.get('enumerants', []), key=functor)

    # SubgroupEqMask and SubgroupEqMaskKHR are the same number with
    # same semantics, but one has no extension list while the other
    # does.  Both should have the extension list.
    # So create a mapping from enum value to the union of the extensions
    # across all those grammar entries.  Preserve order.
    extension_map = {}
    for e in entries:
        value = e.get('value')
        extension_map[value] = []
    for e in entries:
        value = e.get('value')
        exts = e.get('extensions', [])
        for ext in exts:
            if ext not in extension_map[value]:
                extension_map[value].append(ext)
    synthetic_exts_list.extend(extension_map.values())

    name = '{}_{}Entries'.format(PYGEN_VARIABLE_PREFIX, kind)
    entries = ['  {}'.format(generate_enum_operand_kind_entry(e, extension_map))
               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', [])]
    enums = [generate_enum_operand_kind(e, exts) for e in enums]
    exts_arrays = generate_extension_arrays(exts)

    # We have a few operand kinds that require their optional counterpart to
    # exist in the operand info table.
    optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess', 'PackedVectorFormat', 'CooperativeMatrixOperands']
    optional_enums = [e for e in enums if e[0] in optional_enums]
    enums.extend(optional_enums)

    enum_kinds, enum_names, enum_entries = zip(*enums)
    # Mark the last few as optional ones.
    enum_quantifiers = [''] * (len(enums) - len(optional_enums)) + ['?'] * len(optional_enums)
    # And we don't want redefinition of them.
    enum_entries = enum_entries[:-len(optional_enums)]
    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(instructions, operand_kinds):
    """Returns extensions as an alphabetically sorted list of strings."""

    things_with_an_extensions_field = [item for item in instructions]

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

    things_with_an_extensions_field.extend(enumerants)

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

    for item in EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.split():
            # If it's already listed in a grammar, then don't put it in the
            # special exceptions list.
        assert item not in extensions, 'Extension %s is already in a grammar file' % item

    extensions.extend(
        EXTENSIONS_FROM_SPIRV_REGISTRY_AND_NOT_FROM_GRAMMARS.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(operand_kinds):
    """Returns capabilities as a list of JSON objects, in order of
    appearance."""
    enumerants = sum([item.get('enumerants', []) for item in operand_kinds
                      if item.get('kind') in ['Capability']], [])
    return enumerants


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


def generate_extension_to_string_mapping(extensions):
    """Returns mapping function from extensions to corresponding strings."""
    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(extensions):
    """Returns mapping function from strings to corresponding extensions."""

    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(operand_kinds):
    """Returns mapping function from capabilities to corresponding strings.

    We take care to avoid emitting duplicate values.
    """
    cap_str = 'SpvCapability'
    cap_join = ''
    global OUTPUT_LANGUAGE
    if OUTPUT_LANGUAGE == 'c++':
        cap_str = 'spv::Capability'
        cap_join = '::'

    function = 'const char* CapabilityToString(' + cap_str + ' capability) {\n'
    function += '  switch (capability) {\n'
    template = '    case ' + cap_str + cap_join + '{capability}:\n' \
        '      return "{capability}";\n'
    emitted = set()  # The values of capabilities we already have emitted
    for capability in get_capabilities(operand_kinds):
        value = capability.get('value')
        if value not in emitted:
            emitted.add(value)
            function += template.format(capability=capability.get('enumerant'))
    function += '    case ' + cap_str + cap_join + 'Max:\n' \
        '      assert(0 && "Attempting to convert ' + cap_str + cap_join + 'Max to string");\n' \
        '      return "";\n'
    function += '  }\n\n  return "";\n}'
    return function


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


def precondition_operand_kinds(operand_kinds):
    """For operand kinds that have the same number, make sure they all have the
    same extension list."""

    # Map operand kind and value to list of the union of extensions
    # for same-valued enumerants.
    exts = {}
    for kind_entry in operand_kinds:
        kind = kind_entry.get('kind')
        for enum_entry in kind_entry.get('enumerants', []):
            value = enum_entry.get('value')
            key = kind + '.' + str(value)
            if key in exts:
                exts[key].extend(enum_entry.get('extensions', []))
            else:
                exts[key] = enum_entry.get('extensions', [])
            exts[key] = sorted(set(exts[key]))

    # Now make each entry the same list.
    for kind_entry in operand_kinds:
        kind = kind_entry.get('kind')
        for enum_entry in kind_entry.get('enumerants', []):
            value = enum_entry.get('value')
            key = kind + '.' + str(value)
            if len(exts[key]) > 0:
                enum_entry['extensions'] = exts[key]

    return operand_kinds


def prefix_operand_kind_names(prefix, json_dict):
    """Modifies json_dict, by prefixing all the operand kind names
    with the given prefix.  Also modifies their uses in the instructions
    to match.
    """

    old_to_new = {}
    for operand_kind in json_dict["operand_kinds"]:
        old_name = operand_kind["kind"]
        new_name = prefix + old_name
        operand_kind["kind"] = new_name
        old_to_new[old_name] = new_name

    for instruction in json_dict["instructions"]:
        for operand in instruction.get("operands", []):
            replacement = old_to_new.get(operand["kind"])
            if replacement is not None:
                operand["kind"] = replacement


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-cldebuginfo100-grammar', metavar='<path>',
                        type=str, required=False, default=None,
                        help='input JSON grammar file for OpenCL.DebugInfo.100 '
                        '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('--output-language',
                        type=str, required=False, default='c',
                        choices=['c','c++'],
                        help='specify output language type')

    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')
    parser.add_argument('--vendor-operand-kind-prefix', metavar='<string>',
                        type=str, required=False, default=None,
                        help='prefix for operand kinds (to disambiguate operand type enums)')
    args = parser.parse_args()

    global OUTPUT_LANGUAGE
    OUTPUT_LANGUAGE = args.output_language

    # The GN build system needs this because it doesn't handle quoting
    # empty string arguments well.
    if args.vendor_operand_kind_prefix == "...nil...":
        args.vendor_operand_kind_prefix = ""

    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 and
         args.extinst_cldebuginfo100_grammar):
        print('error: --operand-kinds-output requires --spirv-core-grammar '
              'and --extinst-debuginfo-grammar '
              'and --extinst-cldebuginfo100-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:
            core_grammar = json.loads(json_file.read())
            with open(args.extinst_debuginfo_grammar) as debuginfo_json_file:
                debuginfo_grammar = json.loads(debuginfo_json_file.read())
                with open(args.extinst_cldebuginfo100_grammar) as cldebuginfo100_json_file:
                    cldebuginfo100_grammar = json.loads(cldebuginfo100_json_file.read())
                    prefix_operand_kind_names("CLDEBUG100_", cldebuginfo100_grammar)
                    instructions = []
                    instructions.extend(core_grammar['instructions'])
                    instructions.extend(debuginfo_grammar['instructions'])
                    instructions.extend(cldebuginfo100_grammar['instructions'])
                    operand_kinds = []
                    operand_kinds.extend(core_grammar['operand_kinds'])
                    operand_kinds.extend(debuginfo_grammar['operand_kinds'])
                    operand_kinds.extend(cldebuginfo100_grammar['operand_kinds'])
                    extensions = get_extension_list(instructions, operand_kinds)
                    operand_kinds = precondition_operand_kinds(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)
            with open(args.core_insts_output, 'w') as f:
                f.write(generate_instruction_table(
                    core_grammar['instructions']))
            with open(args.operand_kinds_output, 'w') as f:
                f.write(generate_operand_kind_table(operand_kinds))
        if args.extension_enum_output is not None:
            make_path_to_file(args.extension_enum_output)
            with open(args.extension_enum_output, 'w') as f:
                f.write(generate_extension_enum(extensions))
        if args.enum_string_mapping_output is not None:
            make_path_to_file(args.enum_string_mapping_output)
            with open(args.enum_string_mapping_output, 'w') as f:
                f.write(generate_all_string_enum_mappings(
                    extensions, operand_kinds))

    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)
            with open(args.glsl_insts_output, 'w') as f:
                f.write(generate_extended_instruction_table(
                    grammar, 'glsl'))

    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)
            with open(args.opencl_insts_output, 'w') as f:
                f.write(generate_extended_instruction_table(
                    grammar, 'opencl'))

    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('-', '_')
            with open(args.vendor_insts_output, 'w') as f:
                f.write(generate_extended_instruction_table(
                    grammar, name, args.vendor_operand_kind_prefix))


if __name__ == '__main__':
    main()
