#!/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 compressed grammar tables from SPIR-V JSON grammar."""

import errno
import json
import os.path
import re
import sys
from typing import Dict, List, Tuple, Any

# Find modules relative to the directory containing this script.
# This is needed for hermetic Bazel builds, where the Table files are bundled
# together with this script, while keeping their relative locations.
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from Table.Context import Context
from Table.IndexRange import IndexRange
from Table.Operand import Operand

class GrammarError(Exception):
    pass

# 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_gpu_shader_half_float
SPV_AMD_gpu_shader_int16
SPV_KHR_non_semantic_info
SPV_EXT_relaxed_printf_string_address_space
"""

class ExtInst():
    """
    An extended instruction set.

    Properties:
       prefix: the string prefix for operand enums. Often an empty string.
       file: the location of the JSON grammar file
       name: the name, can be used as an identifier
       enum_name: the enum name, e.g. SPV_EXT_INST_OPENCL_STD
       grammar: the JSON object for the grammar, loaded from the file.
    """
    def __init__(self,spec: str):
        matches = re.fullmatch('^([^,]*),(.*)',spec)
        if matches is None:
            raise Exception("Invalid prefix and path: {}".format(spec))
        self.prefix = matches[1]
        if self.prefix is None:
            self.prefix = ""
        self.file = matches[2]
        matches = re.match('.*extinst\\.(.*)\\.grammar.json', self.file)
        if matches is None:
            raise Exception("Invalid grammar file name: {}".format(self.file))
        self.name = matches[1].replace('-','_').replace('.','_')

        self.enum_name = 'SPV_EXT_INST_TYPE_{}'.format(self.name).upper()
        if self.enum_name == "SPV_EXT_INST_TYPE_OPENCL_STD_100":
            # Live with an old decision, by adjusting this name.
            self.enum_name = "SPV_EXT_INST_TYPE_OPENCL_STD"
        if self.enum_name == "SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO":
            # The version-agnostic grammar file name omits "_100", but the
            # public enum in libspirv.h retains the suffix for compatibility.
            self.enum_name = "SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100"

        self.load()

    def load(self):
        """
        Populates self.grammar from the file.
        Applies the self.prefix to operand enums
        """
        with open(self.file) as json_file:
            self.grammar = json.loads(json_file.read())
            if len(self.prefix) > 0:
                prefix_operand_kind_names(self.prefix, self.grammar)


def convert_min_required_version(version): # (version: str | None) -> str
    """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): # (version: str | None) -> str
    """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 c_bool(b: bool) -> str:
    return 'true' if b else 'false'


def ctype(kind: str, quantifier: str) -> str:
    """Returns the corresponding operand type used in spirv-tools for the given
    operand kind and quantifier used in the JSON grammar.

    Arguments:
      - kind, e.g. 'IdRef'
      - quantifier, e.g. '', '?', '*'

    Returns:
      a string of the enumerant name in spv_operand_type_t
    """
    if kind == '':
        raise Error("operand JSON object missing a 'kind' field")
    # 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())


def convert_operand_kind(obj: Dict[str, str]) -> str:
    """Returns the corresponding operand type used in spirv-tools for the given
    operand kind and quantifier used in the JSON grammar.

    Arguments:
      - obj: an instruction operand, having keys:
          - 'kind', e.g. 'IdRef'
          - optionally, a quantifier: '?' or '*'

    Returns:
      a string of the enumerant name in spv_operand_type_t
    """
    kind = obj.get('kind', '')
    quantifier = obj.get('quantifier', '')
    return ctype(kind, quantifier)


def to_safe_identifier(s: str) -> str:
    """
    Returns a new string with all non-letters converted to underscores,
    and prepending 'k'.
    The result should be safe to use as a C identifier.
    """
    return 'k' + re.sub(r'[^a-zA-Z0-9]', '_', s)


class Grammar():
    """
    Accumulates string and enum tables.
    The extensions and operand kinds lists are fixed at creation time.
    Prints tables for instructions, operand kinds, and underlying string
    and enum tables.
    Assumes an index range is emitted by printing an IndexRange object.
    """
    def __init__(self, extensions: List[str], operand_kinds:List[dict], printing_classes: List[str]) -> None:
        self.context = Context()
        self.extensions = sorted(extensions)
        self.operand_kinds = sorted(operand_kinds, key = lambda ok: convert_operand_kind(ok))
        self.printing_classes = sorted([to_safe_identifier(x) for x in printing_classes])

        # The self.header_ignore_decls are only used to debug the flow.
        # They are copied into the C++ source code where they are more likely
        # to be seen by humans.
        self.header_ignore_decls: List[str] = [self.IndexRangeDecls()]

        # The self.header_decls content goes into core_tables_header.inc to be
        # included in a .h file.
        self.header_decls: List[str] = []
        # The self.body_decls content goes into core_tables_body.inc to be included
        # in a .cpp file.  It includes definitions of static variables and
        # hidden functions.
        self.body_decls: List[str] = []

        if len(self.operand_kinds) == 0:
            raise Exception("operand_kinds should be a non-empty list")
        if len(self.extensions) == 0:
            raise Exception("extensions should be a non-empty list")

        self.ComputePrintingClassDecls()
        self.ComputeExtensionDecls()

        # These operand kinds need to have their optional counterpart to also
        # be represented in the lookup tables, with the same content.
        self.operand_kinds_needing_optional_variant = [
                'ImageOperands',
                'AccessQualifier',
                'MemoryAccess',
                'PackedVectorFormat',
                'CooperativeMatrixOperands',
                'MatrixMultiplyAccumulateOperands',
                'RawAccessChainOperands',
                'FPEncoding',
                'TensorOperands',
                'Capability']

    def dump(self) -> None:
        self.context.dump()

    def IndexRangeDecls(self) -> str:
        return """
struct IndexRange {
  uint32_t first = 0; // index of the first element in the range
  uint32_t count = 0; // number of elements in the range
};
constexpr inline IndexRange IR(uint32_t first, uint32_t count) {
  return {first, count};
}
"""

    def ComputePrintingClassDecls(self) -> str:
        parts: List[str] = []
        parts.append("enum class PrintingClass : uint32_t {");
        parts.extend(["  {},".format(x) for x in self.printing_classes])
        parts.append("};\n")
        self.header_decls.extend(parts)

    def ComputeExtensionDecls(self) -> None:
        parts: List[str] = []
        parts.append("enum Extension : uint32_t {");
        parts.extend(["  {},".format(to_safe_identifier(x)) for x in self.extensions])
        parts.append("};\n")
        self.header_decls.extend(parts)

        parts = []
        parts.append("// Returns the name of an extension, as an index into kStrings")
        parts.append("IndexRange ExtensionToIndexRange(Extension extension) {\n  switch(extension) {")
        for e in self.extensions:
            parts.append('    case Extension::k{}: return {};'.format(e,self.context.AddString(e)))
        parts.append("    default: break;");
        parts.append('  }\n  return {};\n}\n');
        self.body_decls.extend(parts)

        parts = []
        parts.append("""// Extension names and values, ordered by name
// The fields in order are:
//   name, indexing into kStrings
//   enum value""")
        parts.append("static const std::array<NameValue,{}> kExtensionNames{{{{".format(len(self.extensions)))
        for e in self.extensions:
            parts.append('    {{{}, static_cast<uint32_t>({})}},'.format(self.context.AddString(e), to_safe_identifier(e)))
        parts.append("}};\n")
        self.body_decls.extend(parts)

    def ComputeOperandTables(self) -> None:
        """
        Returns the string for the C definitions of the operand kind tables.

        An operand kind such as ImageOperands also has an associated
        operand kind that is an 'optional' variant.
        These are represented as two distinct operand kinds in spv_operand_type_t.
        For example, ImageOperands maps to both SPV_OPERAND_TYPE_IMAGE, and also
        to SPV_OPERAND_TYPE_OPTIONAL_IMAGE.

        The definitions are:
         - kOperandsByValue: a 1-dimensional array of all operand descriptions
           sorted first by operand kind, then by operand value.
           Only non-optional operand kinds are represented here.

         - kOperandsByValueRangeByKind: a function mapping from operand kind to
           the index range into kOperandByValue.
           This has mappings for both concrete and corresponding optional operand kinds.

         - kOperandNames: a 1-dimensional array of all operand NameIndex
           entries, sorted first by operand kinds, then by operand name.
           The name part is represented by an index range into the string table.
           The index part is the index of this name's entry into the by-value array.
           This can have more entries than the by-value array, because names
           can have string aliases. For example,the MemorySemantics value 0
           is named both "Relaxed" and "None".
           Only non-optional operand kinds are represented here.

         - kOperandNamesRangeByKind: a mapping from operand kind to the index
           range into kOperandNames.
           This has mappings for both concrete and corresponding optional operand kinds.
        """

        self.header_ignore_decls.append(
"""
struct NameIndex {
  // Location of the null-terminated name in the global string table.
  IndexRange name;
  // Index of this name's entry in in the associated by-value table.
  uint32_t index;
};
struct NameValue {
  // Location of the null-terminated name in the global string table.
  IndexRange name;
  // Enum value in the binary format.
  uint32_t value;
};
// Describes a SPIR-V operand.
struct OperandDesc {
  uint32_t value;
  IndexRange operands_range;      // Indexes kOperandSpans
  IndexRange name_range;          // Indexes kStrings
  IndexRange aliases_range;       // Indexes kAliasSpans
  IndexRange capabilities_range;  // Indexes kCapabilitySpans
  // A set of extensions that enable this feature. If empty then this operand
  // value is in core and its availability is subject to minVersion. The
  // assembler, binary parser, and disassembler ignore this rule, so you can
  // freely process invalid modules.
  IndexRange extensions_range;  // Indexes kExtensionSpans
  // Minimal core SPIR-V version required for this feature, if without
  // extensions. ~0u means reserved for future use. ~0u and non-empty
  // extension lists means only available in extensions.
  uint32_t minVersion;
  uint32_t lastVersion;
  utils::Span<spv_operand_type_t> operands() const;
  utils::Span<char> name() const;
  utils::Span<IndexRange> aliases() const;
  utils::Span<spv::Capability> capabilities() const;
  utils::Span<spvtools::Extension> extensions() const;
  OperandDesc(const OperandDesc&) = delete;
  OperandDesc(OperandDesc&&) = delete;
};
""")

        def ShouldEmit(operand_kind_json: Dict[str,any]):
            """ Returns true if we should emit a table for the given
            operand kind.
            """
            category = operand_kind_json.get('category')
            return category in ['ValueEnum', 'BitEnum']

        # Populate kOperandsByValue
        operands_by_value: List[str] = []
        operands_by_value_by_kind: Dict[str,IndexRange] = {}
        # Maps the operand kind and value to the index into kOperandsByValue
        index_by_kind_and_value: Dict[Tuple(str,int),int] = {}
        index = 0
        for operand_kind_json in self.operand_kinds:
            kind_key: str = convert_operand_kind(operand_kind_json)
            if ShouldEmit(operand_kind_json):
                operands = [Operand(o) for o in operand_kind_json['enumerants']]
                operand_descs: List[str] = []
                for o in sorted(operands, key = lambda o: o.value):
                    suboperands = [convert_operand_kind(p) for p in o.parameters]
                    desc = [
                        o.value,
                        self.context.AddStringList('operand', suboperands),
                        str(self.context.AddString(o.enumerant)) + '/* {} */'.format(o.enumerant),
                        self.context.AddStringList('alias', o.aliases),
                        self.context.AddStringList('capability', o.capabilities),
                        self.context.AddStringList('extension', o.extensions),
                        convert_min_required_version(o.version),
                        convert_max_required_version(o.lastVersion),
                    ]
                    operand_descs.append('{' + ','.join([str(d) for d in desc]) + '}}, // {}'.format(kind_key))
                    index_by_kind_and_value[(kind_key,o.value)] = index
                    index += 1
                operands_by_value_by_kind[kind_key] = IndexRange(len(operands_by_value), len(operand_descs))
                operands_by_value.extend(operand_descs)
            else:
                pass

        parts = []
        parts.append("""// Operand descriptions, ordered by (operand kind, operand enum value).
// The fields in order are:
//   enum value
//   operands, an IndexRange into kOperandSpans
//   name, a character-counting IndexRange into kStrings
//   aliases, an IndexRange into kAliasSpans
//   capabilities, an IndexRange into kCapabilitySpans
//   extensions, as an IndexRange into kExtensionSpans
//   version, first version of SPIR-V that has it
//   lastVersion, last version of SPIR-V that has it""")
        parts.append("static const std::array<OperandDesc, {}> kOperandsByValue{{{{".format(len(operands_by_value)))
        parts.extend(['  ' + str(x) for x in operands_by_value])
        parts.append("}};\n")
        self.body_decls.extend(parts)

        parts = []
        parts.append("""// Maps an operand kind to possible operands for that kind.
// The result is an IndexRange into kOperandsByValue, and the operands
// are sorted by value within that span.
// An optional variant of a kind maps to the details for the corresponding
// concrete operand kind.""")
        parts.append("IndexRange OperandByValueRangeForKind(spv_operand_type_t type) {\n  switch(type) {")
        for kind_key, ir in operands_by_value_by_kind.items():
            parts.append("    case {}: return {};".format(
                kind_key,
                str(operands_by_value_by_kind[kind_key])))
        for kind in self.operand_kinds_needing_optional_variant:
            non_optional_kind = ctype(kind,'')
            if non_optional_kind in operands_by_value_by_kind:
                parts.append("    case {}: return {};".format(
                    ctype(kind, '?'),
                    str(operands_by_value_by_kind[ctype(kind,'')])))
            else:
                raise GrammarError(
                        "error: unknown operand type {}, from JSON grammar operand '{}':".format(non_optional_kind, kind) +
                        " consider updating spv_operand_type_t in spirv-tools/libspirv.h")
            
        parts.append("    default: break;");
        parts.append("  }\n  return IR(0,0);\n}\n")
        self.body_decls.extend(parts)

        # Populate kOperandNames
        operand_names: List[Tuple[IndexRange,int]] = []
        name_range_for_kind: Dict[str,IndexRange] = {}
        for operand_kind_json in self.operand_kinds:
            kind_key: str = convert_operand_kind(operand_kind_json)
            if ShouldEmit(operand_kind_json):
                operands = [Operand(o) for o in operand_kind_json['enumerants']]
                tuples: List[Tuple[str,int,str]] = []
                for o in operands:
                    tuples.append((o.enumerant, o.value, kind_key))
                    for a in o.aliases:
                        tuples.append((a, o.value, kind_key))
                tuples = sorted(tuples, key = lambda t: t[0])
                ir_tuples = [(self.context.AddString(t[0]),t[1],t[2]) for t in tuples]
                name_range_for_kind[kind_key] = IndexRange(len(operand_names), len(ir_tuples))
                operand_names.extend(ir_tuples)
            else:
                pass
        operand_name_strings: List[str] = []
        for i in range(0, len(operand_names)):
            ir, value, kind_key = operand_names[i]
            index = index_by_kind_and_value[(kind_key,value)]
            operand_name_strings.append('{{{}, {}}}, // {} {} in {}'.format(
                str(ir),index,i,self.context.GetString(ir),kind_key))

        parts: List[str] = []
        parts.append("""// Operand names and index into kOperandsByValue, ordered by (operand kind, name)
// The fields in order are:
//   name, either the primary name or an alias, indexing into kStrings
//   index into the kOperandsByValue array""")
        parts.append("static const std::array<NameIndex, {}> kOperandNames{{{{".format(len(operand_name_strings)))
        parts.extend(['  ' + str(x) for x in operand_name_strings])
        parts.append("}};\n")
        self.body_decls.extend(parts)

        parts.append("""// Maps an operand kind to possible names for operands of that kind.
// The result is an IndexRange into kOperandNames, and the names
// are sorted by name within that span.
// An optional variant of a kind maps to the details for the corresponding
// concrete operand kind.""")
        parts = ["IndexRange OperandNameRangeForKind(spv_operand_type_t type) {\n  switch(type) {"]
        for kind_key, ir in name_range_for_kind.items():
            parts.append("    case {}: return {};".format(
                kind_key,
                str(name_range_for_kind[kind_key])))
        for kind in self.operand_kinds_needing_optional_variant:
            parts.append("    case {}: return {};".format(
                ctype(kind, '?'),
                str(name_range_for_kind[ctype(kind,'')])))
        parts.append("    default: break;");
        parts.append("  }\n  return IR(0,0);\n}\n")
        self.body_decls.extend(parts)


    def ComputeInstructionTables(self, insts) -> None:
        """
        Creates declarations for instruction tables.
        Populates self.header_ignore_decls, self.body_decls.

        Params:
            insts: an array of instructions objects using the JSON schema
        """
        self.header_ignore_decls.append("""
// Describes an Instruction
struct InstructionDesc {
  const spv::Op value;
  const bool hasResult;
  const bool hasType;
  const IndexRange operands_range;      // Indexes kOperandSpans
  const IndexRange name_range;          // Indexes kStrings
  const IndexRange aliases_range;       // Indexes kAliasSpans
  const IndexRange capabilities_range;  // Indexes kCapbilitySpans
  // A set of extensions that enable this feature. If empty then this operand
  // value is in core and its availability is subject to minVersion. The
  // assembler, binary parser, and disassembler ignore this rule, so you can
  // freely process invalid modules.
  const IndexRange extensions_range;    // Indexes kExtensionSpans
  // Minimal core SPIR-V version required for this feature, if without
  // extensions. ~0u means reserved for future use. ~0u and non-empty
  // extension lists means only available in extensions.
  uint32_t minVersion;
  uint32_t lastVersion;
  PrintingClass printingClass; // Section of SPIR-V spec. e.g. kComposite, kImage
  utils::Span<spv_operand_type_t> operands() const;
  utils::Span<char> name() const;
  utils::Span<IndexRange> aliases() const;
  utils::Span<spv::Capability> capabilities() const;
  utils::Span<spvtools::Extension> extensions() const;
  OperandDesc(const OperandDesc&) = delete;
  OperandDesc(OperandDesc&&) = delete;
};
""")

        # Create the array of InstructionDesc
        lines: List[str] = []
        # Maps the opcode name (without "Op" prefix) to its index in the table.
        index_by_opcode: Dict[int,int] = {}
        # Sort by opcode, so lookup can use binary search
        for inst in sorted(insts, key = lambda inst: int(inst['opcode'])):
            parts: List[str] = []

            opname: str = inst['opname']

            operand_kinds = [convert_operand_kind(o) for o in inst.get('operands',[])]
            if opname == 'OpExtInst' and operand_kinds[-1] == 'SPV_OPERAND_TYPE_VARIABLE_ID':
                # The published grammar uses 'sequence of ID' at the
                # end of the ExtInst operands. But SPIRV-Tools uses
                # a specific pattern based on the particular opcode.
                # Drop it here.
                # See https://github.com/KhronosGroup/SPIRV-Tools/issues/233
                operand_kinds.pop()

            hasResult = 'SPV_OPERAND_TYPE_RESULT_ID' in operand_kinds
            hasType = 'SPV_OPERAND_TYPE_TYPE_ID' in operand_kinds

            # Remove the "Op" prefix from opcode alias names
            aliases = [name[2:] for name in inst.get('aliases',[])]

            parts.extend([
                'spv::Op::' + opname,
                c_bool(hasResult),
                c_bool(hasType),
                self.context.AddStringList('operand', operand_kinds),
                self.context.AddString(opname[2:]),
                self.context.AddStringList('alias', aliases),
                self.context.AddStringList('capability', inst.get('capabilities',[])),
                self.context.AddStringList('extension', inst.get('extensions',[])),
                convert_min_required_version(inst.get('version', None)),
                convert_max_required_version(inst.get('lastVersion', None)),
                'PrintingClass::' + to_safe_identifier(inst.get('class','@exclude'))
            ])

            index_by_opcode[int(inst['opcode'])] = len(lines)
            lines.append('{{{}}},'.format(', '.join([str(x) for x in parts])))
        parts = []
        parts.append("""// Instruction descriptions, ordered by opcode.
// The fields in order are:
//   opcode
//   a boolean indicating if the instruction produces a result ID
//   a boolean indicating if the instruction result ID has a type
//   operands, an IndexRange into kOperandSpans
//   opcode name (without the 'Op' prefix), a character-counting IndexRange into kStrings
//   aliases, an IndexRange into kAliasSpans
//   capabilities, an IndexRange into kCapabilitySpans
//   extensions, as an IndexRange into kExtensionSpans
//   version, first version of SPIR-V that has it
//   lastVersion, last version of SPIR-V that has it""")
        parts.append("static const std::array<InstructionDesc, {}> kInstructionDesc{{{{".format(len(lines)));
        parts.extend(['  ' + l for l in lines])
        parts.append("}};\n");
        self.body_decls.extend(parts)

        # Create kInstructionNames.
        opcode_name_entries: List[str] = []
        name_value_pairs: List[Tuple[str,int]] = []
        for i in insts:
            name_value_pairs.append((i['opname'][2:], i['opcode']))
            for a in i.get('aliases',[]):
                name_value_pairs.append((a[2:], i['opcode']))
        name_value_pairs = sorted(name_value_pairs)
        inst_name_strings: List[str] = []
        for i in range(0, len(name_value_pairs)):
            name, value = name_value_pairs[i]
            ir = self.context.AddString(name)
            index = index_by_opcode[value]
            inst_name_strings.append('{{{}, {}}}, // {} {}'.format(str(ir),index,i,name))
        parts: List[str] = []
        parts.append("""// Opcode strings (without the 'Op' prefix) and opcode values, ordered by name.
// The fields in order are:
//   name, either the primary name or an alias, indexing into kStrings
//   index into kInstructionDesc""")
        parts.append("static const std::array<NameIndex, {}> kInstructionNames{{{{".format(len(inst_name_strings)))
        parts.extend(['  ' + str(x) for x in inst_name_strings])
        parts.append("}};\n")
        self.body_decls.extend(parts)


    def ComputeExtendedInstructions(self, extinsts) -> None:
        """
        Generates tables for extended instructions

        Args:
            self
            extinsts: a list of extinst objects
        """

        """
            ExtInstDesc {
             value:         uint32_t
             name:          IndexRange
             operands:      IndexRange
             capabilities:  IndexRange
            }

        The definitions are:
         - kExtInstByValue: a 1-dimensional array of all operand descriptions
           sorted first by extended instruction enum, then by operand value.

         - ExtInstByValueRangeForKind: a function mapping from extinst enum to
           the index range into kExtInstByValue.

         - kExtInstNames: a 1-dimensional array of all extinst name-index pairs,
           sorted first by extinst enum, then by operand name.
           The name part is represented by an index range into the string table.
           The index part is the index of this name's entry in the kExtInstByValue
           array.

         - kExtInstNamesRangeByKind: a mapping from operand kind to the index
           range into kOperandNames.
           This has mappings for both concrete and corresponding optional operand kinds.
        """

        # Create kExtInstByValue
        by_value: List[List[Any]] = []
        by_value_by_kind: Dict[str,IndexRange] = {}
        index_by_kind_and_opcode: Dict[Tuple[str,int],int] = {}
        index = 0
        for e in extinsts:
            insts_in_set = []
            for inst in sorted(e.grammar['instructions'], key = lambda inst: inst['opcode']):
                operands = [convert_operand_kind(o) for o in inst.get('operands',[])]
                inst_parts = [
                    inst['opcode'],
                    self.context.AddStringList('operand', operands),
                    self.context.AddString(inst['opname']),
                    self.context.AddStringList('capability', inst.get('capabilities',[])),
                ]
                inst_parts = [str(x) for x in inst_parts]
                insts_in_set.append('    {{{}}}, // {} in {}'.format(
                        ','.join(inst_parts), inst['opname'], e.name))
                index_by_kind_and_opcode[(e.enum_name,int(inst['opcode']))] = index
                index += 1
            by_value_by_kind[e.enum_name] = IndexRange(len(by_value), len(insts_in_set))
            by_value.extend(insts_in_set)

        parts: List[str] = []
        parts.append("""// Extended instruction descriptions, ordered by (extinst enum, opcode value).
// The fields in order are:
//   enum value
//   operands, an IndexRange into kOperandSpans
//   name, a character-counting IndexRange into kStrings
//   capabilities, an IndexRange into kCapabilitySpans""")
        parts.append("static const std::array<ExtInstDesc, {}> kExtInstByValue{{{{".format(len(by_value)))
        parts.extend(by_value)
        parts.append('}};\n')
        self.body_decls.extend(parts)

        # Create kExtInstByValueRangeForKind
        parts = []
        parts.append("""// Maps an extended instruction enum to possible names for operands of that kind.
// The result is an IndexRange into kOperandNames, and the names
// are sorted by name within that span.
// An optional variant of a kind maps to the details for the corresponding
// concrete operand kind.""")
        parts = ["IndexRange ExtInstByValueRangeForKind(spv_ext_inst_type_t type) {\n  switch(type) {"]
        for name, ir in by_value_by_kind.items():
            parts.append("    case {}: return {};".format(name, ir))
        parts.append("    default: break;");
        parts.append("  }\n  return IR(0,0);\n}\n")
        self.body_decls.extend(parts)

        # Create kExtInstNames
        parts = []
        by_name: List[List[Any]] = []
        by_name_by_kind: Dict[str,IndexRange] = {}
        for e in extinsts:
            # Sort by name within a set
            insts_by_name = sorted(e.grammar['instructions'], key = lambda i: i['opname'])
            insts_in_set = []
            for inst in insts_by_name:
                index = index_by_kind_and_opcode[(e.enum_name,int(inst['opcode']))]
                insts_in_set.append(
                        '    {{{}, {}}}, // {} in {}'.format(
                                str(self.context.AddString(inst['opname'])),
                                index,
                                inst['opname'],
                                e.name))
            by_name_by_kind[e.enum_name] = IndexRange(len(by_name), len(insts_in_set))
            by_name.extend(insts_in_set)
        parts.append("""// Extended instruction opcode names sorted by extended instruction kind, then opcode name.
// The fields in order are:
//   name
//   index into kExtInstByValue""")
        parts.append("static const std::array<NameIndex, {}> kExtInstNames{{{{".format(len(by_name)))
        parts.extend(by_name)
        parts.append('}};\n')
        self.body_decls.extend(parts)

        # Create kExtInstNameRangeByKind
        parts = []
        parts.append("""// Maps an extended instruction kind to possible names for instructions of that kind.
// The result is an IndexRange into kExtInstNames, and the names
// are sorted by name within that span.""")
        parts = ["IndexRange ExtInstNameRangeForKind(spv_ext_inst_type_t type) {\n  switch(type) {"]
        for name, ir in by_name_by_kind.items():
            parts.append("    case {}: return {};".format(name, str(ir)))
        parts.append("    default: break;");
        parts.append("  }\n  return IR(0,0);\n}\n")
        self.body_decls.extend(parts)

    def ComputeLeafTables(self) -> None:
        """
        Generates the tables that the instruction and operand tables point to.
        The tables are:
            - the string table
            - the table of sequences of:
               - capabilities
               - extensions
               - operands

        This method must be called after computing instruction and operand tables.
        """

        def c_str(s: str):
            """
            Returns the source for a C string literal or the given string, including
            the explicit null at the end
            """
            return '"{}\\0"'.format(json.dumps(s).strip('"'))

        parts: List[str] = []
        parts.append("// Array of characters, referenced by IndexRanges elsewhere.")
        parts.append("// Each IndexRange denotes a string.")
        parts.append('static const char kStrings[] =');
        parts.extend(['  {} // {}'.format(c_str(s), str(self.context.strings[s])) for s in self.context.string_buffer])
        parts.append(';\n');
        self.body_decls.extend(parts);

        parts: List[str] = []
        parts.append("""// Array of IndexRanges, where each represents a string by referencing
// the kStrings table.
// This array contains all sequences of alias strings used in the grammar.
// This table is referenced by an IndexRange elsewhere, i.e. by the 'aliases'
// field of an instruction or operand description.""")
        parts.append('static const IndexRange kAliasSpans[] = {');
        ranges = self.context.range_buffer['alias']
        for i in range(0, len(ranges)):
            ir = ranges[i]
            parts.append('  {}, // {} {}'.format(str(ir), i, self.context.GetString(ir)))
        parts.append('};\n');
        self.body_decls.extend(parts);

        parts = []
        parts.append("// Array of capabilities, referenced by IndexRanges elsewhere.")
        parts.append("// Contains all sequences of capabilities used in the grammar.")
        parts.append('static const spv::Capability kCapabilitySpans[] = {');
        capability_ranges = self.context.range_buffer['capability']
        for i in range(0, len(capability_ranges)):
            ir = capability_ranges[i]
            cap = self.context.GetString(ir)
            parts.append('  spv::Capability::{}, // {}'.format(cap, i))
        parts.append('};\n');
        self.body_decls.extend(parts);

        parts = []
        parts.append("// Array of extensions, referenced by IndexRanges elsewhere.")
        parts.append("// Contains all sequences of extensions used in the grammar.")
        parts.append('static const spvtools::Extension kExtensionSpans[] = {');
        ranges = self.context.range_buffer['extension']
        for i in range(0, len(ranges)):
            ir = ranges[i]
            name = self.context.GetString(ir)
            parts.append('  spvtools::Extension::k{}, // {}'.format(name, i))
        parts.append('};\n');
        self.body_decls.extend(parts);

        parts = []
        parts.append("// Array of operand types, referenced by IndexRanges elsewhere.")
        parts.append("// Contains all sequences of operand types used in the grammar.")
        parts.append('static const spv_operand_type_t kOperandSpans[] = {');
        ranges = self.context.range_buffer['operand']
        for i in range(0, len(ranges)):
            ir = ranges[i]
            name = self.context.GetString(ir)
            parts.append('  {}, // {}'.format(name, i))
        parts.append('};\n');
        self.body_decls.extend(parts)


def make_path_to_file(f: str) -> None:
    """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 get_extension_list(instructions, operand_kinds):
    """Returns extensions as an alphabetically sorted list of strings.

    Args:
      instructions: list of instruction objects, using the JSON grammar file schema
      operand_kinds: list of operand_kind objects, using the JSON grammar file schema
    """

    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 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', metavar='<path>',
                        type=str, action='append', required=False, default=None,
                        help='extended instruction info: an enum prefix, then a comma, then'
                        ' the file location of the JSON grammar')

    parser.add_argument('--core-tables-body-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for core SPIR-V grammar tables to be included in .cpp')
    parser.add_argument('--core-tables-header-output', metavar='<path>',
                        type=str, required=False, default=None,
                        help='output file for core SPIR-V grammar tables to be included in .h')

    args = parser.parse_args()

    if args.spirv_core_grammar is None:
        print('error: missing --spirv-core-grammar ')
        sys.exit(1)
    if (args.core_tables_body_output is None) and (args.core_tables_header_output is None):
        print('error: need at least one of --core-tables-body-output --core-tables-header-output ')
        sys.exit(1)
    if len(args.extinst) < 1:
        print('error: missing --extinst ')
        sys.exit(1)

    # Load the JSON grammar files.
    extinsts = sorted([ExtInst(e) for e in args.extinst], key = lambda e: e.name)
    with open(args.spirv_core_grammar) as json_file:
        core_grammar = json.loads(json_file.read())
        printing_class: List[str] = [e['tag'] for e in core_grammar['instruction_printing_class']]

    # Collect all operand kinds and instructions, so we can generate
    # extension lists, capability lists, and alias lists.
    # Make a copy to avoid polluting the instruction list.
    instructions = [x for x in core_grammar['instructions']]
    operand_kinds = [x for x in core_grammar['operand_kinds']]
    for e in extinsts:
        instructions.extend(e.grammar.get('instructions',[]))
        operand_kinds.extend(e.grammar.get('operand_kinds',[]))

    extensions = get_extension_list(instructions, operand_kinds)

    g = Grammar(extensions, operand_kinds, printing_class)
    g.ComputeOperandTables()
    g.ComputeInstructionTables(core_grammar['instructions'])
    g.ComputeExtendedInstructions(extinsts)
    g.ComputeLeafTables()

    if args.core_tables_body_output is not None:
        make_path_to_file(args.core_tables_body_output)
        with open(args.core_tables_body_output, 'w') as f:
            f.write('\n'.join(g.body_decls))
    if args.core_tables_header_output is not None:
        make_path_to_file(args.core_tables_header_output)
        with open(args.core_tables_header_output, 'w') as f:
            f.write('\n'.join(g.header_decls))
    sys.exit(0)


if __name__ == '__main__':
  try:
    main()
  except GrammarError as ge:
    print(ge)
    sys.exit(1)
