// Copyright 2021 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 "src/tint/transform/canonicalize_entry_point_io.h"

#include <algorithm>
#include <string>
#include <unordered_set>
#include <utility>
#include <vector>

#include "src/tint/ast/disable_validation_attribute.h"
#include "src/tint/program_builder.h"
#include "src/tint/sem/function.h"
#include "src/tint/transform/unshadow.h"

using namespace tint::number_suffixes;  // NOLINT

TINT_INSTANTIATE_TYPEINFO(tint::transform::CanonicalizeEntryPointIO);
TINT_INSTANTIATE_TYPEINFO(tint::transform::CanonicalizeEntryPointIO::Config);

namespace tint::transform {

CanonicalizeEntryPointIO::CanonicalizeEntryPointIO() = default;
CanonicalizeEntryPointIO::~CanonicalizeEntryPointIO() = default;

namespace {

/// Info for a struct member
struct MemberInfo {
    /// The struct member item
    const ast::StructMember* member;
    /// The struct member location if provided
    std::optional<uint32_t> location;
};

/// FXC is sensitive to field order in structures, this is used by StructMemberComparator to ensure
/// that FXC is happy with the order of emitted fields.
uint32_t BuiltinOrder(ast::BuiltinValue builtin) {
    switch (builtin) {
        case ast::BuiltinValue::kPosition:
            return 1;
        case ast::BuiltinValue::kVertexIndex:
            return 2;
        case ast::BuiltinValue::kInstanceIndex:
            return 3;
        case ast::BuiltinValue::kFrontFacing:
            return 4;
        case ast::BuiltinValue::kFragDepth:
            return 5;
        case ast::BuiltinValue::kLocalInvocationId:
            return 6;
        case ast::BuiltinValue::kLocalInvocationIndex:
            return 7;
        case ast::BuiltinValue::kGlobalInvocationId:
            return 8;
        case ast::BuiltinValue::kWorkgroupId:
            return 9;
        case ast::BuiltinValue::kNumWorkgroups:
            return 10;
        case ast::BuiltinValue::kSampleIndex:
            return 11;
        case ast::BuiltinValue::kSampleMask:
            return 12;
        case ast::BuiltinValue::kPointSize:
            return 13;
        default:
            break;
    }
    return 0;
}

/// Comparison function used to reorder struct members such that all members with
/// location attributes appear first (ordered by location slot), followed by
/// those with builtin attributes.
/// @param a a struct member
/// @param b another struct member
/// @returns true if a comes before b
bool StructMemberComparator(const MemberInfo& a, const MemberInfo& b) {
    auto* a_loc = ast::GetAttribute<ast::LocationAttribute>(a.member->attributes);
    auto* b_loc = ast::GetAttribute<ast::LocationAttribute>(b.member->attributes);
    auto* a_blt = ast::GetAttribute<ast::BuiltinAttribute>(a.member->attributes);
    auto* b_blt = ast::GetAttribute<ast::BuiltinAttribute>(b.member->attributes);
    if (a_loc) {
        if (!b_loc) {
            // `a` has location attribute and `b` does not: `a` goes first.
            return true;
        }
        // Both have location attributes: smallest goes first.
        return a.location < b.location;
    } else {
        if (b_loc) {
            // `b` has location attribute and `a` does not: `b` goes first.
            return false;
        }
        // Both are builtins: order matters for FXC.
        return BuiltinOrder(a_blt->builtin) < BuiltinOrder(b_blt->builtin);
    }
}

// Returns true if `attr` is a shader IO attribute.
bool IsShaderIOAttribute(const ast::Attribute* attr) {
    return attr->IsAnyOf<ast::BuiltinAttribute, ast::InterpolateAttribute, ast::InvariantAttribute,
                         ast::LocationAttribute>();
}

// Returns true if `attrs` contains a `sample_mask` builtin.
bool HasSampleMask(utils::VectorRef<const ast::Attribute*> attrs) {
    auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(attrs);
    return builtin && builtin->builtin == ast::BuiltinValue::kSampleMask;
}

}  // namespace

/// PIMPL state for the transform
struct CanonicalizeEntryPointIO::State {
    /// OutputValue represents a shader result that the wrapper function produces.
    struct OutputValue {
        /// The name of the output value.
        std::string name;
        /// The type of the output value.
        const ast::Type* type;
        /// The shader IO attributes.
        utils::Vector<const ast::Attribute*, 2> attributes;
        /// The value itself.
        const ast::Expression* value;
        /// The output location.
        std::optional<uint32_t> location;
    };

    /// The clone context.
    CloneContext& ctx;
    /// The transform config.
    CanonicalizeEntryPointIO::Config const cfg;
    /// The entry point function (AST).
    const ast::Function* func_ast;
    /// The entry point function (SEM).
    const sem::Function* func_sem;

    /// The new entry point wrapper function's parameters.
    utils::Vector<const ast::Parameter*, 8> wrapper_ep_parameters;

    /// The members of the wrapper function's struct parameter.
    utils::Vector<MemberInfo, 8> wrapper_struct_param_members;
    /// The name of the wrapper function's struct parameter.
    Symbol wrapper_struct_param_name;
    /// The parameters that will be passed to the original function.
    utils::Vector<const ast::Expression*, 8> inner_call_parameters;
    /// The members of the wrapper function's struct return type.
    utils::Vector<MemberInfo, 8> wrapper_struct_output_members;
    /// The wrapper function output values.
    utils::Vector<OutputValue, 8> wrapper_output_values;
    /// The body of the wrapper function.
    utils::Vector<const ast::Statement*, 8> wrapper_body;
    /// Input names used by the entrypoint
    std::unordered_set<std::string> input_names;

    /// Constructor
    /// @param context the clone context
    /// @param config the transform config
    /// @param function the entry point function
    State(CloneContext& context,
          const CanonicalizeEntryPointIO::Config& config,
          const ast::Function* function)
        : ctx(context), cfg(config), func_ast(function), func_sem(ctx.src->Sem().Get(function)) {}

    /// Clones the shader IO attributes from `src`.
    /// @param src the attributes to clone
    /// @param do_interpolate whether to clone InterpolateAttribute
    /// @return the cloned attributes
    template <size_t N>
    auto CloneShaderIOAttributes(utils::Vector<const ast::Attribute*, N> src, bool do_interpolate) {
        utils::Vector<const ast::Attribute*, N> new_attributes;
        for (auto* attr : src) {
            if (IsShaderIOAttribute(attr) &&
                (do_interpolate || !attr->template Is<ast::InterpolateAttribute>())) {
                new_attributes.Push(ctx.Clone(attr));
            }
        }
        return new_attributes;
    }

    /// Create or return a symbol for the wrapper function's struct parameter.
    /// @returns the symbol for the struct parameter
    Symbol InputStructSymbol() {
        if (!wrapper_struct_param_name.IsValid()) {
            wrapper_struct_param_name = ctx.dst->Sym();
        }
        return wrapper_struct_param_name;
    }

    /// Add a shader input to the entry point.
    /// @param name the name of the shader input
    /// @param type the type of the shader input
    /// @param location the location if provided
    /// @param attributes the attributes to apply to the shader input
    /// @returns an expression which evaluates to the value of the shader input
    const ast::Expression* AddInput(std::string name,
                                    const sem::Type* type,
                                    std::optional<uint32_t> location,
                                    utils::Vector<const ast::Attribute*, 8> attributes) {
        auto* ast_type = CreateASTTypeFor(ctx, type);
        if (cfg.shader_style == ShaderStyle::kSpirv || cfg.shader_style == ShaderStyle::kGlsl) {
            // Vulkan requires that integer user-defined fragment inputs are always decorated with
            // `Flat`. See:
            // https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/StandaloneSpirv.html#VUID-StandaloneSpirv-Flat-04744
            // TODO(crbug.com/tint/1224): Remove this once a flat interpolation attribute is
            // required for integers.
            if (func_ast->PipelineStage() == ast::PipelineStage::kFragment &&
                type->is_integer_scalar_or_vector() &&
                !ast::HasAttribute<ast::InterpolateAttribute>(attributes) &&
                (ast::HasAttribute<ast::LocationAttribute>(attributes) ||
                 cfg.shader_style == ShaderStyle::kSpirv)) {
                attributes.Push(ctx.dst->Interpolate(ast::InterpolationType::kFlat,
                                                     ast::InterpolationSampling::kUndefined));
            }

            // Disable validation for use of the `input` address space.
            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));

            // In GLSL, if it's a builtin, override the name with the
            // corresponding gl_ builtin name
            auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(attributes);
            if (cfg.shader_style == ShaderStyle::kGlsl && builtin) {
                name = GLSLBuiltinToString(builtin->builtin, func_ast->PipelineStage(),
                                           ast::AddressSpace::kIn);
            }
            auto symbol = ctx.dst->Symbols().New(name);

            // Create the global variable and use its value for the shader input.
            const ast::Expression* value = ctx.dst->Expr(symbol);

            if (builtin) {
                if (cfg.shader_style == ShaderStyle::kGlsl) {
                    value = FromGLSLBuiltin(builtin->builtin, value, ast_type);
                } else if (builtin->builtin == ast::BuiltinValue::kSampleMask) {
                    // Vulkan requires the type of a SampleMask builtin to be an array.
                    // Declare it as array<u32, 1> and then load the first element.
                    ast_type = ctx.dst->ty.array(ast_type, 1_u);
                    value = ctx.dst->IndexAccessor(value, 0_i);
                }
            }
            ctx.dst->GlobalVar(symbol, ast_type, ast::AddressSpace::kIn, std::move(attributes));
            return value;
        } else if (cfg.shader_style == ShaderStyle::kMsl &&
                   ast::HasAttribute<ast::BuiltinAttribute>(attributes)) {
            // If this input is a builtin and we are targeting MSL, then add it to the
            // parameter list and pass it directly to the inner function.
            Symbol symbol = input_names.emplace(name).second ? ctx.dst->Symbols().Register(name)
                                                             : ctx.dst->Symbols().New(name);
            wrapper_ep_parameters.Push(ctx.dst->Param(symbol, ast_type, std::move(attributes)));
            return ctx.dst->Expr(symbol);
        } else {
            // Otherwise, move it to the new structure member list.
            Symbol symbol = input_names.emplace(name).second ? ctx.dst->Symbols().Register(name)
                                                             : ctx.dst->Symbols().New(name);
            wrapper_struct_param_members.Push(
                {ctx.dst->Member(symbol, ast_type, std::move(attributes)), location});
            return ctx.dst->MemberAccessor(InputStructSymbol(), symbol);
        }
    }

    /// Add a shader output to the entry point.
    /// @param name the name of the shader output
    /// @param type the type of the shader output
    /// @param location the location if provided
    /// @param attributes the attributes to apply to the shader output
    /// @param value the value of the shader output
    void AddOutput(std::string name,
                   const sem::Type* type,
                   std::optional<uint32_t> location,
                   utils::Vector<const ast::Attribute*, 8> attributes,
                   const ast::Expression* value) {
        // Vulkan requires that integer user-defined vertex outputs are always decorated with
        // `Flat`.
        // TODO(crbug.com/tint/1224): Remove this once a flat interpolation attribute is required
        // for integers.
        if (cfg.shader_style == ShaderStyle::kSpirv &&
            func_ast->PipelineStage() == ast::PipelineStage::kVertex &&
            type->is_integer_scalar_or_vector() &&
            ast::HasAttribute<ast::LocationAttribute>(attributes) &&
            !ast::HasAttribute<ast::InterpolateAttribute>(attributes)) {
            attributes.Push(ctx.dst->Interpolate(ast::InterpolationType::kFlat,
                                                 ast::InterpolationSampling::kUndefined));
        }

        // In GLSL, if it's a builtin, override the name with the
        // corresponding gl_ builtin name
        if (cfg.shader_style == ShaderStyle::kGlsl) {
            if (auto* b = ast::GetAttribute<ast::BuiltinAttribute>(attributes)) {
                name = GLSLBuiltinToString(b->builtin, func_ast->PipelineStage(),
                                           ast::AddressSpace::kOut);
                value = ToGLSLBuiltin(b->builtin, value, type);
            }
        }

        OutputValue output;
        output.name = name;
        output.type = CreateASTTypeFor(ctx, type);
        output.attributes = std::move(attributes);
        output.value = value;
        output.location = location;
        wrapper_output_values.Push(output);
    }

    /// Process a non-struct parameter.
    /// This creates a new object for the shader input, moving the shader IO
    /// attributes to it. It also adds an expression to the list of parameters
    /// that will be passed to the original function.
    /// @param param the original function parameter
    void ProcessNonStructParameter(const sem::Parameter* param) {
        // Do not add interpolation attributes on vertex input
        bool do_interpolate = func_ast->PipelineStage() != ast::PipelineStage::kVertex;
        // Remove the shader IO attributes from the inner function parameter, and
        // attach them to the new object instead.
        utils::Vector<const ast::Attribute*, 8> attributes;
        for (auto* attr : param->Declaration()->attributes) {
            if (IsShaderIOAttribute(attr)) {
                ctx.Remove(param->Declaration()->attributes, attr);
                if ((do_interpolate || !attr->Is<ast::InterpolateAttribute>())) {
                    attributes.Push(ctx.Clone(attr));
                }
            }
        }

        auto name = ctx.src->Symbols().NameFor(param->Declaration()->symbol);
        auto* input_expr = AddInput(name, param->Type(), param->Location(), std::move(attributes));
        inner_call_parameters.Push(input_expr);
    }

    /// Process a struct parameter.
    /// This creates new objects for each struct member, moving the shader IO
    /// attributes to them. It also creates the structure that will be passed to
    /// the original function.
    /// @param param the original function parameter
    void ProcessStructParameter(const sem::Parameter* param) {
        // Do not add interpolation attributes on vertex input
        bool do_interpolate = func_ast->PipelineStage() != ast::PipelineStage::kVertex;

        auto* str = param->Type()->As<sem::Struct>();

        // Recreate struct members in the outer entry point and build an initializer
        // list to pass them through to the inner function.
        utils::Vector<const ast::Expression*, 8> inner_struct_values;
        for (auto* member : str->Members()) {
            if (member->Type()->Is<sem::Struct>()) {
                TINT_ICE(Transform, ctx.dst->Diagnostics()) << "nested IO struct";
                continue;
            }

            auto* member_ast = member->Declaration();
            auto name = ctx.src->Symbols().NameFor(member_ast->symbol);

            auto attributes = CloneShaderIOAttributes(member_ast->attributes, do_interpolate);
            auto* input_expr =
                AddInput(name, member->Type(), member->Location(), std::move(attributes));
            inner_struct_values.Push(input_expr);
        }

        // Construct the original structure using the new shader input objects.
        inner_call_parameters.Push(
            ctx.dst->Construct(ctx.Clone(param->Declaration()->type), inner_struct_values));
    }

    /// Process the entry point return type.
    /// This generates a list of output values that are returned by the original
    /// function.
    /// @param inner_ret_type the original function return type
    /// @param original_result the result object produced by the original function
    void ProcessReturnType(const sem::Type* inner_ret_type, Symbol original_result) {
        // Do not add interpolation attributes on fragment output
        bool do_interpolate = func_ast->PipelineStage() != ast::PipelineStage::kFragment;
        if (auto* str = inner_ret_type->As<sem::Struct>()) {
            for (auto* member : str->Members()) {
                if (member->Type()->Is<sem::Struct>()) {
                    TINT_ICE(Transform, ctx.dst->Diagnostics()) << "nested IO struct";
                    continue;
                }

                auto* member_ast = member->Declaration();
                auto name = ctx.src->Symbols().NameFor(member_ast->symbol);
                auto attributes = CloneShaderIOAttributes(member_ast->attributes, do_interpolate);

                // Extract the original structure member.
                AddOutput(name, member->Type(), member->Location(), std::move(attributes),
                          ctx.dst->MemberAccessor(original_result, name));
            }
        } else if (!inner_ret_type->Is<sem::Void>()) {
            auto attributes =
                CloneShaderIOAttributes(func_ast->return_type_attributes, do_interpolate);

            // Propagate the non-struct return value as is.
            AddOutput("value", func_sem->ReturnType(), func_sem->ReturnLocation(),
                      std::move(attributes), ctx.dst->Expr(original_result));
        }
    }

    /// Add a fixed sample mask to the wrapper function output.
    /// If there is already a sample mask, bitwise-and it with the fixed mask.
    /// Otherwise, create a new output value from the fixed mask.
    void AddFixedSampleMask() {
        // Check the existing output values for a sample mask builtin.
        for (auto& outval : wrapper_output_values) {
            if (HasSampleMask(outval.attributes)) {
                // Combine the authored sample mask with the fixed mask.
                outval.value = ctx.dst->And(outval.value, u32(cfg.fixed_sample_mask));
                return;
            }
        }

        // No existing sample mask builtin was found, so create a new output value
        // using the fixed sample mask.
        AddOutput("fixed_sample_mask", ctx.dst->create<sem::U32>(), std::nullopt,
                  {ctx.dst->Builtin(ast::BuiltinValue::kSampleMask)},
                  ctx.dst->Expr(u32(cfg.fixed_sample_mask)));
    }

    /// Add a point size builtin to the wrapper function output.
    void AddVertexPointSize() {
        // Create a new output value and assign it a literal 1.0 value.
        AddOutput("vertex_point_size", ctx.dst->create<sem::F32>(), std::nullopt,
                  {ctx.dst->Builtin(ast::BuiltinValue::kPointSize)}, ctx.dst->Expr(1_f));
    }

    /// Create an expression for gl_Position.[component]
    /// @param component the component of gl_Position to access
    /// @returns the new expression
    const ast::Expression* GLPosition(const char* component) {
        Symbol pos = ctx.dst->Symbols().Register("gl_Position");
        Symbol c = ctx.dst->Symbols().Register(component);
        return ctx.dst->MemberAccessor(ctx.dst->Expr(pos), ctx.dst->Expr(c));
    }

    /// Create the wrapper function's struct parameter and type objects.
    void CreateInputStruct() {
        // Sort the struct members to satisfy HLSL interfacing matching rules.
        std::sort(wrapper_struct_param_members.begin(), wrapper_struct_param_members.end(),
                  StructMemberComparator);

        utils::Vector<const ast::StructMember*, 8> members;
        for (auto& mem : wrapper_struct_param_members) {
            members.Push(mem.member);
        }

        // Create the new struct type.
        auto struct_name = ctx.dst->Sym();
        auto* in_struct = ctx.dst->create<ast::Struct>(struct_name, members, utils::Empty);
        ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func_ast, in_struct);

        // Create a new function parameter using this struct type.
        auto* param = ctx.dst->Param(InputStructSymbol(), ctx.dst->ty.type_name(struct_name));
        wrapper_ep_parameters.Push(param);
    }

    /// Create and return the wrapper function's struct result object.
    /// @returns the struct type
    ast::Struct* CreateOutputStruct() {
        utils::Vector<const ast::Statement*, 8> assignments;

        auto wrapper_result = ctx.dst->Symbols().New("wrapper_result");

        // Create the struct members and their corresponding assignment statements.
        std::unordered_set<std::string> member_names;
        for (auto& outval : wrapper_output_values) {
            // Use the original output name, unless that is already taken.
            Symbol name;
            if (member_names.count(outval.name)) {
                name = ctx.dst->Symbols().New(outval.name);
            } else {
                name = ctx.dst->Symbols().Register(outval.name);
            }
            member_names.insert(ctx.dst->Symbols().NameFor(name));

            wrapper_struct_output_members.Push(
                {ctx.dst->Member(name, outval.type, std::move(outval.attributes)),
                 outval.location});
            assignments.Push(
                ctx.dst->Assign(ctx.dst->MemberAccessor(wrapper_result, name), outval.value));
        }

        // Sort the struct members to satisfy HLSL interfacing matching rules.
        std::sort(wrapper_struct_output_members.begin(), wrapper_struct_output_members.end(),
                  StructMemberComparator);

        utils::Vector<const ast::StructMember*, 8> members;
        for (auto& mem : wrapper_struct_output_members) {
            members.Push(mem.member);
        }

        // Create the new struct type.
        auto* out_struct = ctx.dst->create<ast::Struct>(ctx.dst->Sym(), members, utils::Empty);
        ctx.InsertBefore(ctx.src->AST().GlobalDeclarations(), func_ast, out_struct);

        // Create the output struct object, assign its members, and return it.
        auto* result_object = ctx.dst->Var(wrapper_result, ctx.dst->ty.type_name(out_struct->name));
        wrapper_body.Push(ctx.dst->Decl(result_object));
        for (auto* assignment : assignments) {
            wrapper_body.Push(assignment);
        }
        wrapper_body.Push(ctx.dst->Return(wrapper_result));

        return out_struct;
    }

    /// Create and assign the wrapper function's output variables.
    void CreateGlobalOutputVariables() {
        for (auto& outval : wrapper_output_values) {
            // Disable validation for use of the `output` address space.
            utils::Vector<const ast::Attribute*, 8> attributes = std::move(outval.attributes);
            attributes.Push(ctx.dst->Disable(ast::DisabledValidation::kIgnoreAddressSpace));

            // Create the global variable and assign it the output value.
            auto name = ctx.dst->Symbols().New(outval.name);
            auto* type = outval.type;
            const ast::Expression* lhs = ctx.dst->Expr(name);
            if (HasSampleMask(attributes)) {
                // Vulkan requires the type of a SampleMask builtin to be an array.
                // Declare it as array<u32, 1> and then store to the first element.
                type = ctx.dst->ty.array(type, 1_u);
                lhs = ctx.dst->IndexAccessor(lhs, 0_i);
            }
            ctx.dst->GlobalVar(name, type, ast::AddressSpace::kOut, std::move(attributes));
            wrapper_body.Push(ctx.dst->Assign(lhs, outval.value));
        }
    }

    // Recreate the original function without entry point attributes and call it.
    /// @returns the inner function call expression
    const ast::CallExpression* CallInnerFunction() {
        Symbol inner_name;
        if (cfg.shader_style == ShaderStyle::kGlsl) {
            // In GLSL, clone the original entry point name, as the wrapper will be
            // called "main".
            inner_name = ctx.Clone(func_ast->symbol);
        } else {
            // Add a suffix to the function name, as the wrapper function will take
            // the original entry point name.
            auto ep_name = ctx.src->Symbols().NameFor(func_ast->symbol);
            inner_name = ctx.dst->Symbols().New(ep_name + "_inner");
        }

        // Clone everything, dropping the function and return type attributes.
        // The parameter attributes will have already been stripped during
        // processing.
        auto* inner_function = ctx.dst->create<ast::Function>(
            inner_name, ctx.Clone(func_ast->params), ctx.Clone(func_ast->return_type),
            ctx.Clone(func_ast->body), utils::Empty, utils::Empty);
        ctx.Replace(func_ast, inner_function);

        // Call the function.
        return ctx.dst->Call(inner_function->symbol, inner_call_parameters);
    }

    /// Process the entry point function.
    void Process() {
        bool needs_fixed_sample_mask = false;
        bool needs_vertex_point_size = false;
        if (func_ast->PipelineStage() == ast::PipelineStage::kFragment &&
            cfg.fixed_sample_mask != 0xFFFFFFFF) {
            needs_fixed_sample_mask = true;
        }
        if (func_ast->PipelineStage() == ast::PipelineStage::kVertex &&
            cfg.emit_vertex_point_size) {
            needs_vertex_point_size = true;
        }

        // Exit early if there is no shader IO to handle.
        if (func_sem->Parameters().Length() == 0 && func_sem->ReturnType()->Is<sem::Void>() &&
            !needs_fixed_sample_mask && !needs_vertex_point_size &&
            cfg.shader_style != ShaderStyle::kGlsl) {
            return;
        }

        // Process the entry point parameters, collecting those that need to be
        // aggregated into a single structure.
        if (!func_sem->Parameters().IsEmpty()) {
            for (auto* param : func_sem->Parameters()) {
                if (param->Type()->Is<sem::Struct>()) {
                    ProcessStructParameter(param);
                } else {
                    ProcessNonStructParameter(param);
                }
            }

            // Create a structure parameter for the outer entry point if necessary.
            if (!wrapper_struct_param_members.IsEmpty()) {
                CreateInputStruct();
            }
        }

        // Recreate the original function and call it.
        auto* call_inner = CallInnerFunction();

        // Process the return type, and start building the wrapper function body.
        std::function<const ast::Type*()> wrapper_ret_type = [&] { return ctx.dst->ty.void_(); };
        if (func_sem->ReturnType()->Is<sem::Void>()) {
            // The function call is just a statement with no result.
            wrapper_body.Push(ctx.dst->CallStmt(call_inner));
        } else {
            // Capture the result of calling the original function.
            auto* inner_result = ctx.dst->Let(ctx.dst->Symbols().New("inner_result"), call_inner);
            wrapper_body.Push(ctx.dst->Decl(inner_result));

            // Process the original return type to determine the outputs that the
            // outer function needs to produce.
            ProcessReturnType(func_sem->ReturnType(), inner_result->symbol);
        }

        // Add a fixed sample mask, if necessary.
        if (needs_fixed_sample_mask) {
            AddFixedSampleMask();
        }

        // Add the pointsize builtin, if necessary.
        if (needs_vertex_point_size) {
            AddVertexPointSize();
        }

        // Produce the entry point outputs, if necessary.
        if (!wrapper_output_values.IsEmpty()) {
            if (cfg.shader_style == ShaderStyle::kSpirv || cfg.shader_style == ShaderStyle::kGlsl) {
                CreateGlobalOutputVariables();
            } else {
                auto* output_struct = CreateOutputStruct();
                wrapper_ret_type = [&, output_struct] {
                    return ctx.dst->ty.type_name(output_struct->name);
                };
            }
        }

        if (cfg.shader_style == ShaderStyle::kGlsl &&
            func_ast->PipelineStage() == ast::PipelineStage::kVertex) {
            auto* pos_y = GLPosition("y");
            auto* negate_pos_y =
                ctx.dst->create<ast::UnaryOpExpression>(ast::UnaryOp::kNegation, GLPosition("y"));
            wrapper_body.Push(ctx.dst->Assign(pos_y, negate_pos_y));

            auto* two_z = ctx.dst->Mul(ctx.dst->Expr(2_f), GLPosition("z"));
            auto* fixed_z = ctx.dst->Sub(two_z, GLPosition("w"));
            wrapper_body.Push(ctx.dst->Assign(GLPosition("z"), fixed_z));
        }

        // Create the wrapper entry point function.
        // For GLSL, use "main", otherwise take the name of the original
        // entry point function.
        Symbol name;
        if (cfg.shader_style == ShaderStyle::kGlsl) {
            name = ctx.dst->Symbols().New("main");
        } else {
            name = ctx.Clone(func_ast->symbol);
        }

        auto* wrapper_func = ctx.dst->create<ast::Function>(
            name, wrapper_ep_parameters, wrapper_ret_type(), ctx.dst->Block(wrapper_body),
            ctx.Clone(func_ast->attributes), utils::Empty);
        ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), func_ast, wrapper_func);
    }

    /// Retrieve the gl_ string corresponding to a builtin.
    /// @param builtin the builtin
    /// @param stage the current pipeline stage
    /// @param address_space the address space (input or output)
    /// @returns the gl_ string corresponding to that builtin
    const char* GLSLBuiltinToString(ast::BuiltinValue builtin,
                                    ast::PipelineStage stage,
                                    ast::AddressSpace address_space) {
        switch (builtin) {
            case ast::BuiltinValue::kPosition:
                switch (stage) {
                    case ast::PipelineStage::kVertex:
                        return "gl_Position";
                    case ast::PipelineStage::kFragment:
                        return "gl_FragCoord";
                    default:
                        return "";
                }
            case ast::BuiltinValue::kVertexIndex:
                return "gl_VertexID";
            case ast::BuiltinValue::kInstanceIndex:
                return "gl_InstanceID";
            case ast::BuiltinValue::kFrontFacing:
                return "gl_FrontFacing";
            case ast::BuiltinValue::kFragDepth:
                return "gl_FragDepth";
            case ast::BuiltinValue::kLocalInvocationId:
                return "gl_LocalInvocationID";
            case ast::BuiltinValue::kLocalInvocationIndex:
                return "gl_LocalInvocationIndex";
            case ast::BuiltinValue::kGlobalInvocationId:
                return "gl_GlobalInvocationID";
            case ast::BuiltinValue::kNumWorkgroups:
                return "gl_NumWorkGroups";
            case ast::BuiltinValue::kWorkgroupId:
                return "gl_WorkGroupID";
            case ast::BuiltinValue::kSampleIndex:
                return "gl_SampleID";
            case ast::BuiltinValue::kSampleMask:
                if (address_space == ast::AddressSpace::kIn) {
                    return "gl_SampleMaskIn";
                } else {
                    return "gl_SampleMask";
                }
            default:
                return "";
        }
    }

    /// Convert a given GLSL builtin value to the corresponding WGSL value.
    /// @param builtin the builtin variable
    /// @param value the value to convert
    /// @param ast_type (inout) the incoming WGSL and outgoing GLSL types
    /// @returns an expression representing the GLSL builtin converted to what
    /// WGSL expects
    const ast::Expression* FromGLSLBuiltin(ast::BuiltinValue builtin,
                                           const ast::Expression* value,
                                           const ast::Type*& ast_type) {
        switch (builtin) {
            case ast::BuiltinValue::kVertexIndex:
            case ast::BuiltinValue::kInstanceIndex:
            case ast::BuiltinValue::kSampleIndex:
                // GLSL uses i32 for these, so bitcast to u32.
                value = ctx.dst->Bitcast(ast_type, value);
                ast_type = ctx.dst->ty.i32();
                break;
            case ast::BuiltinValue::kSampleMask:
                // gl_SampleMask is an array of i32. Retrieve the first element and
                // bitcast it to u32.
                value = ctx.dst->IndexAccessor(value, 0_i);
                value = ctx.dst->Bitcast(ast_type, value);
                ast_type = ctx.dst->ty.array(ctx.dst->ty.i32(), 1_u);
                break;
            default:
                break;
        }
        return value;
    }

    /// Convert a given WGSL value to the type expected when assigning to a
    /// GLSL builtin.
    /// @param builtin the builtin variable
    /// @param value the value to convert
    /// @param type (out) the type to which the value was converted
    /// @returns the converted value which can be assigned to the GLSL builtin
    const ast::Expression* ToGLSLBuiltin(ast::BuiltinValue builtin,
                                         const ast::Expression* value,
                                         const sem::Type*& type) {
        switch (builtin) {
            case ast::BuiltinValue::kVertexIndex:
            case ast::BuiltinValue::kInstanceIndex:
            case ast::BuiltinValue::kSampleIndex:
            case ast::BuiltinValue::kSampleMask:
                type = ctx.dst->create<sem::I32>();
                value = ctx.dst->Bitcast(CreateASTTypeFor(ctx, type), value);
                break;
            default:
                break;
        }
        return value;
    }
};

Transform::ApplyResult CanonicalizeEntryPointIO::Apply(const Program* src,
                                                       const DataMap& inputs,
                                                       DataMap&) const {
    ProgramBuilder b;
    CloneContext ctx{&b, src, /* auto_clone_symbols */ true};

    auto* cfg = inputs.Get<Config>();
    if (cfg == nullptr) {
        b.Diagnostics().add_error(diag::System::Transform,
                                  "missing transform data for " + std::string(TypeInfo().name));
        return Program(std::move(b));
    }

    // Remove entry point IO attributes from struct declarations.
    // New structures will be created for each entry point, as necessary.
    for (auto* ty : src->AST().TypeDecls()) {
        if (auto* struct_ty = ty->As<ast::Struct>()) {
            for (auto* member : struct_ty->members) {
                for (auto* attr : member->attributes) {
                    if (IsShaderIOAttribute(attr)) {
                        ctx.Remove(member->attributes, attr);
                    }
                }
            }
        }
    }

    for (auto* func_ast : src->AST().Functions()) {
        if (!func_ast->IsEntryPoint()) {
            continue;
        }

        State state(ctx, *cfg, func_ast);
        state.Process();
    }

    ctx.Clone();
    return Program(std::move(b));
}

CanonicalizeEntryPointIO::Config::Config(ShaderStyle style,
                                         uint32_t sample_mask,
                                         bool emit_point_size)
    : shader_style(style),
      fixed_sample_mask(sample_mask),
      emit_vertex_point_size(emit_point_size) {}

CanonicalizeEntryPointIO::Config::Config(const Config&) = default;
CanonicalizeEntryPointIO::Config::~Config() = default;

}  // namespace tint::transform
