// Copyright 2021 The Dawn & Tint Authors
//
// 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.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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 "src/tint/lang/core/intrinsic/table.h"

#include <algorithm>
#include <limits>
#include <ostream>
#include <utility>

#include "src/tint/lang/core/evaluation_stage.h"
#include "src/tint/lang/core/intrinsic/table_data.h"
#include "src/tint/lang/core/type/invalid.h"
#include "src/tint/lang/core/type/manager.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/utils/containers/slice.h"
#include "src/tint/utils/ice/ice.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/text_style.h"

namespace tint::core::intrinsic {

const Number Number::any{Number::kAny};
const Number Number::invalid{Number::kInvalid};

Any::Any() : Base(0u, core::type::Flags{}) {}
Any::~Any() = default;

bool Any::Equals(const core::type::UniqueNode&) const {
    return false;
}

std::string Any::FriendlyName() const {
    return "<any>";
}

core::type::Type* Any::Clone(core::type::CloneContext&) const {
    return nullptr;
}

namespace {

/// The Vector `N` template argument value for arrays of parameters.
constexpr const size_t kNumFixedParameters = Overload::kNumFixedParameters;

/// The Vector `N` template argument value for arrays of overload candidates.
constexpr const size_t kNumFixedCandidates = 8;

/// A list of candidates
using Candidates = Vector<Candidate, kNumFixedCandidates>;

/// Callback function when no overloads match.
using OnNoMatch = std::function<StyledText(VectorRef<Candidate>)>;

/// Sorts the candidates based on their score, with the lowest (best-ranking) scores first.
static inline void SortCandidates(Candidates& candidates) {
    std::stable_sort(candidates.begin(), candidates.end(),
                     [&](const Candidate& a, const Candidate& b) { return a.score < b.score; });
}

/// Prints a list of types.
static void PrintTypeList(StyledText& ss, VectorRef<const core::type::Type*> types) {
    bool first = true;
    for (auto* arg : types) {
        if (!first) {
            ss << ", ";
        }
        first = false;
        ss << style::Type(arg->FriendlyName());
    }
}

/// Attempts to find a single intrinsic overload that matches the provided argument types.
/// @param context the intrinsic context
/// @param intrinsic the intrinsic being called
/// @param intrinsic_name the name of the intrinsic
/// @param template_args the template argument types
/// @param args the argument types
/// @param on_no_match an error callback when no intrinsic overloads matched the provided
///                    arguments.
/// @returns the matched intrinsic
Result<Overload, StyledText> MatchIntrinsic(Context& context,
                                            const IntrinsicInfo& intrinsic,
                                            std::string_view intrinsic_name,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage,
                                            const OnNoMatch& on_no_match);

/// The scoring mode for ScoreOverload()
enum class ScoreMode {
    /// If the overload doesn't match, then the returned Candidate will simply have a score of 1.
    /// No other fields will be populated.
    kEarlyReject,
    /// A more expensive score calculations will be made for the overload, which can be used
    /// to rank potential overloads
    kFull
};

/// Evaluates the single overload for the provided argument types.
/// @param context the intrinsic context
/// @param overload the overload being considered
/// @param template_args the template argument types
/// @param args the argument types
/// @tparam MODE the scoring mode to use. Passed as a template argument to ensure that the
/// extremely-hot function is specialized without scoring logic for the common code path.
/// @returns the evaluated Candidate information.
template <ScoreMode MODE>
Candidate ScoreOverload(Context& context,
                        const OverloadInfo& overload,
                        VectorRef<const core::type::Type*> template_args,
                        VectorRef<const core::type::Type*> args,
                        EvaluationStage earliest_eval_stage);

/// Performs overload resolution given the list of candidates, by ranking the conversions of
/// arguments to the each of the candidate's parameter types.
/// @param context the intrinsic context
/// @param candidates the list of candidate overloads
/// @param intrinsic_name the name of the intrinsic
/// @param template_args the template argument types
/// @param args the argument types
/// @see https://www.w3.org/TR/WGSL/#overload-resolution-section
/// @returns the resolved Candidate.
Result<Candidate, StyledText> ResolveCandidate(Context& context,
                                               Candidates&& candidates,
                                               std::string_view intrinsic_name,
                                               VectorRef<const core::type::Type*> template_args,
                                               VectorRef<const core::type::Type*> args);

// Prints the list of candidates for emitting diagnostics
void PrintCandidates(StyledText& err,
                     Context& context,
                     VectorRef<Candidate> candidates,
                     std::string_view intrinsic_name,
                     VectorRef<const core::type::Type*> template_args,
                     VectorRef<const core::type::Type*> args);

/// Raises an ICE when no overload is a clear winner of overload resolution
StyledText ErrAmbiguousOverload(Context& context,
                                std::string_view intrinsic_name,
                                VectorRef<const core::type::Type*> template_args,
                                VectorRef<const core::type::Type*> args,
                                VectorRef<Candidate> candidates);

/// @return a string representing a call to a builtin with the given argument types.
StyledText CallSignature(std::string_view intrinsic_name,
                         VectorRef<const core::type::Type*> template_args,
                         VectorRef<const core::type::Type*> args) {
    StyledText out;
    out << style::Code << style::Function(intrinsic_name);
    if (!template_args.IsEmpty()) {
        out << "<";
        PrintTypeList(out, template_args);
        out << ">";
    }
    out << "(";
    PrintTypeList(out, args);
    out << ")";

    return out;
}

Result<Overload, StyledText> MatchIntrinsic(Context& context,
                                            const IntrinsicInfo& intrinsic,
                                            std::string_view intrinsic_name,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage,
                                            const OnNoMatch& on_no_match) {
    const size_t num_overloads = static_cast<size_t>(intrinsic.num_overloads);
    size_t num_matched = 0;
    size_t match_idx = 0;
    Vector<Candidate, kNumFixedCandidates> candidates;
    candidates.Reserve(intrinsic.num_overloads);
    for (size_t overload_idx = 0; overload_idx < num_overloads; overload_idx++) {
        auto& overload = context.data[intrinsic.overloads + overload_idx];
        auto candidate = ScoreOverload<ScoreMode::kEarlyReject>(context, overload, template_args,
                                                                args, earliest_eval_stage);
        if (candidate.score == 0) {
            match_idx = overload_idx;
            num_matched++;
        }
        candidates.Push(std::move(candidate));
    }

    // How many candidates matched?
    if (TINT_UNLIKELY(num_matched == 0)) {
        // Perform the full scoring of each overload
        for (size_t overload_idx = 0; overload_idx < num_overloads; overload_idx++) {
            auto& overload = context.data[intrinsic.overloads + overload_idx];
            candidates[overload_idx] = ScoreOverload<ScoreMode::kFull>(
                context, overload, template_args, args, earliest_eval_stage);
        }
        // Sort the candidates with the most promising first
        SortCandidates(candidates);
        return on_no_match(std::move(candidates));
    }

    Candidate match;

    if (num_matched == 1) {
        match = std::move(candidates[match_idx]);
    } else {
        auto result =
            ResolveCandidate(context, std::move(candidates), intrinsic_name, template_args, args);
        if (TINT_UNLIKELY(result != Success)) {
            return result.Failure();
        }
        match = result.Get();
    }

    // Build the return type
    const core::type::Type* return_type = nullptr;
    if (auto* matcher_indices = context.data[match.overload->return_matcher_indices]) {
        Any any;
        return_type =
            context.Match(match.templates, *match.overload, matcher_indices, earliest_eval_stage)
                .Type(&any);
        if (TINT_UNLIKELY(!return_type)) {
            StyledText err;
            err << "MatchState.MatchState() returned null";
            TINT_ICE() << err.Plain();
        }
    } else {
        return_type = context.types.void_();
    }

    return Overload{match.overload, return_type, std::move(match.parameters),
                    context.data[match.overload->const_eval_fn]};
}

template <ScoreMode MODE>
Candidate ScoreOverload(Context& context,
                        const OverloadInfo& overload,
                        VectorRef<const core::type::Type*> template_args,
                        VectorRef<const core::type::Type*> args,
                        EvaluationStage earliest_eval_stage) {
#define MATCH_FAILURE(PENALTY)                           \
    do {                                                 \
        if constexpr (MODE == ScoreMode::kEarlyReject) { \
            return Candidate{1};                         \
        } else {                                         \
            score += PENALTY;                            \
        }                                                \
    } while (false)

    // Penalty weights for overload mismatching.
    // This scoring is used to order the suggested overloads in diagnostic on overload mismatch, and
    // has no impact for a correct program.
    // The overloads with the lowest score will be displayed first (top-most).
    constexpr int kMismatchedExplicitTemplateCountPenalty = 10;
    constexpr int kMismatchedParamCountPenalty = 3;
    constexpr int kMismatchedParamTypePenalty = 2;
    constexpr int kMismatchedExplicitTemplateTypePenalty = 1;
    constexpr int kMismatchedImplicitTemplateTypePenalty = 1;
    constexpr int kMismatchedImplicitTemplateNumberPenalty = 1;

    const size_t num_parameters = static_cast<size_t>(overload.num_parameters);
    const size_t num_arguments = static_cast<size_t>(args.Length());

    size_t score = 0;

    if (num_parameters != num_arguments) {
        MATCH_FAILURE(kMismatchedParamCountPenalty * (std::max(num_parameters, num_arguments) -
                                                      std::min(num_parameters, num_arguments)));
    }

    // Check that all of the template arguments provided are actually expected by the overload.
    const size_t expected_templates = overload.num_explicit_templates;
    const size_t provided_templates = template_args.Length();
    if (provided_templates != expected_templates) {
        MATCH_FAILURE(kMismatchedExplicitTemplateCountPenalty *
                      (std::max(expected_templates, provided_templates) -
                       std::min(expected_templates, provided_templates)));
    }

    TemplateState templates;

    // Check that the explicit template arguments match the constraint if specified, otherwise
    // just set the template type.
    auto num_tmpl_args = std::min<size_t>(overload.num_explicit_templates, template_args.Length());
    for (size_t i = 0; i < num_tmpl_args; ++i) {
        auto& tmpl = context.data[overload.templates + i];
        auto* type = template_args[i];
        if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
            // Ensure type matches the template's matcher.
            type =
                context.Match(templates, overload, matcher_indices, earliest_eval_stage).Type(type);
            if (!type) {
                MATCH_FAILURE(kMismatchedExplicitTemplateTypePenalty);
                continue;
            }
        }
        templates.SetType(i, type);
    }

    // Invoke the matchers for each parameter <-> argument pair.
    // If any arguments cannot be matched, then `score` will be increased.
    // If the overload has any template types or numbers then these will be set based on the
    // argument types. Template types may be refined by constraining with later argument types. For
    // example calling `F<T>(T, T)` with the argument types (abstract-int, i32) will first set T to
    // abstract-int when matching the first argument, and then constrained down to i32 when matching
    // the second argument.
    // Note that inferred template types are not tested against their matchers at this point.
    auto num_params = std::min(num_parameters, num_arguments);
    for (size_t p = 0; p < num_params; p++) {
        auto& parameter = context.data[overload.parameters + p];
        auto* matcher_indices = context.data[parameter.matcher_indices];
        if (!context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                 .Type(args[p])) {
            MATCH_FAILURE(kMismatchedParamTypePenalty);
        }
    }

    // Check each of the inferred types and numbers for the implicit templates match their
    // respective matcher.
    for (size_t i = overload.num_explicit_templates; i < overload.num_templates; i++) {
        auto& tmpl = context.data[overload.templates + i];
        auto* matcher_indices = context.data[tmpl.matcher_indices];
        if (!matcher_indices) {
            continue;
        }

        auto matcher = context.Match(templates, overload, matcher_indices, earliest_eval_stage);

        switch (tmpl.kind) {
            case TemplateInfo::Kind::kType: {
                // Check all constrained template types matched their constraint matchers.
                // If the template type *does not* match any of the types in the constraint
                // matcher, then `score` is incremented and the template is assigned an invalid
                // type. If the template type *does* match a type, then the template type is
                // replaced with the first matching type. The order of types in the template matcher
                // is important here, which can be controlled with the [[precedence(N)]] decorations
                // on the types in the def file.
                if (auto* type = templates.Type(i)) {
                    if (auto* ty = matcher.Type(type)) {
                        // Template type matched one of the types in the template type's
                        // matcher. Replace the template type with this type.
                        templates.SetType(i, ty);
                        continue;
                    }
                }
                templates.SetType(i, context.types.invalid());
                MATCH_FAILURE(kMismatchedImplicitTemplateTypePenalty);
                break;
            }

            case TemplateInfo::Kind::kNumber: {
                // Checking that the inferred number matches the constraints on the
                // template. Increments `score` and assigns the template an invalid number if the
                // template numbers do not match their constraint matchers.
                auto number = templates.Num(i);
                if (!number.IsValid() || !matcher.Num(number).IsValid()) {
                    templates.SetNum(i, Number::invalid);
                    MATCH_FAILURE(kMismatchedImplicitTemplateNumberPenalty);
                }
            }
        }
    }

    // Now that all the template types have been finalized, we can construct the parameters.
    Vector<Overload::Parameter, kNumFixedParameters> parameters;
    parameters.Reserve(num_params);
    for (size_t p = 0; p < num_params; p++) {
        auto& parameter = context.data[overload.parameters + p];
        auto* matcher_indices = context.data[parameter.matcher_indices];
        auto* ty =
            context.Match(templates, overload, matcher_indices, earliest_eval_stage).Type(args[p]);
        parameters.Emplace(ty, parameter.usage);
    }

    return Candidate{score, &overload, templates, parameters};
#undef MATCH_FAILURE
}

Result<Candidate, StyledText> ResolveCandidate(Context& context,
                                               Candidates&& candidates,
                                               std::string_view intrinsic_name,
                                               VectorRef<const core::type::Type*> template_args,
                                               VectorRef<const core::type::Type*> args) {
    Vector<uint32_t, kNumFixedParameters> best_ranks;
    best_ranks.Resize(args.Length(), 0xffffffff);
    size_t num_matched = 0;
    Candidate* best = nullptr;
    for (auto& candidate : candidates) {
        if (candidate.score > 0) {
            continue;  // Candidate has already been ruled out.
        }
        bool some_won = false;   // An argument ranked less than the 'best' overload's argument
        bool some_lost = false;  // An argument ranked more than the 'best' overload's argument
        for (size_t i = 0; i < args.Length(); i++) {
            auto rank = core::type::Type::ConversionRank(args[i], candidate.parameters[i].type);
            if (best_ranks[i] > rank) {
                best_ranks[i] = rank;
                some_won = true;
            } else if (best_ranks[i] < rank) {
                some_lost = true;
            }
        }
        // If no arguments of this candidate ranked worse than the previous best candidate, then
        // this candidate becomes the new best candidate.
        // If no arguments of this candidate ranked better than the previous best candidate, then
        // this candidate is removed from the list of matches.
        // If neither of the above apply, then we have two candidates with no clear winner, which
        // results in an ambiguous overload error. In this situation the loop ends with
        // `num_matched > 1`.
        if (some_won) {
            // One or more arguments of this candidate ranked better than the previous best
            // candidate's argument(s).
            num_matched++;
            if (!some_lost) {
                // All arguments were at as-good or better than the previous best.
                if (best) {
                    // Mark the previous best candidate as no longer being in the running, by
                    // setting its score to a non-zero value. We pick 1 as this is the closest to 0
                    // (match) as we can get.
                    best->score = 1;
                    num_matched--;
                }
                // This candidate is the new best.
                best = &candidate;
            }
        } else {
            // No arguments ranked better than the current best.
            // Change the score of this candidate to a non-zero value, so that it's not considered a
            // match.
            candidate.score = 1;
        }
    }

    if (num_matched > 1) {
        // Re-sort the candidates with the most promising first
        SortCandidates(candidates);
        // Raise an error
        return ErrAmbiguousOverload(context, intrinsic_name, template_args, args, candidates);
    }

    return std::move(*best);
}

void PrintCandidates(StyledText& ss,
                     Context& context,
                     VectorRef<Candidate> candidates,
                     std::string_view intrinsic_name,
                     VectorRef<const core::type::Type*> template_args,
                     VectorRef<const core::type::Type*> args) {
    for (auto& candidate : candidates) {
        ss << " • ";
        PrintCandidate(ss, context, candidate, intrinsic_name, template_args, args);
        ss << "\n";
    }
}

StyledText ErrAmbiguousOverload(Context& context,
                                std::string_view intrinsic_name,
                                VectorRef<const core::type::Type*> template_args,
                                VectorRef<const core::type::Type*> args,
                                VectorRef<Candidate> candidates) {
    StyledText err;
    err << "ambiguous overload while attempting to match "
        << CallSignature(intrinsic_name, template_args, args) << "\n";

    for (auto& candidate : candidates) {
        if (candidate.score == 0) {
            err << "  ";
            PrintCandidate(err, context, candidate, intrinsic_name, template_args, args);
            err << "\n";
        }
    }
    TINT_ICE() << err.Plain();
}

}  // namespace

void PrintCandidate(StyledText& ss,
                    Context& context,
                    const Candidate& candidate,
                    std::string_view intrinsic_name,
                    VectorRef<const core::type::Type*> template_args,
                    VectorRef<const core::type::Type*> args) {
    // Restore old style before returning.
    auto prev_style = ss.Style();
    TINT_DEFER(ss << prev_style);

    auto& overload = *candidate.overload;

    TemplateState templates = candidate.templates;

    // TODO(crbug.com/tint/1730): Use input evaluation stage to output only relevant overloads.
    auto earliest_eval_stage = EvaluationStage::kConstant;

    ss << style::Code << style::Function(intrinsic_name);

    if (overload.num_explicit_templates > 0) {
        ss << "<";
        for (size_t i = 0; i < overload.num_explicit_templates; i++) {
            const auto& tmpl = context.data[overload.templates + i];

            bool matched = false;
            if (i < template_args.Length()) {
                auto* matcher_indices = context.data[tmpl.matcher_indices];
                matched = !matcher_indices ||
                          context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                              .Type(template_args[i]);
            }

            if (i > 0) {
                ss << ", ";
            }
            ss << style::Type(tmpl.name) << " ";
            if (matched) {
                ss << (style::Code + style::Match)(" ✓ ");
            } else {
                ss << (style::Code + style::Mismatch)(" ✗ ");
            }
        }
        ss << ">";
    }

    bool all_params_match = true;
    ss << "(";
    for (size_t i = 0; i < overload.num_parameters; i++) {
        const auto& parameter = context.data[overload.parameters + i];
        auto* matcher_indices = context.data[parameter.matcher_indices];

        bool matched = false;
        if (i < args.Length()) {
            matched = context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                          .Type(args[i]);
        }
        all_params_match = all_params_match && matched;

        if (i > 0) {
            ss << ", ";
        }

        if (parameter.usage != ParameterUsage::kNone) {
            ss << style::Variable(parameter.usage, ": ");
        }
        context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);

        ss << style::Code << " ";
        if (matched) {
            ss << (style::Code + style::Match)(" ✓ ");
        } else {
            ss << (style::Code + style::Mismatch)(" ✗ ");
        }
    }
    ss << ")";
    if (overload.return_matcher_indices.IsValid()) {
        ss << " -> ";
        auto* matcher_indices = context.data[overload.return_matcher_indices];
        context.Match(templates, overload, matcher_indices, earliest_eval_stage).PrintType(ss);
    }

    bool first = true;
    auto separator = [&] {
        ss << style::Plain(first ? " where:\n     " : "\n     ");
        first = false;
    };

    if (all_params_match && args.Length() > overload.num_parameters) {
        separator();
        ss << style::Mismatch(" ✗ ")
           << style::Plain(" overload expects ", static_cast<int>(overload.num_parameters),
                           " argument", overload.num_parameters != 1 ? "s" : "", ", call passed ",
                           args.Length(), " argument", args.Length() != 1 ? "s" : "");
    }
    if (all_params_match && template_args.Length() > overload.num_explicit_templates) {
        separator();
        ss << style::Mismatch(" ✗ ")
           << style::Plain(" overload expects ", static_cast<int>(overload.num_explicit_templates),
                           " template argument", overload.num_explicit_templates != 1 ? "s" : "",
                           ", call passed ", template_args.Length(), " argument",
                           template_args.Length() != 1 ? "s" : "");
    }

    for (size_t i = 0; i < overload.num_templates; i++) {
        auto& tmpl = context.data[overload.templates + i];
        if (auto* matcher_indices = context.data[tmpl.matcher_indices]) {
            separator();
            bool matched = false;
            if (tmpl.kind == TemplateInfo::Kind::kType) {
                if (auto* ty = templates.Type(i)) {
                    matched =
                        context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                            .Type(ty);
                }
            } else {
                matched = context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                              .Num(templates.Num(i))
                              .IsValid();
            }
            if (matched) {
                ss << style::Match(" ✓ ") << style::Plain(" ");
            } else {
                ss << style::Mismatch(" ✗ ") << style::Plain(" ");
            }

            ss << style::Type(tmpl.name) << style::Plain(" is ");
            if (tmpl.kind == TemplateInfo::Kind::kType) {
                context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                    .PrintType(ss);
            } else {
                context.Match(templates, overload, matcher_indices, earliest_eval_stage)
                    .PrintNum(ss);
            }
        }
    }
}

Result<Overload, StyledText> LookupFn(Context& context,
                                      std::string_view intrinsic_name,
                                      size_t function_id,
                                      VectorRef<const core::type::Type*> template_args,
                                      VectorRef<const core::type::Type*> args,
                                      EvaluationStage earliest_eval_stage) {
    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching call to " << CallSignature(intrinsic_name, template_args, args) << "\n";
        if (!candidates.IsEmpty()) {
            err << "\n"
                << candidates.Length() << " candidate function"
                << (candidates.Length() > 1 ? "s:" : ":") << "\n";
            PrintCandidates(err, context, candidates, intrinsic_name, template_args, args);
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, context.data.builtins[function_id], intrinsic_name,
                          template_args, args, earliest_eval_stage, on_no_match);
}

Result<Overload, StyledText> LookupUnary(Context& context,
                                         core::UnaryOp op,
                                         const core::type::Type* arg,
                                         EvaluationStage earliest_eval_stage) {
    const IntrinsicInfo* intrinsic_info = nullptr;
    std::string_view intrinsic_name;
    switch (op) {
        case core::UnaryOp::kComplement:
            intrinsic_info = &context.data.unary_complement;
            intrinsic_name = "operator ~ ";
            break;
        case core::UnaryOp::kNegation:
            intrinsic_info = &context.data.unary_minus;
            intrinsic_name = "operator - ";
            break;
        case core::UnaryOp::kAddressOf:
            intrinsic_info = &context.data.unary_and;
            intrinsic_name = "operator & ";
            break;
        case core::UnaryOp::kIndirection:
            intrinsic_info = &context.data.unary_star;
            intrinsic_name = "operator * ";
            break;
        case core::UnaryOp::kNot:
            intrinsic_info = &context.data.unary_not;
            intrinsic_name = "operator ! ";
            break;
    }

    Vector args{arg};

    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&, name = intrinsic_name](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching overload for " << CallSignature(name, Empty, args) << "\n";
        if (!candidates.IsEmpty()) {
            err << "\n"
                << candidates.Length() << " candidate operator"
                << (candidates.Length() > 1 ? "s:" : ":") << "\n";
            PrintCandidates(err, context, candidates, name, Empty, Vector{arg});
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, *intrinsic_info, intrinsic_name, Empty, args,
                          earliest_eval_stage, on_no_match);
}

Result<Overload, StyledText> LookupBinary(Context& context,
                                          core::BinaryOp op,
                                          const core::type::Type* lhs,
                                          const core::type::Type* rhs,
                                          EvaluationStage earliest_eval_stage,
                                          bool is_compound) {
    const IntrinsicInfo* intrinsic_info = nullptr;
    std::string_view intrinsic_name;
    switch (op) {
        case core::BinaryOp::kAnd:
            intrinsic_info = &context.data.binary_and;
            intrinsic_name = is_compound ? "operator &= " : "operator & ";
            break;
        case core::BinaryOp::kOr:
            intrinsic_info = &context.data.binary_or;
            intrinsic_name = is_compound ? "operator |= " : "operator | ";
            break;
        case core::BinaryOp::kXor:
            intrinsic_info = &context.data.binary_xor;
            intrinsic_name = is_compound ? "operator ^= " : "operator ^ ";
            break;
        case core::BinaryOp::kLogicalAnd:
            intrinsic_info = &context.data.binary_logical_and;
            intrinsic_name = "operator && ";
            break;
        case core::BinaryOp::kLogicalOr:
            intrinsic_info = &context.data.binary_logical_or;
            intrinsic_name = "operator || ";
            break;
        case core::BinaryOp::kEqual:
            intrinsic_info = &context.data.binary_equal;
            intrinsic_name = "operator == ";
            break;
        case core::BinaryOp::kNotEqual:
            intrinsic_info = &context.data.binary_not_equal;
            intrinsic_name = "operator != ";
            break;
        case core::BinaryOp::kLessThan:
            intrinsic_info = &context.data.binary_less_than;
            intrinsic_name = "operator < ";
            break;
        case core::BinaryOp::kGreaterThan:
            intrinsic_info = &context.data.binary_greater_than;
            intrinsic_name = "operator > ";
            break;
        case core::BinaryOp::kLessThanEqual:
            intrinsic_info = &context.data.binary_less_than_equal;
            intrinsic_name = "operator <= ";
            break;
        case core::BinaryOp::kGreaterThanEqual:
            intrinsic_info = &context.data.binary_greater_than_equal;
            intrinsic_name = "operator >= ";
            break;
        case core::BinaryOp::kShiftLeft:
            intrinsic_info = &context.data.binary_shift_left;
            intrinsic_name = is_compound ? "operator <<= " : "operator << ";
            break;
        case core::BinaryOp::kShiftRight:
            intrinsic_info = &context.data.binary_shift_right;
            intrinsic_name = is_compound ? "operator >>= " : "operator >> ";
            break;
        case core::BinaryOp::kAdd:
            intrinsic_info = &context.data.binary_plus;
            intrinsic_name = is_compound ? "operator += " : "operator + ";
            break;
        case core::BinaryOp::kSubtract:
            intrinsic_info = &context.data.binary_minus;
            intrinsic_name = is_compound ? "operator -= " : "operator - ";
            break;
        case core::BinaryOp::kMultiply:
            intrinsic_info = &context.data.binary_star;
            intrinsic_name = is_compound ? "operator *= " : "operator * ";
            break;
        case core::BinaryOp::kDivide:
            intrinsic_info = &context.data.binary_divide;
            intrinsic_name = is_compound ? "operator /= " : "operator / ";
            break;
        case core::BinaryOp::kModulo:
            intrinsic_info = &context.data.binary_modulo;
            intrinsic_name = is_compound ? "operator %= " : "operator % ";
            break;
    }

    Vector args{lhs, rhs};

    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&, name = intrinsic_name](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching overload for " << CallSignature(name, Empty, args) << "\n";
        if (!candidates.IsEmpty()) {
            err << "\n"
                << candidates.Length() << " candidate operator"
                << (candidates.Length() > 1 ? "s:" : ":") << "\n";
            PrintCandidates(err, context, candidates, name, Empty, args);
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, *intrinsic_info, intrinsic_name, Empty, args,
                          earliest_eval_stage, on_no_match);
}

Result<Overload, StyledText> LookupCtorConv(Context& context,
                                            std::string_view type_name,
                                            size_t type_id,
                                            VectorRef<const core::type::Type*> template_args,
                                            VectorRef<const core::type::Type*> args,
                                            EvaluationStage earliest_eval_stage) {
    // Generates an error when no overloads match the provided arguments
    auto on_no_match = [&](VectorRef<Candidate> candidates) {
        StyledText err;
        err << "no matching constructor for " << CallSignature(type_name, template_args, args)
            << "\n";
        Candidates ctor, conv;
        for (auto candidate : candidates) {
            if (candidate.overload->flags.Contains(OverloadFlag::kIsConstructor)) {
                ctor.Push(candidate);
            } else {
                conv.Push(candidate);
            }
        }
        if (!ctor.IsEmpty()) {
            err << "\n"
                << ctor.Length() << " candidate constructor" << (ctor.Length() > 1 ? "s:" : ":")
                << "\n";
            PrintCandidates(err, context, ctor, type_name, template_args, args);
        }
        if (!conv.IsEmpty()) {
            err << "\n"
                << conv.Length() << " candidate conversion" << (conv.Length() > 1 ? "s:" : ":")
                << "\n";
            PrintCandidates(err, context, conv, type_name, template_args, args);
        }
        return err;
    };

    // Resolve the intrinsic overload
    return MatchIntrinsic(context, context.data.ctor_conv[type_id], type_name, template_args, args,
                          earliest_eval_stage, on_no_match);
}

}  // namespace tint::core::intrinsic

/// TypeInfo for the Any type declared in the anonymous namespace above
TINT_INSTANTIATE_TYPEINFO(tint::core::intrinsic::Any);
