// 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 <charconv>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <limits>
#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>

#if TINT_BUILD_GLSL_WRITER
#include "glslang/Public/ResourceLimits.h"
#include "glslang/Public/ShaderLang.h"
#endif  // TINT_BUILD_GLSL_WRITER

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

#include "src/tint/ast/module.h"
#include "src/tint/utils/io/command.h"
#include "src/tint/utils/string.h"
#include "src/tint/utils/transform.h"
#include "src/tint/val/val.h"
#include "tint/tint.h"

#if TINT_BUILD_IR
#include "src/tint/ir/debug.h"
#include "src/tint/ir/disassembler.h"
#include "src/tint/ir/module.h"
#endif  // TINT_BUILD_IR

namespace {

[[noreturn]] void TintInternalCompilerErrorReporter(const tint::diag::List& diagnostics) {
    auto printer = tint::diag::Printer::create(stderr, true);
    tint::diag::Formatter{}.format(diagnostics, printer.get());
    tint::diag::Style bold_red{tint::diag::Color::kRed, true};
    constexpr const char* please_file_bug = R"(
********************************************************************
*  The tint shader compiler has encountered an unexpected error.   *
*                                                                  *
*  Please help us fix this issue by submitting a bug report at     *
*  crbug.com/tint with the source program that triggered the bug.  *
********************************************************************
)";
    printer->write(please_file_bug, bold_red);
    exit(1);
}

/// Prints the given hash value in a format string that the end-to-end test runner can parse.
void PrintHash(uint32_t hash) {
    std::cout << "<<HASH: 0x" << std::hex << hash << ">>" << std::endl;
}

enum class Format {
    kUnknown,
    kNone,
    kSpirv,
    kSpvAsm,
    kWgsl,
    kMsl,
    kHlsl,
    kGlsl,
};

struct Options {
    bool show_help = false;
    bool verbose = false;

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

    bool parse_only = false;
    bool disable_workgroup_init = false;
    bool validate = false;
    bool print_hash = false;
    bool demangle = false;
    bool dump_inspector_bindings = false;

    std::unordered_set<uint32_t> skip_hash;

    Format format = Format::kUnknown;

    bool emit_single_entry_point = false;
    std::string ep_name;

    bool rename_all = false;

#if TINT_BUILD_SPV_READER
    tint::reader::spirv::Options spirv_reader_options;
#endif

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

    std::string fxc_path;
    std::string dxc_path;
    std::string xcrun_path;
    std::unordered_map<std::string, double> overrides;
    std::optional<tint::sem::BindingPoint> hlsl_root_constant_binding_point;

#if TINT_BUILD_IR
    bool dump_ir = false;
    bool dump_ir_graph = false;
#endif  // TINT_BUILD_IR
};

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

 options:
  --format <spirv|spvasm|wgsl|msl|hlsl|none>  -- 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 <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:
${transforms} --parse-only              -- Stop after parsing the input
  --allow-non-uniform-derivatives  -- When using SPIR-V input, allow non-uniform derivatives by
                               inserting a module-scope directive to suppress any uniformity
                               violations that may be produced.
  --disable-workgroup-init  -- Disable workgroup memory zero initialization.
  --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
  --hlsl-root-constant-binding-point <group>,<binding>  -- Binding point for root constant.
                               Specify the binding point for generated uniform buffer
                               used for num_workgroups in HLSL. If not specified, then
                               default to binding 0 of the largest used group plus 1,
                               or group 0 if no resource bound.
  --validate                -- Validates the generated shader with all available validators
  --skip-hash <hash list>   -- Skips validation if the hash of the output is equal to any
                               of the hash codes in the comma separated list of hashes
  --print-hash              -- Emit the hash of the output program
  --fxc                     -- Path to FXC dll, used to validate HLSL output.
                               When specified, automatically enables HLSL validation with FXC
  --dxc                     -- Path to DXC executable, used to validate HLSL output.
                               When specified, automatically enables HLSL validation with DXC
  --xcrun                   -- Path to xcrun executable, used to validate MSL output.
                               When specified, automatically enables MSL validation
  --overrides               -- Override values as IDENTIFIER=VALUE, comma-separated.
  --rename-all              -- Renames all symbols.
)";

Format parse_format(const std::string& fmt) {
    (void)fmt;

#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

#if TINT_BUILD_GLSL_WRITER
    if (fmt == "glsl") {
        return Format::kGlsl;
    }
#endif  // TINT_BUILD_GLSL_WRITER

    if (fmt == "none") {
        return Format::kNone;
    }

    return Format::kUnknown;
}

#if TINT_BUILD_SPV_WRITER || TINT_BUILD_WGSL_WRITER || TINT_BUILD_MSL_WRITER || \
    TINT_BUILD_HLSL_WRITER
/// @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));
}
#endif

/// @param filename the filename to inspect
/// @returns the inferred format for the filename suffix
Format infer_format(const std::string& filename) {
    (void)filename;

#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::kUnknown;
}

std::vector<std::string> split_on_char(std::string list, char c) {
    std::vector<std::string> res;

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

std::vector<std::string> split_on_comma(std::string list) {
    return split_on_char(list, ',');
}

std::vector<std::string> split_on_equal(std::string list) {
    return split_on_char(list, '=');
}

std::optional<uint64_t> parse_unsigned_number(std::string number) {
    for (char c : number) {
        if (!std::isdigit(c)) {
            // Found a non-digital char, return nullopt
            return std::nullopt;
        }
    }

    errno = 0;
    char* p_end;
    uint64_t result;
    // std::strtoull will not throw exception.
    result = std::strtoull(number.c_str(), &p_end, 10);
    if ((errno != 0) || (static_cast<size_t>(p_end - number.c_str()) != number.length())) {
        // Unexpected conversion result
        return std::nullopt;
    }

    return result;
}

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 TexelFormatToString(tint::inspector::ResourceBinding::TexelFormat format) {
    switch (format) {
        case tint::inspector::ResourceBinding::TexelFormat::kR32Uint:
            return "R32Uint";
        case tint::inspector::ResourceBinding::TexelFormat::kR32Sint:
            return "R32Sint";
        case tint::inspector::ResourceBinding::TexelFormat::kR32Float:
            return "R32Float";
        case tint::inspector::ResourceBinding::TexelFormat::kBgra8Unorm:
            return "Bgra8Unorm";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba8Unorm:
            return "Rgba8Unorm";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba8Snorm:
            return "Rgba8Snorm";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba8Uint:
            return "Rgba8Uint";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba8Sint:
            return "Rgba8Sint";
        case tint::inspector::ResourceBinding::TexelFormat::kRg32Uint:
            return "Rg32Uint";
        case tint::inspector::ResourceBinding::TexelFormat::kRg32Sint:
            return "Rg32Sint";
        case tint::inspector::ResourceBinding::TexelFormat::kRg32Float:
            return "Rg32Float";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba16Uint:
            return "Rgba16Uint";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba16Sint:
            return "Rgba16Sint";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba16Float:
            return "Rgba16Float";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba32Uint:
            return "Rgba32Uint";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba32Sint:
            return "Rgba32Sint";
        case tint::inspector::ResourceBinding::TexelFormat::kRgba32Float:
            return "Rgba32Float";
        case tint::inspector::ResourceBinding::TexelFormat::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::kWriteOnlyStorageTexture:
            return "WriteOnlyStorageTexture";
        case tint::inspector::ResourceBinding::ResourceType::kDepthTexture:
            return "DepthTexture";
        case tint::inspector::ResourceBinding::ResourceType::kDepthMultisampledTexture:
            return "DepthMultisampledTexture";
        case tint::inspector::ResourceBinding::ResourceType::kExternalTexture:
            return "ExternalTexture";
    }

    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::kUnknown) {
                std::cerr << "Unknown output format: " << args[i] << std::endl;
                return false;
            }
        } else if (arg == "-ep") {
            if (i + 1 >= args.size()) {
                std::cerr << "Missing value for -ep" << 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 == "-v" || arg == "--verbose") {
            opts->verbose = true;
        } else if (arg == "--transform") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing value for " << arg << std::endl;
                return false;
            }
            opts->transforms = split_on_comma(args[i]);
        } else if (arg == "--parse-only") {
            opts->parse_only = true;
        } else if (arg == "--allow-non-uniform-derivatives") {
#if TINT_BUILD_SPV_READER
            opts->spirv_reader_options.allow_non_uniform_derivatives = true;
#else
            std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
            return false;
#endif
        } else if (arg == "--disable-workgroup-init") {
            opts->disable_workgroup_init = true;
        } else if (arg == "--demangle") {
            opts->demangle = true;
        } else if (arg == "--dump-inspector-bindings") {
            opts->dump_inspector_bindings = true;
        } else if (arg == "--validate") {
            opts->validate = true;
        } else if (arg == "--skip-hash") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing hash value for " << arg << std::endl;
                return false;
            }
            for (auto hash : split_on_comma(args[i])) {
                uint32_t value = 0;
                int base = 10;
                if (hash.size() > 2 && hash[0] == '0' && (hash[1] == 'x' || hash[1] == 'X')) {
                    hash = hash.substr(2);
                    base = 16;
                }
                std::from_chars(hash.data(), hash.data() + hash.size(), value, base);
                opts->skip_hash.emplace(value);
            }
        } else if (arg == "--print-hash") {
            opts->print_hash = true;
        } else if (arg == "--fxc") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing value for " << arg << std::endl;
                return false;
            }
            opts->fxc_path = args[i];
        } else if (arg == "--dxc") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing value for " << arg << std::endl;
                return false;
            }
            opts->dxc_path = args[i];
#if TINT_BUILD_IR
        } else if (arg == "--dump-ir") {
            opts->dump_ir = true;
        } else if (arg == "--dump-ir-graph") {
            opts->dump_ir_graph = true;
#endif  // TINT_BUILD_IR
        } else if (arg == "--xcrun") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing value for " << arg << std::endl;
                return false;
            }
            opts->xcrun_path = args[i];
            opts->validate = true;
        } else if (arg == "--overrides") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing value for " << arg << std::endl;
                return false;
            }
            for (const auto& o : split_on_comma(args[i])) {
                auto parts = split_on_equal(o);
                opts->overrides.insert({parts[0], std::stod(parts[1])});
            }
        } else if (arg == "--rename-all") {
            ++i;
            opts->rename_all = true;
        } else if (arg == "--hlsl-root-constant-binding-point") {
            ++i;
            if (i >= args.size()) {
                std::cerr << "Missing value for " << arg << std::endl;
                return false;
            }
            auto binding_points = split_on_comma(args[i]);
            if (binding_points.size() != 2) {
                std::cerr << "Invalid binding point for " << arg << ": " << args[i] << std::endl;
                return false;
            }
            auto group = parse_unsigned_number(binding_points[0]);
            if ((!group.has_value()) || (group.value() > std::numeric_limits<uint32_t>::max())) {
                std::cerr << "Invalid group for " << arg << ": " << binding_points[0] << std::endl;
                return false;
            }
            auto binding = parse_unsigned_number(binding_points[1]);
            if ((!binding.has_value()) ||
                (binding.value() > std::numeric_limits<uint32_t>::max())) {
                std::cerr << "Invalid binding for " << arg << ": " << binding_points[1]
                          << std::endl;
                return false;
            }
            opts->hlsl_root_constant_binding_point = tint::sem::BindingPoint{
                static_cast<uint32_t>(group.value()), static_cast<uint32_t>(binding.value())};
        } 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);
    const auto file_size = static_cast<size_t>(ftell(file));
    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

/// PrintWGSL writes the WGSL of the program to the provided ostream, if the
/// WGSL writer is enabled, otherwise it does nothing.
/// @param out the output stream to write the WGSL to
/// @param program the program
void PrintWGSL(std::ostream& out, const tint::Program& program) {
#if TINT_BUILD_WGSL_WRITER
    tint::writer::wgsl::Options options;
    auto result = tint::writer::wgsl::Generate(&program, options);
    out << std::endl << result.wgsl << std::endl;
#else
    (void)out;
    (void)program;
#endif
}

/// Generate SPIR-V code for a program.
/// @param program the program to generate
/// @param options the options that Tint was invoked with
/// @returns true on success
bool GenerateSpirv(const tint::Program* program, const Options& options) {
#if TINT_BUILD_SPV_WRITER
    // TODO(jrprice): Provide a way for the user to set non-default options.
    tint::writer::spirv::Options gen_options;
    gen_options.disable_workgroup_init = options.disable_workgroup_init;
    gen_options.generate_external_texture_bindings = true;
    auto result = tint::writer::spirv::Generate(program, gen_options);
    if (!result.success) {
        PrintWGSL(std::cerr, *program);
        std::cerr << "Failed to generate: " << result.error << std::endl;
        return false;
    }

    if (options.format == Format::kSpvAsm) {
        if (!WriteFile(options.output_file, "w", Disassemble(result.spirv))) {
            return false;
        }
    } else {
        if (!WriteFile(options.output_file, "wb", result.spirv)) {
            return false;
        }
    }

    const auto hash = tint::utils::CRC32(result.spirv.data(), result.spirv.size());
    if (options.print_hash) {
        PrintHash(hash);
    }

    if (options.validate && options.skip_hash.count(hash) == 0) {
        // Use Vulkan 1.1, since this is what Tint, internally, uses.
        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;
            });
        if (!tools.Validate(result.spirv.data(), result.spirv.size(),
                            spvtools::ValidatorOptions())) {
            return false;
        }
    }

    return true;
#else
    (void)program;
    (void)options;
    std::cerr << "SPIR-V writer not enabled in tint build" << std::endl;
    return false;
#endif  // TINT_BUILD_SPV_WRITER
}

/// Generate WGSL code for a program.
/// @param program the program to generate
/// @param options the options that Tint was invoked with
/// @returns true on success
bool GenerateWgsl(const tint::Program* program, const Options& options) {
#if TINT_BUILD_WGSL_WRITER
    // TODO(jrprice): Provide a way for the user to set non-default options.
    tint::writer::wgsl::Options gen_options;
    auto result = tint::writer::wgsl::Generate(program, gen_options);
    if (!result.success) {
        std::cerr << "Failed to generate: " << result.error << std::endl;
        return false;
    }

    if (!WriteFile(options.output_file, "w", result.wgsl)) {
        return false;
    }

    const auto hash = tint::utils::CRC32(result.wgsl.data(), result.wgsl.size());
    if (options.print_hash) {
        PrintHash(hash);
    }

    if (options.validate && options.skip_hash.count(hash) == 0) {
        // Attempt to re-parse the output program with Tint's WGSL reader.
        auto source = std::make_unique<tint::Source::File>(options.input_filename, result.wgsl);
        auto reparsed_program = tint::reader::wgsl::Parse(source.get());
        if (!reparsed_program.IsValid()) {
            auto diag_printer = tint::diag::Printer::create(stderr, true);
            tint::diag::Formatter diag_formatter;
            diag_formatter.format(reparsed_program.Diagnostics(), diag_printer.get());
            return false;
        }
    }

    return true;
#else
    (void)program;
    (void)options;
    std::cerr << "WGSL writer not enabled in tint build" << std::endl;
    return false;
#endif  // TINT_BUILD_WGSL_WRITER
}

/// Generate MSL code for a program.
/// @param program the program to generate
/// @param options the options that Tint was invoked with
/// @returns true on success
bool GenerateMsl(const tint::Program* program, const Options& options) {
#if TINT_BUILD_MSL_WRITER
    // Remap resource numbers to a flat namespace.
    // TODO(crbug.com/tint/1501): Do this via Options::BindingMap.
    const tint::Program* input_program = program;
    auto flattened = tint::writer::FlattenBindings(program);
    if (flattened) {
        input_program = &*flattened;
    }

    // TODO(jrprice): Provide a way for the user to set non-default options.
    tint::writer::msl::Options gen_options;
    gen_options.disable_workgroup_init = options.disable_workgroup_init;
    gen_options.generate_external_texture_bindings = true;
    auto result = tint::writer::msl::Generate(input_program, gen_options);
    if (!result.success) {
        PrintWGSL(std::cerr, *program);
        std::cerr << "Failed to generate: " << result.error << std::endl;
        return false;
    }

    if (!WriteFile(options.output_file, "w", result.msl)) {
        return false;
    }

    const auto hash = tint::utils::CRC32(result.msl.c_str());
    if (options.print_hash) {
        PrintHash(hash);
    }

    if (options.validate && options.skip_hash.count(hash) == 0) {
        tint::val::Result res;
#ifdef TINT_ENABLE_MSL_VALIDATION_USING_METAL_API
        res = tint::val::MslUsingMetalAPI(result.msl);
#else
#ifdef _WIN32
        const char* default_xcrun_exe = "metal.exe";
#else
        const char* default_xcrun_exe = "xcrun";
#endif
        auto xcrun = tint::utils::Command::LookPath(
            options.xcrun_path.empty() ? default_xcrun_exe : options.xcrun_path);
        if (xcrun.Found()) {
            res = tint::val::Msl(xcrun.Path(), result.msl);
        } else {
            res.output = "xcrun executable not found. Cannot validate.";
            res.failed = true;
        }
#endif  // TINT_ENABLE_MSL_VALIDATION_USING_METAL_API
        if (res.failed) {
            std::cerr << res.output << std::endl;
            return false;
        }
    }

    return true;
#else
    (void)program;
    (void)options;
    std::cerr << "MSL writer not enabled in tint build" << std::endl;
    return false;
#endif  // TINT_BUILD_MSL_WRITER
}

/// Generate HLSL code for a program.
/// @param program the program to generate
/// @param options the options that Tint was invoked with
/// @returns true on success
bool GenerateHlsl(const tint::Program* program, const Options& options) {
#if TINT_BUILD_HLSL_WRITER
    // TODO(jrprice): Provide a way for the user to set non-default options.
    tint::writer::hlsl::Options gen_options;
    gen_options.disable_workgroup_init = options.disable_workgroup_init;
    gen_options.generate_external_texture_bindings = true;
    gen_options.root_constant_binding_point = options.hlsl_root_constant_binding_point;
    auto result = tint::writer::hlsl::Generate(program, gen_options);
    if (!result.success) {
        PrintWGSL(std::cerr, *program);
        std::cerr << "Failed to generate: " << result.error << std::endl;
        return false;
    }

    if (!WriteFile(options.output_file, "w", result.hlsl)) {
        return false;
    }

    const auto hash = tint::utils::CRC32(result.hlsl.c_str());
    if (options.print_hash) {
        PrintHash(hash);
    }

    // If --fxc or --dxc was passed, then we must explicitly find and validate with that respective
    // compiler.
    const bool must_validate_dxc = !options.dxc_path.empty();
    const bool must_validate_fxc = !options.fxc_path.empty();
    if ((options.validate || must_validate_dxc || must_validate_fxc) &&
        (options.skip_hash.count(hash) == 0)) {
        tint::val::Result dxc_res;
        bool dxc_found = false;
        if (options.validate || must_validate_dxc) {
            auto dxc =
                tint::utils::Command::LookPath(options.dxc_path.empty() ? "dxc" : options.dxc_path);
            if (dxc.Found()) {
                dxc_found = true;

                auto enable_list = program->AST().Enables();
                bool dxc_require_16bit_types = false;
                for (auto enable : enable_list) {
                    if (enable->extension == tint::ast::Extension::kF16) {
                        dxc_require_16bit_types = true;
                        break;
                    }
                }

                dxc_res = tint::val::HlslUsingDXC(dxc.Path(), result.hlsl, result.entry_points,
                                                  dxc_require_16bit_types);
            } else if (must_validate_dxc) {
                // DXC was explicitly requested. Error if it could not be found.
                dxc_res.failed = true;
                dxc_res.output =
                    "DXC executable '" + options.dxc_path + "' not found. Cannot validate";
            }
        }

        tint::val::Result fxc_res;
        bool fxc_found = false;
        if (options.validate || must_validate_fxc) {
            auto fxc = tint::utils::Command::LookPath(
                options.fxc_path.empty() ? tint::val::kFxcDLLName : options.fxc_path);

#ifdef _WIN32
            if (fxc.Found()) {
                fxc_found = true;
                fxc_res = tint::val::HlslUsingFXC(fxc.Path(), result.hlsl, result.entry_points);
            } else if (must_validate_fxc) {
                // FXC was explicitly requested. Error if it could not be found.
                fxc_res.failed = true;
                fxc_res.output = "FXC DLL '" + options.fxc_path + "' not found. Cannot validate";
            }
#else
            if (must_validate_dxc) {
                fxc_res.failed = true;
                fxc_res.output = "FXC can only be used on Windows.";
            }
#endif  // _WIN32
        }

        if (fxc_res.failed) {
            std::cerr << "FXC validation failure:" << std::endl << fxc_res.output << std::endl;
        }
        if (dxc_res.failed) {
            std::cerr << "DXC validation failure:" << std::endl << dxc_res.output << std::endl;
        }
        if (fxc_res.failed || dxc_res.failed) {
            return false;
        }
        if (!fxc_found && !dxc_found) {
            std::cerr << "Couldn't find FXC or DXC. Cannot validate" << std::endl;
            return false;
        }
        if (options.verbose) {
            if (fxc_found && !fxc_res.failed) {
                std::cout << "Passed FXC validation" << std::endl;
                std::cout << fxc_res.output;
                std::cout << std::endl;
            }
            if (dxc_found && !dxc_res.failed) {
                std::cout << "Passed DXC validation" << std::endl;
                std::cout << dxc_res.output;
                std::cout << std::endl;
            }
        }
    }

    return true;
#else
    (void)program;
    (void)options;
    std::cerr << "HLSL writer not enabled in tint build" << std::endl;
    return false;
#endif  // TINT_BUILD_HLSL_WRITER
}

#if TINT_BUILD_GLSL_WRITER
EShLanguage pipeline_stage_to_esh_language(tint::ast::PipelineStage stage) {
    switch (stage) {
        case tint::ast::PipelineStage::kFragment:
            return EShLangFragment;
        case tint::ast::PipelineStage::kVertex:
            return EShLangVertex;
        case tint::ast::PipelineStage::kCompute:
            return EShLangCompute;
        default:
            TINT_ASSERT(AST, false);
            return EShLangVertex;
    }
}
#endif

/// Generate GLSL code for a program.
/// @param program the program to generate
/// @param options the options that Tint was invoked with
/// @returns true on success
bool GenerateGlsl(const tint::Program* program, const Options& options) {
#if TINT_BUILD_GLSL_WRITER
    if (options.validate) {
        glslang::InitializeProcess();
    }

    auto generate = [&](const tint::Program* prg, const std::string entry_point_name) -> bool {
        tint::writer::glsl::Options gen_options;
        gen_options.generate_external_texture_bindings = true;
        auto result = tint::writer::glsl::Generate(prg, gen_options, entry_point_name);
        if (!result.success) {
            PrintWGSL(std::cerr, *prg);
            std::cerr << "Failed to generate: " << result.error << std::endl;
            return false;
        }

        if (!WriteFile(options.output_file, "w", result.glsl)) {
            return false;
        }

        const auto hash = tint::utils::CRC32(result.glsl.c_str());
        if (options.print_hash) {
            PrintHash(hash);
        }

        if (options.validate && options.skip_hash.count(hash) == 0) {
            for (auto entry_pt : result.entry_points) {
                EShLanguage lang = pipeline_stage_to_esh_language(entry_pt.second);
                glslang::TShader shader(lang);
                const char* strings[1] = {result.glsl.c_str()};
                int lengths[1] = {static_cast<int>(result.glsl.length())};
                shader.setStringsWithLengths(strings, lengths, 1);
                shader.setEntryPoint("main");
                bool glslang_result = shader.parse(GetDefaultResources(), 310, EEsProfile, false,
                                                   false, EShMsgDefault);
                if (!glslang_result) {
                    std::cerr << "Error parsing GLSL shader:\n"
                              << shader.getInfoLog() << "\n"
                              << shader.getInfoDebugLog() << "\n";
                    return false;
                }
            }
        }
        return true;
    };

    tint::inspector::Inspector inspector(program);

    if (inspector.GetEntryPoints().empty()) {
        // Pass empty string here so that the GLSL generator will generate
        // code for all functions, reachable or not.
        return generate(program, "");
    }

    bool success = true;
    for (auto& entry_point : inspector.GetEntryPoints()) {
        success &= generate(program, entry_point.name);
    }
    return success;
#else
    (void)program;
    (void)options;
    std::cerr << "GLSL writer not enabled in tint build" << std::endl;
    return false;
#endif  // TINT_BUILD_GLSL_WRITER
}

}  // namespace

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

    tint::SetInternalCompilerErrorReporter(&TintInternalCompilerErrorReporter);

#if TINT_BUILD_WGSL_WRITER
    tint::Program::printer = [](const tint::Program* program) {
        auto result = tint::writer::wgsl::Generate(program, {});
        if (!result.error.empty()) {
            return "error: " + result.error;
        }
        return result.wgsl;
    };
#endif  // TINT_BUILD_WGSL_WRITER

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

    struct TransformFactory {
        const char* name;
        /// Build and adds the transform to the transform manager.
        /// Parameters:
        ///   inspector - an inspector created from the parsed program
        ///   manager   - the transform manager. Add transforms to this.
        ///   inputs    - the input data to the transform manager. Add inputs to this.
        /// Returns true on success, false on error (program will immediately exit)
        std::function<bool(tint::inspector::Inspector& inspector,
                           tint::transform::Manager& manager,
                           tint::transform::DataMap& inputs)>
            make;
    };
    std::vector<TransformFactory> transforms = {
        {"first_index_offset",
         [](tint::inspector::Inspector&, tint::transform::Manager& m, tint::transform::DataMap& i) {
             i.Add<tint::transform::FirstIndexOffset::BindingPoint>(0, 0);
             m.Add<tint::transform::FirstIndexOffset>();
             return true;
         }},
        {"renamer",
         [](tint::inspector::Inspector&, tint::transform::Manager& m, tint::transform::DataMap&) {
             m.Add<tint::transform::Renamer>();
             return true;
         }},
        {"robustness",
         [](tint::inspector::Inspector&, tint::transform::Manager& m, tint::transform::DataMap&) {
             m.Add<tint::transform::Robustness>();
             return true;
         }},
        {"substitute_override",
         [&](tint::inspector::Inspector& inspector, tint::transform::Manager& m,
             tint::transform::DataMap& i) {
             tint::transform::SubstituteOverride::Config cfg;

             std::unordered_map<tint::OverrideId, double> values;
             values.reserve(options.overrides.size());

             for (const auto& [name, value] : options.overrides) {
                 if (name.empty()) {
                     std::cerr << "empty override name";
                     return false;
                 }
                 if (isdigit(name[0])) {
                     tint::OverrideId id{
                         static_cast<decltype(tint::OverrideId::value)>(atoi(name.c_str()))};
                     values.emplace(id, value);
                 } else {
                     auto override_names = inspector.GetNamedOverrideIds();
                     auto it = override_names.find(name);
                     if (it == override_names.end()) {
                         std::cerr << "unknown override '" << name << "'";
                         return false;
                     }
                     values.emplace(it->second, value);
                 }
             }

             cfg.map = std::move(values);

             i.Add<tint::transform::SubstituteOverride::Config>(cfg);
             m.Add<tint::transform::SubstituteOverride>();
             return true;
         }},
        {"multiplaner_external_texture",
         [](tint::inspector::Inspector& inspector, tint::transform::Manager& m,
            tint::transform::DataMap& i) {
             using MET = tint::transform::MultiplanarExternalTexture;

             // Generate the MultiplanarExternalTexture::NewBindingPoints by finding two free
             // binding points. We may wish to expose these binding points via a command line flag
             // in the future.

             // Set of all the group-0 bindings in use.
             std::unordered_set<uint32_t> group0_bindings_in_use;
             auto allocate_binding = [&] {
                 for (uint32_t idx = 0;; idx++) {
                     auto binding = tint::transform::BindingPoint{0u, idx};
                     if (group0_bindings_in_use.emplace(idx).second) {
                         return binding;
                     }
                 }
             };
             // Populate group0_bindings_in_use with the existing bindings across all entry points.
             for (auto ep : inspector.GetEntryPoints()) {
                 for (auto binding : inspector.GetResourceBindings(ep.name)) {
                     if (binding.bind_group == 0) {
                         group0_bindings_in_use.emplace(binding.binding);
                     }
                 }
             }
             // Allocate new binding points for the external texture's planes and parameters.
             MET::BindingsMap met_bindings;
             for (auto ep : inspector.GetEntryPoints()) {
                 for (auto ext_tex : inspector.GetExternalTextureResourceBindings(ep.name)) {
                     auto binding = tint::transform::BindingPoint{
                         ext_tex.bind_group,
                         ext_tex.binding,
                     };
                     if (met_bindings.count(binding)) {
                         continue;
                     }
                     met_bindings.emplace(binding, MET::BindingPoints{
                                                       /* plane_1 */ allocate_binding(),
                                                       /* params */ allocate_binding(),
                                                   });
                 }
             }

             i.Add<MET::NewBindingPoints>(std::move(met_bindings));
             m.Add<MET>();
             return true;
         }},
    };
    auto transform_names = [&] {
        std::stringstream names;
        for (auto& t : transforms) {
            names << "   " << t.name << std::endl;
        }
        return names.str();
    };

    if (options.show_help) {
        std::string usage = tint::utils::ReplaceAll(kUsage, "${transforms}", transform_names());
#if TINT_BUILD_IR
        usage +=
            "  --dump-ir                 -- Writes the IR to stdout\n"
            "  --dump-ir-graph           -- Writes the IR graph to 'tint.dot' as a dot graph\n";
#endif  // TINT_BUILD_IR

        std::cout << usage << std::endl;
        return 0;
    }

    // Implement output format defaults.
    if (options.format == Format::kUnknown) {
        // Try inferring from filename.
        options.format = infer_format(options.output_file);
    }
    if (options.format == Format::kUnknown) {
        // 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;

    enum class InputFormat {
        kUnknown,
        kWgsl,
        kSpirvBin,
        kSpirvAsm,
    };
    auto input_format = InputFormat::kUnknown;

    if (options.input_filename.size() > 5 &&
        options.input_filename.substr(options.input_filename.size() - 5) == ".wgsl") {
        input_format = InputFormat::kWgsl;
    } else if (options.input_filename.size() > 4 &&
               options.input_filename.substr(options.input_filename.size() - 4) == ".spv") {
        input_format = InputFormat::kSpirvBin;
    } else if (options.input_filename.size() > 7 &&
               options.input_filename.substr(options.input_filename.size() - 7) == ".spvasm") {
        input_format = InputFormat::kSpirvAsm;
    }

    switch (input_format) {
        case InputFormat::kUnknown: {
            std::cerr << "Unknown input format" << std::endl;
            return 1;
        }
        case InputFormat::kWgsl: {
#if TINT_BUILD_WGSL_READER
            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()));
            break;
#else
            std::cerr << "Tint not built with the WGSL reader enabled" << std::endl;
            return 1;
#endif  // TINT_BUILD_WGSL_READER
        }
        case InputFormat::kSpirvBin: {
#if TINT_BUILD_SPV_READER
            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, options.spirv_reader_options));
            break;
#else
            std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
            return 1;
#endif  // TINT_BUILD_SPV_READER
        }
        case InputFormat::kSpirvAsm: {
#if TINT_BUILD_SPV_READER
            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, options.spirv_reader_options));
            break;
#else
            std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
            return 1;
#endif  // TINT_BUILD_SPV_READER
        }
    }

    if (!program) {
        std::cerr << "Failed to parse input file: " << options.input_filename << std::endl;
        return 1;
    }
    if (program->Diagnostics().count() > 0) {
        if (!program->IsValid() && input_format != InputFormat::kWgsl) {
            // Invalid program from a non-wgsl source. Print the WGSL, to help
            // understand the diagnostics.
            PrintWGSL(std::cout, *program);
        }
        diag_formatter.format(program->Diagnostics(), diag_printer.get());
    }

    if (!program->IsValid()) {
        return 1;
    }
    if (options.parse_only) {
        return 1;
    }

#if TINT_BUILD_IR
    if (options.dump_ir || options.dump_ir_graph) {
        auto result = tint::ir::Module::FromProgram(program.get());
        if (!result) {
            std::cerr << "Failed to build IR from program: " << result.Failure() << std::endl;
        } else {
            auto mod = result.Move();
            if (options.dump_ir) {
                tint::ir::Disassembler d(mod);
                std::cout << d.Disassemble() << std::endl;
            }
            if (options.dump_ir_graph) {
                auto graph = tint::ir::Debug::AsDotGraph(&mod);
                WriteFile("tint.dot", "w", graph);
            }
        }
    }
#endif  // TINT_BUILD_IR

    tint::inspector::Inspector inspector(program.get());

    if (options.dump_inspector_bindings) {
        std::cout << std::string(80, '-') << std::endl;
        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 = " << TexelFormatToString(binding.image_format)
                          << std::endl;
            }
        }
        std::cout << std::string(80, '-') << std::endl;
    }

    tint::transform::Manager transform_manager;
    tint::transform::DataMap transform_inputs;

    // Renaming must always come first
    switch (options.format) {
        case Format::kMsl: {
#if TINT_BUILD_MSL_WRITER
            transform_inputs.Add<tint::transform::Renamer::Config>(
                options.rename_all ? tint::transform::Renamer::Target::kAll
                                   : tint::transform::Renamer::Target::kMslKeywords,
                /* preserve_unicode */ false);
            transform_manager.Add<tint::transform::Renamer>();
#endif  // TINT_BUILD_MSL_WRITER
            break;
        }
#if TINT_BUILD_GLSL_WRITER
        case Format::kGlsl: {
            transform_inputs.Add<tint::transform::Renamer::Config>(
                options.rename_all ? tint::transform::Renamer::Target::kAll
                                   : tint::transform::Renamer::Target::kGlslKeywords,
                /* preserve_unicode */ false);
            transform_manager.Add<tint::transform::Renamer>();
            break;
        }
#endif  // TINT_BUILD_GLSL_WRITER
        case Format::kHlsl: {
#if TINT_BUILD_HLSL_WRITER
            transform_inputs.Add<tint::transform::Renamer::Config>(
                options.rename_all ? tint::transform::Renamer::Target::kAll
                                   : tint::transform::Renamer::Target::kHlslKeywords,
                /* preserve_unicode */ false);
            transform_manager.Add<tint::transform::Renamer>();
#endif  // TINT_BUILD_HLSL_WRITER
            break;
        }
        default: {
            if (options.rename_all) {
                transform_manager.Add<tint::transform::Renamer>();
            }
            break;
        }
    }

    auto enable_transform = [&](std::string_view name) {
        for (auto& t : transforms) {
            if (t.name == name) {
                return t.make(inspector, transform_manager, transform_inputs);
            }
        }

        std::cerr << "Unknown transform: " << name << std::endl;
        std::cerr << "Available transforms: " << std::endl << transform_names();
        return false;
    };

    // If overrides are provided, add the SubstituteOverride transform.
    if (!options.overrides.empty()) {
        if (!enable_transform("substitute_override")) {
            return 1;
        }
    }

    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 (!enable_transform(name)) {
            return 1;
        }
    }

    if (options.emit_single_entry_point) {
        transform_manager.append(std::make_unique<tint::transform::SingleEntryPoint>());
        transform_inputs.Add<tint::transform::SingleEntryPoint::Config>(options.ep_name);
    }

    auto out = transform_manager.Run(program.get(), std::move(transform_inputs));
    if (!out.program.IsValid()) {
        PrintWGSL(std::cerr, out.program);
        diag_formatter.format(out.program.Diagnostics(), diag_printer.get());
        return 1;
    }

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

    bool success = false;
    switch (options.format) {
        case Format::kSpirv:
        case Format::kSpvAsm:
            success = GenerateSpirv(program.get(), options);
            break;
        case Format::kWgsl:
            success = GenerateWgsl(program.get(), options);
            break;
        case Format::kMsl:
            success = GenerateMsl(program.get(), options);
            break;
        case Format::kHlsl:
            success = GenerateHlsl(program.get(), options);
            break;
        case Format::kGlsl:
            success = GenerateGlsl(program.get(), options);
            break;
        case Format::kNone:
            break;
        default:
            std::cerr << "Unknown output format specified" << std::endl;
            return 1;
    }
    if (!success) {
        return 1;
    }

    return 0;
}
