/*
 * Copyright (c) 2023 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Overload.h"

#include "Types.h"
#include <wtf/DataLog.h>

namespace WGSL {

static constexpr bool shouldDumpOverloadDebugInformation = false;
static constexpr ASCIILiteral logPrefix = "> overload: "_s;

template<typename... Arguments>
inline void log(Arguments&&... arguments)
{
    if (shouldDumpOverloadDebugInformation)
        dataLog(logPrefix, std::forward<Arguments>(arguments)...);
}

template<typename... Arguments>
inline void logLn(Arguments&&... arguments)
{
    if (shouldDumpOverloadDebugInformation)
        dataLogLn(logPrefix, std::forward<Arguments>(arguments)...);
}

AbstractPointer::AbstractPointer(AbstractValue addressSpace, AbstractType element)
    : AbstractPointer(addressSpace, WTFMove(element), WTF::enumToUnderlyingType(defaultAccessModeForAddressSpace(static_cast<AddressSpace>(std::get<unsigned>(addressSpace)))))
{
}

AbstractPointer::AbstractPointer(AbstractValue addressSpace, AbstractType element, AbstractValue accessMode)
    : addressSpace(addressSpace)
    , element(WTFMove(element))
    , accessMode(accessMode)
{
}

struct ViableOverload {
    const OverloadCandidate* candidate;
    FixedVector<unsigned> ranks;
    FixedVector<const Type*> parameters;
    const Type* result;
};

class OverloadResolver {
public:
    OverloadResolver(TypeStore&, const Vector<OverloadCandidate>&, const Vector<const Type*>& valueArguments, const Vector<const Type*>& typeArguments, unsigned numberOfTypeSubstitutions, unsigned numberOfValueSubstitutions);

    std::optional<SelectedOverload> resolve();

private:
    FixedVector<std::optional<ViableOverload>> considerCandidates();
    std::optional<ViableOverload> considerCandidate(const OverloadCandidate&);
    ConversionRank calculateRank(const AbstractType&, const Type*);
    ConversionRank conversionRank(const Type*, const Type*) const;

    bool unify(const TypeVariable*, const Type*);
    bool unify(const AbstractType&, const Type*);
    bool assign(TypeVariable, const Type*);
    const Type* resolve(TypeVariable) const;
    const Type* materialize(const AbstractType&) const;

    bool unify(const AbstractValue&, unsigned);
    void assign(ValueVariable, unsigned);
    std::optional<unsigned> resolve(ValueVariable) const;
    unsigned materialize(const AbstractValue&) const;

    TypeStore& m_types;
    const Vector<OverloadCandidate>& m_candidates;
    const Vector<const Type*>& m_valueArguments;
    const Vector<const Type*>& m_typeArguments;
    FixedVector<const Type*> m_typeSubstitutions;
    FixedVector<std::optional<unsigned>> m_valueSubstitutions;
};

OverloadResolver::OverloadResolver(TypeStore& types, const Vector<OverloadCandidate>& candidates, const Vector<const Type*>& valueArguments, const Vector<const Type*>& typeArguments, unsigned numberOfTypeSubstitutions, unsigned numberOfValueSubstitutions)
    : m_types(types)
    , m_candidates(candidates)
    , m_valueArguments(valueArguments)
    , m_typeArguments(typeArguments)
    , m_typeSubstitutions(numberOfTypeSubstitutions)
    , m_valueSubstitutions(numberOfValueSubstitutions)
{
}

std::optional<SelectedOverload> OverloadResolver::resolve()
{
    auto candidates = considerCandidates();
    std::optional<ViableOverload> selectedCandidate = std::nullopt;

    for (auto& candidate : candidates) {
        if (!candidate.has_value())
            continue;

        if (!selectedCandidate.has_value()) {
            std::exchange(selectedCandidate, candidate);
            continue;
        }
        ASSERT(selectedCandidate->ranks.size() == candidate->ranks.size());

        bool isBetterOrEqual = true;
        bool hasStrictlyBetter = false;
        for (unsigned i = 0; i < candidate->ranks.size(); ++i) {
            if (candidate->ranks[i] > selectedCandidate->ranks[i]) {
                isBetterOrEqual = false;
                break;
            }
            if (candidate->ranks[i] < selectedCandidate->ranks[i])
                hasStrictlyBetter = true;
        }
        if (isBetterOrEqual && hasStrictlyBetter)
            std::exchange(selectedCandidate, candidate);
    }

    if (!selectedCandidate.has_value()) {
        logLn("no suitable overload found");
        return std::nullopt;
    }

    logLn("selected overload: ", *selectedCandidate->candidate);
    logLn("materialized result type: ", *selectedCandidate->result);

    return { { WTFMove(selectedCandidate->parameters), selectedCandidate->result } };
}

const Type* OverloadResolver::materialize(const AbstractType& abstractType) const
{
    return WTF::switchOn(*abstractType,
        [&](const Type* type) -> const Type* {
            return type;
        },
        [&](TypeVariable variable) -> const Type* {
            const Type* type = resolve(variable);
            if (!type)
                return nullptr;
            type = satisfyOrPromote(type, variable.constraints, m_types);
            RELEASE_ASSERT(type);
            return type;
        },
        [&](const AbstractVector& vector) -> const Type* {
            if (auto* element = materialize(vector.element)) {
                auto size = materialize(vector.size);
                return m_types.vectorType(size, element);
            }
            return nullptr;
        },
        [&](const AbstractMatrix& matrix) -> const Type* {
            if (auto* element = materialize(matrix.element)) {
                auto columns = materialize(matrix.columns);
                auto rows = materialize(matrix.rows);
                return m_types.matrixType(columns, rows, element);
            }
            return nullptr;
        },
        [&](const AbstractTexture& texture) -> const Type* {
            if (auto* element = materialize(texture.element))
                return m_types.textureType(texture.kind, element);
            return nullptr;
        },
        [&](const AbstractTextureStorage& texture) -> const Type* {
            auto format = materialize(texture.format);
            auto access = materialize(texture.access);
            return m_types.textureStorageType(texture.kind, static_cast<TexelFormat>(format), static_cast<AccessMode>(access));
        },
        [&](const AbstractChannelFormat& channelFormat) -> const Type* {
            auto format = materialize(channelFormat.format);
            return shaderTypeForTexelFormat(static_cast<TexelFormat>(format), m_types);
        },
        [&](const AbstractReference& reference) -> const Type* {
            if (auto* element = materialize(reference.element)) {
                auto addressSpace = materialize(reference.addressSpace);
                auto accessMode = materialize(reference.accessMode);
                return m_types.referenceType(static_cast<AddressSpace>(addressSpace), element, static_cast<AccessMode>(accessMode));
            }
            return nullptr;
        },
        [&](const AbstractPointer& pointer) -> const Type* {
            if (auto* element = materialize(pointer.element)) {
                auto addressSpace = materialize(pointer.addressSpace);
                auto accessMode = materialize(pointer.accessMode);
                return m_types.pointerType(static_cast<AddressSpace>(addressSpace), element, static_cast<AccessMode>(accessMode));
            }
            return nullptr;
        },
        [&](const AbstractArray& array) -> const Type* {
            if (auto* element = materialize(array.element))
                return m_types.arrayType(element, std::monostate { });
            return nullptr;
        },
        [&](const AbstractAtomic& atomic) -> const Type* {
            if (auto* element = materialize(atomic.element))
                return m_types.atomicType(element);
            return nullptr;
        });
}

unsigned OverloadResolver::materialize(const AbstractValue& abstractValue) const
{
    return WTF::switchOn(abstractValue,
        [&](unsigned value) -> unsigned {
            return value;
        },
        [&](ValueVariable variable) -> unsigned {
            std::optional<unsigned> resolvedValue = resolve(variable);
            ASSERT(resolvedValue.has_value());
            return *resolvedValue;
        });
}

FixedVector<std::optional<ViableOverload>> OverloadResolver::considerCandidates()
{
    FixedVector<std::optional<ViableOverload>> candidates(m_candidates.size());
    for (unsigned i = 0; i < m_candidates.size(); ++i)
        candidates[i] = considerCandidate(m_candidates[i]);
    return candidates;
}

std::optional<ViableOverload> OverloadResolver::considerCandidate(const OverloadCandidate& candidate)
{
    if (candidate.parameters.size() != m_valueArguments.size())
        return std::nullopt;

    if (m_typeArguments.size() > candidate.typeVariables.size())
        return std::nullopt;

    m_typeSubstitutions.fill(nullptr);
    m_valueSubstitutions.fill(std::nullopt);

    for (unsigned i = 0; i < m_typeArguments.size(); ++i) {
        if (!assign(candidate.typeVariables[i], m_typeArguments[i]))
            return std::nullopt;
    }

    logLn("Considering overload: ", candidate);

    ViableOverload viableOverload {
        &candidate,
        FixedVector<unsigned>(m_valueArguments.size()),
        FixedVector<const Type*>(m_valueArguments.size()),
        nullptr
    };
    for (unsigned i = 0; i < m_valueArguments.size(); ++i) {
        auto& parameter = candidate.parameters[i];
        auto* argument = m_valueArguments[i];
        logLn("matching parameter #", i, " '", parameter, "' with argument '", *argument, "'");
        if (!unify(parameter, argument)) {
            logLn("rejected on parameter #", i);
            return std::nullopt;
        }
    }
    for (unsigned i = 0; i < m_valueArguments.size(); ++i) {
        auto& parameter = candidate.parameters[i];
        auto* argument = m_valueArguments[i];
        auto rank = calculateRank(parameter, argument);
        ASSERT(!!rank);
        viableOverload.ranks[i] = *rank;
        viableOverload.parameters[i] = materialize(parameter);
    }

    viableOverload.result = materialize(candidate.result);
    if (!viableOverload.result)
        return std::nullopt;

    if (shouldDumpOverloadDebugInformation) {
        log("found a viable candidate '", candidate, "' materialized as '(");
        bool first = true;
        for (auto& parameter : candidate.parameters) {
            if (!first)
                dataLog(", ");
            first = false;
            dataLog(*materialize(parameter));
        }
        dataLog(") -> ", *viableOverload.result, "'");
        dataLogLn();
    }


    return { WTFMove(viableOverload) };
}

ConversionRank OverloadResolver::calculateRank(const AbstractType& parameter, const Type* argumentType)
{
    if (auto* variable = std::get_if<TypeVariable>(parameter.get())) {
        auto* resolvedType = resolve(*variable);
        ASSERT(resolvedType);
        if (variable->constraints) {
            resolvedType = satisfyOrPromote(resolvedType, variable->constraints, m_types);
            RELEASE_ASSERT(resolvedType);
        }
        return conversionRank(argumentType, resolvedType);
    }

    if (auto* referenceParameter = std::get_if<AbstractReference>(parameter.get())) {
        auto& referenceArgument = std::get<Types::Reference>(*argumentType);
        return calculateRank(referenceParameter->element, referenceArgument.element);
    }

    if (auto* pointerParameter = std::get_if<AbstractPointer>(parameter.get())) {
        auto& pointerArgument = std::get<Types::Pointer>(*argumentType);
        return calculateRank(pointerParameter->element, pointerArgument.element);
    }

    if (auto* reference = std::get_if<Types::Reference>(argumentType)) {
        ASSERT(reference->accessMode != AccessMode::Write);
        return calculateRank(parameter, reference->element);
    }

    if (auto* vectorParameter = std::get_if<AbstractVector>(parameter.get())) {
        auto& vectorArgument = std::get<Types::Vector>(*argumentType);
        return calculateRank(vectorParameter->element, vectorArgument.element);
    }

    if (auto* matrixParameter = std::get_if<AbstractMatrix>(parameter.get())) {
        auto& matrixArgument = std::get<Types::Matrix>(*argumentType);
        return calculateRank(matrixParameter->element, matrixArgument.element);
    }

    if (auto* textureParameter = std::get_if<AbstractTexture>(parameter.get())) {
        auto& textureArgument = std::get<Types::Texture>(*argumentType);
        return calculateRank(textureParameter->element, textureArgument.element);
    }

    if (auto* arrayParameter = std::get_if<AbstractArray>(parameter.get())) {
        auto& arrayArgument = std::get<Types::Array>(*argumentType);
        return calculateRank(arrayParameter->element, arrayArgument.element);
    }

    if (auto* atomicParameter = std::get_if<AbstractAtomic>(parameter.get())) {
        auto& atomicArgument = std::get<Types::Atomic>(*argumentType);
        return calculateRank(atomicParameter->element, atomicArgument.element);
    }

    if (std::holds_alternative<AbstractTextureStorage>(*parameter.get()))
        return 0;

    if (auto* channelFormat = std::get_if<AbstractChannelFormat>(parameter.get())) {
        auto format = materialize(channelFormat->format);
        return conversionRank(argumentType, shaderTypeForTexelFormat(static_cast<TexelFormat>(format), m_types));
    }

    auto* parameterType = std::get<const Type*>(*parameter);
    return conversionRank(argumentType, parameterType);
}

bool OverloadResolver::unify(const TypeVariable* variable, const Type* argumentType)
{
    auto* resolvedType = resolve(*variable);
    if (!resolvedType)
        return assign(*variable, argumentType);

    logLn("resolved '", *variable, "' to '", *resolvedType, "'");

    // Consider the following:
    // + :: (T, T) -> T
    // 1 + 1u
    //
    // We first unify `Var(T)` with `Type(AbstractInt)`, and assign `T` to `AbstractInt`
    // Next, we unify `Var(T) with `Type(u32)`, we look up `T => AbstractInt`,
    //   and promote `T` to `u32`.
    //
    // A few more examples to illustrate it:
    //
    // vec3 :: (T, T, T) -> T
    // vec3(1, 1.0, 1.0f) -> vec3<f32>
    // 1) unify(Var(T), Type(AbstractInt); T => AbstractInt (assign)
    // 2) unify(Var(T), Type(AbstractFloat); T => AbstractFloat (promote T)
    // 3) unify(Var(T), Type(f32); T => f32 (promote T again)
    //
    // vec3 :: (T, T, T) -> T
    // vec3(1.0, 1, 1.0f) -> vec3<f32>
    // 1) unify(Var(T), Type(AbstractFloat); T => AbstractFloat (assign)
    // 2) unify(Var(T), Type(AbstractInt); T => AbstractFloat (convert the argument to AbstractInt)
    // 3) unify(Var(T), Type(f32); T => f32 (promote T)
    //
    // vec3 :: (T, T, T) -> T
    // vec3(1.0, 1u, 1.0f) -> vec3<f32>
    // 1) unify(Var(T), Type(AbstractInt); T => AbstractFloat (assign)
    // 2) unify(Var(T), Type(u32); Failed! Can't unify AbstractFloat and u32
    auto variablePromotionRank = conversionRank(resolvedType, argumentType);
    auto argumentConversionRank = conversionRank(argumentType, resolvedType);
    logLn("variablePromotionRank: ", variablePromotionRank.unsafeValue(), ", argumentConversionRank: ", argumentConversionRank.unsafeValue());
    if (variablePromotionRank.unsafeValue() < argumentConversionRank.unsafeValue())
        return assign(*variable, argumentType);

    return !!argumentConversionRank;
}

bool OverloadResolver::unify(const AbstractType& parameter, const Type* argumentType)
{
    logLn("unify parameter type '", parameter, "' with argument '", *argumentType, "'");
    if (auto* variable = std::get_if<TypeVariable>(parameter.get()))
        return unify(variable, argumentType);

    if (auto* referenceParameter = std::get_if<AbstractReference>(parameter.get())) {
        auto* referenceArgument = std::get_if<Types::Reference>(argumentType);
        if (!referenceArgument)
            return false;
        if (!unify(referenceParameter->addressSpace, WTF::enumToUnderlyingType(referenceArgument->addressSpace)))
            return false;
        if (!unify(referenceParameter->accessMode, WTF::enumToUnderlyingType(referenceArgument->accessMode)))
            return false;
        return unify(referenceParameter->element, referenceArgument->element);
    }

    if (auto* pointerParameter = std::get_if<AbstractPointer>(parameter.get())) {
        auto* pointerArgument = std::get_if<Types::Pointer>(argumentType);
        if (!pointerArgument)
            return false;
        if (!unify(pointerParameter->addressSpace, WTF::enumToUnderlyingType(pointerArgument->addressSpace)))
            return false;
        if (!unify(pointerParameter->accessMode, WTF::enumToUnderlyingType(pointerArgument->accessMode)))
            return false;
        return unify(pointerParameter->element, pointerArgument->element);
    }

    if (auto* reference = std::get_if<Types::Reference>(argumentType)) {
        if (reference->accessMode == AccessMode::Write)
            return false;
        return unify(parameter, reference->element);
    }

    if (auto* vectorParameter = std::get_if<AbstractVector>(parameter.get())) {
        auto* vectorArgument = std::get_if<Types::Vector>(argumentType);
        if (!vectorArgument)
            return false;
        if (!unify(vectorParameter->element, vectorArgument->element))
            return false;
        return unify(vectorParameter->size, vectorArgument->size);
    }

    if (auto* matrixParameter = std::get_if<AbstractMatrix>(parameter.get())) {
        auto* matrixArgument = std::get_if<Types::Matrix>(argumentType);
        if (!matrixArgument)
            return false;
        if (!unify(matrixParameter->element, matrixArgument->element))
            return false;
        if (!unify(matrixParameter->columns, matrixArgument->columns))
            return false;
        return unify(matrixParameter->rows, matrixArgument->rows);
    }

    if (auto* textureParameter = std::get_if<AbstractTexture>(parameter.get())) {
        auto* textureArgument = std::get_if<Types::Texture>(argumentType);
        if (!textureArgument)
            return false;
        if (textureParameter->kind != textureArgument->kind)
            return false;
        return unify(textureParameter->element, textureArgument->element);
    }

    if (auto* textureStorageParameter = std::get_if<AbstractTextureStorage>(parameter.get())) {
        auto* textureStorageArgument = std::get_if<Types::TextureStorage>(argumentType);
        if (!textureStorageArgument)
            return false;
        if (textureStorageParameter->kind != textureStorageArgument->kind)
            return false;
        if (!unify(textureStorageParameter->format, WTF::enumToUnderlyingType(textureStorageArgument->format)))
            return false;
        return unify(textureStorageParameter->access, WTF::enumToUnderlyingType(textureStorageArgument->access));
    }

    if (auto* channelFormat = std::get_if<AbstractChannelFormat>(parameter.get())) {
        auto format = materialize(channelFormat->format);
        return !!conversionRank(argumentType, shaderTypeForTexelFormat(static_cast<TexelFormat>(format), m_types));
    }

    if (auto* arrayParameter = std::get_if<AbstractArray>(parameter.get())) {
        auto* arrayArgument = std::get_if<Types::Array>(argumentType);
        if (!arrayArgument)
            return false;
        // For now, we only support dynamic arrays
        if (!arrayArgument->isRuntimeSized())
            return false;
        return unify(arrayParameter->element, arrayArgument->element);
    }

    if (auto* atomicParameter = std::get_if<AbstractAtomic>(parameter.get())) {
        auto* atomicArgument = std::get_if<Types::Atomic>(argumentType);
        if (!atomicArgument)
            return false;
        return unify(atomicParameter->element, atomicArgument->element);
    }

    auto* parameterType = std::get<const Type*>(*parameter);
    return !!conversionRank(argumentType, parameterType);
}

bool OverloadResolver::unify(const AbstractValue& parameter, unsigned argumentValue)
{
    if (auto* parameterValue = std::get_if<unsigned>(&parameter))
        return *parameterValue == argumentValue;

    auto variable = std::get<ValueVariable>(parameter);
    auto resolvedValue = resolve(variable);
    if (!resolvedValue.has_value()) {
        assign(variable, argumentValue);
        return true;
    }
    return *resolvedValue == argumentValue;
}

bool OverloadResolver::assign(TypeVariable variable, const Type* type)
{
    logLn("assign ", variable, " => ", *type);
    if (variable.constraints) {
        if (!satisfies(type, variable.constraints))
            return false;
    }
    m_typeSubstitutions[variable.id] = type;
    return true;
}

void OverloadResolver::assign(ValueVariable variable, unsigned value)
{
    logLn("assign ", variable, " => ", value);
    m_valueSubstitutions[variable.id] = { value };
}

const Type* OverloadResolver::resolve(TypeVariable variable) const
{
    return m_typeSubstitutions[variable.id];
}

std::optional<unsigned> OverloadResolver::resolve(ValueVariable variable) const
{
    return m_valueSubstitutions[variable.id];
}

ConversionRank OverloadResolver::conversionRank(const Type* from, const Type* to) const
{
    auto rank = ::WGSL::conversionRank(from, to);
    logLn("conversionRank(from: ", *from, ", to: ", *to, ") = ", rank.unsafeValue());
    return rank;
}

std::optional<SelectedOverload> resolveOverloads(TypeStore& types, const Vector<OverloadCandidate>& candidates, const Vector<const Type*>& valueArguments, const Vector<const Type*>& typeArguments)
{

    unsigned numberOfTypeSubstitutions = 0;
    unsigned numberOfValueSubstitutions = 0;
    for (const auto& candidate : candidates) {
        numberOfTypeSubstitutions = std::max(numberOfTypeSubstitutions, static_cast<unsigned>(candidate.typeVariables.size()));
        numberOfValueSubstitutions = std::max(numberOfValueSubstitutions, static_cast<unsigned>(candidate.valueVariables.size()));
    }
    OverloadResolver resolver(types, candidates, valueArguments, typeArguments, numberOfTypeSubstitutions, numberOfValueSubstitutions);
    return resolver.resolve();
}

} // namespace WGSL

namespace WTF {

void printInternal(PrintStream& out, const WGSL::ValueVariable& variable)
{
    out.print("val", variable.id);
}

void printInternal(PrintStream& out, const WGSL::AbstractValue& value)
{
    WTF::switchOn(value,
        [&](unsigned value) {
            out.print(value);
        },
        [&](WGSL::ValueVariable variable) {
            printInternal(out, variable);
        });
}

void printInternal(PrintStream& out, const WGSL::TypeVariable& variable)
{
    out.print("type", variable.id);
}

void printInternal(PrintStream& out, const WGSL::AbstractType& type)
{
    WTF::switchOn(*type,
        [&](const WGSL::Type* type) {
            printInternal(out, *type);
        },
        [&](WGSL::TypeVariable variable) {
            printInternal(out, variable);
        },
        [&](const WGSL::AbstractVector& vector) {
            out.print("vector<");
            printInternal(out, vector.element);
            out.print(", ");
            printInternal(out, vector.size);
            out.print(">");
        },
        [&](const WGSL::AbstractMatrix& matrix) {
            out.print("matrix<");
            printInternal(out, matrix.element);
            out.print(", ");
            printInternal(out, matrix.columns);
            out.print(", ");
            printInternal(out, matrix.rows);
            out.print(">");
        },
        [&](const WGSL::AbstractTexture& texture) {
            printInternal(out, texture.kind);
            out.print("<");
            printInternal(out, texture.element);
            out.print(">");
        },
        [&](const WGSL::AbstractTextureStorage& texture) {
            printInternal(out, texture.kind);
            out.print("<");
            printInternal(out, texture.format);
            out.print(", ");
            printInternal(out, texture.access);
            out.print(">");
        },
        [&](const WGSL::AbstractChannelFormat& channelFormat) {
            out.print("ChannelFormat<", channelFormat.format, ">");
        },
        [&](const WGSL::AbstractReference& reference) {
            out.print("ref<");
            printInternal(out, reference.addressSpace);
            out.print(", ");
            printInternal(out, reference.element);
            out.print(", ");
            printInternal(out, reference.accessMode);
            out.print(">");
        },
        [&](const WGSL::AbstractPointer& pointer) {
            out.print("ptr<");
            printInternal(out, pointer.addressSpace);
            out.print(", ");
            printInternal(out, pointer.element);
            out.print(", ");
            printInternal(out, pointer.accessMode);
            out.print(">");
        },
        [&](const WGSL::AbstractArray& array) {
            out.print("array<");
            printInternal(out, array.element);
            out.print(">");
        },
        [&](const WGSL::AbstractAtomic& atomic) {
            out.print("atomic<");
            printInternal(out, atomic.element);
            out.print(">");
        });
}

void printInternal(PrintStream& out, const WGSL::OverloadCandidate& candidate)
{
    if (candidate.typeVariables.size() || candidate.valueVariables.size()) {
        bool first = true;
        out.print("<");
        for (auto& typeVariable : candidate.typeVariables) {
            if (!first)
                out.print(", ");
            first = false;
            printInternal(out, typeVariable);
        }
        for (auto& valueVariable : candidate.valueVariables) {
            if (!first)
                out.print(", ");
            first = false;
            printInternal(out, valueVariable);
        }
        out.print(">");
    }
    out.print("(");
    bool first = true;
    for (auto& parameter : candidate.parameters) {
        if (!first)
            out.print(", ");
        first = false;
        printInternal(out, parameter);
    }
    out.print(") -> ");
    printInternal(out, candidate.result);
}

void printInternal(PrintStream& out, WGSL::Types::Texture::Kind textureKind)
{
    switch (textureKind) {
    case WGSL::Types::Texture::Kind::Texture1d:
        out.print("texture_1d");
        return;
    case WGSL::Types::Texture::Kind::Texture2d:
        out.print("texture_2d");
        return;
    case WGSL::Types::Texture::Kind::Texture2dArray:
        out.print("texture_2d_array");
        return;
    case WGSL::Types::Texture::Kind::Texture3d:
        out.print("texture_3d");
        return;
    case WGSL::Types::Texture::Kind::TextureCube:
        out.print("texture_cube");
        return;
    case WGSL::Types::Texture::Kind::TextureCubeArray:
        out.print("texture_cube_array");
        return;
    case WGSL::Types::Texture::Kind::TextureMultisampled2d:
        out.print("texture_multisampled_2d");
        return;
    }
}

void printInternal(PrintStream& out, WGSL::Types::TextureStorage::Kind textureKind)
{
    switch (textureKind) {
    case WGSL::Types::TextureStorage::Kind::TextureStorage1d:
        out.print("texture_storage_1d");
        return;
    case WGSL::Types::TextureStorage::Kind::TextureStorage2d:
        out.print("texture_storage_2d");
        return;
    case WGSL::Types::TextureStorage::Kind::TextureStorage2dArray:
        out.print("texture_storage_2d_array");
        return;
    case WGSL::Types::TextureStorage::Kind::TextureStorage3d:
        out.print("texture_storage_3d");
        return;
    }
}


} // namespace WTF
