// Copyright (c) 2015-2016 The Khronos Group 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.

#ifndef SOURCE_TEXT_HANDLER_H_
#define SOURCE_TEXT_HANDLER_H_

#include <iomanip>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>

#include "source/diagnostic.h"
#include "source/instruction.h"
#include "source/text.h"
#include "spirv-tools/libspirv.h"

namespace spvtools {

// Structures

// This is a lattice for tracking types.
enum class IdTypeClass {
  kBottom = 0,  // We have no information yet.
  kScalarIntegerType,
  kScalarFloatType,
  kOtherType
};

// Contains ID type information that needs to be tracked across all Ids.
// Bitwidth is only valid when type_class is kScalarIntegerType or
// kScalarFloatType.
struct IdType {
  uint32_t bitwidth;  // Safe to assume that we will not have > 2^32 bits.
  bool isSigned;      // This is only significant if type_class is integral.
  IdTypeClass type_class;
  spv_fp_encoding_t encoding;
};

// Default equality operator for IdType. Tests if all members are the same.
inline bool operator==(const IdType& first, const IdType& second) {
  return (first.bitwidth == second.bitwidth) &&
         (first.isSigned == second.isSigned) &&
         (first.type_class == second.type_class);
}

// Tests whether any member of the IdTypes do not match.
inline bool operator!=(const IdType& first, const IdType& second) {
  return !(first == second);
}

// A value representing an unknown type.
extern const IdType kUnknownType;

// Returns true if the type is a scalar integer type.
inline bool isScalarIntegral(const IdType& type) {
  return type.type_class == IdTypeClass::kScalarIntegerType;
}

// Returns true if the type is a scalar floating point type.
inline bool isScalarFloating(const IdType& type) {
  return type.type_class == IdTypeClass::kScalarFloatType;
}

// Returns the number of bits in the type.
// This is only valid for bottom, scalar integer, and scalar floating
// classes.  For bottom, assume 32 bits.
inline int assumedBitWidth(const IdType& type) {
  switch (type.type_class) {
    case IdTypeClass::kBottom:
      return 32;
    case IdTypeClass::kScalarIntegerType:
    case IdTypeClass::kScalarFloatType:
      return type.bitwidth;
    default:
      break;
  }
  // We don't care about this case.
  return 0;
}

// A templated class with a static member function Clamp, where Clamp
// sets a referenced value of type T to 0 if T is an unsigned
// integer type, and returns true if it modified the referenced
// value.
template <typename T, typename = void>
class ClampToZeroIfUnsignedType {
 public:
  // The default specialization does not clamp the value.
  static bool Clamp(T*) { return false; }
};

// The specialization of ClampToZeroIfUnsignedType for unsigned integer
// types.
template <typename T>
class ClampToZeroIfUnsignedType<
    T, typename std::enable_if<std::is_unsigned<T>::value>::type> {
 public:
  static bool Clamp(T* value_pointer) {
    if (*value_pointer) {
      *value_pointer = 0;
      return true;
    }
    return false;
  }
};

// Encapsulates the data used during the assembly of a SPIR-V module.
class AssemblyContext {
 public:
  AssemblyContext(spv_text text, const MessageConsumer& consumer,
                  std::set<uint32_t>&& ids_to_preserve = std::set<uint32_t>())
      : current_position_({}),
        consumer_(consumer),
        text_(text),
        bound_(1),
        next_id_(1),
        ids_to_preserve_(std::move(ids_to_preserve)) {}

  // Assigns a new integer value to the given text ID, or returns the previously
  // assigned integer value if the ID has been seen before.
  uint32_t spvNamedIdAssignOrGet(const char* textValue);

  // Returns the largest largest numeric ID that has been assigned.
  uint32_t getBound() const;

  // Advances position to point to the next word in the input stream.
  // Returns SPV_SUCCESS on success.
  spv_result_t advance();

  // Sets word to the next word in the input text. Fills next_position with
  // the next location past the end of the word.  Returns an error if the
  // context is invalid or has no more text. Otherwise returns SPV_SUCCESS.
  // Assumes the next part of the input is not whitespace.
  //
  // A word ends at the next comment or whitespace.  However, double-quoted
  // strings remain intact, and a backslash always escapes the next character.
  // The input stream may end before a matching double-quote, or immediately
  // after a backslash. Both such cases still count as success.
  spv_result_t getWord(std::string* word, spv_position next_position);

  // Returns true if the next word in the input is the start of a new Opcode.
  bool startsWithOp();

  // Returns true if the next word in the input is the start of a new
  // instruction.
  bool isStartOfNewInst();

  // Returns a diagnostic object initialized with current position in the input
  // stream, and for the given error code. Any data written to this object will
  // show up in pDiagnsotic on destruction.
  DiagnosticStream diagnostic(spv_result_t error) {
    return DiagnosticStream(current_position_, consumer_, "", error);
  }

  // Returns a diagnostic object with the default assembly error code.
  DiagnosticStream diagnostic() {
    // The default failure for assembly is invalid text.
    return diagnostic(SPV_ERROR_INVALID_TEXT);
  }

  // Returns then next character in the input stream.
  char peek() const;

  // Returns true if there is more text in the input stream.
  bool hasText() const;

  // Seeks the input stream forward by 'size' characters.
  void seekForward(uint32_t size);

  // Sets the current position in the input stream to the given position.
  void setPosition(const spv_position_t& newPosition) {
    current_position_ = newPosition;
  }

  // Returns the current position in the input stream.
  const spv_position_t& position() const { return current_position_; }

  // Appends the given 32-bit value to the given instruction.
  // Returns SPV_SUCCESS if the value could be correctly inserted in the
  // instruction.
  spv_result_t binaryEncodeU32(const uint32_t value, spv_instruction_t* pInst);

  // Appends the given string to the given instruction.
  // Returns SPV_SUCCESS if the value could be correctly inserted in the
  // instruction.
  spv_result_t binaryEncodeString(const char* value, spv_instruction_t* pInst);

  // Appends the given numeric literal to the given instruction.
  // Validates and respects the bitwidth supplied in the IdType argument.
  // If the type is of class kBottom the value will be encoded as a
  // 32-bit integer.
  // Returns SPV_SUCCESS if the value could be correctly added to the
  // instruction.  Returns the given error code on failure, and emits
  // a diagnostic if that error code is not SPV_FAILED_MATCH.
  spv_result_t binaryEncodeNumericLiteral(const char* numeric_literal,
                                          spv_result_t error_code,
                                          const IdType& type,
                                          spv_instruction_t* pInst);

  // Returns the IdType associated with this type-generating value.
  // If the type has not been previously recorded with recordTypeDefinition,
  // kUnknownType  will be returned.
  IdType getTypeOfTypeGeneratingValue(uint32_t value) const;

  // Returns the IdType that represents the return value of this Value
  // generating instruction.
  // If the value has not been recorded with recordTypeIdForValue, or the type
  // could not be determined kUnknownType will be returned.
  IdType getTypeOfValueInstruction(uint32_t value) const;

  // Tracks the type-defining instruction. The result of the tracking can
  // later be queried using getValueType.
  // pInst is expected to be completely filled in by the time this instruction
  // is called.
  // Returns SPV_SUCCESS on success, or SPV_ERROR_INVALID_VALUE on error.
  spv_result_t recordTypeDefinition(const spv_instruction_t* pInst);

  // Tracks the relationship between the value and its type.
  spv_result_t recordTypeIdForValue(uint32_t value, uint32_t type);

  // Records the given Id as being the import of the given extended instruction
  // type.
  spv_result_t recordIdAsExtInstImport(uint32_t id, spv_ext_inst_type_t type);

  // Returns the extended instruction type corresponding to the import with
  // the given Id, if it exists.  Returns SPV_EXT_INST_TYPE_NONE if the
  // id is not the id for an extended instruction type.
  spv_ext_inst_type_t getExtInstTypeForId(uint32_t id) const;

  // Returns a set consisting of each ID generated by spvNamedIdAssignOrGet from
  // a numeric ID text representation. For example, generated from "%12" but not
  // from "%foo".
  std::set<uint32_t> GetNumericIds() const;

 private:
  // Maps ID names to their corresponding numerical ids.
  using spv_named_id_table = std::unordered_map<std::string, uint32_t>;
  // Maps type-defining IDs to their IdType.
  using spv_id_to_type_map = std::unordered_map<uint32_t, IdType>;
  // Maps Ids to the id of their type.
  using spv_id_to_type_id = std::unordered_map<uint32_t, uint32_t>;

  spv_named_id_table named_ids_;
  spv_id_to_type_map types_;
  spv_id_to_type_id value_types_;
  // Maps an extended instruction import Id to the extended instruction type.
  std::unordered_map<uint32_t, spv_ext_inst_type_t> import_id_to_ext_inst_type_;
  spv_position_t current_position_;
  MessageConsumer consumer_;
  spv_text text_;
  uint32_t bound_;
  uint32_t next_id_;
  std::set<uint32_t> ids_to_preserve_;
};

}  // namespace spvtools

#endif  // SOURCE_TEXT_HANDLER_H_
