// 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/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 {
    kNone = -1,
    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::kNone;

    bool emit_single_entry_point = false;
    std::string ep_name;

    bool rename_all = false;

    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_graph = false;
#endif  // TINT_BUILD_IR
};

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 <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
  --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

    return Format::kNone;
}

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

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::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::kNone) {
                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 == "--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-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-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::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;

    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));
            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));
            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_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();
            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;
        default:
            std::cerr << "Unknown output format specified" << std::endl;
            return 1;
    }
    if (!success) {
        return 1;
    }

    return 0;
}
