// Copyright 2023 Google LLC
//
// 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
//
//     https://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 "mpact/sim/decoder/format.h"

#include <algorithm>
#include <cstdint>
#include <string>
#include <tuple>
#include <utility>

#include "absl/numeric/bits.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "antlr4-runtime/Token.h"
#include "mpact/sim/decoder/format_name.h"
#include "mpact/sim/decoder/overlay.h"

namespace mpact {
namespace sim {
namespace decoder {
namespace bin_format {

using ::mpact::sim::machine_description::instruction_set::ToSnakeCase;

FieldOrFormat::~FieldOrFormat() {
  if (is_field_) {
    delete field_;
  }
  field_ = nullptr;
  format_ = nullptr;
}

// The equality operator compares to verify that the field/format definitions
// are equivalent, i.e., refers to the same bits.
bool FieldOrFormat::operator==(const FieldOrFormat &rhs) const {
  if (is_field_ != rhs.is_field_) return false;
  if (is_field_) {
    if (high_ != rhs.high_) return false;
    if (size_ != rhs.size_) return false;
  } else {
    if (format_ != rhs.format_) return false;
  }
  return true;
}

bool FieldOrFormat::operator!=(const FieldOrFormat &rhs) const {
  return !(*this == rhs);
}

using ::mpact::sim::machine_description::instruction_set::ToPascalCase;

Format::Format(std::string name, int width, BinEncodingInfo *encoding_info)
    : Format(name, width, "", encoding_info) {}

Format::Format(std::string name, int width, std::string base_format_name,
               BinEncodingInfo *encoding_info)
    : name_(name),
      base_format_name_(base_format_name),
      declared_width_(width),
      encoding_info_(encoding_info) {}

Format::~Format() {
  // for (auto &[unused, field_ptr] : field_map_) {
  //   delete field_ptr;
  // }
  field_map_.clear();
  for (auto &[unused, overlay_ptr] : overlay_map_) {
    delete overlay_ptr;
  }
  overlay_map_.clear();
  for (auto *field : field_vec_) {
    delete field;
  }
  field_vec_.clear();
}

// Add a field to the current format with the given width and signed/unsigned
// attribute.
absl::Status Format::AddField(std::string name, bool is_signed, int width) {
  // Make sure that the name isn't used already in the format.
  if (field_map_.contains(name)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Field '", name, "' already defined"));
  }
  auto field = new Field(name, is_signed, width, this);
  field_vec_.push_back(new FieldOrFormat(field));
  field_map_.insert(std::make_pair(name, field));
  return absl::OkStatus();
}

// Add a format reference field - name of another format - to the current
// format. This will be resolved once all the formats have been parsed.
void Format::AddFormatReferenceField(std::string format_alias,
                                     std::string format_name, int size,
                                     antlr4::Token *ctx) {
  field_vec_.push_back(new FieldOrFormat(format_alias, format_name, size, ctx));
}

// Add an overlay to the current format. An overlay is a named alias for a
// not necessarily contiguous nor in order collection of bits in the format.
absl::StatusOr<Overlay *> Format::AddFieldOverlay(std::string name,
                                                  bool is_signed, int width) {
  // Make sure that the name isn't used already in the format.
  if (overlay_map_.contains(name)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Overlay '", name, "' already defined as an overlay"));
  }
  if (field_map_.contains(name)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Overlay '", name, "' already defined as a field"));
  }
  auto overlay = new Overlay(name, is_signed, width, this);
  overlay_map_.insert(std::make_pair(name, overlay));
  return overlay;
}

// Return the named field if it exists, nullptr otherwise.
Field *Format::GetField(absl::string_view field_name) const {
  auto iter = field_map_.find(field_name);
  if (iter == field_map_.end()) return nullptr;
  return iter->second;
}

// Return the named field if it exists, nullptr otherwise.
Overlay *Format::GetOverlay(absl::string_view overlay_name) const {
  auto iter = overlay_map_.find(overlay_name);
  if (iter == overlay_map_.end()) return nullptr;
  return iter->second;
}

// Return the string containing the integer type used to contain the current
// format. If it is greater than 128 bits, will use a byte array (int8_t *).
// If it is 65 to 128 bits, will use absl::[u]int128.
std::string Format::GetUIntType(int bitwidth) const {
  if (bitwidth > 128) return "uint8_t *";
  if (bitwidth > 64) return "absl::uint128";
  return absl::StrCat("uint", GetIntTypeBitWidth(bitwidth), "_t");
}

std::string Format::GetIntType(int bitwidth) const {
  if (bitwidth > 128) return "int8_t *";
  if (bitwidth > 64) return "absl::int128";
  return absl::StrCat("int", GetIntTypeBitWidth(bitwidth), "_t");
}

// Return the int type byte width (1, 2, 4, 8, 16) or (-1 if it's bigger), of
// the integer type that would fit this format.
int Format::GetIntTypeBitWidth(int bitwidth) const {
  auto shift = absl::bit_width(static_cast<unsigned>(bitwidth)) - 1;
  if (absl::popcount(static_cast<unsigned>(bitwidth)) > 1) shift++;
  shift = std::max(shift, 3);
  if (shift > 7) return -1;
  return 1 << shift;
}

// Once all the formats have been read in, this method is called to check the
// format and update any widths that depended on other formats being read in.
absl::Status Format::ComputeAndCheckFormatWidth() {
  // If there is a base format name, look up that format, verify that the widths
  // are the same.
  if (!base_format_name_.empty()) {
    auto *base_format = encoding_info_->GetFormat(base_format_name_);
    if (base_format == nullptr) {
      return absl::InternalError(
          absl::StrCat("Format ", name(), " refers to undefined base format ",
                       base_format_name_));
    }
    if (base_format->declared_width() != declared_width_) {
      return absl::InternalError(absl::StrCat(
          "Format ", name_, " (", declared_width_,
          ") differs in width from base format ", base_format->name(), " (",
          base_format->declared_width(), ")"));
    }
    base_format_ = base_format;
    base_format_->derived_formats_.push_back(this);
  }
  if (computed_width_ == 0) {
    // Go through the list of fields/format references. Get the declared widths
    // of the formats and add to the computed width. Signal error if the
    // computed width differs from the declared width.
    for (auto *field_or_format : field_vec_) {
      // Field.
      if (field_or_format->is_field()) {
        auto *field = field_or_format->field();
        field->high = declared_width_ - computed_width_ - 1;
        field->low = field->high - field->width + 1;
        computed_width_ += field->width;
        extractors_.insert(std::make_pair(field->name, field_or_format));
        continue;
      }

      // Format;
      auto *format = field_or_format->format();
      if (format == nullptr) {
        std::string fmt_name = field_or_format->format_name();
        format = encoding_info_->GetFormat(fmt_name);
        if (format == nullptr) {
          return absl::InternalError(absl::StrCat(
              "Format '", name(), "' refers to undefined format ", fmt_name));
        }
        field_or_format->set_format(format);
      }
      field_or_format->set_high(declared_width_ - computed_width_ - 1);
      computed_width_ += format->declared_width() * field_or_format->size();
      extractors_.insert(
          std::make_pair(field_or_format->format_alias(), field_or_format));
    }
    if (computed_width_ != declared_width_) {
      return absl::InternalError(absl::StrCat(
          "Format '", name_, "' declared width (", declared_width_,
          ") differs from computed width (", computed_width_, ")"));
    }
  }
  for (auto &[name, overlay_ptr] : overlay_map_) {
    auto status = overlay_ptr->ComputeHighLow();
    if (!status.ok()) return status;
    overlay_extractors_.insert(std::make_pair(name, overlay_ptr));
  }
  // Set the type names.
  int_type_name_ = GetIntType(declared_width_);
  uint_type_name_ = absl::StrCat("u", int_type_name_);
  return absl::OkStatus();
}

// The extractor functions in the generated code are all generated within a
// namespace specific to the format they're associated with. However, extractors
// that don't conflict in the bits they select may be promoted to be generated
// in the base format namespace. This method is used to propagate such
// potential promotions upward in the inheritance tree.
void Format::PropagateExtractorsUp() {
  for (auto *fmt : derived_formats_) {
    fmt->PropagateExtractorsUp();
  }
  if (base_format_ != nullptr) {
    // Try to propagate extractors up the inheritance tree.
    for (auto const &[name, field_or_format_ptr] : extractors_) {
      // Ignore those that have a nullptr, they have already failed to be
      // promoted.
      if (field_or_format_ptr == nullptr) continue;
      auto iter = base_format_->extractors_.find(name);
      // If it isn't in the parent, add it.
      if (iter == base_format_->extractors_.end()) {
        base_format_->extractors_.insert(
            std::make_pair(name, field_or_format_ptr));
      } else if (iter->second == nullptr) {
        // Can't promote it, a previous attempt failed.
        continue;
      } else if (*field_or_format_ptr != *(iter->second)) {
        // If the base extractor refers to a different object, fail the
        // promotion.
        base_format_->extractors_[name] = nullptr;
      }
    }
    for (auto const &[name, overlay_ptr] : overlay_extractors_) {
      // Ignore those that have a nullptr, they have already failed to be
      // promoted.
      if (overlay_ptr == nullptr) continue;
      auto iter = base_format_->overlay_extractors_.find(name);
      // If it isn't in the parent, add it.
      if (iter == base_format_->overlay_extractors_.end()) {
        base_format_->overlay_extractors_.insert(
            std::make_pair(name, overlay_ptr));
      } else if (iter->second == nullptr) {
        // Previous attempt fail, don't promote.
        continue;
      } else if (*overlay_ptr != *(iter->second)) {
        // If the base format extractor refers to a different overlay type,
        // fail the promotion.
        base_format_->overlay_extractors_[name] = nullptr;
      }
    }
  }
}

// This is the counterpart to the previous method and cleans up extractors that
// were attempted to be promoted, but couldn't be due to conflicts with others,
// e.g., two fields were named the same in different formats but referred to
// different bits.
void Format::PropagateExtractorsDown() {
  // Remove the extractor entries with null ptrs and any extractors that
  // have been promoted.
  auto e_iter = extractors_.begin();
  while (e_iter != extractors_.end()) {
    auto cur = e_iter++;
    // Failed promotion from derived format extractors.
    if (cur->second == nullptr) {
      extractors_.erase(cur);
      continue;
    }
    // If the name exists in overlay extractors, erase both.
    if (overlay_extractors_.find(cur->first) != overlay_extractors_.end()) {
      overlay_extractors_.erase(cur->first);
      extractors_.erase(cur);
      continue;
    }
  }
  // Remove the overlay extractor entries with null ptrs.
  auto o_iter = overlay_extractors_.begin();
  while (o_iter != overlay_extractors_.end()) {
    auto cur = o_iter++;
    // Failed promotion from derived format extractors.
    if (cur->second == nullptr) {
      overlay_extractors_.erase(cur);
      continue;
    }
    // If the name exists in overlay extractors, erase both.
    if (extractors_.find(cur->first) != extractors_.end()) {
      extractors_.erase(cur->first);
      overlay_extractors_.erase(cur);
      continue;
    }
  }
  for (auto *fmt : derived_formats_) {
    fmt->PropagateExtractorsDown();
  }
}

// Returns true if the current format, or a base format, contains an
// extractor for field 'name'.
bool Format::HasExtract(const std::string &name) const {
  auto iter = extractors_.find(name);
  if ((iter != extractors_.end()) && (iter->second != nullptr)) return true;

  if (base_format_ != nullptr) return base_format_->HasExtract(name);

  return false;
}

// Returns true if the current format, or a base format, contains an
// extractor for overlay 'name'.
bool Format::HasOverlayExtract(const std::string &name) const {
  auto iter = overlay_extractors_.find(name);
  if ((iter != overlay_extractors_.end()) && (iter->second != nullptr)) {
    return true;
  }

  if (base_format_ != nullptr) return base_format_->HasOverlayExtract(name);

  return false;
}

// This method generates the C++ code for the field extractors for the current
// format.
std::string Format::GenerateFieldExtractor(const Field *field) const {
  std::string h_output;
  int return_width = GetIntTypeBitWidth(field->width);
  std::string result_type_name =
      field->is_signed ? GetIntType(return_width) : GetUIntType(return_width);
  std::string argument_type_name = GetUIntType(computed_width_);
  std::string signature = absl::StrCat(
      result_type_name, " Extract", ToPascalCase(field->name), "(",
      computed_width_ > 128 ? "const " : "", argument_type_name, " value)");

  absl::StrAppend(&h_output, "inline ", signature, " {\n");

  // Generate extraction function. For fields it's a simple shift and mask if
  // the source format width <= 64 bits. Slightly more involved with format
  // <= 128 bits. For larger formats use the templated extract helper function.
  std::string expr;
  if (declared_width_ <= 64) {
    uint64_t mask = (1ULL << field->width) - 1;
    if (field->low == 0) {
      expr = absl::StrCat("value & 0x", absl::Hex(mask));
    } else {
      expr = absl::StrCat(" (value >> ", field->low, ") & 0x", absl::Hex(mask));
    }
  } else if (declared_width_ <= 128) {
    absl::StrAppend(&h_output,
                    "  absl::uint128 mask = 1;\n"
                    "  mask = (mask << ",
                    field->width, ") - 1;\n");
    if (field->low == 0) {
      expr = absl::StrCat("value & mask");
    } else {
      expr = absl::StrCat(" (value >> ", field->low, ") & mask");
    }
  } else {
    // For format width > 128 bits, use the templated extract helper function.
    int byte_size = (declared_width_ + 7) / 8;
    expr = absl::StrCat("internal::ExtractBits<", result_type_name, ">(value, ",
                        byte_size, ", ", field->high, ", ", field->width, ")");
  }

  // Add sign-extension if the field is signed.
  std::string sign_extension;
  if (field->is_signed) {
    int shift = return_width - field->width;
    sign_extension =
        absl::StrCat("  ", result_type_name, " result = (", expr, ") << ",
                     shift, ";\n  result = result >> ", shift, ";\n");
    expr = "result";
  }
  if (declared_width_ <= 64) {
    absl::StrAppend(&h_output, sign_extension, "  return ", expr, ";\n}\n\n");
  } else if ((declared_width_ <= 128) && (return_width <= 64)) {
    absl::StrAppend(&h_output, sign_extension, "  return absl::Uint128Low64(",
                    expr, ");\n}\n\n");
  } else {
    absl::StrAppend(&h_output, sign_extension, "  return ", expr, ";\n}\n\n");
  }
  // If the parent format size is not a power of two, also create an extractor
  // that takes a uint8_t * parameter.
  if ((declared_width_ <= 128) &&
      (absl::popcount(static_cast<unsigned>(declared_width_)) > 1)) {
    absl::StrAppend(&h_output, "inline ", result_type_name, " Extract",
                    ToPascalCase(field->name), "(const uint8_t *value) {\n");
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  return internal::ExtractBits<",
                    result_type_name, ">(value, ", byte_size, ", ", field->high,
                    ", ", field->width, ");\n}\n\n");
  }
  return h_output;
}

// This method generates the C++ code for field inserters for the current
// format. That is, the generated code will take the value of a field and insert
// it into the right place in the instruction word.
std::string Format::GenerateFieldInserter(const Field *field) const {
  std::string h_output;
  std::string field_type_name;
  std::string inst_word_type_name = GetUIntType(computed_width_);
  if (declared_width_ <= 128) {
    field_type_name = inst_word_type_name;
  } else {
    field_type_name = GetUIntType(field->width);
  }
  absl::StrAppend(&h_output, "static inline ", inst_word_type_name, " Insert",
                  ToPascalCase(field->name), "(", field_type_name, " value, ",
                  inst_word_type_name, " inst_word) {\n");
  if (declared_width_ <= 64) {
    uint64_t mask = ((1ULL << field->width) - 1) << field->low;
    std::string shift;
    if (field->low != 0) {
      shift = absl::StrCat(" << ", field->low);
    }
    absl::StrAppend(&h_output, "  inst_word = (inst_word & ~0x",
                    absl::Hex(mask), "ULL)", " | ((value", shift, ") & 0x",
                    absl::Hex(mask),
                    "ULL);\n"
                    "  return inst_word;\n"
                    "}\n");
  } else if (declared_width_ <= 128) {
    absl::StrAppend(&h_output,
                    "  absl::uint128 mask = 1;\n"
                    "  mask = (mask << ",
                    field->width, ") - 1;\n");
    if (field->low != 0) {
      absl::StrAppend(&h_output, "  mask = mask << ", field->low, ";\n");
    }
    absl::StrAppend(&h_output,
                    "  inst_word = (inst_word & ~mask) | (value & mask);\n"
                    "  return inst_word;\n"
                    "}\n");
  } else if (field->width <= 128) {
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ", byte_size,
                    ", ", field->high, ", ", field->width,
                    ", value);\n"
                    "  return inst_word;\n"
                    "}\n");
  } else {
    absl::StrAppend(
        &h_output,
        "  LOG(FATAL) << \" Support for fields > 128 bits not implemented - "
        "yet.\";\n"
        "  return 0;\n}\n");
  }
  return h_output;
}

// This method generates the C++ code for overlay inserters for the current
// format. That is, the generated code will take the value of an overlay and
// insert its components into the right places in the instruction word.
std::string Format::GenerateOverlayInserter(Overlay *overlay) const {
  std::string h_output;
  std::string result_type_name = GetUIntType(computed_width_);
  std::string overlay_type_name;
  if (computed_width_ <= 128) {
    overlay_type_name = result_type_name;
  } else {
    overlay_type_name = GetUIntType(overlay->declared_width());
  }
  absl::StrAppend(&h_output, "static inline ", result_type_name, " Insert",
                  ToPascalCase(overlay->name()), "(", overlay_type_name,
                  " value, ", result_type_name, " inst_word) {\n");
  // Mark error if either the overlay or the format is > 64 bits.
  if (overlay->declared_width() > 128) {
    absl::StrAppend(
        &h_output,
        "  LOG(FATAL) << \" Support for overlays > 128 bits not implemented - "
        "yet.\";\n"
        "  return 0;\n}\n");
    return h_output;
  }
  bool use_mask_variable = false;
  int remaining = overlay->declared_width();
  int byte_size = (declared_width_ + 7) / 8;
  if (declared_width_ <= 128) {
    absl::StrAppend(&h_output, "  ", result_type_name, " tmp;\n");
    // Track the leftmost bit in the overlay.
    if (declared_width_ > 64) {
      absl::StrAppend(&h_output, "  absl::uint128 mask;\n");
      use_mask_variable = true;
    }
  } else {
    absl::StrAppend(&h_output, "  ", overlay_type_name, " tmp;\n");
    if (overlay->declared_width() > 64) {
      absl::StrAppend(&h_output, "  absl::uint128 mask;\n");
      use_mask_variable = true;
    }
  }
  for (auto &bits_or_field : overlay->component_vec()) {
    int width = bits_or_field->width();
    // Ignore the bit fields in the overlay.
    if (bits_or_field->high() < 0) {
      remaining -= width;
      continue;
    }
    std::string shift;
    if (remaining - width > 0) {
      shift = absl::StrCat(" >> ", remaining - width);
    }
    if (use_mask_variable) {
      absl::StrAppend(&h_output,
                      "  mask = 1;\n"
                      "  mask = (mask << ",
                      width, ") - 1;\n");
      absl::StrAppend(&h_output, "  tmp = (value ", shift, ") & mask;\n");
    } else {
      uint64_t mask = ((1ULL << width) - 1);
      // Extract the bits from the overlay value for the current component.
      absl::StrAppend(&h_output, "  tmp = (value ", shift, ") & 0x",
                      absl::Hex(mask), "ULL;\n");
    }
    shift.clear();
    if (bits_or_field->low() != 0) {
      shift = absl::StrCat(" << ", bits_or_field->low());
    }
    if (declared_width_ <= 128) {
      absl::StrAppend(&h_output, "  inst_word |= (tmp ", shift, ");\n");
    } else {
      absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ",
                      byte_size, ", ", bits_or_field->high(), ", ", width,
                      ",  tmp);\n");
    }

    remaining -= width;
  }
  absl::StrAppend(&h_output, "  return inst_word;\n}\n");
  return h_output;
}

// This method generates the C++ code for format inserters for the current
// format. That is, the generated code will take the value of a format and
// insert it into the right place in the instruction word.
std::string Format::GenerateFormatInserter(std::string_view format_alias,
                                           const Format *format, int high,
                                           int size) const {
  if (size > 1) {
    return GenerateReplicatedFormatInserter(format_alias, format, high, size);
  }
  return GenerateSingleFormatInserter(format_alias, format, high);
}

std::string Format::GenerateReplicatedFormatInserter(
    std::string_view format_alias, const Format *format, int high,
    int size) const {
  std::string h_output;
  std::string target_type_name = GetUIntType(declared_width_);
  std::string format_type_name;

  if (declared_width_ <= 128) {
    format_type_name = target_type_name;
  } else {
    format_type_name = GetUIntType(format->declared_width());
  }
  absl::StrAppend(&h_output, "static inline ", target_type_name, " Insert",
                  ToPascalCase(format_alias), "(", "int index, ",
                  format_type_name, " value, ", target_type_name,
                  " inst_word) {\n");
  if (format->declared_width() > 128) {
    absl::StrAppend(
        &h_output,
        "  LOG(FATAL) << \" Support for formats > 128 bits not implemented - "
        "yet.\";\n"
        "  return 0;\n}\n");
    return h_output;
  }
  int width = format->declared_width();
  int low = high - width + 1;
  if (declared_width_ <= 64) {
    uint64_t mask = (1ULL << width) - 1;
    absl::StrAppend(&h_output, "  int low = ", low, " - (index * ", width,
                    ");\n"
                    "  return (inst_word & (~0x",
                    absl::Hex(mask), "ULL << low))", " | ((value << low) & (0x",
                    absl::Hex(mask), "ULL << low));\n}\n");
  } else if (declared_width_ <= 128) {
    absl::StrAppend(
        &h_output, "  int low = ", low, " - (index * ", width,
        ");\n"
        "  absl::uint128 mask = 1;\n"
        "  mask = (mask << ",
        width,
        ") - 1;\n"
        "  mask <<= low;\n"
        "  return (inst_word & ~mask) | (value << low) & mask;\n}\n");
  } else {
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ", byte_size,
                    ", ", high, " - (index * ", width, "), ", width,
                    ", value);\n"
                    "  return inst_word;\n}\n");
  }
  return h_output;
}

std::string Format::GenerateSingleFormatInserter(std::string_view format_alias,
                                                 const Format *format,
                                                 int high) const {
  std::string h_output;
  std::string target_type_name = GetUIntType(declared_width_);
  std::string format_type_name;
  if (declared_width_ <= 128) {
    format_type_name = target_type_name;
  } else {
    format_type_name = GetUIntType(format->declared_width());
  }

  absl::StrAppend(&h_output, "static inline ", target_type_name, " Insert",
                  ToPascalCase(format_alias), "(", format_type_name, " value, ",
                  target_type_name, " inst_word) {\n");
  if (format->declared_width() > 128) {
    absl::StrAppend(
        &h_output,
        "  LOG(FATAL) << \" Support for formats > 128 bits not implemented - "
        "yet.\";\n"
        "  return 0;\n}\n");
    return h_output;
  }
  int width = format->declared_width();
  int low = high - width + 1;
  std::string shift;
  if (low != 0) {
    shift = absl::StrCat(" << ", low);
  }
  if (declared_width_ <= 64) {
    uint64_t mask = ((1ULL << width) - 1) << low;
    absl::StrAppend(&h_output, "  return (inst_word & (~0x", absl::Hex(mask),
                    "ULL))", " | ((value ", shift, ") & 0x", absl::Hex(mask),
                    "ULL);\n}\n");
  } else if (declared_width_ <= 128) {
    absl::StrAppend(&h_output,
                    "  absl::uint128 mask = 1;\n"
                    "  mask = (mask << ",
                    width, ") - 1;\n");
    if (low > 0) {
      absl::StrAppend(&h_output, "  mask = mask << ", low, ";\n");
    }
    absl::StrAppend(&h_output, "  return (inst_word & ~mask) | (value ", shift,
                    ") & mask;\n}\n");
  } else {
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ", byte_size,
                    ", ", high, ", ", width,
                    ", value);\n"
                    "  return inst_word;\n}\n");
  }
  return h_output;
}

// This method generates the format extractors for the current format (for when
// a format contains other formats).
std::string Format::GenerateFormatExtractor(absl::string_view format_alias,
                                            const Format *format, int high,
                                            int size) const {
  std::string h_output;  // For each format generate am extractor.
  int width = format->declared_width();
  // An extraction can only be for 64 bits or less.
  if (width > 128) {
    encoding_info_->error_listener()->semanticError(
        nullptr,
        absl::StrCat("Cannot generate a format extractor for format '",
                     format->name(), "': format is wider than 128 bits"));
    return "";
  }
  std::string return_type = GetUIntType(width);
  std::string signature = absl::StrCat("inline ", return_type, " Extract",
                                       ToPascalCase(format_alias), "(");
  if (declared_width_ <= 128) {
    // If the source format is <= 128 bits, then use an int type.
    std::string arg_type = GetUIntType(declared_width_);
    absl::StrAppend(&signature, arg_type, " value");
  } else {
    // Otherwise use a pointer to uint8_t type.
    absl::StrAppend(&signature, "const uint8_t *value");
  }
  // If the format has multiple instances add an index parameter.
  if (size > 1) {
    absl::StrAppend(&signature, ", int index");
  }
  absl::StrAppend(&signature, ")");
  // Now start the body.
  absl::StrAppend(&h_output, signature, " {\n");
  std::string expr;
  if (declared_width_ <= 128) {
    // If the source format can be stored in a uint128 or smaller.
    int low = high - width + 1;
    std::string shift;
    if (size > 1) {
      shift = absl::StrCat("(", low, " + (index - 1) * ", width, ")");
    } else {
      shift = absl::StrCat(low);
    }
    if (declared_width_ <= 64) {
      uint64_t mask = (1ULL << width) - 1;
      expr =
          absl::StrCat("(value >> ", shift, ") & 0x", absl::Hex(mask), ";\n");
      absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
    } else {
      absl::StrAppend(&h_output,
                      "  absl::uint128 mask = 1;\n"
                      "  mask = (mask << ",
                      width, ") - 1;\n");
      expr = absl::StrCat("(value >> ", shift, ") & mask");
      if (width <= 64) {
        absl::StrAppend(&h_output, "  return absl::Uint128Low64(", expr,
                        ");\n}\n\n");
      } else {
        absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
      }
    }
  } else {
    // If the source format is stored in uint8_t[].
    int byte_size = (declared_width_ + 7) / 8;
    expr = absl::StrCat("internal::ExtractBits<", return_type, ">(value, ",
                        byte_size, ", ", high);
    if (size > 1) {
      absl::StrAppend(&expr, " - (index * ", width, ")");
    }
    absl::StrAppend(&expr, ", ", width, ")");
    absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
  }
  // If the parent format size is not a power of two, also create an extractor
  // that takes a uint8_t * parameter.
  if ((declared_width_ <= 128) &&
      (absl::popcount(static_cast<unsigned>(declared_width_)) > 1)) {
    absl::StrAppend(&h_output, "inline ", return_type, " Extract",
                    ToPascalCase(format_alias), "(const uint8_t *value) {\n");
    int byte_size = (declared_width_ + 7) / 8;
    expr = absl::StrCat("internal::ExtractBits<", return_type, ">(value, ",
                        byte_size, ", ", high);
    if (size > 1) {
      absl::StrAppend(&expr, " - (index * ", width, ")");
    }
    absl::StrAppend(&expr, ", ", width, ")");
    absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
  }
  return h_output;
}

// Generates the C++ code for the overlay extractors in the current format.
std::string Format::GenerateOverlayExtractor(Overlay *overlay) const {
  std::string h_output;

  std::string return_type = overlay->is_signed()
                                ? GetIntType(overlay->declared_width())
                                : GetUIntType(overlay->declared_width());

  std::string arg_type = GetUIntType(declared_width_);
  std::string signature =
      absl::StrCat("inline ", return_type, " Extract",
                   ToPascalCase(overlay->name()), "(", arg_type, " value)");

  // Generate definition.
  absl::StrAppend(&h_output, signature,
                  " {\n"
                  "  ",
                  return_type, " result;\n");
  if (declared_width_ <= 64) {
    absl::StrAppend(&h_output,
                    overlay->WriteSimpleValueExtractor("value", "result"));
  } else {
    absl::StrAppend(&h_output, overlay->WriteComplexValueExtractor(
                                   "value", "result", return_type));
  }
  if (overlay->is_signed()) {
    int shift = GetIntTypeBitWidth(overlay->declared_width()) -
                overlay->declared_width();
    absl::StrAppend(&h_output, "  result = result << ", shift,
                    ";\n"
                    "  result = result >> ",
                    shift, ";\n");
  }
  if ((declared_width_ > 64) && (overlay->declared_width() <= 64)) {
    absl::StrAppend(&h_output,
                    "  return UInt128Low64(result();\n"
                    "}\n\n");
  } else {
    absl::StrAppend(&h_output,
                    "  return result;\n"
                    "}\n\n");
  }
  return h_output;
}

// Top level function called to generate all the inserters for this format.
std::string Format::GenerateInserters() const {
  std::string class_output;
  std::string h_output;
  if (extractors_.empty() && overlay_extractors_.empty()) {
    return h_output;
  }
  absl::StrAppend(&h_output, "struct ", ToPascalCase(name()), " {\n\n");
  // First fields and formats.
  for (auto &[unused, field_or_format_ptr] : extractors_) {
    if (field_or_format_ptr->is_field()) {
      auto inserter = GenerateFieldInserter(field_or_format_ptr->field());
      absl::StrAppend(&h_output, inserter);
    } else {
      auto inserter = GenerateFormatInserter(
          field_or_format_ptr->format_alias(), field_or_format_ptr->format(),
          field_or_format_ptr->high(), field_or_format_ptr->size());
      absl::StrAppend(&h_output, inserter);
    }
  }
  // Next the overlays.
  for (auto &[unused, overlay_ptr] : overlay_extractors_) {
    auto inserter = GenerateOverlayInserter(overlay_ptr);
    absl::StrAppend(&h_output, inserter);
  }
  absl::StrAppend(&h_output, "};  // struct ", ToPascalCase(name()), "\n\n");
  return h_output;
}

// Top level function called to generate all the extractors for this format.
std::tuple<std::string, std::string> Format::GenerateExtractors() const {
  std::string class_output;
  std::string h_output;
  if (extractors_.empty() && overlay_extractors_.empty()) {
    return std::tie(h_output, class_output);
  }

  class_output = absl::StrCat("class ", ToPascalCase(name()), " {\n public:\n",
                              "  ", ToPascalCase(name()), "() = default;\n\n");

  // Use a separate namespace for each format.
  h_output = absl::StrCat("namespace ", ToSnakeCase(name()), " {\n\n");

  std::string get_size = absl::StrCat("constexpr int k", ToPascalCase(name()),
                                      "Size = ", declared_width(), ";\n\n");
  absl::StrAppend(&h_output, get_size);
  absl::StrAppend(&class_output, "static ", get_size);

  // First fields and formats.
  for (auto &[unused, field_or_format_ptr] : extractors_) {
    if (field_or_format_ptr->is_field()) {
      auto extractor = GenerateFieldExtractor(field_or_format_ptr->field());
      absl::StrAppend(&h_output, extractor);
      absl::StrAppend(&class_output, "static ", extractor);
    } else {
      auto extractor = GenerateFormatExtractor(
          field_or_format_ptr->format_alias(), field_or_format_ptr->format(),
          field_or_format_ptr->high(), field_or_format_ptr->size());
      absl::StrAppend(&h_output, extractor);
      absl::StrAppend(&class_output, "static ", extractor);
    }
  }

  // Then the overlays.
  for (auto &[unused, overlay_ptr] : overlay_extractors_) {
    auto extractor = GenerateOverlayExtractor(overlay_ptr);
    absl::StrAppend(&h_output, extractor);
    absl::StrAppend(&class_output, "static ", extractor);
  }

  absl::StrAppend(&h_output, "}  // namespace ", ToSnakeCase(name()), "\n\n");
  absl::StrAppend(&class_output, "};\n\n");
  return std::tie(h_output, class_output);
}

bool Format::IsDerivedFrom(const Format *format) {
  if (format == this) return true;
  if (base_format_ == nullptr) return false;
  if (base_format_ == format) return true;
  return base_format_->IsDerivedFrom(format);
}

}  // namespace bin_format
}  // namespace decoder
}  // namespace sim
}  // namespace mpact
