// Copyright (c) 2015-2020 The Khronos Group Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
// reserved.
//
// 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.

#include "source/binary.h"

#include <algorithm>
#include <cassert>
#include <cstring>
#include <iterator>
#include <limits>
#include <string>
#include <unordered_map>
#include <vector>

#include "source/assembly_grammar.h"
#include "source/diagnostic.h"
#include "source/ext_inst.h"
#include "source/latest_version_spirv_header.h"
#include "source/opcode.h"
#include "source/operand.h"
#include "source/spirv_constant.h"
#include "source/spirv_endian.h"
#include "source/table2.h"
#include "source/util/string_utils.h"

spv_result_t spvBinaryHeaderGet(const spv_const_binary binary,
                                const spv_endianness_t endian,
                                spv_header_t* pHeader) {
  if (!binary->code) return SPV_ERROR_INVALID_BINARY;
  if (binary->wordCount < SPV_INDEX_INSTRUCTION)
    return SPV_ERROR_INVALID_BINARY;
  if (!pHeader) return SPV_ERROR_INVALID_POINTER;

  // TODO: Validation checking?
  pHeader->magic = spvFixWord(binary->code[SPV_INDEX_MAGIC_NUMBER], endian);
  pHeader->version = spvFixWord(binary->code[SPV_INDEX_VERSION_NUMBER], endian);
  // Per 2.3.1 version's high and low bytes are 0
  if ((pHeader->version & 0x000000ff) || pHeader->version & 0xff000000)
    return SPV_ERROR_INVALID_BINARY;
  // Minimum version was 1.0 and max version is defined by SPV_VERSION.
  if (pHeader->version < SPV_SPIRV_VERSION_WORD(1, 0) ||
      pHeader->version > SPV_VERSION)
    return SPV_ERROR_INVALID_BINARY;

  pHeader->generator =
      spvFixWord(binary->code[SPV_INDEX_GENERATOR_NUMBER], endian);
  pHeader->bound = spvFixWord(binary->code[SPV_INDEX_BOUND], endian);
  pHeader->schema = spvFixWord(binary->code[SPV_INDEX_SCHEMA], endian);
  pHeader->instructions = &binary->code[SPV_INDEX_INSTRUCTION];

  return SPV_SUCCESS;
}

std::string spvDecodeLiteralStringOperand(const spv_parsed_instruction_t& inst,
                                          const uint16_t operand_index) {
  assert(operand_index < inst.num_operands);
  const spv_parsed_operand_t& operand = inst.operands[operand_index];

  return spvtools::utils::MakeString(inst.words + operand.offset,
                                     operand.num_words);
}

namespace {

// A SPIR-V binary parser.  A parser instance communicates detailed parse
// results via callbacks.
class Parser {
 public:
  // The user_data value is provided to the callbacks as context.
  Parser(const spv_const_context context, void* user_data,
         spv_parsed_header_fn_t parsed_header_fn,
         spv_parsed_instruction_fn_t parsed_instruction_fn)
      : grammar_(context),
        consumer_(context->consumer),
        user_data_(user_data),
        parsed_header_fn_(parsed_header_fn),
        parsed_instruction_fn_(parsed_instruction_fn) {}

  // Parses the specified binary SPIR-V module, issuing callbacks on a parsed
  // header and for each parsed instruction.  Returns SPV_SUCCESS on success.
  // Otherwise returns an error code and issues a diagnostic.
  spv_result_t parse(const uint32_t* words, size_t num_words,
                     spv_diagnostic* diagnostic);

 private:
  // All remaining methods work on the current module parse state.

  // Like the parse method, but works on the current module parse state.
  spv_result_t parseModule();

  // Parses an instruction at the current position of the binary.  Assumes
  // the header has been parsed, the endian has been set, and the word index is
  // still in range.  Advances the parsing position past the instruction, and
  // updates other parsing state for the current module.
  // On success, returns SPV_SUCCESS and issues the parsed-instruction callback.
  // On failure, returns an error code and issues a diagnostic.
  spv_result_t parseInstruction();

  // Parses an instruction operand with the given type, for an instruction
  // starting at inst_offset words into the SPIR-V binary.
  // If the SPIR-V binary is the same endianness as the host, then the
  // endian_converted_inst_words parameter is ignored.  Otherwise, this method
  // appends the words for this operand, converted to host native endianness,
  // to the end of endian_converted_inst_words.  This method also updates the
  // expected_operands parameter, and the scalar members of the inst parameter.
  // On success, returns SPV_SUCCESS, advances past the operand, and pushes a
  // new entry on to the operands vector.  Otherwise returns an error code and
  // issues a diagnostic.
  spv_result_t parseOperand(size_t inst_offset, spv_parsed_instruction_t* inst,
                            const spv_operand_type_t type,
                            std::vector<uint32_t>* endian_converted_inst_words,
                            std::vector<spv_parsed_operand_t>* operands,
                            spv_operand_pattern_t* expected_operands);

  // Records the numeric type for an operand according to the type information
  // associated with the given non-zero type Id.  This can fail if the type Id
  // is not a type Id, or if the type Id does not reference a scalar numeric
  // type.  On success, return SPV_SUCCESS and populates the num_words,
  // number_kind, and number_bit_width fields of parsed_operand.
  spv_result_t setNumericTypeInfoForType(spv_parsed_operand_t* parsed_operand,
                                         uint32_t type_id);

  // Records the number type for an instruction at the given offset, if that
  // instruction generates a type.  For types that aren't scalar numbers,
  // record something with number kind SPV_NUMBER_NONE.
  void recordNumberType(size_t inst_offset,
                        const spv_parsed_instruction_t* inst);

  // Returns a diagnostic stream object initialized with current position in
  // the input stream, and for the given error code. Any data written to the
  // returned object will be propagated to the current parse's diagnostic
  // object.
  spvtools::DiagnosticStream diagnostic(spv_result_t error) {
    return spvtools::DiagnosticStream({0, 0, _.instruction_count}, consumer_,
                                      "", error);
  }

  // Returns a diagnostic stream object with the default parse error code.
  spvtools::DiagnosticStream diagnostic() {
    // The default failure for parsing is invalid binary.
    return diagnostic(SPV_ERROR_INVALID_BINARY);
  }

  // Issues a diagnostic describing an exhaustion of input condition when
  // trying to decode an instruction operand, and returns
  // SPV_ERROR_INVALID_BINARY.
  spv_result_t exhaustedInputDiagnostic(size_t inst_offset, spv::Op opcode,
                                        spv_operand_type_t type) {
    return diagnostic() << "End of input reached while decoding Op"
                        << spvOpcodeString(opcode) << " starting at word "
                        << inst_offset
                        << ((_.word_index < _.num_words) ? ": truncated "
                                                         : ": missing ")
                        << spvOperandTypeStr(type) << " operand at word offset "
                        << _.word_index - inst_offset << ".";
  }

  // Returns the endian-corrected word at the current position.
  uint32_t peek() const { return peekAt(_.word_index); }

  // Returns the endian-corrected word at the given position.
  uint32_t peekAt(size_t index) const {
    assert(index < _.num_words);
    return spvFixWord(_.words[index], _.endian);
  }

  // Data members

  const spvtools::AssemblyGrammar grammar_;        // SPIR-V syntax utility.
  const spvtools::MessageConsumer& consumer_;      // Message consumer callback.
  void* const user_data_;                          // Context for the callbacks
  const spv_parsed_header_fn_t parsed_header_fn_;  // Parsed header callback
  const spv_parsed_instruction_fn_t
      parsed_instruction_fn_;  // Parsed instruction callback

  // Describes the format of a typed literal number.
  struct NumberType {
    spv_number_kind_t type;
    uint32_t bit_width;
    spv_fp_encoding_t encoding;
  };

  // The state used to parse a single SPIR-V binary module.
  struct State {
    State(const uint32_t* words_arg, size_t num_words_arg,
          spv_diagnostic* diagnostic_arg)
        : words(words_arg),
          num_words(num_words_arg),
          diagnostic(diagnostic_arg),
          word_index(0),
          instruction_count(0),
          endian(),
          requires_endian_conversion(false) {
      // Temporary storage for parser state within a single instruction.
      // Most instructions require fewer than 25 words or operands.
      operands.reserve(25);
      endian_converted_words.reserve(25);
      expected_operands.reserve(25);
    }
    State() : State(0, 0, nullptr) {}
    const uint32_t* words;       // Words in the binary SPIR-V module.
    size_t num_words;            // Number of words in the module.
    spv_diagnostic* diagnostic;  // Where diagnostics go.
    size_t word_index;           // The current position in words.
    size_t instruction_count;    // The count of processed instructions
    spv_endianness_t endian;     // The endianness of the binary.
    // Is the SPIR-V binary in a different endianness from the host native
    // endianness?
    bool requires_endian_conversion;

    // Maps a result ID to its type ID.  By convention:
    //  - a result ID that is a type definition maps to itself.
    //  - a result ID without a type maps to 0.  (E.g. for OpLabel)
    std::unordered_map<uint32_t, uint32_t> id_to_type_id;
    // Maps a type ID to its number type description.
    std::unordered_map<uint32_t, NumberType> type_id_to_number_type_info;
    // Maps an ExtInstImport id to the extended instruction type.
    std::unordered_map<uint32_t, spv_ext_inst_type_t>
        import_id_to_ext_inst_type;

    // Used by parseOperand
    std::vector<spv_parsed_operand_t> operands;
    std::vector<uint32_t> endian_converted_words;
    spv_operand_pattern_t expected_operands;
  } _;
};

spv_result_t Parser::parse(const uint32_t* words, size_t num_words,
                           spv_diagnostic* diagnostic_arg) {
  _ = State(words, num_words, diagnostic_arg);

  const spv_result_t result = parseModule();

  // Clear the module state.  The tables might be big.
  _ = State();

  return result;
}

spv_result_t Parser::parseModule() {
  if (!_.words) return diagnostic() << "Missing module.";

  if (_.num_words < SPV_INDEX_INSTRUCTION)
    return diagnostic() << "Module has incomplete header: only " << _.num_words
                        << " words instead of " << SPV_INDEX_INSTRUCTION;

  // Check the magic number and detect the module's endianness.
  spv_const_binary_t binary{_.words, _.num_words};
  if (spvBinaryEndianness(&binary, &_.endian)) {
    return diagnostic() << "Invalid SPIR-V magic number '" << std::hex
                        << _.words[0] << "'.";
  }
  _.requires_endian_conversion = !spvIsHostEndian(_.endian);

  // Process the header.
  spv_header_t header;
  if (spvBinaryHeaderGet(&binary, _.endian, &header)) {
    // It turns out there is no way to trigger this error since the only
    // failure cases are already handled above, with better messages.
    return diagnostic(SPV_ERROR_INTERNAL)
           << "Internal error: unhandled header parse failure";
  }
  if (parsed_header_fn_) {
    if (auto error = parsed_header_fn_(user_data_, _.endian, header.magic,
                                       header.version, header.generator,
                                       header.bound, header.schema)) {
      return error;
    }
  }

  // Process the instructions.
  _.word_index = SPV_INDEX_INSTRUCTION;
  while (_.word_index < _.num_words)
    if (auto error = parseInstruction()) return error;

  // Running off the end should already have been reported earlier.
  assert(_.word_index == _.num_words);

  return SPV_SUCCESS;
}

spv_result_t Parser::parseInstruction() {
  _.instruction_count++;

  // The zero values for all members except for opcode are the
  // correct initial values.
  spv_parsed_instruction_t inst = {};

  const uint32_t first_word = peek();

  // If the module's endianness is different from the host native endianness,
  // then converted_words contains the endian-translated words in the
  // instruction.
  _.endian_converted_words.clear();
  _.endian_converted_words.push_back(first_word);

  // After a successful parse of the instruction, the inst.operands member
  // will point to this vector's storage.
  _.operands.clear();

  assert(_.word_index < _.num_words);
  // Decompose and check the first word.
  uint16_t inst_word_count = 0;
  spvOpcodeSplit(first_word, &inst_word_count, &inst.opcode);
  if (inst_word_count < 1) {
    return diagnostic() << "Invalid instruction word count: "
                        << inst_word_count;
  }
  const spvtools::InstructionDesc* opcode_desc = nullptr;
  if (spvtools::LookupOpcode(static_cast<spv::Op>(inst.opcode), &opcode_desc))
    return diagnostic() << "Invalid opcode: " << inst.opcode;

  // Advance past the opcode word.  But remember the of the start
  // of the instruction.
  const size_t inst_offset = _.word_index;
  _.word_index++;

  // Maintains the ordered list of expected operand types.
  // For many instructions we only need the {numTypes, operandTypes}
  // entries in opcode_desc.  However, sometimes we need to modify
  // the list as we parse the operands. This occurs when an operand
  // has its own logical operands (such as the LocalSize operand for
  // ExecutionMode), or for extended instructions that may have their
  // own operands depending on the selected extended instruction.
  _.expected_operands.clear();

  spvPushOperandTypes(opcode_desc->operands(), &_.expected_operands);

  while (_.word_index < inst_offset + inst_word_count) {
    const uint16_t inst_word_index = uint16_t(_.word_index - inst_offset);
    if (_.expected_operands.empty()) {
      return diagnostic() << "Invalid instruction Op"
                          << opcode_desc->name().data() << " starting at word "
                          << inst_offset << ": expected no more operands after "
                          << inst_word_index
                          << " words, but stated word count is "
                          << inst_word_count << ".";
    }

    spv_operand_type_t type =
        spvTakeFirstMatchableOperand(&_.expected_operands);

    if (auto error =
            parseOperand(inst_offset, &inst, type, &_.endian_converted_words,
                         &_.operands, &_.expected_operands)) {
      return error;
    }
  }

  if (!_.expected_operands.empty() &&
      !spvOperandIsOptional(_.expected_operands.back())) {
    return diagnostic() << "End of input reached while decoding Op"
                        << opcode_desc->name().data() << " starting at word "
                        << inst_offset << ": expected more operands after "
                        << inst_word_count << " words.";
  }

  if ((inst_offset + inst_word_count) != _.word_index) {
    return diagnostic() << "Invalid word count: Op"
                        << opcode_desc->name().data() << " starting at word "
                        << inst_offset << " says it has " << inst_word_count
                        << " words, but found " << _.word_index - inst_offset
                        << " words instead.";
  }

  // Check the computed length of the endian-converted words vector against
  // the declared number of words in the instruction.  If endian conversion
  // is required, then they should match.  If no endian conversion was
  // performed, then the vector only contains the initial opcode/word-count
  // word.
  assert(!_.requires_endian_conversion ||
         (inst_word_count == _.endian_converted_words.size()));
  assert(_.requires_endian_conversion ||
         (_.endian_converted_words.size() == 1));

  if (_.requires_endian_conversion) {
    // We must wait until here to set this pointer, because the vector might
    // have been be resized while we accumulated its elements.
    inst.words = _.endian_converted_words.data();
  } else {
    // If no conversion is required, then just point to the underlying binary.
    // This saves time and space.
    inst.words = _.words + inst_offset;
  }
  inst.num_words = inst_word_count;

  recordNumberType(inst_offset, &inst);

  // We must wait until here to set this pointer, because the vector might
  // have been be resized while we accumulated its elements.
  inst.operands = _.operands.data();
  inst.num_operands = uint16_t(_.operands.size());

  // Issue the callback.  The callee should know that all the storage in inst
  // is transient, and will disappear immediately afterward.
  if (parsed_instruction_fn_) {
    if (auto error = parsed_instruction_fn_(user_data_, &inst)) return error;
  }

  return SPV_SUCCESS;
}

spv_result_t Parser::parseOperand(size_t inst_offset,
                                  spv_parsed_instruction_t* inst,
                                  const spv_operand_type_t type,
                                  std::vector<uint32_t>* words,
                                  std::vector<spv_parsed_operand_t>* operands,
                                  spv_operand_pattern_t* expected_operands) {
  const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
  // We'll fill in this result as we go along.
  spv_parsed_operand_t parsed_operand;
  parsed_operand.offset = uint16_t(_.word_index - inst_offset);
  // Most operands occupy one word.  This might be be adjusted later.
  parsed_operand.num_words = 1;
  // The type argument is the one used by the grammar to parse the instruction.
  // But it can exposes internal parser details such as whether an operand is
  // optional or actually represents a variable-length sequence of operands.
  // The resulting type should be adjusted to avoid those internal details.
  // In most cases, the resulting operand type is the same as the grammar type.
  parsed_operand.type = type;

  // Assume non-numeric values.  This will be updated for literal numbers.
  parsed_operand.number_kind = SPV_NUMBER_NONE;
  parsed_operand.number_bit_width = 0;

  if (_.word_index >= _.num_words)
    return exhaustedInputDiagnostic(inst_offset, opcode, type);

  const uint32_t word = peek();

  // Do the words in this operand have to be converted to native endianness?
  // True for all but literal strings.
  bool convert_operand_endianness = true;

  switch (type) {
    case SPV_OPERAND_TYPE_TYPE_ID:
      if (!word)
        return diagnostic(SPV_ERROR_INVALID_ID) << "Error: Type Id is 0";
      inst->type_id = word;
      break;

    case SPV_OPERAND_TYPE_RESULT_ID:
      if (!word)
        return diagnostic(SPV_ERROR_INVALID_ID) << "Error: Result Id is 0";
      inst->result_id = word;
      // Save the result ID to type ID mapping.
      // In the grammar, type ID always appears before result ID.
      if (_.id_to_type_id.find(inst->result_id) != _.id_to_type_id.end())
        return diagnostic(SPV_ERROR_INVALID_ID)
               << "Id " << inst->result_id << " is defined more than once";
      // Record it.
      // A regular value maps to its type.  Some instructions (e.g. OpLabel)
      // have no type Id, and will map to 0.  The result Id for a
      // type-generating instruction (e.g. OpTypeInt) maps to itself.
      _.id_to_type_id[inst->result_id] =
          spvOpcodeGeneratesType(opcode) ? inst->result_id : inst->type_id;
      break;

    case SPV_OPERAND_TYPE_ID:
    case SPV_OPERAND_TYPE_OPTIONAL_ID:
      if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0";
      parsed_operand.type = SPV_OPERAND_TYPE_ID;

      if (spvIsExtendedInstruction(opcode) && parsed_operand.offset == 3) {
        // The current word is the extended instruction set Id.
        // Set the extended instruction set type for the current instruction.
        auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word);
        if (ext_inst_type_iter == _.import_id_to_ext_inst_type.end()) {
          return diagnostic(SPV_ERROR_INVALID_ID)
                 << "OpExtInst set Id " << word
                 << " does not reference an OpExtInstImport result Id";
        }
        inst->ext_inst_type = ext_inst_type_iter->second;
      }
      break;

    case SPV_OPERAND_TYPE_SCOPE_ID:
    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
      // Check for trivially invalid values.  The operand descriptions already
      // have the word "ID" in them.
      if (!word) return diagnostic() << spvOperandTypeStr(type) << " is 0";
      break;

    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
      assert(spvIsExtendedInstruction(opcode));
      assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE);

      const spvtools::ExtInstDesc* desc = nullptr;
      if (spvtools::LookupExtInst(inst->ext_inst_type, word, &desc) ==
          SPV_SUCCESS) {
        // Push VARIABLE_ID so extra trailing operands from future NSDI
        // versions are silently absorbed after the instruction-specific ones.
        if (spvExtInstIsNonSemantic(inst->ext_inst_type)) {
          expected_operands->push_back(SPV_OPERAND_TYPE_VARIABLE_ID);
        }

        // if we know about this ext inst, push the expected operands
        spvPushOperandTypes(desc->operands(), expected_operands);
      } else {
        // if we don't know this extended instruction and the set isn't
        // non-semantic, we cannot process further
        if (!spvExtInstIsNonSemantic(inst->ext_inst_type)) {
          return diagnostic()
                 << "Invalid extended instruction number: " << word;
        } else {
          // for non-semantic instruction sets, we know the form of all such
          // extended instructions contains a series of IDs as parameters
          expected_operands->push_back(SPV_OPERAND_TYPE_VARIABLE_ID);
        }
      }
    } break;

    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
      assert(spv::Op::OpSpecConstantOp == opcode);
      if (word > static_cast<uint32_t>(spv::Op::Max) ||
          grammar_.lookupSpecConstantOpcode(spv::Op(word))) {
        return diagnostic()
               << "Invalid " << spvOperandTypeStr(type) << ": " << word;
      }
      const spvtools::InstructionDesc* opcode_entry = nullptr;
      if (spvtools::LookupOpcode(spv::Op(word), &opcode_entry)) {
        return diagnostic(SPV_ERROR_INTERNAL)
               << "OpSpecConstant opcode table out of sync";
      }
      // OpSpecConstant opcodes must have a type and result. We've already
      // processed them, so skip them when preparing to parse the other
      // operants for the opcode.
      assert(opcode_entry->hasType);
      assert(opcode_entry->hasResult);
      assert(opcode_entry->operands().size() >= 2);
      spvPushOperandTypes(opcode_entry->operands().subspan(2),
                          expected_operands);
    } break;

    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
      // These are regular single-word literal integer operands.
      // Post-parsing validation should check the range of the parsed value.
      parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_INTEGER;
      // It turns out they are always unsigned integers!
      parsed_operand.number_kind = SPV_NUMBER_UNSIGNED_INT;
      parsed_operand.number_bit_width = 32;
      break;

    case SPV_OPERAND_TYPE_LITERAL_FLOAT:
      // These are regular single-word literal float operands.
      parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_FLOAT;
      parsed_operand.number_kind = SPV_NUMBER_FLOATING;
      parsed_operand.number_bit_width = 32;
      break;

    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
    case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
      parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER;
      if (opcode == spv::Op::OpSwitch) {
        // The literal operands have the same type as the value
        // referenced by the selector Id.
        const uint32_t selector_id = peekAt(inst_offset + 1);
        const auto type_id_iter = _.id_to_type_id.find(selector_id);
        if (type_id_iter == _.id_to_type_id.end() ||
            type_id_iter->second == 0) {
          return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
                              << " has no type";
        }
        uint32_t type_id = type_id_iter->second;

        if (selector_id == type_id) {
          // Recall that by convention, a result ID that is a type definition
          // maps to itself.
          return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
                              << " is a type, not a value";
        }
        if (auto error = setNumericTypeInfoForType(&parsed_operand, type_id))
          return error;
        if (parsed_operand.number_kind != SPV_NUMBER_UNSIGNED_INT &&
            parsed_operand.number_kind != SPV_NUMBER_SIGNED_INT) {
          return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
                              << " is not a scalar integer";
        }
      } else {
        assert(opcode == spv::Op::OpConstant ||
               opcode == spv::Op::OpSpecConstant);
        // The literal number type is determined by the type Id for the
        // constant.
        assert(inst->type_id);
        if (auto error =
                setNumericTypeInfoForType(&parsed_operand, inst->type_id))
          return error;
      }
      break;

    case SPV_OPERAND_TYPE_LITERAL_STRING:
    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: {
      const size_t max_words = _.num_words - _.word_index;
      std::string string =
          spvtools::utils::MakeString(_.words + _.word_index, max_words, false);

      if (string.length() == max_words * 4)
        return exhaustedInputDiagnostic(inst_offset, opcode, type);

      // Make sure we can record the word count without overflow.
      //
      // This error can't currently be triggered because of validity
      // checks elsewhere.
      const size_t string_num_words = string.length() / 4 + 1;
      if (string_num_words > std::numeric_limits<uint16_t>::max()) {
        return diagnostic() << "Literal string is longer than "
                            << std::numeric_limits<uint16_t>::max()
                            << " words: " << string_num_words << " words long";
      }
      parsed_operand.num_words = uint16_t(string_num_words);
      parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_STRING;

      if (spv::Op::OpExtInstImport == opcode) {
        // Record the extended instruction type for the ID for this import.
        // There is only one string literal argument to OpExtInstImport,
        // so it's sufficient to guard this just on the opcode.
        const spv_ext_inst_type_t ext_inst_type =
            spvExtInstImportTypeGet(string.c_str());
        if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) {
          return diagnostic()
                 << "Invalid extended instruction import '" << string << "'";
        }
        // We must have parsed a valid result ID.  It's a condition
        // of the grammar, and we only accept non-zero result Ids.
        assert(inst->result_id);
        _.import_id_to_ext_inst_type[inst->result_id] = ext_inst_type;
      }
    } break;

    case SPV_OPERAND_TYPE_CAPABILITY:
    case SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY:
    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
    case SPV_OPERAND_TYPE_MEMORY_MODEL:
    case SPV_OPERAND_TYPE_EXECUTION_MODE:
    case SPV_OPERAND_TYPE_STORAGE_CLASS:
    case SPV_OPERAND_TYPE_DIMENSIONALITY:
    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
    case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
    case SPV_OPERAND_TYPE_DECORATION:
    case SPV_OPERAND_TYPE_BUILT_IN:
    case SPV_OPERAND_TYPE_GROUP_OPERATION:
    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
    case SPV_OPERAND_TYPE_RAY_FLAGS:
    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
    case SPV_OPERAND_TYPE_FPDENORM_MODE:
    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
    case SPV_OPERAND_TYPE_OVERFLOW_MODES:
    case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
    case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
    case SPV_OPERAND_TYPE_FPENCODING:
    case SPV_OPERAND_TYPE_OPTIONAL_FPENCODING:
    case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
    case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
    case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
    case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS: {
      // A single word that is a plain enum value.

      // Map an optional operand type to its corresponding concrete type.
      if (type == SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER)
        parsed_operand.type = SPV_OPERAND_TYPE_ACCESS_QUALIFIER;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT)
        parsed_operand.type = SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_FPENCODING)
        parsed_operand.type = SPV_OPERAND_TYPE_FPENCODING;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_CAPABILITY)
        parsed_operand.type = SPV_OPERAND_TYPE_CAPABILITY;

      const spvtools::OperandDesc* entry = nullptr;
      if (spvtools::LookupOperand(type, word, &entry)) {
        return diagnostic()
               << "Invalid " << spvOperandTypeStr(parsed_operand.type)
               << " operand: " << word;
      }
      // Prepare to accept operands to this operand, if needed.
      spvPushOperandTypes(entry->operands(), expected_operands);
    } break;

    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: {
      const spvtools::OperandDesc* entry = nullptr;
      if (spvtools::LookupOperand(type, word, &entry)) {
        return diagnostic()
               << "Invalid " << spvOperandTypeStr(parsed_operand.type)
               << " operand: " << word
               << ", if you are creating a new source language please use "
                  "value 0 "
                  "(Unknown) and when ready, add your source language to "
                  "SPIRV-Headers";
      }
      // Prepare to accept operands to this operand, if needed.
      spvPushOperandTypes(entry->operands(), expected_operands);
    } break;

    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
    case SPV_OPERAND_TYPE_LOOP_CONTROL:
    case SPV_OPERAND_TYPE_IMAGE:
    case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
    case SPV_OPERAND_TYPE_MEMORY_ACCESS:
    case SPV_OPERAND_TYPE_TENSOR_OPERANDS:
    case SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS:
    case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
    case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
    case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
    case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE:
    case SPV_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS:
    case SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS:
    case SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS: {
      // This operand is a mask.

      // Map an optional operand type to its corresponding concrete type.
      if (type == SPV_OPERAND_TYPE_OPTIONAL_IMAGE)
        parsed_operand.type = SPV_OPERAND_TYPE_IMAGE;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS)
        parsed_operand.type = SPV_OPERAND_TYPE_MEMORY_ACCESS;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS)
        parsed_operand.type = SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS)
        parsed_operand.type = SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS)
        parsed_operand.type =
            SPV_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS;
      if (type == SPV_OPERAND_TYPE_OPTIONAL_TENSOR_OPERANDS)
        parsed_operand.type = SPV_OPERAND_TYPE_TENSOR_OPERANDS;

      // Check validity of set mask bits. Also prepare for operands for those
      // masks if they have any.  To get operand order correct, scan from
      // MSB to LSB since we can only prepend operands to a pattern.
      // The only case in the grammar where you have more than one mask bit
      // having an operand is for image operands.  See SPIR-V 3.14 Image
      // Operands.
      uint32_t remaining_word = word;
      for (uint32_t mask = (1u << 31); remaining_word; mask >>= 1) {
        if (remaining_word & mask) {
          const spvtools::OperandDesc* entry = nullptr;
          if (spvtools::LookupOperand(type, mask, &entry)) {
            return diagnostic()
                   << "Invalid " << spvOperandTypeStr(parsed_operand.type)
                   << " operand: " << word << " has invalid mask component "
                   << mask;
          }
          remaining_word ^= mask;
          spvPushOperandTypes(entry->operands(), expected_operands);
        }
      }
      if (word == 0) {
        // An all-zeroes mask *might* also be valid.
        const spvtools::OperandDesc* entry = nullptr;
        if (SPV_SUCCESS == spvtools::LookupOperand(type, 0, &entry)) {
          // Prepare for its operands, if any.
          spvPushOperandTypes(entry->operands(), expected_operands);
        }
      }
    } break;
    default:
      return diagnostic() << "Internal error: Unhandled operand type: " << type;
  }

  assert(spvOperandIsConcrete(parsed_operand.type));

  operands->push_back(parsed_operand);

  const size_t index_after_operand = _.word_index + parsed_operand.num_words;

  // Avoid buffer overrun for the cases where the operand has more than one
  // word, and where it isn't a string.  (Those other cases have already been
  // handled earlier.)  For example, this error can occur for a multi-word
  // argument to OpConstant, or a multi-word case literal operand for OpSwitch.
  if (_.num_words < index_after_operand)
    return exhaustedInputDiagnostic(inst_offset, opcode, type);

  if (_.requires_endian_conversion) {
    // Copy instruction words.  Translate to native endianness as needed.
    if (convert_operand_endianness) {
      const spv_endianness_t endianness = _.endian;
      std::transform(_.words + _.word_index, _.words + index_after_operand,
                     std::back_inserter(*words),
                     [endianness](const uint32_t raw_word) {
                       return spvFixWord(raw_word, endianness);
                     });
    } else {
      words->insert(words->end(), _.words + _.word_index,
                    _.words + index_after_operand);
    }
  }

  // Advance past the operand.
  _.word_index = index_after_operand;

  return SPV_SUCCESS;
}

spv_result_t Parser::setNumericTypeInfoForType(
    spv_parsed_operand_t* parsed_operand, uint32_t type_id) {
  assert(type_id != 0);
  auto type_info_iter = _.type_id_to_number_type_info.find(type_id);
  if (type_info_iter == _.type_id_to_number_type_info.end()) {
    return diagnostic() << "Type Id " << type_id << " is not a type";
  }
  const NumberType& info = type_info_iter->second;
  if (info.type == SPV_NUMBER_NONE) {
    // This is a valid type, but for something other than a scalar number.
    return diagnostic() << "Type Id " << type_id
                        << " is not a scalar numeric type";
  }

  parsed_operand->number_kind = info.type;
  parsed_operand->number_bit_width = info.bit_width;
  parsed_operand->fp_encoding = info.encoding;
  // Round up the word count.
  parsed_operand->num_words = static_cast<uint16_t>((info.bit_width + 31) / 32);
  return SPV_SUCCESS;
}

void Parser::recordNumberType(size_t inst_offset,
                              const spv_parsed_instruction_t* inst) {
  const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
  if (spvOpcodeGeneratesType(opcode)) {
    NumberType info = {SPV_NUMBER_NONE, 0};
    if (spv::Op::OpTypeInt == opcode) {
      const bool is_signed = peekAt(inst_offset + 3) != 0;
      info.type = is_signed ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT;
      info.bit_width = peekAt(inst_offset + 2);
    } else if (spv::Op::OpTypeFloat == opcode) {
      info.type = SPV_NUMBER_FLOATING;
      info.bit_width = peekAt(inst_offset + 2);
      if (inst->num_words >= 4) {
        const spvtools::OperandDesc* desc = nullptr;
        spv_result_t status = spvtools::LookupOperand(
            SPV_OPERAND_TYPE_FPENCODING, peekAt(inst_offset + 3), &desc);
        if (status == SPV_SUCCESS) {
          info.encoding = spvFPEncodingFromOperandFPEncoding(
              static_cast<spv::FPEncoding>(desc->value));
        } else {
          info.encoding = SPV_FP_ENCODING_UNKNOWN;
        }
      }
    }
    // The *result* Id of a type generating instruction is the type Id.
    _.type_id_to_number_type_info[inst->result_id] = info;
  }
}

}  // anonymous namespace

spv_result_t spvBinaryParse(const spv_const_context context, void* user_data,
                            const uint32_t* code, const size_t num_words,
                            spv_parsed_header_fn_t parsed_header,
                            spv_parsed_instruction_fn_t parsed_instruction,
                            spv_diagnostic* diagnostic) {
  spv_context_t hijack_context = *context;
  if (diagnostic) {
    *diagnostic = nullptr;
    spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, diagnostic);
  }
  Parser parser(&hijack_context, user_data, parsed_header, parsed_instruction);
  return parser.parse(code, num_words, diagnostic);
}

// TODO(dneto): This probably belongs in text.cpp since that's the only place
// that a spv_binary_t value is created.
void spvBinaryDestroy(spv_binary binary) {
  if (binary) {
    if (binary->code) delete[] binary->code;
    delete binary;
  }
}

size_t spv_strnlen_s(const char* str, size_t strsz) {
  if (!str) return 0;
  for (size_t i = 0; i < strsz; i++) {
    if (!str[i]) return i;
  }
  return strsz;
}
