// Copyright 2020 The Tint Authors.
//
// 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 <cstdio>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>

#if TINT_BUILD_SPV_READER
#include "spirv-tools/libspirv.hpp"
#endif  // TINT_BUILD_SPV_READER

#include "tint/tint.h"

namespace {

[[noreturn]] void TintInternalCompilerErrorReporter(
    const tint::diag::List& diagnostics) {
  auto printer = tint::diag::Printer::create(stderr, true);
  tint::diag::Formatter{}.format(diagnostics, printer.get());
  exit(1);
}

enum class Format {
  kNone = -1,
  kSpirv,
  kSpvAsm,
  kWgsl,
  kMsl,
  kHlsl,
};

struct Options {
  bool show_help = false;

  std::string input_filename;
  std::string output_file = "-";  // Default to stdout

  bool parse_only = false;
  bool dump_ast = false;
  bool dawn_validation = false;
  bool demangle = false;
  bool dump_inspector_bindings = false;

  Format format = Format::kNone;

  bool emit_single_entry_point = false;
  tint::ast::PipelineStage stage;
  std::string ep_name;

  std::vector<std::string> transforms;
};

const char kUsage[] = R"(Usage: tint [options] <input-file>

 options:
  --format <spirv|spvasm|wgsl|msl|hlsl>  -- Output format.
                               If not provided, will be inferred from output
                               filename extension:
                                   .spvasm -> spvasm
                                   .spv    -> spirv
                                   .wgsl   -> wgsl
                                   .metal  -> msl
                                   .hlsl   -> hlsl
                               If none matches, then default to SPIR-V assembly.
  -ep <compute|fragment|vertex> <name>  -- Output single entry point
  --output-file <name>      -- Output file name.  Use "-" for standard output
  -o <name>                 -- Output file name.  Use "-" for standard output
  --transform <name list>   -- Runs transforms, name list is comma separated
                               Available transforms:
                                bound_array_accessors
                                emit_vertex_point_size
                                first_index_offset
  --parse-only              -- Stop after parsing the input
  --dump-ast                -- Dump the generated AST to stdout
  --dawn-validation         -- SPIRV outputs are validated with the same flags
                               as Dawn does. Has no effect on non-SPIRV outputs.
  --demangle                -- Preserve original source names. Demangle them.
                               Affects AST dumping, and text-based output languages.
  --dump-inspector-bindings -- Dump reflection data about bindins to stdout.
  -h                        -- This help text)";

#ifdef _MSC_VER
#pragma warning(disable : 4068; suppress : 4100)
#endif
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
Format parse_format(const std::string& fmt) {
#pragma clang diagnostic pop
#ifdef _MSC_VER
#pragma warning(default : 4068)
#endif

#if TINT_BUILD_SPV_WRITER
  if (fmt == "spirv")
    return Format::kSpirv;
  if (fmt == "spvasm")
    return Format::kSpvAsm;
#endif  // TINT_BUILD_SPV_WRITER

#if TINT_BUILD_WGSL_WRITER
  if (fmt == "wgsl")
    return Format::kWgsl;
#endif  // TINT_BUILD_WGSL_WRITER

#if TINT_BUILD_MSL_WRITER
  if (fmt == "msl")
    return Format::kMsl;
#endif  // TINT_BUILD_MSL_WRITER

#if TINT_BUILD_HLSL_WRITER
  if (fmt == "hlsl")
    return Format::kHlsl;
#endif  // TINT_BUILD_HLSL_WRITER

  return Format::kNone;
}

/// @param input input string
/// @param suffix potential suffix string
/// @returns true if input ends with the given suffix.
bool ends_with(const std::string& input, const std::string& suffix) {
  const auto input_len = input.size();
  const auto suffix_len = suffix.size();
  // Avoid integer overflow.
  return (input_len >= suffix_len) &&
         (input_len - suffix_len == input.rfind(suffix));
}

/// @param filename the filename to inspect
/// @returns the inferred format for the filename suffix
#ifdef _MSC_VER
#pragma warning(disable : 4068; suppress : 4100)
#endif
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
Format infer_format(const std::string& filename) {
#pragma clang diagnostic pop
#ifdef _MSC_VER
#pragma warning(default : 4068)
#endif

#if TINT_BUILD_SPV_WRITER
  if (ends_with(filename, ".spv")) {
    return Format::kSpirv;
  }
  if (ends_with(filename, ".spvasm")) {
    return Format::kSpvAsm;
  }
#endif  // TINT_BUILD_SPV_WRITER

#if TINT_BUILD_WGSL_WRITER
  if (ends_with(filename, ".wgsl")) {
    return Format::kWgsl;
  }
#endif  // TINT_BUILD_WGSL_WRITER

#if TINT_BUILD_MSL_WRITER
  if (ends_with(filename, ".metal")) {
    return Format::kMsl;
  }
#endif  // TINT_BUILD_MSL_WRITER

#if TINT_BUILD_HLSL_WRITER
  if (ends_with(filename, ".hlsl")) {
    return Format::kHlsl;
  }
#endif  // TINT_BUILD_HLSL_WRITER

  return Format::kNone;
}

tint::ast::PipelineStage convert_to_pipeline_stage(const std::string& name) {
  if (name == "compute") {
    return tint::ast::PipelineStage::kCompute;
  }
  if (name == "fragment") {
    return tint::ast::PipelineStage::kFragment;
  }
  if (name == "vertex") {
    return tint::ast::PipelineStage::kVertex;
  }
  return tint::ast::PipelineStage::kNone;
}

std::vector<std::string> split_transform_names(std::string list) {
  std::vector<std::string> res;

  std::stringstream str(list);
  while (str.good()) {
    std::string substr;
    getline(str, substr, ',');
    res.push_back(substr);
  }
  return res;
}

std::string TextureDimensionToString(
    tint::inspector::ResourceBinding::TextureDimension dim) {
  switch (dim) {
    case tint::inspector::ResourceBinding::TextureDimension::kNone:
      return "None";
    case tint::inspector::ResourceBinding::TextureDimension::k1d:
      return "1d";
    case tint::inspector::ResourceBinding::TextureDimension::k2d:
      return "2d";
    case tint::inspector::ResourceBinding::TextureDimension::k2dArray:
      return "2dArray";
    case tint::inspector::ResourceBinding::TextureDimension::k3d:
      return "3d";
    case tint::inspector::ResourceBinding::TextureDimension::kCube:
      return "Cube";
    case tint::inspector::ResourceBinding::TextureDimension::kCubeArray:
      return "CubeArray";
  }

  return "Unknown";
}

std::string SampledKindToString(
    tint::inspector::ResourceBinding::SampledKind kind) {
  switch (kind) {
    case tint::inspector::ResourceBinding::SampledKind::kFloat:
      return "Float";
    case tint::inspector::ResourceBinding::SampledKind::kUInt:
      return "UInt";
    case tint::inspector::ResourceBinding::SampledKind::kSInt:
      return "SInt";
    case tint::inspector::ResourceBinding::SampledKind::kUnknown:
      break;
  }

  return "Unknown";
}

std::string ImageFormatToString(
    tint::inspector::ResourceBinding::ImageFormat format) {
  switch (format) {
    case tint::inspector::ResourceBinding::ImageFormat::kR8Unorm:
      return "R8Unorm";
    case tint::inspector::ResourceBinding::ImageFormat::kR8Snorm:
      return "R8Snorm";
    case tint::inspector::ResourceBinding::ImageFormat::kR8Uint:
      return "R8Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kR8Sint:
      return "R8Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kR16Uint:
      return "R16Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kR16Sint:
      return "R16Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kR16Float:
      return "R16Float";
    case tint::inspector::ResourceBinding::ImageFormat::kRg8Unorm:
      return "Rg8Unorm";
    case tint::inspector::ResourceBinding::ImageFormat::kRg8Snorm:
      return "Rg8Snorm";
    case tint::inspector::ResourceBinding::ImageFormat::kRg8Uint:
      return "Rg8Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kRg8Sint:
      return "Rg8Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kR32Uint:
      return "R32Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kR32Sint:
      return "R32Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kR32Float:
      return "R32Float";
    case tint::inspector::ResourceBinding::ImageFormat::kRg16Uint:
      return "Rg16Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kRg16Sint:
      return "Rg16Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kRg16Float:
      return "Rg16Float";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba8Unorm:
      return "Rgba8Unorm";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba8UnormSrgb:
      return "Rgba8UnormSrgb";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba8Snorm:
      return "Rgba8Snorm";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba8Uint:
      return "Rgba8Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba8Sint:
      return "Rgba8Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kBgra8Unorm:
      return "Bgra8Unorm";
    case tint::inspector::ResourceBinding::ImageFormat::kBgra8UnormSrgb:
      return "Bgra8UnormSrgb";
    case tint::inspector::ResourceBinding::ImageFormat::kRgb10A2Unorm:
      return "Rgb10A2Unorm";
    case tint::inspector::ResourceBinding::ImageFormat::kRg11B10Float:
      return "Rg11B10Float";
    case tint::inspector::ResourceBinding::ImageFormat::kRg32Uint:
      return "Rg32Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kRg32Sint:
      return "Rg32Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kRg32Float:
      return "Rg32Float";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba16Uint:
      return "Rgba16Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba16Sint:
      return "Rgba16Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba16Float:
      return "Rgba16Float";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba32Uint:
      return "Rgba32Uint";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba32Sint:
      return "Rgba32Sint";
    case tint::inspector::ResourceBinding::ImageFormat::kRgba32Float:
      return "Rgba32Float";
    case tint::inspector::ResourceBinding::ImageFormat::kNone:
      return "None";
  }
  return "Unknown";
}

std::string ResourceTypeToString(
    tint::inspector::ResourceBinding::ResourceType type) {
  switch (type) {
    case tint::inspector::ResourceBinding::ResourceType::kUniformBuffer:
      return "UniformBuffer";
    case tint::inspector::ResourceBinding::ResourceType::kStorageBuffer:
      return "StorageBuffer";
    case tint::inspector::ResourceBinding::ResourceType::kReadOnlyStorageBuffer:
      return "ReadOnlyStorageBuffer";
    case tint::inspector::ResourceBinding::ResourceType::kSampler:
      return "Sampler";
    case tint::inspector::ResourceBinding::ResourceType::kComparisonSampler:
      return "ComparisonSampler";
    case tint::inspector::ResourceBinding::ResourceType::kSampledTexture:
      return "SampledTexture";
    case tint::inspector::ResourceBinding::ResourceType::kMultisampledTexture:
      return "MultisampledTexture";
    case tint::inspector::ResourceBinding::ResourceType::
        kReadOnlyStorageTexture:
      return "ReadOnlyStorageTexture";
    case tint::inspector::ResourceBinding::ResourceType::
        kWriteOnlyStorageTexture:
      return "WriteOnlyStorageTexture";
    case tint::inspector::ResourceBinding::ResourceType::kDepthTexture:
      return "DepthTexture";
  }

  return "Unknown";
}

bool ParseArgs(const std::vector<std::string>& args, Options* opts) {
  for (size_t i = 1; i < args.size(); ++i) {
    const std::string& arg = args[i];
    if (arg == "--format") {
      ++i;
      if (i >= args.size()) {
        std::cerr << "Missing value for --format argument." << std::endl;
        return false;
      }
      opts->format = parse_format(args[i]);

      if (opts->format == Format::kNone) {
        std::cerr << "Unknown output format: " << args[i] << std::endl;
        return false;
      }
    } else if (arg == "-ep") {
      if (i + 2 >= args.size()) {
        std::cerr << "Missing values for -ep" << std::endl;
        return false;
      }
      i++;
      opts->stage = convert_to_pipeline_stage(args[i]);
      if (opts->stage == tint::ast::PipelineStage::kNone) {
        std::cerr << "Invalid pipeline stage: " << args[i] << std::endl;
        return false;
      }

      i++;
      opts->ep_name = args[i];
      opts->emit_single_entry_point = true;

    } else if (arg == "-o" || arg == "--output-name") {
      ++i;
      if (i >= args.size()) {
        std::cerr << "Missing value for " << arg << std::endl;
        return false;
      }
      opts->output_file = args[i];

    } else if (arg == "-h" || arg == "--help") {
      opts->show_help = true;
    } else if (arg == "--transform") {
      ++i;
      if (i >= args.size()) {
        std::cerr << "Missing value for " << arg << std::endl;
        return false;
      }
      opts->transforms = split_transform_names(args[i]);
    } else if (arg == "--parse-only") {
      opts->parse_only = true;
    } else if (arg == "--dump-ast") {
      opts->dump_ast = true;
    } else if (arg == "--dawn-validation") {
      opts->dawn_validation = true;
    } else if (arg == "--demangle") {
      opts->demangle = true;
    } else if (arg == "--dump-inspector-bindings") {
      opts->dump_inspector_bindings = true;
    } else if (!arg.empty()) {
      if (arg[0] == '-') {
        std::cerr << "Unrecognized option: " << arg << std::endl;
        return false;
      }
      if (!opts->input_filename.empty()) {
        std::cerr << "More than one input file specified: '"
                  << opts->input_filename << "' and '" << arg << "'"
                  << std::endl;
        return false;
      }
      opts->input_filename = arg;
    }
  }
  return true;
}

/// Copies the content from the file named `input_file` to `buffer`,
/// assuming each element in the file is of type `T`.  If any error occurs,
/// writes error messages to the standard error stream and returns false.
/// Assumes the size of a `T` object is divisible by its required alignment.
/// @returns true if we successfully read the file.
template <typename T>
bool ReadFile(const std::string& input_file, std::vector<T>* buffer) {
  if (!buffer) {
    std::cerr << "The buffer pointer was null" << std::endl;
    return false;
  }

  FILE* file = nullptr;
#if defined(_MSC_VER)
  fopen_s(&file, input_file.c_str(), "rb");
#else
  file = fopen(input_file.c_str(), "rb");
#endif
  if (!file) {
    std::cerr << "Failed to open " << input_file << std::endl;
    return false;
  }

  fseek(file, 0, SEEK_END);
  uint64_t tell_file_size = static_cast<uint64_t>(ftell(file));
  if (tell_file_size <= 0) {
    std::cerr << "Input file of incorrect size: " << input_file << std::endl;
    fclose(file);
    return {};
  }
  const auto file_size = static_cast<size_t>(tell_file_size);
  if (0 != (file_size % sizeof(T))) {
    std::cerr << "File " << input_file
              << " does not contain an integral number of objects: "
              << file_size << " bytes in the file, require " << sizeof(T)
              << " bytes per object" << std::endl;
    fclose(file);
    return false;
  }
  fseek(file, 0, SEEK_SET);

  buffer->clear();
  buffer->resize(file_size / sizeof(T));

  size_t bytes_read = fread(buffer->data(), 1, file_size, file);
  fclose(file);
  if (bytes_read != file_size) {
    std::cerr << "Failed to read " << input_file << std::endl;
    return false;
  }

  return true;
}

/// Writes the given `buffer` into the file named as `output_file` using the
/// given `mode`.  If `output_file` is empty or "-", writes to standard
/// output. If any error occurs, returns false and outputs error message to
/// standard error. The ContainerT type must have data() and size() methods,
/// like `std::string` and `std::vector` do.
/// @returns true on success
template <typename ContainerT>
bool WriteFile(const std::string& output_file,
               const std::string mode,
               const ContainerT& buffer) {
  const bool use_stdout = output_file.empty() || output_file == "-";
  FILE* file = stdout;

  if (!use_stdout) {
#if defined(_MSC_VER)
    fopen_s(&file, output_file.c_str(), mode.c_str());
#else
    file = fopen(output_file.c_str(), mode.c_str());
#endif
    if (!file) {
      std::cerr << "Could not open file " << output_file << " for writing"
                << std::endl;
      return false;
    }
  }

  size_t written =
      fwrite(buffer.data(), sizeof(typename ContainerT::value_type),
             buffer.size(), file);
  if (buffer.size() != written) {
    if (use_stdout) {
      std::cerr << "Could not write all output to standard output" << std::endl;
    } else {
      std::cerr << "Could not write to file " << output_file << std::endl;
      fclose(file);
    }
    return false;
  }
  if (!use_stdout) {
    fclose(file);
  }

  return true;
}

#if TINT_BUILD_SPV_WRITER
std::string Disassemble(const std::vector<uint32_t>& data) {
  std::string spv_errors;
  spv_target_env target_env = SPV_ENV_UNIVERSAL_1_0;

  auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
                                    const spv_position_t& position,
                                    const char* message) {
    switch (level) {
      case SPV_MSG_FATAL:
      case SPV_MSG_INTERNAL_ERROR:
      case SPV_MSG_ERROR:
        spv_errors += "error: line " + std::to_string(position.index) + ": " +
                      message + "\n";
        break;
      case SPV_MSG_WARNING:
        spv_errors += "warning: line " + std::to_string(position.index) + ": " +
                      message + "\n";
        break;
      case SPV_MSG_INFO:
        spv_errors += "info: line " + std::to_string(position.index) + ": " +
                      message + "\n";
        break;
      case SPV_MSG_DEBUG:
        break;
    }
  };

  spvtools::SpirvTools tools(target_env);
  tools.SetMessageConsumer(msg_consumer);

  std::string result;
  if (!tools.Disassemble(data, &result,
                         SPV_BINARY_TO_TEXT_OPTION_INDENT |
                             SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES)) {
    std::cerr << spv_errors << std::endl;
  }
  return result;
}
#endif  // TINT_BUILD_SPV_WRITER

}  // namespace

int main(int argc, const char** argv) {
  std::vector<std::string> args(argv, argv + argc);
  Options options;

  tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);

  if (!ParseArgs(args, &options)) {
    std::cerr << "Failed to parse arguments." << std::endl;
    return 1;
  }

  if (options.show_help) {
    std::cout << kUsage << std::endl;
    return 0;
  }

  // Implement output format defaults.
  if (options.format == Format::kNone) {
    // Try inferring from filename.
    options.format = infer_format(options.output_file);
  }
  if (options.format == Format::kNone) {
    // Ultimately, default to SPIR-V assembly. That's nice for interactive use.
    options.format = Format::kSpvAsm;
  }

  auto diag_printer = tint::diag::Printer::create(stderr, true);
  tint::diag::Formatter diag_formatter;

  std::unique_ptr<tint::Program> program;
  std::unique_ptr<tint::Source::File> source_file;
#if TINT_BUILD_WGSL_READER
  if (options.input_filename.size() > 5 &&
      options.input_filename.substr(options.input_filename.size() - 5) ==
          ".wgsl") {
    std::vector<uint8_t> data;
    if (!ReadFile<uint8_t>(options.input_filename, &data)) {
      return 1;
    }
    source_file = std::make_unique<tint::Source::File>(
        options.input_filename, std::string(data.begin(), data.end()));
    program = std::make_unique<tint::Program>(
        tint::reader::wgsl::Parse(source_file.get()));
  }
#endif  // TINT_BUILD_WGSL_READER

#if TINT_BUILD_SPV_READER
  // Handle SPIR-V binary input, in files ending with .spv
  if (options.input_filename.size() > 4 &&
      options.input_filename.substr(options.input_filename.size() - 4) ==
          ".spv") {
    std::vector<uint32_t> data;
    if (!ReadFile<uint32_t>(options.input_filename, &data)) {
      return 1;
    }
    program = std::make_unique<tint::Program>(tint::reader::spirv::Parse(data));
  }
  // Handle SPIR-V assembly input, in files ending with .spvasm
  if (options.input_filename.size() > 7 &&
      options.input_filename.substr(options.input_filename.size() - 7) ==
          ".spvasm") {
    std::vector<char> text;
    if (!ReadFile<char>(options.input_filename, &text)) {
      return 1;
    }
    // Use Vulkan 1.1, since this is what Tint, internally, is expecting.
    spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
    tools.SetMessageConsumer([](spv_message_level_t, const char*,
                                const spv_position_t& pos, const char* msg) {
      std::cerr << (pos.line + 1) << ":" << (pos.column + 1) << ": " << msg
                << std::endl;
    });
    std::vector<uint32_t> data;
    if (!tools.Assemble(text.data(), text.size(), &data,
                        SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS)) {
      return 1;
    }
    program = std::make_unique<tint::Program>(tint::reader::spirv::Parse(data));
  }
#endif  // TINT_BUILD_SPV_READER

  if (!program) {
    std::cerr << "Failed to create reader for input file: "
              << options.input_filename << std::endl;
    return 1;
  }
  if (!program->IsValid()) {
    diag_formatter.format(program->Diagnostics(), diag_printer.get());
    return 1;
  }

  if (options.dump_ast) {
    std::cout << std::endl << program->to_str(options.demangle) << std::endl;
  }
  if (options.parse_only) {
    return 1;
  }

  tint::Validator v;
  if (!v.Validate(program.get())) {
    diag_formatter.format(v.diagnostics(), diag_printer.get());
    return 1;
  }

  tint::transform::Manager transform_manager;
  for (const auto& name : options.transforms) {
    // TODO(dsinclair): The vertex pulling transform requires setup code to
    // be run that needs user input. Should we find a way to support that here
    // maybe through a provided file?

    if (name == "bound_array_accessors") {
      transform_manager.append(
          std::make_unique<tint::transform::BoundArrayAccessors>());
    } else if (name == "emit_vertex_point_size") {
      transform_manager.append(
          std::make_unique<tint::transform::EmitVertexPointSize>());
    } else if (name == "first_index_offset") {
      transform_manager.append(
          std::make_unique<tint::transform::FirstIndexOffset>(0, 0));
    } else {
      std::cerr << "Unknown transform name: " << name << std::endl;
      return 1;
    }
  }

  switch (options.format) {
#if TINT_BUILD_SPV_WRITER
    case Format::kSpirv:
    case Format::kSpvAsm:
      transform_manager.append(std::make_unique<tint::transform::Spirv>());
      break;
#endif  // TINT_BUILD_SPV_WRITER
#if TINT_BUILD_MSL_WRITER
    case Format::kMsl:
      transform_manager.append(
          std::make_unique<tint::transform::CanonicalizeEntryPointIO>());
      transform_manager.append(std::make_unique<tint::transform::Msl>());
      break;
#endif  // TINT_BUILD_MSL_WRITER
#if TINT_BUILD_HLSL_WRITER
    case Format::kHlsl:
      transform_manager.append(
          std::make_unique<tint::transform::CanonicalizeEntryPointIO>());
      transform_manager.append(std::make_unique<tint::transform::Hlsl>());
      break;
#endif  // TINT_BUILD_HLSL_WRITER
    default:
      break;
  }

  auto out = transform_manager.Run(program.get());
  if (!out.program.IsValid()) {
    diag_formatter.format(out.program.Diagnostics(), diag_printer.get());
    return 1;
  }

  *program = std::move(out.program);

  if (options.dump_inspector_bindings) {
    std::cout << std::string(80, '-') << std::endl;
    tint::inspector::Inspector inspector(program.get());
    auto entry_points = inspector.GetEntryPoints();
    if (!inspector.error().empty()) {
      std::cerr << "Failed to get entry points from Inspector: "
                << inspector.error() << std::endl;
      return 1;
    }

    for (auto& entry_point : entry_points) {
      auto bindings = inspector.GetResourceBindings(entry_point.name);
      if (!inspector.error().empty()) {
        std::cerr << "Failed to get bindings from Inspector: "
                  << inspector.error() << std::endl;
        return 1;
      }
      std::cout << "Entry Point = " << entry_point.name << std::endl;
      for (auto& binding : bindings) {
        std::cout << "\t[" << binding.bind_group << "][" << binding.binding
                  << "]:" << std::endl;
        std::cout << "\t\t resource_type = "
                  << ResourceTypeToString(binding.resource_type) << std::endl;
        std::cout << "\t\t dim = " << TextureDimensionToString(binding.dim)
                  << std::endl;
        std::cout << "\t\t sampled_kind = "
                  << SampledKindToString(binding.sampled_kind) << std::endl;
        std::cout << "\t\t image_format = "
                  << ImageFormatToString(binding.image_format) << std::endl;
      }
    }
    std::cout << std::string(80, '-') << std::endl;
  }

  std::unique_ptr<tint::writer::Writer> writer;

#if TINT_BUILD_SPV_WRITER
  if (options.format == Format::kSpirv || options.format == Format::kSpvAsm) {
    writer = std::make_unique<tint::writer::spirv::Generator>(program.get());
  }
#endif  // TINT_BUILD_SPV_WRITER

#if TINT_BUILD_WGSL_WRITER
  if (options.format == Format::kWgsl) {
    writer = std::make_unique<tint::writer::wgsl::Generator>(program.get());
  }
#endif  // TINT_BUILD_WGSL_WRITER

#if TINT_BUILD_MSL_WRITER
  if (options.format == Format::kMsl) {
    writer = std::make_unique<tint::writer::msl::Generator>(program.get());
  }
#endif  // TINT_BUILD_MSL_WRITER

#if TINT_BUILD_HLSL_WRITER
  if (options.format == Format::kHlsl) {
    writer = std::make_unique<tint::writer::hlsl::Generator>(program.get());
  }
#endif  // TINT_BUILD_HLSL_WRITER

  if (!writer) {
    std::cerr << "Unknown output format specified" << std::endl;
    return 1;
  }

  if (options.emit_single_entry_point) {
    if (!writer->GenerateEntryPoint(options.stage, options.ep_name)) {
      std::cerr << "Failed to generate: " << writer->error() << std::endl;
      return 1;
    }
  } else {
    if (!writer->Generate()) {
      std::cerr << "Failed to generate: " << writer->error() << std::endl;
      return 1;
    }
  }

#if TINT_BUILD_SPV_WRITER
  bool dawn_validation_failed = false;
  std::ostringstream stream;

  if (options.dawn_validation &&
      (options.format == Format::kSpvAsm || options.format == Format::kSpirv)) {
    // Use Vulkan 1.1, since this is what Tint, internally, uses.
    spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_1);
    tools.SetMessageConsumer([&stream](spv_message_level_t, const char*,
                                       const spv_position_t& pos,
                                       const char* msg) {
      stream << (pos.line + 1) << ":" << (pos.column + 1) << ": " << msg
             << std::endl;
    });
    auto* w = static_cast<tint::writer::spirv::Generator*>(writer.get());
    if (!tools.Validate(w->result().data(), w->result().size(),
                        spvtools::ValidatorOptions())) {
      dawn_validation_failed = true;
    }
  }

  if (options.format == Format::kSpvAsm) {
    auto* w = static_cast<tint::writer::spirv::Generator*>(writer.get());
    auto str = Disassemble(w->result());
    if (!WriteFile(options.output_file, "w", str)) {
      return 1;
    }
  }
  if (options.format == Format::kSpirv) {
    auto* w = static_cast<tint::writer::spirv::Generator*>(writer.get());
    if (!WriteFile(options.output_file, "wb", w->result())) {
      return 1;
    }
  }
  if (dawn_validation_failed) {
    std::cerr << std::endl << std::endl << "Validation Failure:" << std::endl;
    std::cerr << stream.str();
    return 1;
  }
#endif  // TINT_BUILD_SPV_WRITER

  if (options.format != Format::kSpvAsm && options.format != Format::kSpirv) {
    auto* w = static_cast<tint::writer::Text*>(writer.get());
    auto output = w->result();
    if (options.demangle) {
      output = tint::Demangler().Demangle(program->Symbols(), output);
    }
    if (!WriteFile(options.output_file, "w", output)) {
      return 1;
    }
  }

  return 0;
}
