/*
 * Copyright 2022 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/sksl/codegen/SkSLWGSLCodeGenerator.h"

#include "include/core/SkSpan.h"
#include "include/core/SkTypes.h"
#include "include/private/SkEnumBitMask.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTo.h"
#include "src/core/SkStringView.h"
#include "src/core/SkTHash.h"
#include "src/core/SkTraceEvent.h"
#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLBuiltinTypes.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLConstantFolder.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLDefines.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLIntrinsicList.h"
#include "src/sksl/SkSLMemoryLayout.h"
#include "src/sksl/SkSLOperator.h"
#include "src/sksl/SkSLOutputStream.h"
#include "src/sksl/SkSLPosition.h"
#include "src/sksl/SkSLProgramSettings.h"
#include "src/sksl/SkSLString.h"
#include "src/sksl/SkSLStringStream.h"
#include "src/sksl/SkSLUtil.h"
#include "src/sksl/analysis/SkSLProgramUsage.h"
#include "src/sksl/analysis/SkSLProgramVisitor.h"
#include "src/sksl/codegen/SkSLCodeGenTypes.h"
#include "src/sksl/codegen/SkSLCodeGenerator.h"
#include "src/sksl/codegen/SkSLNativeShader.h"
#include "src/sksl/ir/SkSLBinaryExpression.h"
#include "src/sksl/ir/SkSLBlock.h"
#include "src/sksl/ir/SkSLConstructor.h"
#include "src/sksl/ir/SkSLConstructorArrayCast.h"
#include "src/sksl/ir/SkSLConstructorCompound.h"
#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
#include "src/sksl/ir/SkSLDoStatement.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLExpressionStatement.h"
#include "src/sksl/ir/SkSLFieldAccess.h"
#include "src/sksl/ir/SkSLFieldSymbol.h"
#include "src/sksl/ir/SkSLForStatement.h"
#include "src/sksl/ir/SkSLFunctionCall.h"
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
#include "src/sksl/ir/SkSLFunctionDefinition.h"
#include "src/sksl/ir/SkSLIRHelpers.h"
#include "src/sksl/ir/SkSLIRNode.h"
#include "src/sksl/ir/SkSLIfStatement.h"
#include "src/sksl/ir/SkSLIndexExpression.h"
#include "src/sksl/ir/SkSLInterfaceBlock.h"
#include "src/sksl/ir/SkSLLayout.h"
#include "src/sksl/ir/SkSLLiteral.h"
#include "src/sksl/ir/SkSLModifierFlags.h"
#include "src/sksl/ir/SkSLModifiers.h"
#include "src/sksl/ir/SkSLModifiersDeclaration.h"
#include "src/sksl/ir/SkSLPostfixExpression.h"
#include "src/sksl/ir/SkSLPrefixExpression.h"
#include "src/sksl/ir/SkSLProgram.h"
#include "src/sksl/ir/SkSLProgramElement.h"
#include "src/sksl/ir/SkSLReturnStatement.h"
#include "src/sksl/ir/SkSLSetting.h"
#include "src/sksl/ir/SkSLStatement.h"
#include "src/sksl/ir/SkSLStructDefinition.h"
#include "src/sksl/ir/SkSLSwitchCase.h"
#include "src/sksl/ir/SkSLSwitchStatement.h"
#include "src/sksl/ir/SkSLSwizzle.h"
#include "src/sksl/ir/SkSLTernaryExpression.h"
#include "src/sksl/ir/SkSLType.h"
#include "src/sksl/ir/SkSLVarDeclarations.h"
#include "src/sksl/ir/SkSLVariable.h"
#include "src/sksl/ir/SkSLVariableReference.h"
#include "src/sksl/spirv.h"
#include "src/sksl/transform/SkSLTransform.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>

using namespace skia_private;

namespace {

// Represents a function's dependencies that are not accessible in global scope. For instance,
// pipeline stage input and output parameters must be passed in as an argument.
//
// This is a bitmask enum. (It would be inside `class WGSLCodeGenerator`, but this leads to build
// errors in MSVC.)
enum class WGSLFunctionDependency : uint8_t {
    kNone = 0,
    kPipelineInputs  = 1 << 0,
    kPipelineOutputs = 1 << 1,
};
using WGSLFunctionDependencies = SkEnumBitMask<WGSLFunctionDependency>;

SK_MAKE_BITMASK_OPS(WGSLFunctionDependency)

}  // namespace

namespace SkSL {

class WGSLCodeGenerator : public CodeGenerator {
public:
    // See https://www.w3.org/TR/WGSL/#builtin-values
    enum class Builtin {
        // Vertex stage:
        kVertexIndex,    // input
        kInstanceIndex,  // input
        kPosition,       // output, fragment stage input

        // Fragment stage:
        kLastFragColor,  // input
        kFrontFacing,    // input
        kSampleIndex,    // input
        kFragDepth,      // output
        kSampleMaskIn,   // input
        kSampleMask,     // output

        // Compute stage:
        kLocalInvocationId,     // input
        kLocalInvocationIndex,  // input
        kGlobalInvocationId,    // input
        kWorkgroupId,           // input
        kNumWorkgroups,         // input
    };

    // Variable declarations can be terminated by:
    //   - comma (","), e.g. in struct member declarations or function parameters
    //   - semicolon (";"), e.g. in function scope variables
    // A "none" option is provided to skip the delimiter when not needed, e.g. at the end of a list
    // of declarations.
    enum class Delimiter {
        kComma,
        kSemicolon,
        kNone,
    };

    struct ProgramRequirements {
        using DepsMap = skia_private::THashMap<const FunctionDeclaration*,
                                               WGSLFunctionDependencies>;

        // Mappings used to synthesize function parameters according to dependencies on pipeline
        // input/output variables.
        DepsMap fDependencies;

        // These flags track extensions that will need to be enabled.
        bool fPixelLocalExtension = false;
    };

    WGSLCodeGenerator(const Context* context,
                      const ShaderCaps* caps,
                      const Program* program,
                      OutputStream* out,
                      PrettyPrint pp,
                      IncludeSyntheticCode isc)
            : CodeGenerator(context, caps, program, out)
            , fPrettyPrint(pp)
            , fGenSyntheticCode(isc) {}

    bool generateCode() override;

private:
    using Precedence = OperatorPrecedence;
    class AutoConstEvalWorkaround;

    // Called by generateCode() as the first step.
    void preprocessProgram();

    // Write output content while correctly handling indentation.
    void write(std::string_view s);
    void writeLine(std::string_view s = std::string_view());
    void finishLine();

    // Helpers to declare a pipeline stage IO parameter declaration.
    void writePipelineIODeclaration(const Layout& layout,
                                    const Type& type,
                                    ModifierFlags modifiers,
                                    std::string_view name,
                                    Delimiter delimiter);
    void writeUserDefinedIODecl(const Layout& layout,
                                const Type& type,
                                ModifierFlags modifiers,
                                std::string_view name,
                                Delimiter delimiter);
    void writeBuiltinIODecl(const Type& type,
                            std::string_view name,
                            Builtin builtin,
                            Delimiter delimiter);
    void writeVariableDecl(const Layout& layout,
                           const Type& type,
                           std::string_view name,
                           Delimiter delimiter);

    // Write a function definition.
    void writeFunction(const FunctionDefinition& f);
    void writeFunctionDeclaration(const FunctionDeclaration& f,
                                  SkSpan<const bool> paramNeedsDedicatedStorage);

    // Write the program entry point.
    void writeEntryPoint(const FunctionDefinition& f);

    // Writers for supported statement types.
    void writeStatement(const Statement& s);
    void writeStatements(const StatementArray& statements);
    void writeBlock(const Block& b);
    void writeDoStatement(const DoStatement& expr);
    void writeExpressionStatement(const Expression& expr);
    void writeForStatement(const ForStatement& s);
    void writeIfStatement(const IfStatement& s);
    void writeReturnStatement(const ReturnStatement& s);
    void writeSwitchStatement(const SwitchStatement& s);
    void writeSwitchCases(SkSpan<const SwitchCase* const> cases);
    void writeEmulatedSwitchFallthroughCases(SkSpan<const SwitchCase* const> cases,
                                             std::string_view switchValue);
    void writeSwitchCaseList(SkSpan<const SwitchCase* const> cases);
    void writeVarDeclaration(const VarDeclaration& varDecl);

    // Synthesizes an LValue for an expression.
    class LValue;
    class PointerLValue;
    class SwizzleLValue;
    class VectorComponentLValue;
    std::unique_ptr<LValue> makeLValue(const Expression& e);

    std::string variableReferenceNameForLValue(const VariableReference& r);
    std::string variablePrefix(const Variable& v);

    bool binaryOpNeedsComponentwiseMatrixPolyfill(const Type& left, const Type& right, Operator op);

    enum AssembleMode {
        kAuto,              // Will either be inlined expression or let to avoid const-eval
        kUsedMultipleTimes, // Will be inlined if trivial, or a let so reuse by caller is free
        kForceLet,          // Will be written to a let
    };
    // Writers for expressions. These return the final expression text as a string, and emit any
    // necessary setup code directly into the program as necessary. The returned expression may be
    // a `let`-alias that cannot be assigned-into; use `makeLValue` for an assignable expression.
    std::string assembleExpression(const Expression& e, Precedence parentPrecedence,
                                   AssembleMode mode = kAuto);

    std::string assembleBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence);
    std::string assembleBinaryExpression(const Expression& left,
                                         Operator op,
                                         const Expression& right,
                                         const Type& resultType,
                                         Precedence parentPrecedence);
    std::string assembleFieldAccess(const FieldAccess& f);
    std::string assembleFunctionCall(const FunctionCall& call, Precedence parentPrecedence);
    std::string assembleIndexExpression(const IndexExpression& i);
    std::string assembleLiteral(const Literal& l);
    std::string assemblePostfixExpression(const PostfixExpression& p, Precedence parentPrecedence);
    std::string assemblePrefixExpression(const PrefixExpression& p, Precedence parentPrecedence);
    std::string assembleSwizzle(const Swizzle& swizzle);
    std::string assembleTernaryExpression(const TernaryExpression& t, Precedence parentPrecedence);
    std::string assembleVariableReference(const VariableReference& r);
    std::string assembleName(std::string_view name);

    std::string assembleIncrementExpr(const Type& type);

    // Intrinsic helper functions.
    std::string assembleIntrinsicCall(const FunctionCall& call,
                                      IntrinsicKind kind,
                                      Precedence parentPrecedence);
    std::string assembleSimpleIntrinsic(std::string_view intrinsicName,
                                        const FunctionCall& call,
                                        bool wgslOnlySupportsHighPrecision=false);
    std::string assembleUnaryOpIntrinsic(Operator op,
                                         const FunctionCall& call,
                                         Precedence parentPrecedence);
    std::string assembleBinaryOpIntrinsic(Operator op,
                                          const FunctionCall& call,
                                          Precedence parentPrecedence);
    std::string assembleVectorizedIntrinsic(std::string_view intrinsicName,
                                            const FunctionCall& call);
    std::string assembleOutAssignedIntrinsic(std::string_view intrinsicName,
                                             std::string_view returnFieldName,
                                             std::string_view outFieldName,
                                             const FunctionCall& call);
    // Returns the beginning of the expression and the closing parentheses string to append once
    // any additional arguments are added.
    std::pair<std::string, const char*> assemblePartialSampleCall(std::string_view intrinsicName,
                                                                  const Type& type,
                                                                  const Expression& sampler,
                                                                  const Expression& coords);
    std::string assembleInversePolyfill(const FunctionCall& call);
    std::string assembleOuterProductPolyfill(const FunctionCall& call);
    std::string assembleComponentwiseMatrixBinary(const Type& leftType,
                                                  const Type& rightType,
                                                  const std::string& left,
                                                  const std::string& right,
                                                  Operator op);

    // Constructor expressions
    std::string assembleAnyConstructor(const AnyConstructor& c);
    std::string assembleConstructorCompound(const ConstructorCompound& c);
    std::string assembleConstructorCompoundVector(const ConstructorCompound& c);
    std::string assembleConstructorCompoundMatrix(const ConstructorCompound& c);
    std::string assembleConstructorDiagonalMatrix(const ConstructorDiagonalMatrix& c);
    std::string assembleConstructorMatrixResize(const ConstructorMatrixResize& ctor);
    std::string assembleConstructorArrayCast(const ConstructorArrayCast& c,
                                             Precedence parentPrecedence);

    // Synthesized helper functions for comparison operators that are not supported by WGSL.
    std::string assembleEqualityExpression(const Type& left,
                                           const std::string& leftName,
                                           const Type& right,
                                           const std::string& rightName,
                                           Operator op,
                                           Precedence parentPrecedence);
    std::string assembleEqualityExpression(const Expression& left,
                                           const Expression& right,
                                           Operator op,
                                           Precedence parentPrecedence);

    // Helper for accessing textures from polyfilled texture and samplers
    std::string assembleTextureFromImageOrSampler(const Expression& arg);

    // Writes a scratch variable into the program and returns its name (e.g. `_skTemp123`).
    std::string writeScratchVar(const Type& type, const std::string& value = "");

    // Writes a scratch let-variable into the program, gives it the value of `expr`, and returns its
    // name (e.g. `_skTemp123`). This can be `const` instead of `let` when isCompileTimeConstant is
    // true and at function scope.
    //
    // Prefer using assembleExpression() with an AssembleMode to control when scratch lets should
    // be created automatically.
    std::string writeScratchLet(const std::string& expr, bool isCompileTimeConstant = false);

    // Generic recursive ProgramElement visitor.
    void writeProgramElement(const ProgramElement& e);
    void writeGlobalVarDeclaration(const GlobalVarDeclaration& d);
    void writeStructDefinition(const StructDefinition& s);
    void writeModifiersDeclaration(const ModifiersDeclaration&);

    // Writes the WGSL struct fields for SkSL structs and interface blocks. Enforces WGSL address
    // space layout constraints
    // (https://www.w3.org/TR/WGSL/#address-space-layout-constraints) if a `layout` is
    // provided. A struct that does not need to be host-shareable does not require a `layout`.
    void writeFields(SkSpan<const Field> fields, const MemoryLayout* memoryLayout = nullptr);

    // We bundle uniforms, and all varying pipeline stage inputs and outputs, into separate structs.
    bool needsStageInputStruct() const;
    void writeStageInputStruct();
    bool needsStageOutputStruct() const;
    void writeStageOutputStruct();
    void writeUniformsAndBuffers();
    void writeInterfaceBlock(const InterfaceBlock& ib);

    void prepareUniformPolyfillsForInterfaceBlock(const InterfaceBlock* interfaceBlock,
                                                  std::string_view instanceName,
                                                  MemoryLayout::Standard nativeLayout);
    void writeEnables();
    void writeUniformPolyfills();

    void writeTextureOrSampler(const Variable& var,
                               int bindingLocation,
                               std::string_view suffix,
                               std::string_view wgslType);

    // Writes all top-level non-opaque global uniform declarations (i.e. not part of an interface
    // block) into a single uniform block binding.
    //
    // In complete fragment/vertex/compute programs, uniforms will be declared only as interface
    // blocks and global opaque types (like textures and samplers) which we expect to be declared
    // with a unique binding and descriptor set index. However, test files that are declared as RTE
    // programs may contain OpenGL-style global uniform declarations with no clear binding index to
    // use for the containing synthesized block.
    //
    // Since we are handling these variables only to generate gold files from RTEs and never run
    // them, we always declare them at the default bind group and binding index.
    void writeNonBlockUniformsForTests();

    // For a given function declaration, writes out any implicitly required pipeline stage arguments
    // based on the function's pre-determined dependencies. These are expected to be written out as
    // the first parameters for a function that requires them. Returns true if any arguments were
    // written.
    std::string functionDependencyArgs(const FunctionDeclaration&);
    bool writeFunctionDependencyParams(const FunctionDeclaration&);

    // Code in the header appears before the main body of code.
    StringStream fHeader;

    // We assign unique names to anonymous interface blocks based on the type.
    skia_private::THashMap<const Type*, std::string> fInterfaceBlockNameMap;

    // Stores the functions which use stage inputs/outputs as well as required WGSL extensions.
    ProgramRequirements fRequirements;
    skia_private::TArray<const Variable*> fPipelineInputs;
    skia_private::TArray<const Variable*> fPipelineOutputs;

    // These fields track whether we have written the polyfill for `inverse()` for a given matrix
    // type. Indexed by row or column count - 2, i.e. [2,3,4] -> idx [0,1,2]
    struct WrittenPolyfills {
        std::array<bool, 3> fInverse;
        std::array<std::array<bool, 3>, 3> fOuterProduct;

        WrittenPolyfills() : fInverse({false, false, false})
                           , fOuterProduct({std::array{false, false, false},
                                            std::array{false, false, false},
                                            std::array{false, false, false}}) {}
    };
    WrittenPolyfills fF32Polyfills;
    WrittenPolyfills fF16Polyfills;

    PrettyPrint fPrettyPrint;
    IncludeSyntheticCode fGenSyntheticCode;

    // These fields control uniform polyfill support in cases where WGSL and std140 disagree.
    // In std140 layout, matrices need to be represented as arrays of @align(16) vectors, and
    // array elements are wrapped in a struct containing a single @align(16) element. Arrays
    // of matrices combine both wrappers. These wrapper structs are unpacked into natively-typed
    // globals at the shader entrypoint.
    struct FieldPolyfillInfo {
        const InterfaceBlock* fInterfaceBlock;
        std::string fReplacementName;
        bool fIsArray = false;
        bool fIsMatrix = false;
        bool fWasAccessed = false;
    };
    using FieldPolyfillMap = skia_private::THashMap<const Field*, FieldPolyfillInfo>;
    FieldPolyfillMap fFieldPolyfillMap;

    std::unique_ptr<InterfaceBlock> fSyntheticGlobalUniformsBlock;

    // Output processing state.
    int fIndentation = 0;
    bool fAtLineStart = false;
    bool fHasUnconditionalReturn = false;
    bool fAtFunctionScope = false;
    bool fNeedsConstEvalWorkaround = false; // See skbug.com/40045457
    int fConditionalScopeDepth = 0;
    int fLocalSizeX = 1;
    int fLocalSizeY = 1;
    int fLocalSizeZ = 1;

    int fScratchCount = 0;
};

enum class ProgramKind : int8_t;

namespace {

static constexpr char kSamplerSuffix[] = "_Sampler";
static constexpr char kTextureSuffix[] = "_Texture";

// See https://www.w3.org/TR/WGSL/#memory-view-types
enum class PtrAddressSpace {
    kFunction,
    kPrivate,
    kStorage,
};

const char* operator_name(Operator op) {
    switch (op.kind()) {
        case Operator::Kind::LOGICALXOR:  return " != ";
        default:                          return op.operatorName();
    }
}

bool is_reserved_word(std::string_view word) {
    static const THashSet<std::string_view> kReservedWords{
            // Used by SkSL:
            "FSIn",
            "FSOut",
            "VSIn",
            "VSOut",
            "CSIn",
            "_globalUniforms",
            "_GlobalUniforms",
            "_return",
            "_stageIn",
            "_stageOut",
            // Keywords: https://www.w3.org/TR/WGSL/#keyword-summary
            "alias",
            "break",
            "case",
            "const",
            "const_assert",
            "continue",
            "continuing",
            "default",
            "diagnostic",
            "discard",
            "else",
            "enable",
            "false",
            "fn",
            "for",
            "if",
            "let",
            "loop",
            "override",
            "requires",
            "return",
            "struct",
            "switch",
            "true",
            "var",
            "while",
            // Pre-declared types: https://www.w3.org/TR/WGSL/#predeclared-types
            "bool",
            "f16",
            "f32",
            "i32",
            "u32",
            // ... and pre-declared type generators:
            "array",
            "atomic",
            "mat2x2",
            "mat2x3",
            "mat2x4",
            "mat3x2",
            "mat3x3",
            "mat3x4",
            "mat4x2",
            "mat4x3",
            "mat4x4",
            "ptr",
            "texture_1d",
            "texture_2d",
            "texture_2d_array",
            "texture_3d",
            "texture_cube",
            "texture_cube_array",
            "texture_multisampled_2d",
            "texture_storage_1d",
            "texture_storage_2d",
            "texture_storage_2d_array",
            "texture_storage_3d",
            "vec2",
            "vec3",
            "vec4",
            // Pre-declared enumerants: https://www.w3.org/TR/WGSL/#predeclared-enumerants
            "read",
            "write",
            "read_write",
            "function",
            "private",
            "workgroup",
            "uniform",
            "storage",
            "perspective",
            "linear",
            "flat",
            "center",
            "centroid",
            "sample",
            "vertex_index",
            "instance_index",
            "position",
            "front_facing",
            "frag_depth",
            "local_invocation_id",
            "local_invocation_index",
            "global_invocation_id",
            "workgroup_id",
            "num_workgroups",
            "sample_index",
            "sample_mask",
            "rgba8unorm",
            "rgba8snorm",
            "rgba8uint",
            "rgba8sint",
            "rgba16uint",
            "rgba16sint",
            "rgba16float",
            "r32uint",
            "r32sint",
            "r32float",
            "rg32uint",
            "rg32sint",
            "rg32float",
            "rgba32uint",
            "rgba32sint",
            "rgba32float",
            "bgra8unorm",
            // Reserved words: https://www.w3.org/TR/WGSL/#reserved-words
            "_",
            "NULL",
            "Self",
            "abstract",
            "active",
            "alignas",
            "alignof",
            "as",
            "asm",
            "asm_fragment",
            "async",
            "attribute",
            "auto",
            "await",
            "become",
            "binding_array",
            "cast",
            "catch",
            "class",
            "co_await",
            "co_return",
            "co_yield",
            "coherent",
            "column_major",
            "common",
            "compile",
            "compile_fragment",
            "concept",
            "const_cast",
            "consteval",
            "constexpr",
            "constinit",
            "crate",
            "debugger",
            "decltype",
            "delete",
            "demote",
            "demote_to_helper",
            "do",
            "dynamic_cast",
            "enum",
            "explicit",
            "export",
            "extends",
            "extern",
            "external",
            "fallthrough",
            "filter",
            "final",
            "finally",
            "friend",
            "from",
            "fxgroup",
            "get",
            "goto",
            "groupshared",
            "highp",
            "impl",
            "implements",
            "import",
            "inline",
            "instanceof",
            "interface",
            "layout",
            "lowp",
            "macro",
            "macro_rules",
            "match",
            "mediump",
            "meta",
            "mod",
            "module",
            "move",
            "mut",
            "mutable",
            "namespace",
            "new",
            "nil",
            "noexcept",
            "noinline",
            "nointerpolation",
            "noperspective",
            "null",
            "nullptr",
            "of",
            "operator",
            "package",
            "packoffset",
            "partition",
            "pass",
            "patch",
            "pixelfragment",
            "precise",
            "precision",
            "premerge",
            "priv",
            "protected",
            "pub",
            "public",
            "readonly",
            "ref",
            "regardless",
            "register",
            "reinterpret_cast",
            "require",
            "resource",
            "restrict",
            "self",
            "set",
            "shared",
            "sizeof",
            "smooth",
            "snorm",
            "static",
            "static_assert",
            "static_cast",
            "std",
            "subroutine",
            "super",
            "target",
            "template",
            "this",
            "thread_local",
            "throw",
            "trait",
            "try",
            "type",
            "typedef",
            "typeid",
            "typename",
            "typeof",
            "union",
            "unless",
            "unorm",
            "unsafe",
            "unsized",
            "use",
            "using",
            "varying",
            "virtual",
            "volatile",
            "wgsl",
            "where",
            "with",
            "writeonly",
            "yield",
    };

    return kReservedWords.contains(word);
}

std::string_view pipeline_struct_prefix(ProgramKind kind) {
    if (ProgramConfig::IsVertex(kind)) {
        return "VS";
    }
    if (ProgramConfig::IsFragment(kind)) {
        return "FS";
    }
    if (ProgramConfig::IsCompute(kind)) {
        return "CS";
    }
    // Compute programs don't have stage-in/stage-out pipeline structs.
    return "";
}

std::string_view address_space_to_str(PtrAddressSpace addressSpace) {
    switch (addressSpace) {
        case PtrAddressSpace::kFunction:
            return "function";
        case PtrAddressSpace::kPrivate:
            return "private";
        case PtrAddressSpace::kStorage:
            return "storage";
    }
    SkDEBUGFAIL("unsupported ptr address space");
    return "unsupported";
}

bool type_is_low_precision(const Type& type, bool f16Available) {
    // For now only consider half vs. float, not short vs int
    return f16Available && (type.componentType().isFloat() && !type.highPrecision());
}

bool type_is_low_precision(const Type& type, const Context& context) {
    return type_is_low_precision(type, !context.fConfig->fSettings.fForceHighPrecision);
}

std::string_view to_scalar_type(const Type& type, bool f16Available) {
    SkASSERT(type.typeKind() == Type::TypeKind::kScalar);
    switch (type.numberKind()) {
        case Type::NumberKind::kFloat:
            // Floating point numbers can map to f32 or f16 depending on whether or not the
            // shader-f16 wgsl extension is supported.
            return type_is_low_precision(type, f16Available) ? "f16" : "f32";
        case Type::NumberKind::kSigned:
            return "i32";
        case Type::NumberKind::kUnsigned:
            return "u32";
        case Type::NumberKind::kBoolean:
            return "bool";
        case Type::NumberKind::kNonnumeric:
            [[fallthrough]];
        default:
            break;
    }
    return type.name();
}

// Convert a SkSL type to a WGSL type. Handles all plain types except structure types
// (see https://www.w3.org/TR/WGSL/#plain-types-section).
std::string to_wgsl_type(const Context& context, const Type& raw,
                         const Layout* layout = nullptr, bool forceHighPrecision=false) {
    const Type& type = raw.resolve().scalarTypeForLiteral();
    const bool f16Available = !context.fConfig->fSettings.fForceHighPrecision &&
                              !forceHighPrecision;

    switch (type.typeKind()) {
        case Type::TypeKind::kScalar:
            return std::string(to_scalar_type(type, f16Available));

        case Type::TypeKind::kAtomic:
            SkASSERT(type.matches(*context.fTypes.fAtomicUInt));
            return "atomic<u32>";

        case Type::TypeKind::kVector: {
            std::string_view ct = to_scalar_type(type.componentType(), f16Available);
            return String::printf("vec%d<%.*s>", type.columns(), (int)ct.length(), ct.data());
        }
        case Type::TypeKind::kMatrix: {
            std::string_view ct = to_scalar_type(type.componentType(), f16Available);
            return String::printf("mat%dx%d<%.*s>",
                                  type.columns(), type.rows(), (int)ct.length(), ct.data());
        }
        case Type::TypeKind::kArray: {
            std::string result = "array<" + to_wgsl_type(context, type.componentType(), layout);
            if (!type.isUnsizedArray()) {
                result += ", ";
                result += std::to_string(type.columns());
            }
            return result + '>';
        }
        case Type::TypeKind::kTexture: {
            if (type.matches(*context.fTypes.fWriteOnlyTexture2D)) {
                std::string result = "texture_storage_2d<";
                // Write-only storage texture types require a pixel format, which is in the layout.
                SkASSERT(layout);
                LayoutFlags pixelFormat = layout->fFlags & LayoutFlag::kAllPixelFormats;
                switch (pixelFormat.value()) {
                    case (int)LayoutFlag::kRGBA8:
                        return result + "rgba8unorm, write>";

                    case (int)LayoutFlag::kRGBA32F:
                        return result + "rgba32float, write>";

                    case (int)LayoutFlag::kR32F:
                        return result + "r32float, write>";

                    default:
                        // The front-end should have rejected this.
                        return result + "write>";
                }
            }
            if (type.matches(*context.fTypes.fReadOnlyTexture2D)) {
                return "texture_2d<f32>";
            }
            break;
        }
        default:
            break;
    }
    return std::string(type.name());
}

std::string to_ptr_type(const Context& context,
                        const Type& type,
                        const Layout* layout,
                        PtrAddressSpace addressSpace = PtrAddressSpace::kFunction) {
    return "ptr<" + std::string(address_space_to_str(addressSpace)) + ", " +
           to_wgsl_type(context, type, layout) + '>';
}

std::string_view wgsl_builtin_name(WGSLCodeGenerator::Builtin builtin) {
    using Builtin = WGSLCodeGenerator::Builtin;
    switch (builtin) {
        case Builtin::kVertexIndex:
            return "@builtin(vertex_index)";
        case Builtin::kInstanceIndex:
            return "@builtin(instance_index)";
        case Builtin::kPosition:
            return "@builtin(position)";
        case Builtin::kLastFragColor:
            return "@color(0)";
        case Builtin::kFrontFacing:
            return "@builtin(front_facing)";
        case Builtin::kSampleIndex:
            return "@builtin(sample_index)";
        case Builtin::kFragDepth:
            return "@builtin(frag_depth)";
        case Builtin::kSampleMask:
        case Builtin::kSampleMaskIn:
            return "@builtin(sample_mask)";
        case Builtin::kLocalInvocationId:
            return "@builtin(local_invocation_id)";
        case Builtin::kLocalInvocationIndex:
            return "@builtin(local_invocation_index)";
        case Builtin::kGlobalInvocationId:
            return "@builtin(global_invocation_id)";
        case Builtin::kWorkgroupId:
            return "@builtin(workgroup_id)";
        case Builtin::kNumWorkgroups:
            return "@builtin(num_workgroups)";
        default:
            break;
    }

    SkDEBUGFAIL("unsupported builtin");
    return "unsupported";
}

std::string_view wgsl_builtin_type(WGSLCodeGenerator::Builtin builtin, const Context& context) {
    using Builtin = WGSLCodeGenerator::Builtin;
    switch (builtin) {
        case Builtin::kVertexIndex:
            return "u32";
        case Builtin::kInstanceIndex:
            return "u32";
        case Builtin::kPosition:
            return "vec4<f32>";
        case Builtin::kLastFragColor:
            // The last frag color is declared as a half4 in SkSL, so its type depends on f16
            // being available or not.
            return context.fConfig->fSettings.fForceHighPrecision ? "vec4<f32>" : "vec4<f16>";
        case Builtin::kFrontFacing:
            return "bool";
        case Builtin::kSampleIndex:
            return "u32";
        case Builtin::kFragDepth:
            return "f32";
        case Builtin::kSampleMask:
            return "u32";
        case Builtin::kSampleMaskIn:
            return "u32";
        case Builtin::kLocalInvocationId:
            return "vec3<u32>";
        case Builtin::kLocalInvocationIndex:
            return "u32";
        case Builtin::kGlobalInvocationId:
            return "vec3<u32>";
        case Builtin::kWorkgroupId:
            return "vec3<u32>";
        case Builtin::kNumWorkgroups:
            return "vec3<u32>";
        default:
            break;
    }

    SkDEBUGFAIL("unsupported builtin");
    return "unsupported";
}

// Some built-in variables have a type that differs from their SkSL counterpart (e.g. signed vs
// unsigned integer). We handle these cases with an explicit type conversion during a variable
// reference. Returns the WGSL type of the conversion target if conversion is needed, otherwise
// returns std::nullopt.
std::optional<std::string_view> needs_builtin_type_conversion(const Variable& v) {
    switch (v.layout().fBuiltin) {
        case SK_VERTEXID_BUILTIN:
        case SK_INSTANCEID_BUILTIN:
            return {"i32"};
        default:
            break;
    }
    return std::nullopt;
}

// Map a SkSL builtin flag to a WGSL builtin kind. Returns std::nullopt if `builtin` is not
// not supported for WGSL.
//
// Also see //src/sksl/sksl_vert.sksl and //src/sksl/sksl_frag.sksl for supported built-ins.
std::optional<WGSLCodeGenerator::Builtin> builtin_from_sksl_name(int builtin) {
    using Builtin = WGSLCodeGenerator::Builtin;
    switch (builtin) {
        case SK_POSITION_BUILTIN:
            [[fallthrough]];
        case SK_FRAGCOORD_BUILTIN:
            return Builtin::kPosition;
        case SK_VERTEXID_BUILTIN:
            return Builtin::kVertexIndex;
        case SK_INSTANCEID_BUILTIN:
            return Builtin::kInstanceIndex;
        case SK_LASTFRAGCOLOR_BUILTIN:
            return Builtin::kLastFragColor;
        case SK_CLOCKWISE_BUILTIN:
            // TODO(skbug.com/40044196): While `front_facing` is the corresponding built-in, it does not
            // imply a particular winding order. We correctly compute the face orientation based
            // on how Skia configured the render pipeline for all references to this built-in
            // variable (see `SkSL::Program::Interface::fRTFlipUniform`).
            return Builtin::kFrontFacing;
        case SK_SAMPLEMASKIN_BUILTIN:
            return Builtin::kSampleMaskIn;
        case SK_SAMPLEMASK_BUILTIN:
            return Builtin::kSampleMask;
        case SK_NUMWORKGROUPS_BUILTIN:
            return Builtin::kNumWorkgroups;
        case SK_WORKGROUPID_BUILTIN:
            return Builtin::kWorkgroupId;
        case SK_LOCALINVOCATIONID_BUILTIN:
            return Builtin::kLocalInvocationId;
        case SK_GLOBALINVOCATIONID_BUILTIN:
            return Builtin::kGlobalInvocationId;
        case SK_LOCALINVOCATIONINDEX_BUILTIN:
            return Builtin::kLocalInvocationIndex;
        default:
            break;
    }
    return std::nullopt;
}

const char* delimiter_to_str(WGSLCodeGenerator::Delimiter delimiter) {
    using Delim = WGSLCodeGenerator::Delimiter;
    switch (delimiter) {
        case Delim::kComma:
            return ",";
        case Delim::kSemicolon:
            return ";";
        case Delim::kNone:
        default:
            break;
    }
    return "";
}

bool all_arguments_constant(const ExpressionArray& arguments) {
    // Returns true if all arguments in the ExpressionArray are compile-time constants. If we are
    // calling an intrinsic and all of its inputs are constant, but we didn't constant-fold it, this
    // generally indicates that constant-folding resulted in an infinity or nan. The WGSL compiler
    // will reject such an expression with a compile-time error. We can dodge the error, taking on
    // the risk of indeterminate behavior instead, by replacing one of the constant values with a
    // scratch let-variable. (skbug.com/40045457)
    for (const std::unique_ptr<Expression>& arg : arguments) {
        if (!ConstantFolder::GetConstantValueOrNull(*arg)) {
            return false;
        }
    }
    return true;
}

bool is_nontrivial_expression(const Expression& expr) {
    // We consider a "trivial expression" one which we can repeat multiple times in the output
    // without being dangerous or spammy. We avoid emitting temporary variables for very trivial
    // expressions: literals, unadorned variable references, or constant vectors.
    if (expr.is<VariableReference>() || expr.is<Literal>()) {
        // Variables and literals are trivial; adding a let-declaration won't simplify anything.
        return false;
    }
    if (expr.type().isVector() && Analysis::IsConstantExpression(expr)) {
        // Compile-time constant vectors are also considered trivial; they're short and sweet.
        return false;
    }
    return true;
}

// FunctionDependencyResolver visits the IR tree rooted at a particular function definition and
// computes that function's dependencies on pipeline stage IO parameters. These are later used to
// synthesize arguments when writing out function definitions.
class FunctionDependencyResolver : public ProgramVisitor {
public:
    using Deps = WGSLFunctionDependencies;
    using DepsMap = WGSLCodeGenerator::ProgramRequirements::DepsMap;

    FunctionDependencyResolver(const Program* p,
                               const FunctionDeclaration* f,
                               DepsMap* programDependencyMap)
            : fProgram(p), fFunction(f), fDependencyMap(programDependencyMap) {}

    Deps resolve() {
        fDeps = WGSLFunctionDependency::kNone;
        this->visit(*fProgram);
        return fDeps;
    }

private:
    bool visitProgramElement(const ProgramElement& p) override {
        // Only visit the program that matches the requested function.
        if (p.is<FunctionDefinition>() && &p.as<FunctionDefinition>().declaration() == fFunction) {
            return ProgramVisitor::visitProgramElement(p);
        }
        // Continue visiting other program elements.
        return false;
    }

    bool visitExpression(const Expression& e) override {
        if (e.is<VariableReference>()) {
            const VariableReference& v = e.as<VariableReference>();
            if (v.variable()->storage() == Variable::Storage::kGlobal) {
                ModifierFlags flags = v.variable()->modifierFlags();
                if (flags & ModifierFlag::kIn) {
                    fDeps |= WGSLFunctionDependency::kPipelineInputs;
                }
                if (flags & ModifierFlag::kOut) {
                    fDeps |= WGSLFunctionDependency::kPipelineOutputs;
                }
            }
        } else if (e.is<FunctionCall>()) {
            // The current function that we're processing (`fFunction`) inherits the dependencies of
            // functions that it makes calls to, because the pipeline stage IO parameters need to be
            // passed down as an argument.
            const FunctionCall& callee = e.as<FunctionCall>();

            // Don't process a function again if we have already resolved it.
            Deps* found = fDependencyMap->find(&callee.function());
            if (found) {
                fDeps |= *found;
            } else {
                // Store the dependencies that have been discovered for the current function so far.
                // If `callee` directly or indirectly calls the current function, then this value
                // will prevent an infinite recursion.
                fDependencyMap->set(fFunction, fDeps);

                // Separately traverse the called function's definition and determine its
                // dependencies.
                FunctionDependencyResolver resolver(fProgram, &callee.function(), fDependencyMap);
                Deps calleeDeps = resolver.resolve();

                // Store the callee's dependencies in the global map to avoid processing
                // the function again for future calls.
                fDependencyMap->set(&callee.function(), calleeDeps);

                // Add to the current function's dependencies.
                fDeps |= calleeDeps;
            }
        }
        return ProgramVisitor::visitExpression(e);
    }

    const Program* const fProgram;
    const FunctionDeclaration* const fFunction;
    DepsMap* const fDependencyMap;
    Deps fDeps = WGSLFunctionDependency::kNone;
};

WGSLCodeGenerator::ProgramRequirements resolve_program_requirements(const Program* program) {
    WGSLCodeGenerator::ProgramRequirements requirements;

    for (const ProgramElement* e : program->elements()) {
        switch (e->kind()) {
            case ProgramElement::Kind::kFunction: {
                const FunctionDeclaration& decl = e->as<FunctionDefinition>().declaration();

                FunctionDependencyResolver resolver(program, &decl, &requirements.fDependencies);
                requirements.fDependencies.set(&decl, resolver.resolve());
                break;
            }
            case ProgramElement::Kind::kGlobalVar: {
                const GlobalVarDeclaration& decl = e->as<GlobalVarDeclaration>();
                if (decl.varDeclaration().var()->modifierFlags().isPixelLocal()) {
                    requirements.fPixelLocalExtension = true;
                }
                break;
            }
            default:
                break;
        }
    }

    return requirements;
}

void collect_pipeline_io_vars(const Program* program,
                              TArray<const Variable*>* ioVars,
                              ModifierFlag ioType) {
    for (const ProgramElement* e : program->elements()) {
        if (e->is<GlobalVarDeclaration>()) {
            const Variable* v = e->as<GlobalVarDeclaration>().varDeclaration().var();
            if (v->modifierFlags() & ioType) {
                ioVars->push_back(v);
            }
        } else if (e->is<InterfaceBlock>()) {
            const Variable* v = e->as<InterfaceBlock>().var();
            if (v->modifierFlags() & ioType) {
                ioVars->push_back(v);
            }
        }
    }
}

bool is_in_global_uniforms(const Variable& var) {
    return  var.storage() == VariableStorage::kGlobal &&
            var.modifierFlags().isUniform() &&
           !var.type().isOpaque() &&
           !var.interfaceBlock();
}

}  // namespace

class WGSLCodeGenerator::LValue {
public:
    virtual ~LValue() = default;

    // Returns a WGSL expression that loads from the lvalue with no side effects.
    // (e.g. `array[index].field`)
    virtual std::string load() = 0;

    // Returns a WGSL statement that stores into the lvalue with no side effects.
    // (e.g. `array[index].field = the_passed_in_value_string;`)
    virtual std::string store(const std::string& value) = 0;
};

class WGSLCodeGenerator::PointerLValue : public WGSLCodeGenerator::LValue {
public:
    // `name` must be a WGSL expression with no side-effects, which we can safely take the address
    // of. (e.g. `array[index].field` would be valid, but `array[Func()]` or `vector.x` are not.)
    PointerLValue(std::string name) : fName(std::move(name)) {}

    std::string load() override {
        return fName;
    }

    std::string store(const std::string& value) override {
        return fName + " = " + value + ";";
    }

private:
    std::string fName;
};

class WGSLCodeGenerator::VectorComponentLValue : public WGSLCodeGenerator::LValue {
public:
    // `name` must be a WGSL expression with no side-effects that points to a single component of a
    // WGSL vector.
    VectorComponentLValue(std::string name) : fName(std::move(name)) {}

    std::string load() override {
        return fName;
    }

    std::string store(const std::string& value) override {
        return fName + " = " + value + ";";
    }

private:
    std::string fName;
};

class WGSLCodeGenerator::SwizzleLValue : public WGSLCodeGenerator::LValue {
public:
    // `name` must be a WGSL expression with no side-effects that points to a WGSL vector.
    SwizzleLValue(const Context& ctx, std::string name, const Type& t, const ComponentArray& c)
            : fContext(ctx)
            , fName(std::move(name))
            , fType(t)
            , fComponents(c) {
        // If the component array doesn't cover the entire value, we need to create masks for
        // writing back into the lvalue. For example, if the type is vec4 and the component array
        // holds `zx`, a GLSL assignment would look like:
        //     name.zx = new_value;
        //
        // The equivalent WGSL assignment statement would look like:
        //     name = vec4<f32>(new_value, name.xw).yzxw;
        //
        // This replaces name.zy with new_value.xy, and leaves name.xw at their original values.
        // By convention, we always put the new value first and the original values second; it might
        // be possible to find better arrangements which simplify the assignment overall, but we
        // don't attempt this.
        int fullSlotCount = fType.slotCount();
        SkASSERT(fullSlotCount <= 4);

        // First, see which components are used.
        // The assignment swizzle must not reuse components.
        bool used[4] = {};
        for (int8_t component : fComponents) {
            SkASSERT(!used[component]);
            used[component] = true;
        }

        // Any untouched components will need to be fetched from the original value.
        for (int index = 0; index < fullSlotCount; ++index) {
            if (!used[index]) {
                fUntouchedComponents.push_back(index);
            }
        }

        // The reintegration swizzle needs to move the components back into their proper slots.
        fReintegrationSwizzle.resize(fullSlotCount);
        int reintegrateIndex = 0;

        // This refills the untouched slots with the original values.
        auto refillUntouchedSlots = [&] {
            for (int index = 0; index < fullSlotCount; ++index) {
                if (!used[index]) {
                    fReintegrationSwizzle[index] = reintegrateIndex++;
                }
            }
        };

        // This places the new-value components into the proper slots.
        auto insertNewValuesIntoSlots = [&] {
            for (int index = 0; index < fComponents.size(); ++index) {
                fReintegrationSwizzle[fComponents[index]] = reintegrateIndex++;
            }
        };

        // When reintegrating the untouched and new values, if the `x` slot is overwritten, we
        // reintegrate the new value first. Otherwise, we reintegrate the original value first.
        // This increases our odds of getting an identity swizzle for the reintegration.
        if (used[0]) {
            fReintegrateNewValueFirst = true;
            insertNewValuesIntoSlots();
            refillUntouchedSlots();
        } else {
            fReintegrateNewValueFirst = false;
            refillUntouchedSlots();
            insertNewValuesIntoSlots();
        }
    }

    std::string load() override {
        return fName + "." + Swizzle::MaskString(fComponents);
    }

    std::string store(const std::string& value) override {
        // `variable = `
        std::string result = fName;
        result += " = ";

        if (fUntouchedComponents.empty()) {
            // `(new_value);`
            result += '(';
            result += value;
            result += ")";
        } else if (fReintegrateNewValueFirst) {
            // `vec4<f32>((new_value), `
            result += to_wgsl_type(fContext, fType);
            result += "((";
            result += value;
            result += "), ";

            // `variable.yz)`
            result += fName;
            result += '.';
            result += Swizzle::MaskString(fUntouchedComponents);
            result += ')';
        } else {
            // `vec4<f32>(variable.yz`
            result += to_wgsl_type(fContext, fType);
            result += '(';
            result += fName;
            result += '.';
            result += Swizzle::MaskString(fUntouchedComponents);

            // `, (new_value))`
            result += ", (";
            result += value;
            result += "))";
        }

        if (!Swizzle::IsIdentity(fReintegrationSwizzle)) {
            // `.wzyx`
            result += '.';
            result += Swizzle::MaskString(fReintegrationSwizzle);
        }

        return result + ';';
    }

private:
    const Context& fContext;
    std::string fName;
    const Type& fType;
    ComponentArray fComponents;
    ComponentArray fUntouchedComponents;
    ComponentArray fReintegrationSwizzle;
    bool fReintegrateNewValueFirst = false;
};

class WGSLCodeGenerator::AutoConstEvalWorkaround {
public:
    AutoConstEvalWorkaround(WGSLCodeGenerator* generator, const Expression& parent)
            : fGenerator(generator)
            , fOriginalValue(generator->fNeedsConstEvalWorkaround) {
        // Each scope can apply the workaround separately from the parent scope, so default to
        // not requiring it
        fGenerator->fNeedsConstEvalWorkaround = false;

        // Intrinsic function calls and operators can be const-evaluated by the WGSL compiler,
        // which may cause it complain if said evaluation would produce non-finite values.
        if (parent.kind() == ExpressionKind::kFunctionCall) {
            const FunctionCall& call = parent.as<FunctionCall>();
            // User-defined functions can never be const-evaluated.
            if (call.function().isIntrinsic() && all_arguments_constant(call.arguments())) {
                fGenerator->fNeedsConstEvalWorkaround = true;
            }
        } else if (parent.kind() == ExpressionKind::kBinary) {
            const BinaryExpression& op = parent.as<BinaryExpression>();
            fGenerator->fNeedsConstEvalWorkaround =
                    op_needs_workaround(*op.left(), *op.right(), op.getOperator().kind());

        }
    }

    ~AutoConstEvalWorkaround() {
        fGenerator->fNeedsConstEvalWorkaround = fOriginalValue;
    }

private:
    static bool op_needs_workaround(const Expression& l, const Expression& r, OperatorKind op) {
        // Only ops that produce overflows or non-finite values need to be worked round: +,-,*,/
        switch (op) {
            case Operator::Kind::MINUS:
            case Operator::Kind::PLUS:
            case Operator::Kind::STAR:
            case Operator::Kind::SLASH:
                return ConstantFolder::GetConstantValueOrNull(l) &&
                       ConstantFolder::GetConstantValueOrNull(r);
            default:
                return false;
        }
    }

    WGSLCodeGenerator* fGenerator;
    bool fOriginalValue;
};

bool WGSLCodeGenerator::generateCode() {
    // The resources of a WGSL program are structured in the following way:
    // - Stage attribute inputs and outputs are bundled inside synthetic structs called
    //   VSIn/VSOut/FSIn/FSOut/CSIn.
    // - All uniform and storage type resources are declared in global scope.
    this->preprocessProgram();

    {
        AutoOutputStream outputToHeader(this, &fHeader, &fIndentation);
        this->writeEnables();
        this->writeStageInputStruct();
        this->writeStageOutputStruct();
        this->writeUniformsAndBuffers();
        this->writeNonBlockUniformsForTests();
    }
    StringStream body;
    {
        // Emit the program body.
        AutoOutputStream outputToBody(this, &body, &fIndentation);
        const FunctionDefinition* mainFunc = nullptr;
        for (const ProgramElement* e : fProgram.elements()) {
            this->writeProgramElement(*e);

            if (e->is<FunctionDefinition>()) {
                const FunctionDefinition& func = e->as<FunctionDefinition>();
                if (func.declaration().isMain()) {
                    mainFunc = &func;
                }
            }
        }

        // At the bottom of the program body, emit the entrypoint function.
        // The entrypoint relies on state that has been collected while we emitted the rest of the
        // program, so it's important to do it last to make sure we don't miss anything.
        if (mainFunc) {
            this->writeEntryPoint(*mainFunc);
        }
    }

    write_stringstream(fHeader, *fOut);
    write_stringstream(body, *fOut);

    this->writeUniformPolyfills();

    return fContext.fErrors->errorCount() == 0;
}

void WGSLCodeGenerator::writeUniformPolyfills() {
    // If we didn't encounter any uniforms that need polyfilling, there is nothing to do.
    if (fFieldPolyfillMap.empty()) {
        return;
    }

    // We store the list of polyfilled fields as pointers in a hash-map, so the order can be
    // inconsistent across runs. For determinism, we sort the polyfilled objects by name here.
    TArray<const FieldPolyfillMap::Pair*> orderedFields;
    orderedFields.reserve_exact(fFieldPolyfillMap.count());

    fFieldPolyfillMap.foreach([&](const FieldPolyfillMap::Pair& pair) {
        orderedFields.push_back(&pair);
    });

    std::sort(orderedFields.begin(),
              orderedFields.end(),
              [](const FieldPolyfillMap::Pair* a, const FieldPolyfillMap::Pair* b) {
                  return a->second.fReplacementName < b->second.fReplacementName;
              });

    THashSet<const Type*> writtenArrayElementPolyfill;
    bool writtenUniformMatrixPolyfill[2][5][5] = {};  // {h,f} x m[column][row] for each matrix type
    bool writtenUniformRowPolyfill[2][5] = {};        // {h,f} x for each matrix row-size
    bool anyFieldAccessed = false;
    for (const FieldPolyfillMap::Pair* pair : orderedFields) {
        const auto& [field, info] = *pair;
        const Type* fieldType = field->fType;
        const Layout* fieldLayout = &field->fLayout;

        if (info.fIsArray) {
            fieldType = &fieldType->componentType();
            if (!writtenArrayElementPolyfill.contains(fieldType)) {
                writtenArrayElementPolyfill.add(fieldType);
                this->write("struct _skArrayElement_");
                this->write(fieldType->abbreviatedName());
                this->writeLine(" {");

                if (info.fIsMatrix) {
                    // Create a struct representing the array containing std140-padded matrices.
                    this->write("  e : _skMatrix");
                    this->write(std::to_string(fieldType->columns()));
                    this->write(std::to_string(fieldType->rows()));
                    this->writeLine(type_is_low_precision(*fieldType, fContext) ? "h" : "f");
                } else {
                    // Create a struct representing the array with extra padding between elements.
                    this->write("  @align(16) e : ");
                    this->writeLine(to_wgsl_type(fContext, *fieldType, fieldLayout));
                }
                this->writeLine("};");
            }
        }

        if (info.fIsMatrix) {
            // Create structs representing the matrix as an array of vectors, whether or not the
            // matrix is ever accessed by the SkSL. (The struct itself is mentioned in the list of
            // uniforms.)
            const bool useF16 = type_is_low_precision(*fieldType, fContext);
            int t = useF16 ? 0 : 1;
            int c = fieldType->columns();
            int r = fieldType->rows();
            if (!writtenUniformRowPolyfill[t][r]) {
                writtenUniformRowPolyfill[t][r] = true;

                this->write("struct _skRow");
                this->write(std::to_string(r));
                this->write(useF16 ? "h" : "f");
                this->writeLine(" {");
                this->write("  @align(16) r : vec");
                this->write(std::to_string(r));
                this->write("<");
                this->write(to_wgsl_type(fContext, fieldType->componentType(), fieldLayout));
                this->writeLine(">");
                this->writeLine("};");
            }

            if (!writtenUniformMatrixPolyfill[t][c][r]) {
                writtenUniformMatrixPolyfill[t][c][r] = true;

                this->write("struct _skMatrix");
                this->write(std::to_string(c));
                this->write(std::to_string(r));
                this->write(useF16 ? "h" : "f");
                this->writeLine(" {");
                this->write("  c : array<_skRow");
                this->write(std::to_string(r));
                this->write(useF16 ? "h" : "f");
                this->write(", ");
                this->write(std::to_string(c));
                this->writeLine(">");
                this->writeLine("};");
            }
        }

        // We create a polyfill variable only if the uniform was actually accessed.
        if (!info.fWasAccessed) {
            continue;
        }
        anyFieldAccessed = true;
        this->write("var<private> ");
        this->write(info.fReplacementName);
        this->write(": ");

        const Type& interfaceBlockType = info.fInterfaceBlock->var()->type();
        if (interfaceBlockType.isArray()) {
            this->write("array<");
            this->write(to_wgsl_type(fContext, *field->fType, fieldLayout));
            this->write(", ");
            this->write(std::to_string(interfaceBlockType.columns()));
            this->write(">");
        } else {
            this->write(to_wgsl_type(fContext, *field->fType, fieldLayout));
        }
        this->writeLine(";");
    }

    // If no fields were actually accessed, _skInitializePolyfilledUniforms will not be called and
    // we can avoid emitting an empty, dead function.
    if (!anyFieldAccessed) {
        return;
    }

    this->writeLine("fn _skInitializePolyfilledUniforms() {");
    ++fIndentation;

    for (const FieldPolyfillMap::Pair* pair : orderedFields) {
        // Only initialize a polyfill global if the uniform was actually accessed.
        const auto& [field, info] = *pair;
        if (!info.fWasAccessed) {
            continue;
        }

        // Synthesize the name of this uniform variable
        std::string_view instanceName = info.fInterfaceBlock->instanceName();
        const Type& interfaceBlockType = info.fInterfaceBlock->var()->type();
        if (instanceName.empty()) {
            instanceName = fInterfaceBlockNameMap[&interfaceBlockType.componentType()];
        }

        // Initialize the global variable associated with this uniform.
        // If the interface block is arrayed, the associated global will be arrayed as well.
        int numIBElements = interfaceBlockType.isArray() ? interfaceBlockType.columns() : 1;
        for (int ibIdx = 0; ibIdx < numIBElements; ++ibIdx) {
            this->write(info.fReplacementName);
            if (interfaceBlockType.isArray()) {
                this->write("[");
                this->write(std::to_string(ibIdx));
                this->write("]");
            }
            this->write(" = ");

            const Type* fieldType = field->fType;
            const Layout* fieldLayout = &field->fLayout;

            int numArrayElements;
            if (info.fIsArray) {
                this->write(to_wgsl_type(fContext, *fieldType, fieldLayout));
                this->write("(");
                numArrayElements = fieldType->columns();
                fieldType = &fieldType->componentType();
            } else {
                numArrayElements = 1;
            }

            auto arraySeparator = String::Separator();
            for (int arrayIdx = 0; arrayIdx < numArrayElements; arrayIdx++) {
                this->write(arraySeparator());

                std::string fieldName{instanceName};
                if (interfaceBlockType.isArray()) {
                    fieldName += '[';
                    fieldName += std::to_string(ibIdx);
                    fieldName += ']';
                }
                fieldName += '.';
                fieldName += this->assembleName(field->fName);

                if (info.fIsArray) {
                    fieldName += '[';
                    fieldName += std::to_string(arrayIdx);
                    fieldName += "].e";
                }

                if (info.fIsMatrix) {
                    this->write(to_wgsl_type(fContext, *fieldType, fieldLayout));
                    this->write("(");
                    int numColumns = fieldType->columns();
                    auto matrixSeparator = String::Separator();
                    for (int column = 0; column < numColumns; column++) {
                        this->write(matrixSeparator());
                        this->write(fieldName);
                        this->write(".c[");
                        this->write(std::to_string(column));
                        this->write("].r");
                    }
                    this->write(")");
                } else {
                    this->write(fieldName);
                }
            }

            if (info.fIsArray) {
                this->write(")");
            }

            this->writeLine(";");
        }
    }

    --fIndentation;
    this->writeLine("}");
}


void WGSLCodeGenerator::preprocessProgram() {
    fRequirements = resolve_program_requirements(&fProgram);
    collect_pipeline_io_vars(&fProgram, &fPipelineInputs, ModifierFlag::kIn);
    collect_pipeline_io_vars(&fProgram, &fPipelineOutputs, ModifierFlag::kOut);
}

void WGSLCodeGenerator::write(std::string_view s) {
    if (s.empty()) {
        return;
    }
    if (fAtLineStart && fPrettyPrint == PrettyPrint::kYes) {
        for (int i = 0; i < fIndentation; i++) {
            fOut->writeText("  ");
        }
    }
    fOut->writeText(std::string(s).c_str());
    fAtLineStart = false;
}

void WGSLCodeGenerator::writeLine(std::string_view s) {
    this->write(s);
    fOut->writeText("\n");
    fAtLineStart = true;
}

void WGSLCodeGenerator::finishLine() {
    if (!fAtLineStart) {
        this->writeLine();
    }
}

std::string WGSLCodeGenerator::assembleName(std::string_view name) {
    if (name.empty()) {
        // WGSL doesn't allow anonymous function parameters.
        return "_skAnonymous" + std::to_string(fScratchCount++);
    }
    // Add `R_` before reserved names to avoid any potential reserved-word conflict.
    return (skstd::starts_with(name, "_sk") ||
            skstd::starts_with(name, "R_") ||
            is_reserved_word(name))
                   ? std::string("R_") + std::string(name)
                   : std::string(name);
}

void WGSLCodeGenerator::writeVariableDecl(const Layout& layout,
                                          const Type& type,
                                          std::string_view name,
                                          Delimiter delimiter) {
    this->write(this->assembleName(name));
    this->write(": " + to_wgsl_type(fContext, type, &layout));
    this->writeLine(delimiter_to_str(delimiter));
}

void WGSLCodeGenerator::writePipelineIODeclaration(const Layout& layout,
                                                   const Type& type,
                                                   ModifierFlags modifiers,
                                                   std::string_view name,
                                                   Delimiter delimiter) {
    // In WGSL, an entry-point IO parameter is "one of either a built-in value or assigned a
    // location". However, some SkSL declarations, specifically sk_FragColor, can contain both a
    // location and a builtin modifier. In addition, WGSL doesn't have a built-in equivalent for
    // sk_FragColor as it relies on the user-defined location for a render target.
    //
    // Instead of special-casing sk_FragColor, we just give higher precedence to a location modifier
    // if a declaration happens to both have a location and it's a built-in.
    //
    // Also see:
    // https://www.w3.org/TR/WGSL/#input-output-locations
    // https://www.w3.org/TR/WGSL/#attribute-location
    // https://www.w3.org/TR/WGSL/#builtin-inputs-outputs
    if (layout.fLocation >= 0) {
        this->writeUserDefinedIODecl(layout, type, modifiers, name, delimiter);
        return;
    }
    if (layout.fBuiltin >= 0) {
        if (layout.fBuiltin == SK_POINTSIZE_BUILTIN) {
            // WebGPU does not support the point-size builtin, but we silently replace it with a
            // global variable when it is used, instead of reporting an error.
            return;
        }
        auto builtin = builtin_from_sksl_name(layout.fBuiltin);
        if (builtin.has_value()) {
            // Builtin IO parameters should only have in/out modifiers, which are then implicit in
            // the generated WGSL, hence why writeBuiltinIODecl does not need them passed in.
            SkASSERT(!(modifiers & ~(ModifierFlag::kIn | ModifierFlag::kOut)));
            this->writeBuiltinIODecl(type, name, *builtin, delimiter);
            return;
        }
    }
    fContext.fErrors->error(Position(), "declaration '" + std::string(name) + "' is not supported");
}

void WGSLCodeGenerator::writeUserDefinedIODecl(const Layout& layout,
                                               const Type& type,
                                               ModifierFlags flags,
                                               std::string_view name,
                                               Delimiter delimiter) {
    this->write("@location(" + std::to_string(layout.fLocation) + ") ");

    // @blend_src is only allowed when doing dual-source blending, and only on color attachment 0.
    if (layout.fLocation == 0 && layout.fIndex >= 0 && fProgram.fInterface.fOutputSecondaryColor) {
        this->write("@blend_src(" + std::to_string(layout.fIndex) + ") ");
    }

    // "User-defined IO of scalar or vector integer type must always be specified as
    // @interpolate(flat)" (see https://www.w3.org/TR/WGSL/#interpolation)
    if (flags.isFlat() || type.isInteger() ||
        (type.isVector() && type.componentType().isInteger())) {
        // We can use 'either' to hint to WebGPU that we don't care about the provoking vertex and
        // avoid any expensive shader or data rewriting to ensure 'first'. Skia has a long-standing
        // policy to only use flat shading when it's constant for a primitive so the vertex doesn't
        // matter. See https://www.w3.org/TR/WGSL/#interpolation-sampling-either
        this->write("@interpolate(flat, either) ");
    } else if (flags & ModifierFlag::kNoPerspective) {
        this->write("@interpolate(linear) ");
    }

    this->writeVariableDecl(layout, type, name, delimiter);
}

void WGSLCodeGenerator::writeBuiltinIODecl(const Type& type,
                                           std::string_view name,
                                           Builtin builtin,
                                           Delimiter delimiter) {
    this->write(wgsl_builtin_name(builtin));
    this->write(" ");
    this->write(this->assembleName(name));
    this->write(": ");
    this->write(wgsl_builtin_type(builtin, fContext));
    this->writeLine(delimiter_to_str(delimiter));
}

void WGSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
    const FunctionDeclaration& decl = f.declaration();
    fHasUnconditionalReturn = false;
    fConditionalScopeDepth = 0;

    SkASSERT(!fAtFunctionScope);
    fAtFunctionScope = true;

    // WGSL parameters are immutable and are considered as taking no storage, but SkSL parameters
    // are real variables. To work around this, we make var-based copies of parameters. It's
    // wasteful to make a copy of every single parameter--even if the compiler can eventually
    // optimize them all away, that takes time and generates bloated code. So, we only make
    // parameter copies if the variable is actually written-to.
    STArray<32, bool> paramNeedsDedicatedStorage;
    paramNeedsDedicatedStorage.push_back_n(decl.parameters().size(), true);

    for (size_t index = 0; index < decl.parameters().size(); ++index) {
        const Variable& param = *decl.parameters()[index];
        if (param.type().isOpaque() || param.name().empty()) {
            // Opaque-typed or anonymous parameters don't need dedicated storage.
            paramNeedsDedicatedStorage[index] = false;
            continue;
        }

        const ProgramUsage::VariableCounts counts = fProgram.fUsage->get(param);
        if ((param.modifierFlags() & ModifierFlag::kOut) || counts.fWrite == 0) {
            // Variables which are never written-to don't need dedicated storage.
            // Out-parameters are passed as pointers; the pointer itself is never modified, so
            // it doesn't need dedicated storage.
            paramNeedsDedicatedStorage[index] = false;
        }
    }

    this->writeFunctionDeclaration(decl, paramNeedsDedicatedStorage);
    this->writeLine(" {");
    ++fIndentation;

    // The parameters were given generic names like `_skParam1`, because WGSL parameters don't have
    // storage and are immutable. If mutability is required, we create variables here; otherwise, we
    // create properly-named `let` aliases.
    for (size_t index = 0; index < decl.parameters().size(); ++index) {
        if (paramNeedsDedicatedStorage[index]) {
            const Variable& param = *decl.parameters()[index];
            this->write("var ");
            this->write(this->assembleName(param.mangledName()));
            this->write(" = _skParam");
            this->write(std::to_string(index));
            this->writeLine(";");
        }
    }

    this->writeBlock(f.body()->as<Block>());

    // If fConditionalScopeDepth isn't zero, we have an unbalanced +1 or -1 when updating the depth.
    SkASSERT(fConditionalScopeDepth == 0);
    if (!fHasUnconditionalReturn && !f.declaration().returnType().isVoid()) {
        this->write("return ");
        this->write(to_wgsl_type(fContext, f.declaration().returnType()));
        this->writeLine("();");
    }

    --fIndentation;
    this->writeLine("}");

    SkASSERT(fAtFunctionScope);
    fAtFunctionScope = false;
}

void WGSLCodeGenerator::writeFunctionDeclaration(const FunctionDeclaration& decl,
                                                 SkSpan<const bool> paramNeedsDedicatedStorage) {
    this->write("fn ");
    if (decl.isMain()) {
        this->write("_skslMain(");
    } else {
        this->write(this->assembleName(decl.mangledName()));
        this->write("(");
    }
    auto separator = SkSL::String::Separator();
    if (this->writeFunctionDependencyParams(decl)) {
        separator();  // update the separator as parameters have been written
    }
    for (size_t index = 0; index < decl.parameters().size(); ++index) {
        this->write(separator());

        const Variable& param = *decl.parameters()[index];
        if (param.type().isOpaque()) {
            SkASSERT(!paramNeedsDedicatedStorage[index]);
            if (param.type().isSampler()) {
                // Create parameters for both the texture and associated sampler.
                this->write(param.name());
                this->write(kTextureSuffix);
                this->write(": texture_2d<f32>, ");
                this->write(param.name());
                this->write(kSamplerSuffix);
                this->write(": sampler");
            } else {
                // Create a parameter for the opaque object.
                this->write(param.name());
                this->write(": ");
                this->write(to_wgsl_type(fContext, param.type(), &param.layout()));
            }
        } else {
            if (paramNeedsDedicatedStorage[index] || param.name().empty()) {
                // Create an unnamed parameter. If the parameter needs dedicated storage, it will
                // later be assigned a `var` in the function body. (If it's anonymous, a var isn't
                // needed.)
                this->write("_skParam");
                this->write(std::to_string(index));
            } else {
                // Use the name directly from the SkSL program.
                this->write(this->assembleName(param.name()));
            }
            this->write(": ");
            if (param.type().isUnsizedArray()) {
                // Creates a storage address space pointer for unsized array parameters.
                // The buffer the array resides in must be marked `readonly` to have the array
                // be used in function parameters, since access modes in wgsl must exactly match.
                this->write("ptr<storage, ");
                this->write(to_wgsl_type(fContext, param.type(), &param.layout()));
                this->write(", read>");
            } else if (param.modifierFlags() & ModifierFlag::kOut) {
                // Declare an "out" function parameter as a pointer.
                this->write(to_ptr_type(fContext, param.type(), &param.layout()));
            } else {
                this->write(to_wgsl_type(fContext, param.type(), &param.layout()));
            }
        }
    }
    this->write(")");
    if (!decl.returnType().isVoid()) {
        this->write(" -> ");
        this->write(to_wgsl_type(fContext, decl.returnType()));
    }
}

void WGSLCodeGenerator::writeEntryPoint(const FunctionDefinition& main) {
    SkASSERT(main.declaration().isMain());
    const ProgramKind programKind = fProgram.fConfig->fKind;

    bool initPolyfill = false;
    for (const auto& [field, info] : fFieldPolyfillMap) {
        if (info.fWasAccessed) {
            initPolyfill = true;
            break;
        }
    }

    if (fGenSyntheticCode == IncludeSyntheticCode::kYes &&
        ProgramConfig::IsRuntimeShader(programKind)) {
        // Synthesize a basic entrypoint which just calls straight through to main.
        // This is only used by skslc and just needs to pass the WGSL validator; Skia won't ever
        // emit functions like this.
        this->write("@fragment fn main(@location(0) _coords: vec2<f32>) -> @location(0) ");
        this->write(to_wgsl_type(fContext, main.declaration().returnType()));
        this->writeLine(" {");

        ++fIndentation;
        if (initPolyfill) {
            this->writeLine("_skInitializePolyfilledUniforms();");
        }
        this->writeLine("return _skslMain(_coords);");
        --fIndentation;
        this->writeLine("}");
        return;
    }

    // The input and output parameters for a vertex/fragment stage entry point function have the
    // FSIn/FSOut/VSIn/VSOut/CSIn struct types that have been synthesized in generateCode(). An
    // entrypoint always has a predictable signature and acts as a trampoline to the user-defined
    // main function.
    if (ProgramConfig::IsVertex(programKind)) {
        this->write("@vertex");
    } else if (ProgramConfig::IsFragment(programKind)) {
        this->write("@fragment");
    } else if (ProgramConfig::IsCompute(programKind)) {
        this->write("@compute @workgroup_size(");
        this->write(std::to_string(fLocalSizeX));
        this->write(", ");
        this->write(std::to_string(fLocalSizeY));
        this->write(", ");
        this->write(std::to_string(fLocalSizeZ));
        this->write(")");
    } else {
        fContext.fErrors->error(Position(), "program kind not supported");
        return;
    }

    this->write(" fn main(");
    // The stage input struct is a parameter passed to main().
    if (this->needsStageInputStruct()) {
        this->write("_stageIn: ");
        this->write(pipeline_struct_prefix(programKind));
        this->write("In");
    }
    // The stage output struct is returned from main().
    if (this->needsStageOutputStruct()) {
        this->write(") -> ");
        this->write(pipeline_struct_prefix(programKind));
        this->writeLine("Out {");
    } else {
        this->writeLine(") {");
    }
    // Initialize polyfilled matrix uniforms if any were used.
    fIndentation++;
    if (initPolyfill) {
        this->writeLine("_skInitializePolyfilledUniforms();");
    }

    // Declare the stage output struct.
    if (this->needsStageOutputStruct()) {
        this->write("var _stageOut: ");
        this->write(pipeline_struct_prefix(programKind));
        this->writeLine("Out;");
    }

    // We are compiling a Runtime Effect as a fragment shader, for testing purposes. We assign the
    // result from _skslMain into sk_FragColor if the user-defined main returns a color. This
    // doesn't actually matter, but it is more indicative of what a real program would do.
    // `addImplicitFragColorWrite` from Transform::FindAndDeclareBuiltinVariables has already
    // injected sk_FragColor into our stage outputs even if it wasn't explicitly referenced.
    if (fGenSyntheticCode == IncludeSyntheticCode::kYes && ProgramConfig::IsFragment(programKind)) {
        if (main.declaration().returnType().matches(*fContext.fTypes.fHalf4)) {
            this->write("_stageOut.sk_FragColor = ");
        }
    }

    // Generate a function call to the user-defined main.
    this->write("_skslMain(");
    auto separator = SkSL::String::Separator();
    WGSLFunctionDependencies* deps = fRequirements.fDependencies.find(&main.declaration());
    if (deps) {
        if (*deps & WGSLFunctionDependency::kPipelineInputs) {
            this->write(separator());
            this->write("_stageIn");
        }
        if (*deps & WGSLFunctionDependency::kPipelineOutputs) {
            this->write(separator());
            this->write("&_stageOut");
        }
    }

    if (fGenSyntheticCode == IncludeSyntheticCode::kYes) {
        if (const Variable* v = main.declaration().getMainCoordsParameter()) {
            // We are compiling a Runtime Effect as a fragment shader, for testing purposes.
            // We need to synthesize a coordinates parameter, but the coordinates don't matter.
            SkASSERT(ProgramConfig::IsFragment(programKind));
            const Type& type = v->type();
            if (!type.matches(*fContext.fTypes.fFloat2)) {
                fContext.fErrors->error(
                        main.fPosition,
                        "main function has unsupported parameter: " + type.description());
                return;
            }
            this->write(separator());
            this->write("/*fragcoord*/ vec2<f32>()");
        }
    }

    this->writeLine(");");

    if (this->needsStageOutputStruct()) {
        // Return the stage output struct.
        this->writeLine("return _stageOut;");
    }

    fIndentation--;
    this->writeLine("}");
}

void WGSLCodeGenerator::writeStatement(const Statement& s) {
    switch (s.kind()) {
        case Statement::Kind::kBlock:
            this->writeBlock(s.as<Block>());
            break;
        case Statement::Kind::kBreak:
            this->writeLine("break;");
            break;
        case Statement::Kind::kContinue:
            this->writeLine("continue;");
            break;
        case Statement::Kind::kDiscard:
            this->writeLine("discard;");
            break;
        case Statement::Kind::kDo:
            this->writeDoStatement(s.as<DoStatement>());
            break;
        case Statement::Kind::kExpression:
            this->writeExpressionStatement(*s.as<ExpressionStatement>().expression());
            break;
        case Statement::Kind::kFor:
            this->writeForStatement(s.as<ForStatement>());
            break;
        case Statement::Kind::kIf:
            this->writeIfStatement(s.as<IfStatement>());
            break;
        case Statement::Kind::kNop:
            this->writeLine(";");
            break;
        case Statement::Kind::kReturn:
            this->writeReturnStatement(s.as<ReturnStatement>());
            break;
        case Statement::Kind::kSwitch:
            this->writeSwitchStatement(s.as<SwitchStatement>());
            break;
        case Statement::Kind::kSwitchCase:
            SkDEBUGFAIL("switch-case statements should only be present inside a switch");
            break;
        case Statement::Kind::kVarDeclaration:
            this->writeVarDeclaration(s.as<VarDeclaration>());
            break;
    }
}

void WGSLCodeGenerator::writeStatements(const StatementArray& statements) {
    for (const auto& s : statements) {
        if (!s->isEmpty()) {
            this->writeStatement(*s);
            this->finishLine();
        }
    }
}

void WGSLCodeGenerator::writeBlock(const Block& b) {
    // Write scope markers if this block is a scope, or if the block is empty (since we need to emit
    // something here to make the code valid).
    bool isScope = b.isScope() || b.isEmpty();
    if (isScope) {
        this->writeLine("{");
        fIndentation++;
    }
    this->writeStatements(b.children());
    if (isScope) {
        fIndentation--;
        this->writeLine("}");
    }
}

void WGSLCodeGenerator::writeExpressionStatement(const Expression& expr) {
    // Any expression-related side effects must be emitted as separate statements when
    // `assembleExpression` is called.
    // The final result of the expression will be a variable, let-reference, or an expression with
    // no side effects (`foo + bar`). Discarding this result is safe, as the program never uses it.
    (void)this->assembleExpression(expr, Precedence::kStatement);
}

void WGSLCodeGenerator::writeDoStatement(const DoStatement& s) {
    // Generate a loop structure like this:
    //   loop {
    //       body-statement;
    //       continuing {
    //           break if inverted-test-expression;
    //       }
    //   }

    ++fConditionalScopeDepth;

    std::unique_ptr<Expression> invertedTestExpr = PrefixExpression::Make(
            fContext, s.test()->fPosition, OperatorKind::LOGICALNOT, s.test()->clone());

    this->writeLine("loop {");
    fIndentation++;
    this->writeStatement(*s.statement());
    this->finishLine();

    this->writeLine("continuing {");
    fIndentation++;
    std::string breakIfExpr = this->assembleExpression(*invertedTestExpr, Precedence::kExpression);
    this->write("break if ");
    this->write(breakIfExpr);
    this->writeLine(";");
    fIndentation--;
    this->writeLine("}");
    fIndentation--;
    this->writeLine("}");

    --fConditionalScopeDepth;
}

void WGSLCodeGenerator::writeForStatement(const ForStatement& s) {
    // When the next expression is a single expression and the condition needs no scratch
    // variables, emit a native for-loop:
    //
    //   {
    //       init;
    //       for (; cond; next) {
    //           body
    //       }
    //   }
    //
    // Otherwise (comma next expression, or condition assembly emits preparatory 'let'
    // statements), fall back to:
    //
    //   {
    //       init;
    //       loop {
    //           cond-prep-stmts;   // scratch lets for the condition, if any
    //           if (cond) {
    //               body
    //           } else {
    //               break;
    //           }
    //           continuing {
    //               next;
    //           }
    //       }
    //   }
    //
    // The outer block scopes any init variable declarations.

    ++fConditionalScopeDepth;

    // If there is an initializer, wrap in an outer block to scope any variable declarations.
    // This must be emitted regardless of unroll count.
    if (s.initializer()) {
        this->writeLine("{");
        fIndentation++;
        this->writeStatement(*s.initializer());
        this->finishLine();
    }

    if (s.unrollInfo() && s.unrollInfo()->fCount <= 0) {
        // Loops which are known to never execute don't need to be emitted at all.
        // (However, the front end should have already replaced this loop with a Nop.)
    } else {
        bool hasCommaNext = s.next() &&
                            s.next()->is<BinaryExpression>() &&
                            s.next()->as<BinaryExpression>().getOperator().kind() ==
                                    OperatorKind::COMMA;

        // Assemble cond and next into temporary buffers. If either assembly allocates
        // scratch variables (_skTemp), those must run on every loop iteration and the
        // native for-loop form cannot be used; fall back to loop{} in that case.
        int scratchBefore = fScratchCount;

        StringStream condBuf;
        std::string condStr;
        if (s.test()) {
            AutoOutputStream captureOutput(this, &condBuf, &fIndentation);
            condStr = this->assembleExpression(*s.test(), Precedence::kExpression);
        }

        StringStream nextBuf;
        if (s.next()) {
            AutoOutputStream captureOutput(this, &nextBuf, &fIndentation);
            this->writeExpressionStatement(*s.next());
        }

        bool needsLoopForm = hasCommaNext || (fScratchCount != scratchBefore);

        if (!needsLoopForm) {
            // Single next expression, no scratch variables: emit a native for-loop.
            // Strip the trailing ';' and newline from nextBuf to get the for-update expression.
            std::string updateStr = nextBuf.str();
            while (!updateStr.empty() && (updateStr.back() == '\n' || updateStr.back() == '\r')) {
                updateStr.pop_back();
            }
            if (!updateStr.empty() && updateStr.back() == ';') {
                updateStr.pop_back();
            }

            this->write("for (;");
            if (!condStr.empty()) {
                this->write(" ");
                this->write(condStr);
            }
            this->write("; ");
            this->write(updateStr);
            this->writeLine(") {");

            fIndentation++;
            this->writeStatement(*s.statement());
            this->finishLine();
            fIndentation--;
            this->writeLine("}");
        } else {
            // Comma next, or scratch variables needed: use
            // loop { cond-scratch; if (cond) { body } else { break; } continuing { next; } }.
            this->writeLine("loop {");
            fIndentation++;

            // Inline cond prep statements on the same line as the if-check by replacing
            // newlines with spaces (avoids indentation issues with a pre-captured string).
            std::string condPrep = condBuf.str();
            std::replace(condPrep.begin(), condPrep.end(), '\n', ' ');

            this->write(condPrep);

            if (!condStr.empty()) {
                this->write("if ");
                this->write(condStr);
                this->writeLine(" {");
                fIndentation++;
                this->writeStatement(*s.statement());
                this->finishLine();
                fIndentation--;
                this->writeLine("} else {");
                fIndentation++;
                this->writeLine("break;");
                fIndentation--;
                this->writeLine("}");
            } else {
                this->writeStatement(*s.statement());
                this->finishLine();
            }

            if (s.next()) {
                this->writeLine("continuing {");
                fIndentation++;
                std::string nextStr = nextBuf.str();
                std::replace(nextStr.begin(), nextStr.end(), '\n', ' ');
                this->write(nextStr);
                this->finishLine();
                fIndentation--;
                this->writeLine("}");
            }

            fIndentation--;
            this->writeLine("}");
        }
    }

    if (s.initializer()) {
        fIndentation--;
        this->writeLine("}");
    }

    --fConditionalScopeDepth;
}

void WGSLCodeGenerator::writeIfStatement(const IfStatement& s) {
    ++fConditionalScopeDepth;

    std::string testExpr = this->assembleExpression(*s.test(), Precedence::kExpression);
    this->write("if ");
    this->write(testExpr);
    this->writeLine(" {");
    fIndentation++;
    this->writeStatement(*s.ifTrue());
    this->finishLine();
    fIndentation--;
    if (s.ifFalse()) {
        this->writeLine("} else {");
        fIndentation++;
        this->writeStatement(*s.ifFalse());
        this->finishLine();
        fIndentation--;
    }
    this->writeLine("}");

    --fConditionalScopeDepth;
}

void WGSLCodeGenerator::writeReturnStatement(const ReturnStatement& s) {
    fHasUnconditionalReturn |= (fConditionalScopeDepth == 0);

    std::string expr = s.expression()
                               ? this->assembleExpression(*s.expression(), Precedence::kExpression)
                               : std::string();
    this->write("return ");
    this->write(expr);
    this->write(";");
}

void WGSLCodeGenerator::writeSwitchCaseList(SkSpan<const SwitchCase* const> cases) {
    auto separator = SkSL::String::Separator();
    for (const SwitchCase* const sc : cases) {
        this->write(separator());
        if (sc->isDefault()) {
            this->write("default");
        } else {
            this->write(std::to_string(sc->value()));
        }
    }
}

void WGSLCodeGenerator::writeSwitchCases(SkSpan<const SwitchCase* const> cases) {
    if (!cases.empty()) {
        // Only the last switch-case should have a non-empty statement.
        SkASSERT(std::all_of(cases.begin(), std::prev(cases.end()), [](const SwitchCase* sc) {
            return sc->statement()->isEmpty();
        }));

        // Emit the cases in a comma-separated list.
        this->write("case ");
        this->writeSwitchCaseList(cases);
        this->writeLine(" {");
        ++fIndentation;

        // Emit the switch-case body.
        this->writeStatement(*cases.back()->statement());
        this->finishLine();

        --fIndentation;
        this->writeLine("}");
    }
}

void WGSLCodeGenerator::writeEmulatedSwitchFallthroughCases(SkSpan<const SwitchCase* const> cases,
                                                            std::string_view switchValue) {
    // There's no need for fallthrough handling unless we actually have multiple case blocks.
    if (cases.size() < 2) {
        this->writeSwitchCases(cases);
        return;
    }

    // Match against the entire case group.
    this->write("case ");
    this->writeSwitchCaseList(cases);
    this->writeLine(" {");
    ++fIndentation;

    std::string fallthroughVar = this->writeScratchVar(*fContext.fTypes.fBool, "false");
    const size_t secondToLastCaseIndex = cases.size() - 2;
    const size_t lastCaseIndex = cases.size() - 1;

    for (size_t index = 0; index < cases.size(); ++index) {
        const SwitchCase& sc = *cases[index];
        if (index < lastCaseIndex) {
            // The default case must come last in SkSL, and this case isn't the last one, so it
            // can't possibly be the default.
            SkASSERT(!sc.isDefault());

            this->write("if ");
            if (index > 0) {
                this->write(fallthroughVar);
                this->write(" || ");
            }
            this->write(switchValue);
            this->write(" == ");
            this->write(std::to_string(sc.value()));
            this->writeLine(" {");
            fIndentation++;

            // We write the entire case-block statement here, and then set `switchFallthrough`
            // to 1. If the case-block had a break statement in it, we break out of the outer
            // for-loop entirely, meaning the `switchFallthrough` assignment never occurs, nor
            // does any code after it inside the switch. We've forbidden `continue` statements
            // inside switch case-blocks entirely, so we don't need to consider their effect on
            // control flow; see the Finalizer in FunctionDefinition::Convert.
            this->writeStatement(*sc.statement());
            this->finishLine();

            if (index < secondToLastCaseIndex) {
                // Set a variable to indicate falling through to the next block. The very last
                // case-block is reached by process of elimination and doesn't need this
                // variable, so we don't actually need to set it if we are on the second-to-last
                // case block.
                this->write(fallthroughVar);
                this->write(" = true;  ");
            }
#if defined(SK_DEBUG)
            this->writeLine("// fallthrough");
#endif

            fIndentation--;
            this->writeLine("}");
        } else {
            // This is the final case. Since it's always last, we can just dump in the code.
            // (If we didn't match any of the other values, we must have matched this one by
            // process of elimination. If we did match one of the other values, we either hit a
            // `break` statement earlier--and won't get this far--or we're falling through.)
            this->writeStatement(*sc.statement());
            this->finishLine();
        }
    }

    --fIndentation;
    this->writeLine("}");
}

void WGSLCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
    // WGSL supports the `switch` statement in a limited capacity. A default case must always be
    // specified. Each switch-case must be scoped inside braces. Fallthrough is not supported; a
    // trailing break is implied at the end of each switch-case block. (Explicit breaks are also
    // allowed.)  One minor improvement over a traditional switch is that switch-cases take a list
    // of values to match, instead of a single value:
    //   case 1, 2       { foo(); }
    //   case 3, default { bar(); }
    //
    // We will use the native WGSL switch statement for any switch-cases in the SkSL which can be
    // made to conform to these limitations. The remaining cases which cannot conform will be
    // emulated with if-else blocks (similar to our GLSL ES2 switch-statement emulation path). This
    // should give us good performance in the common case, since most switches naturally conform.

    // First, let's emit the switch itself.
    std::string valueExpr = this->assembleExpression(*s.value(), Precedence::kExpression,
                                                     kUsedMultipleTimes);
    this->write("switch ");
    this->write(valueExpr);
    this->writeLine(" {");
    ++fIndentation;

    // Now let's go through the switch-cases, and emit the ones that don't fall through.
    TArray<const SwitchCase*> nativeCases;
    TArray<const SwitchCase*> fallthroughCases;
    bool previousCaseFellThrough = false;
    bool foundNativeDefault = false;
    [[maybe_unused]] bool foundFallthroughDefault = false;

    const int lastSwitchCaseIdx = s.cases().size() - 1;
    for (int index = 0; index <= lastSwitchCaseIdx; ++index) {
        const SwitchCase& sc = s.cases()[index]->as<SwitchCase>();

        if (sc.statement()->isEmpty()) {
            // This is a `case X:` that immediately falls through to the next case.
            // If we aren't already falling through, we can handle this via a comma-separated list.
            if (previousCaseFellThrough) {
                fallthroughCases.push_back(&sc);
                foundFallthroughDefault |= sc.isDefault();
            } else {
                nativeCases.push_back(&sc);
                foundNativeDefault |= sc.isDefault();
            }
            continue;
        }

        if (index == lastSwitchCaseIdx || Analysis::SwitchCaseContainsUnconditionalExit(sc)) {
            // This is a `case X:` that never falls through.
            if (previousCaseFellThrough) {
                // Because the previous cases fell through, we can't use a native switch-case here.
                fallthroughCases.push_back(&sc);
                foundFallthroughDefault |= sc.isDefault();

                this->writeEmulatedSwitchFallthroughCases(fallthroughCases, valueExpr);
                fallthroughCases.clear();

                // Fortunately, we're no longer falling through blocks, so we might be able to use a
                // native switch-case list again.
                previousCaseFellThrough = false;
            } else {
                // Emit a native switch-case block with a comma-separated case list.
                nativeCases.push_back(&sc);
                foundNativeDefault |= sc.isDefault();

                this->writeSwitchCases(nativeCases);
                nativeCases.clear();
            }
            continue;
        }

        // This case falls through, so it will need to be handled via emulation.
        // If we have put together a collection of "native" cases (cases that fall through with no
        // actual case-body), we will need to slide them over into the fallthrough-case list.
        fallthroughCases.push_back_n(nativeCases.size(), nativeCases.data());
        nativeCases.clear();

        fallthroughCases.push_back(&sc);
        foundFallthroughDefault |= sc.isDefault();
        previousCaseFellThrough = true;
    }

    // Finish out the remaining switch-cases.
    this->writeSwitchCases(nativeCases);
    nativeCases.clear();

    this->writeEmulatedSwitchFallthroughCases(fallthroughCases, valueExpr);
    fallthroughCases.clear();

    // WGSL requires a default case.
    if (!foundNativeDefault && !foundFallthroughDefault) {
        this->writeLine("case default {}");
    }

    --fIndentation;
    this->writeLine("}");
}

void WGSLCodeGenerator::writeVarDeclaration(const VarDeclaration& varDecl) {
    std::string initialValue =
            varDecl.value() ? this->assembleExpression(*varDecl.value(), Precedence::kAssignment)
                            : std::string();

    if (varDecl.var()->modifierFlags().isConst() ||
        (fProgram.fUsage->get(*varDecl.var()).fWrite == 1 && varDecl.value())) {
        // Use `const` at global scope, or if the value is a compile-time constant.
        SkASSERTF(varDecl.value(), "an immutable variable must specify a value");
        const bool useConst =
                !fAtFunctionScope || Analysis::IsCompileTimeConstant(*varDecl.value());
        this->write(useConst ? "const " : "let ");
    } else {
        this->write("var ");
    }
    this->write(this->assembleName(varDecl.var()->mangledName()));
    this->write(": ");
    this->write(to_wgsl_type(fContext, varDecl.var()->type(), &varDecl.var()->layout()));

    if (varDecl.value()) {
        this->write(" = ");
        this->write(initialValue);
    }

    this->write(";");
}

std::unique_ptr<WGSLCodeGenerator::LValue> WGSLCodeGenerator::makeLValue(const Expression& e) {
    if (e.is<VariableReference>()) {
        return std::make_unique<PointerLValue>(
                this->variableReferenceNameForLValue(e.as<VariableReference>()));
    }
    if (e.is<FieldAccess>()) {
        return std::make_unique<PointerLValue>(this->assembleFieldAccess(e.as<FieldAccess>()));
    }
    if (e.is<IndexExpression>()) {
        const IndexExpression& idx = e.as<IndexExpression>();
        if (idx.base()->type().isVector()) {
            // Rewrite indexed-swizzle accesses like `myVec.zyx[i]` into an index onto `myVec`.
            if (std::unique_ptr<Expression> rewrite =
                        Transform::RewriteIndexedSwizzle(fContext, idx)) {
                return std::make_unique<VectorComponentLValue>(
                        this->assembleExpression(*rewrite, Precedence::kAssignment));
            } else {
                return std::make_unique<VectorComponentLValue>(this->assembleIndexExpression(idx));
            }
        } else {
            return std::make_unique<PointerLValue>(this->assembleIndexExpression(idx));
        }
    }
    if (e.is<Swizzle>()) {
        const Swizzle& swizzle = e.as<Swizzle>();
        if (swizzle.components().size() == 1) {
            return std::make_unique<VectorComponentLValue>(this->assembleSwizzle(swizzle));
        } else {
            return std::make_unique<SwizzleLValue>(
                    fContext,
                    this->assembleExpression(*swizzle.base(), Precedence::kAssignment),
                    swizzle.base()->type(),
                    swizzle.components());
        }
    }

    fContext.fErrors->error(e.fPosition, "unsupported lvalue type");
    return nullptr;
}

std::string WGSLCodeGenerator::assembleExpression(const Expression& e,
                                                  Precedence parentPrecedence,
                                                  AssembleMode mode) {
    // Determine if we need to introduce a scratch let for this expression. There are three
    // situations that require this:
    //   1. Explicitly requested by caller.
    //   2. outer context would reference it multiple reasons for *reasons*, and the expression is
    //      not trivial
    //   3. skbug.com/asdf, where the first child const expression needs to be lifted to avoid
    //      WGSL's stricter const eval rules.
    if (mode == kForceLet ||
        (mode == kUsedMultipleTimes && is_nontrivial_expression(e)) ||
        /* mode == kAuto && */ fNeedsConstEvalWorkaround) {
        // Allow the scratch let to be considered const as long as we don't have to force it to
        // a let for the const-eval workaround or by `mode`.
        const bool canBeConst = !fNeedsConstEvalWorkaround &&
                                mode != kForceLet &&
                                Analysis::IsCompileTimeConstant(e);
        // Setting this to false and not overriding the AssembleMode means this next call to
        // assembleExpression gives us the original expression value.
        fNeedsConstEvalWorkaround = false;
        std::string expr = this->assembleExpression(e, Precedence::kAssignment);
        return this->writeScratchLet(expr, canBeConst);
    }

    AutoConstEvalWorkaround constEval{this, e};
    switch (e.kind()) {
        case Expression::Kind::kBinary:
            return this->assembleBinaryExpression(e.as<BinaryExpression>(), parentPrecedence);

        case Expression::Kind::kConstructorCompound:
            return this->assembleConstructorCompound(e.as<ConstructorCompound>());

        case Expression::Kind::kConstructorArrayCast:
            return this->assembleConstructorArrayCast(e.as<ConstructorArrayCast>(),
                                                      parentPrecedence);

        case Expression::Kind::kConstructorArray:
        case Expression::Kind::kConstructorCompoundCast:
        case Expression::Kind::kConstructorScalarCast:
        case Expression::Kind::kConstructorSplat:
        case Expression::Kind::kConstructorStruct:
            return this->assembleAnyConstructor(e.asAnyConstructor());

        case Expression::Kind::kConstructorDiagonalMatrix:
            return this->assembleConstructorDiagonalMatrix(e.as<ConstructorDiagonalMatrix>());

        case Expression::Kind::kConstructorMatrixResize:
            return this->assembleConstructorMatrixResize(e.as<ConstructorMatrixResize>());

        case Expression::Kind::kEmpty:
            return "false";

        case Expression::Kind::kFieldAccess:
            return this->assembleFieldAccess(e.as<FieldAccess>());

        case Expression::Kind::kFunctionCall:
            return this->assembleFunctionCall(e.as<FunctionCall>(), parentPrecedence);

        case Expression::Kind::kIndex:
            return this->assembleIndexExpression(e.as<IndexExpression>());

        case Expression::Kind::kLiteral:
            return this->assembleLiteral(e.as<Literal>());

        case Expression::Kind::kPrefix:
            return this->assemblePrefixExpression(e.as<PrefixExpression>(), parentPrecedence);

        case Expression::Kind::kPostfix:
            return this->assemblePostfixExpression(e.as<PostfixExpression>(), parentPrecedence);

        case Expression::Kind::kSetting:
            return this->assembleExpression(*e.as<Setting>().toLiteral(fCaps), parentPrecedence);

        case Expression::Kind::kSwizzle:
            return this->assembleSwizzle(e.as<Swizzle>());

        case Expression::Kind::kTernary:
            return this->assembleTernaryExpression(e.as<TernaryExpression>(), parentPrecedence);

        case Expression::Kind::kVariableReference:
            return this->assembleVariableReference(e.as<VariableReference>());

        default:
            SkDEBUGFAILF("unsupported expression:\n%s", e.description().c_str());
            return {};
    }
}

static bool binary_op_is_ambiguous_in_wgsl(Operator op) {
    // WGSL always requires parentheses for some operators which are deemed to be ambiguous.
    // (8.19. Operator Precedence and Associativity)
    switch (op.kind()) {
        case OperatorKind::LOGICALOR:
        case OperatorKind::LOGICALAND:
        case OperatorKind::BITWISEOR:
        case OperatorKind::BITWISEAND:
        case OperatorKind::BITWISEXOR:
        case OperatorKind::SHL:
        case OperatorKind::SHR:
        case OperatorKind::LT:
        case OperatorKind::GT:
        case OperatorKind::LTEQ:
        case OperatorKind::GTEQ:
            return true;

        default:
            return false;
    }
}

bool WGSLCodeGenerator::binaryOpNeedsComponentwiseMatrixPolyfill(const Type& left,
                                                                 const Type& right,
                                                                 Operator op) {
    switch (op.kind()) {
        case OperatorKind::SLASH:
        case OperatorKind::SLASHEQ:
            // WGSL does not natively support componentwise matrix-op-matrix for division.
            if (left.isMatrix() && right.isMatrix()) {
                return true;
            }
            [[fallthrough]];

        case OperatorKind::PLUS:
        case OperatorKind::PLUSEQ:
        case OperatorKind::MINUS:
        case OperatorKind::MINUSEQ:
            // WGSL does not natively support componentwise matrix-op-scalar or scalar-op-matrix for
            // addition, subtraction or division.
            return (left.isMatrix() && right.isScalar()) ||
                   (left.isScalar() && right.isMatrix());

        default:
            return false;
    }
}

std::string WGSLCodeGenerator::assembleBinaryExpression(const BinaryExpression& b,
                                                        Precedence parentPrecedence) {
    return this->assembleBinaryExpression(*b.left(), b.getOperator(), *b.right(), b.type(),
                                          parentPrecedence);
}

std::string WGSLCodeGenerator::assembleBinaryExpression(const Expression& left,
                                                        Operator op,
                                                        const Expression& right,
                                                        const Type& resultType,
                                                        Precedence parentPrecedence) {
    // If the operator is && or ||, we need to handle short-circuiting properly. Specifically, we
    // sometimes need to emit extra statements to paper over functionality that WGSL lacks, like
    // assignment in the middle of an expression. We need to guard those extra statements, to ensure
    // that they don't occur if the expression evaluation is short-circuited. Converting the
    // expression into an if-else block keeps the short-circuit property intact even when extra
    // statements are involved.
    // If the RHS doesn't have any side effects, then it's safe to just leave the expression as-is,
    // since we know that any possible extra statements are non-side-effecting.
    std::string expr;
    if (op.kind() == OperatorKind::LOGICALAND && Analysis::HasSideEffects(right)) {
        // Converts `left_expression && right_expression` into the following block:

        // var _skTemp1: bool;
        // [[ prepare left_expression ]]
        // if left_expression {
        //     [[ prepare right_expression ]]
        //     _skTemp1 = right_expression;
        // } else {
        //     _skTemp1 = false;
        // }

        expr = this->writeScratchVar(resultType);

        std::string leftExpr = this->assembleExpression(left, Precedence::kExpression);
        this->write("if ");
        this->write(leftExpr);
        this->writeLine(" {");

        ++fIndentation;
        std::string rightExpr = this->assembleExpression(right, Precedence::kAssignment);
        this->write(expr);
        this->write(" = ");
        this->write(rightExpr);
        this->writeLine(";");
        --fIndentation;

        this->writeLine("} else {");

        ++fIndentation;
        this->write(expr);
        this->writeLine(" = false;");
        --fIndentation;

        this->writeLine("}");
        return expr;
    }

    if (op.kind() == OperatorKind::LOGICALOR && Analysis::HasSideEffects(right)) {
        // Converts `left_expression || right_expression` into the following block:

        // var _skTemp1: bool;
        // [[ prepare left_expression ]]
        // if left_expression {
        //     _skTemp1 = true;
        // } else {
        //     [[ prepare right_expression ]]
        //     _skTemp1 = right_expression;
        // }

        expr = this->writeScratchVar(resultType);

        std::string leftExpr = this->assembleExpression(left, Precedence::kExpression);
        this->write("if ");
        this->write(leftExpr);
        this->writeLine(" {");

        ++fIndentation;
        this->write(expr);
        this->writeLine(" = true;");
        --fIndentation;

        this->writeLine("} else {");

        ++fIndentation;
        std::string rightExpr = this->assembleExpression(right, Precedence::kAssignment);
        this->write(expr);
        this->write(" = ");
        this->write(rightExpr);
        this->writeLine(";");
        --fIndentation;

        this->writeLine("}");
        return expr;
    }

    // Handle comma-expressions.
    if (op.kind() == OperatorKind::COMMA) {
        // The result from the left-expression is ignored, but its side effects must occur.
        this->assembleExpression(left, Precedence::kStatement);

        // Evaluate the right side normally.
        return this->assembleExpression(right, parentPrecedence);
    }

    // Handle assignment-expressions.
    const bool compMatrixOp =
            this->binaryOpNeedsComponentwiseMatrixPolyfill(left.type(), right.type(), op);

    if (op.isAssignment()) {
        std::unique_ptr<LValue> lvalue = this->makeLValue(left);
        if (!lvalue) {
            return "";
        }

        if (op.kind() == OperatorKind::EQ) {
            // Evaluate the right-hand side of simple assignment (`a = b` --> `b`).
            expr = this->assembleExpression(right, Precedence::kAssignment);
        } else {
            // Evaluate the right-hand side of compound-assignment (`a += b` --> `a + b`).
            op = op.removeAssignment();

            std::string lhs = lvalue->load();
            std::string rhs = this->assembleExpression(right, op.getBinaryPrecedence(),
                                                       compMatrixOp ? kUsedMultipleTimes : kAuto);

            if (compMatrixOp) {
                expr = this->assembleComponentwiseMatrixBinary(left.type(), right.type(),
                                                               lhs, rhs, op);
            } else {
                expr = lhs + operator_name(op) + rhs;
            }
        }

        // Emit the assignment statement (`a = a + b`).
        this->writeLine(lvalue->store(expr));

        // Return the lvalue (`a`) as the result, since the value might be used by the caller.
        return lvalue->load();
    }

    if (op.isEquality()) {
        return this->assembleEqualityExpression(left, right, op, parentPrecedence);
    }

    Precedence precedence = op.getBinaryPrecedence();
    bool needParens = precedence >= parentPrecedence;
    if (binary_op_is_ambiguous_in_wgsl(op)) {
        precedence = Precedence::kParentheses;
    }
    if (needParens) {
        expr = "(";
    }

    std::string lhs = this->assembleExpression(left, precedence,
                                               compMatrixOp ? kUsedMultipleTimes : kAuto);
    std::string rhs = this->assembleExpression(right, precedence,
                                               compMatrixOp ? kUsedMultipleTimes : kAuto);
    if (compMatrixOp) {
        expr += this->assembleComponentwiseMatrixBinary(left.type(), right.type(), lhs, rhs, op);
    } else {
        expr += lhs + operator_name(op) + rhs;
    }

    if (needParens) {
        expr += ')';
    }

    return expr;
}

std::string WGSLCodeGenerator::assembleFieldAccess(const FieldAccess& f) {
    const Field* field = &f.base()->type().fields()[f.fieldIndex()];
    std::string expr;

    if (FieldPolyfillInfo* polyfillInfo = fFieldPolyfillMap.find(field)) {
        // We found a matrix uniform. We are required to pass some matrix uniforms as array vectors,
        // since the std140 layout for a matrix assumes 4-column vectors for each row, and WGSL
        // tightly packs 2-column matrices. When emitting code, we replace the field-access
        // expression with a global variable which holds an unpacked version of the uniform.
        polyfillInfo->fWasAccessed = true;

        // The polyfill can either be based directly onto a uniform in an interface block, or it
        // might be based on an index-expression onto a uniform if the interface block is arrayed.
        const Expression* base = f.base().get();
        const IndexExpression* indexExpr = nullptr;
        if (base->is<IndexExpression>()) {
            indexExpr = &base->as<IndexExpression>();
            base = indexExpr->base().get();
        }

        SkASSERT(base->is<VariableReference>());
        expr = polyfillInfo->fReplacementName;

        // If we had an index expression, we must append the index.
        if (indexExpr) {
            expr += '[';
            expr += this->assembleExpression(*indexExpr->index(), Precedence::kSequence);
            expr += ']';
        }
        return expr;
    }

    switch (f.ownerKind()) {
        case FieldAccess::OwnerKind::kDefault:
            expr = this->assembleExpression(*f.base(), Precedence::kPostfix) + '.';
            break;

        case FieldAccess::OwnerKind::kAnonymousInterfaceBlock:
            if (f.base()->is<VariableReference>() &&
                field->fLayout.fBuiltin != SK_POINTSIZE_BUILTIN) {
                expr = this->variablePrefix(*f.base()->as<VariableReference>().variable());
            }
            break;
    }

    expr += this->assembleName(field->fName);
    return expr;
}

std::string WGSLCodeGenerator::assembleSimpleIntrinsic(std::string_view intrinsicName,
                                                       const FunctionCall& call,
                                                       bool wgslOnlySupportsHighPrecision) {
    // Invoke the function, passing each function argument.
    std::string expr = std::string(intrinsicName);
    expr.push_back('(');
    const ExpressionArray& args = call.arguments();
    auto separator = SkSL::String::Separator();
    for (int index = 0; index < args.size(); ++index) {
        expr += separator();

        std::string argument = this->assembleExpression(*args[index], Precedence::kSequence);
        if (wgslOnlySupportsHighPrecision && type_is_low_precision(args[index]->type(), fContext)) {
            // Add a cast to high precision
            SkASSERT(!args[index]->type().isAtomic());
            const std::string highPType = to_wgsl_type(fContext,
                                                       args[index]->type(),
                                                       /*layout=*/nullptr,
                                                       /*forceHighPrecision=*/true);
            expr += highPType + "(" + argument + ")";
        } else if (args[index]->type().isAtomic()) {
            // WGSL passes atomic values to intrinsics as pointers.
            expr += '&';
            expr += argument;
        } else {
            expr += argument;
        }
    }
    expr.push_back(')');

    // Wrap the call expression in a cast back to its low precision type if necessary.
    if (wgslOnlySupportsHighPrecision && type_is_low_precision(call.type(), fContext)) {
        const std::string lowPType = to_wgsl_type(fContext, call.type());
        expr = lowPType + "(" + expr + ")";
    }

    return expr;
}

std::string WGSLCodeGenerator::assembleVectorizedIntrinsic(std::string_view intrinsicName,
                                                           const FunctionCall& call) {
    SkASSERT(!call.type().isVoid());

    // Invoke the function, passing each function argument.
    std::string expr = std::string(intrinsicName);
    expr.push_back('(');

    auto separator = SkSL::String::Separator();
    const ExpressionArray& args = call.arguments();
    bool returnsVector = call.type().isVector();
    for (int index = 0; index < args.size(); ++index) {
        expr += separator();

        bool vectorize = returnsVector && args[index]->type().isScalar();
        if (vectorize) {
            expr += to_wgsl_type(fContext, call.type());
            expr.push_back('(');
        }

        expr += this->assembleExpression(*args[index], Precedence::kSequence);
        if (vectorize) {
            expr.push_back(')');
        }
    }
    expr.push_back(')');

    return expr;
}

std::string WGSLCodeGenerator::assembleUnaryOpIntrinsic(Operator op,
                                                        const FunctionCall& call,
                                                        Precedence parentPrecedence) {
    SkASSERT(!call.type().isVoid());

    bool needParens = Precedence::kPrefix >= parentPrecedence;

    std::string expr;
    if (needParens) {
        expr.push_back('(');
    }

    expr += operator_name(op);
    expr += this->assembleExpression(*call.arguments()[0], Precedence::kPrefix);

    if (needParens) {
        expr.push_back(')');
    }

    return expr;
}

std::string WGSLCodeGenerator::assembleBinaryOpIntrinsic(Operator op,
                                                         const FunctionCall& call,
                                                         Precedence parentPrecedence) {
    SkASSERT(!call.type().isVoid());

    Precedence precedence = op.getBinaryPrecedence();
    bool needParens = precedence >= parentPrecedence ||
                      binary_op_is_ambiguous_in_wgsl(op);
    std::string expr;
    if (needParens) {
        expr.push_back('(');
    }

    expr += this->assembleExpression(*call.arguments()[0], precedence);
    expr += operator_name(op);
    expr += this->assembleExpression(*call.arguments()[1], precedence);

    if (needParens) {
        expr.push_back(')');
    }

    return expr;
}

// Rewrite a WGSL intrinsic of the form "intrinsicName(in) -> struct" to the SkSL's
// "intrinsicName(in, outField) -> returnField", where outField and returnField are the names of the
// fields in the struct returned by the WGSL intrinsic.
std::string WGSLCodeGenerator::assembleOutAssignedIntrinsic(std::string_view intrinsicName,
                                                            std::string_view returnField,
                                                            std::string_view outField,
                                                            const FunctionCall& call) {
    SkASSERT(call.type().componentType().isNumber());
    SkASSERT(call.arguments().size() == 2);
    SkASSERT(call.function().parameters()[1]->modifierFlags() & ModifierFlag::kOut);

    // Invoke the intrinsic with the first parameter.
    std::string expr = std::string(intrinsicName);
    expr += "(";
    expr += this->assembleExpression(*call.arguments()[0], Precedence::kSequence);
    expr += ")";
    // In WGSL the intrinsic returns a struct; assign it to a local so that its fields can be
    // accessed multiple times.
    expr = this->writeScratchLet(expr);
    expr += ".";

    // Store the outField of `expr` to the intended "out" argument
    std::unique_ptr<LValue> lvalue = this->makeLValue(*call.arguments()[1]);
    if (!lvalue) {
        return "";
    }
    std::string outValue = expr;
    outValue += outField;
    this->writeLine(lvalue->store(outValue));

    // And return the expression accessing the returnField.
    expr += returnField;
    return expr;
}

std::pair<std::string, const char*> WGSLCodeGenerator::assemblePartialSampleCall(
        std::string_view functionName,
        const Type& type,
        const Expression& sampler,
        const Expression& coords) {
    // This function returns `functionName(inSampler_texture, inSampler_sampler, coords` without a
    // terminating comma or close-parenthesis. This allows the caller to add more arguments as
    // needed.
    std::string expr = std::string(functionName) + '(';
    if (sampler.type().typeKind() == Type::TypeKind::kSampler) {
        // Split combined texture+sampler into two args with suffixes.
        expr += this->assembleExpression(sampler, Precedence::kSequence);
        expr += kTextureSuffix;
        expr += ", ";
        expr += this->assembleExpression(sampler, Precedence::kSequence);
        expr += kSamplerSuffix;
        expr += ", ";
    } else {
        SkASSERT(sampler.type().typeKind() == Type::TypeKind::kTexture);
        // Pass through the texture expression without any extra suffix
        expr += this->assembleExpression(sampler, Precedence::kSequence);
        expr += ", ";
    }

    // Compute the sample coordinates, dividing out the Z if a vec3 was provided.
    SkASSERT(coords.type().isVector());
    if (coords.type().columns() == 3) {
        // The coordinates were passed as a vec3, so we need to emit `coords.xy / coords.z`.
        // This is a binary op applied to `coords` twice, so explicitly reapply the const eval
        // workaround with just it in mind.
        const bool coordsConst = ConstantFolder::GetConstantValueOrNull(coords);
        std::string vec3Coords = this->assembleExpression(coords, Precedence::kMultiplicative,
                                                          coordsConst ? kForceLet
                                                                      : kUsedMultipleTimes);
        expr += vec3Coords + ".xy / " + vec3Coords + ".z";
    } else {
        // The coordinates should be a plain vec2; emit the expression as-is.
        SkASSERT(coords.type().columns() == 2);
        expr += this->assembleExpression(coords, Precedence::kSequence);
    }

    // WGSL does not support f16 textures while all of SkSL's sample functions return "half4", so
    // add a cast back to f16 if necessary.
    if (type_is_low_precision(type, fContext)) {
        std::string lowPType = to_wgsl_type(fContext, type);
        return {lowPType + "(" + expr, "))"};
    } else {
        return {expr, ")"};
    }
}

std::string WGSLCodeGenerator::assembleComponentwiseMatrixBinary(const Type& leftType,
                                                                 const Type& rightType,
                                                                 const std::string& left,
                                                                 const std::string& right,
                                                                 Operator op) {
    bool leftIsMatrix = leftType.isMatrix();
    bool rightIsMatrix = rightType.isMatrix();
    const Type& matrixType = leftIsMatrix ? leftType : rightType;

    std::string expr = to_wgsl_type(fContext, matrixType) + '(';
    auto separator = String::Separator();
    int columns = matrixType.columns();
    for (int c = 0; c < columns; ++c) {
        expr += separator();
        expr += left;
        if (leftIsMatrix) {
            expr += '[';
            expr += std::to_string(c);
            expr += ']';
        }
        expr += op.operatorName();
        expr += right;
        if (rightIsMatrix) {
            expr += '[';
            expr += std::to_string(c);
            expr += ']';
        }
    }
    return expr + ')';
}

std::string WGSLCodeGenerator::assembleIntrinsicCall(const FunctionCall& call,
                                                     IntrinsicKind kind,
                                                     Precedence parentPrecedence) {
    // Be careful: WGSL 1.0 will reject any intrinsic calls which can be constant-evaluated to
    // infinity or nan with a compile error. If all arguments to an intrinsic are compile-time
    // constants (`all_arguments_constant`), it is safest to copy one argument into a scratch-let so
    // that the call will be seen as runtime-evaluated, which defuses the overflow checks.
    // Don't worry; a competent driver should still optimize it away. This was automatically handled
    // in appendExpression()'s AutoConstEvalWorkaround before this was reached.

    const ExpressionArray& arguments = call.arguments();
    switch (kind) {
        case k_workgroupUniformLoad_IntrinsicKind: {
            // WGSL 17.11.4: workgroupUniformLoad(p : ptr<workgroup, T>) -> T
            // The argument must be a pointer-addressable reference expression (variable reference,
            // struct field, or array element) rooted in a variable declared in the 'workgroup'
            // address space. Vector components (swizzles or indexed vector elements) and rvalues
            // are not addressable.
            std::string argument = this->assembleExpression(*arguments[0], Precedence::kSequence);
            return "workgroupUniformLoad(&" + argument + ")";
        }

        case k_atan_IntrinsicKind: {
            const char* name = (arguments.size() == 1) ? "atan" : "atan2";
            return this->assembleSimpleIntrinsic(name, call);
        }

        // Derivative functions in WGSL are only defined for full precision types
        case k_dFdx_IntrinsicKind:
            return this->assembleSimpleIntrinsic("dpdx", call,
                                                 /*wgslOnlySupportsHighPrecision=*/true);

        case k_dFdy_IntrinsicKind:
            // WSGL is only generated for Graphite, which does not use RTFlip so there's no need
            // to flip the Y derivatives either.
            SkASSERT(fContext.fConfig->fSettings.fForceNoRTFlip);
            return this->assembleSimpleIntrinsic("dpdy", call,
                                                 /*wgslOnlySupportsHighPrecision=*/true);

        case k_dot_IntrinsicKind: {
            if (arguments[0]->type().isScalar()) {
                return this->assembleBinaryOpIntrinsic(OperatorKind::STAR, call, parentPrecedence);
            }
            return this->assembleSimpleIntrinsic("dot", call);
        }
        case k_equal_IntrinsicKind:
            return this->assembleBinaryOpIntrinsic(OperatorKind::EQEQ, call, parentPrecedence);

        case k_faceforward_IntrinsicKind: {
            if (arguments[0]->type().isScalar()) {
                // select(-N, N, (I * Nref) < 0)
                fNeedsConstEvalWorkaround = false; // Disable for N, we'll handle it in I*Nref
                std::string N = this->assembleExpression(*arguments[0], Precedence::kPrefix,
                                                         kUsedMultipleTimes);
                const bool INrefConst = ConstantFolder::GetConstantValueOrNull(*arguments[1]) &&
                                        ConstantFolder::GetConstantValueOrNull(*arguments[2]);
                std::string I = this->assembleExpression(*arguments[1],
                                                         Precedence::kMultiplicative,
                                                         INrefConst ? kForceLet : kAuto);
                std::string Nref = this->assembleExpression(*arguments[2],
                                                            Precedence::kMultiplicative);
                return "select(-" + N + ", " + N + ", " + I + " * " + Nref + " < 0)";
            }
            return this->assembleSimpleIntrinsic("faceForward", call);
        }
        case k_frexp_IntrinsicKind:
            // SkSL frexp is "$genType fract = frexp($genType, out $genIType exp)" whereas WGSL
            // returns a struct with no out param: "let [fract, exp] = frexp($genType)".
            return this->assembleOutAssignedIntrinsic("frexp", "fract", "exp", call);

        case k_greaterThan_IntrinsicKind:
            return this->assembleBinaryOpIntrinsic(OperatorKind::GT, call, parentPrecedence);

        case k_greaterThanEqual_IntrinsicKind:
            return this->assembleBinaryOpIntrinsic(OperatorKind::GTEQ, call, parentPrecedence);

        case k_inverse_IntrinsicKind:
            return this->assembleInversePolyfill(call);

        case k_outerProduct_IntrinsicKind:
            return this->assembleOuterProductPolyfill(call);

        case k_inversesqrt_IntrinsicKind:
            return this->assembleSimpleIntrinsic("inverseSqrt", call);

        case k_lessThan_IntrinsicKind:
            return this->assembleBinaryOpIntrinsic(OperatorKind::LT, call, parentPrecedence);

        case k_lessThanEqual_IntrinsicKind:
            return this->assembleBinaryOpIntrinsic(OperatorKind::LTEQ, call, parentPrecedence);

        case k_matrixCompMult_IntrinsicKind: {
            std::string arg0 = this->assembleExpression(*arguments[0], Precedence::kPostfix,
                                                        kUsedMultipleTimes);
            std::string arg1 = this->assembleExpression(*arguments[1], Precedence::kPostfix,
                                                        kUsedMultipleTimes);
            return this->assembleComponentwiseMatrixBinary(arguments[0]->type(),
                                                           arguments[1]->type(),
                                                           arg0,
                                                           arg1,
                                                           OperatorKind::STAR);
        }
        case k_mix_IntrinsicKind: {
            const char* name = arguments[2]->type().componentType().isBoolean() ? "select" : "mix";
            return this->assembleVectorizedIntrinsic(name, call);
        }
        case k_mod_IntrinsicKind: {
            // WGSL has no intrinsic equivalent to `mod`. Synthesize `x - y * floor(x / y)`.
            // NOTE: While we are introducing a new binary op between two possible constant
            // expressions, it is consistent with the const-ness already handled by
            // AutoConstEvalWorkaround.
            std::string arg0 = this->assembleExpression(*arguments[0], Precedence::kAdditive,
                                                        kUsedMultipleTimes);
            std::string arg1 = this->assembleExpression(*arguments[1], Precedence::kAdditive,
                                                        kUsedMultipleTimes);
            return "(" + arg0 + " - " + arg1 + " * floor(" + arg0 + " / " + arg1 + "))";
        }

        case k_modf_IntrinsicKind:
            // SkSL modf is "$genType fract = modf($genType, out $genType whole)" whereas WGSL
            // returns a struct with no out param: "let [fract, whole] = modf($genType)".
            return this->assembleOutAssignedIntrinsic("modf", "fract", "whole", call);

        case k_normalize_IntrinsicKind: {
            const char* name = arguments[0]->type().isScalar() ? "sign" : "normalize";
            return this->assembleSimpleIntrinsic(name, call);
        }
        case k_not_IntrinsicKind:
            return this->assembleUnaryOpIntrinsic(OperatorKind::LOGICALNOT, call, parentPrecedence);

        case k_notEqual_IntrinsicKind:
            return this->assembleBinaryOpIntrinsic(OperatorKind::NEQ, call, parentPrecedence);

        case k_packHalf2x16_IntrinsicKind:
            return this->assembleSimpleIntrinsic("pack2x16float", call);

        case k_packSnorm2x16_IntrinsicKind:
            return this->assembleSimpleIntrinsic("pack2x16snorm", call);

        case k_packSnorm4x8_IntrinsicKind:
            return this->assembleSimpleIntrinsic("pack4x8snorm", call);

        case k_packUnorm2x16_IntrinsicKind:
            return this->assembleSimpleIntrinsic("pack2x16unorm", call);

        case k_packUnorm4x8_IntrinsicKind:
            return this->assembleSimpleIntrinsic("pack4x8unorm", call);

        case k_findLSB_IntrinsicKind: {
            // firstTrailingBit (and firstLeadingBit) return a type matching their input, but
            // findLSB and findMSB in SkSL return signed types. Add a cast if needed.
            std::string lsb = this->assembleSimpleIntrinsic("firstTrailingBit", call);
            return arguments[0]->type().componentType().isSigned() ? lsb :
                    (to_wgsl_type(fContext, call.type()) + "(" + lsb + ")");
        }

        case k_findMSB_IntrinsicKind: {
            std::string msb = this->assembleSimpleIntrinsic("firstLeadingBit", call);
            return arguments[0]->type().componentType().isSigned() ? msb :
                    (to_wgsl_type(fContext, call.type()) + "(" + msb + ")");
        }

        case k_bitCount_IntrinsicKind: {
            // countOneBits returns a type matching its input, but bitCount in SkSL returns a
            // signed type. Add a cast if needed.
            std::string bitCount = this->assembleSimpleIntrinsic("countOneBits", call);
            return arguments[0]->type().componentType().isSigned() ? bitCount :
                    (to_wgsl_type(fContext, call.type()) + "(" + bitCount + ")");
        }

        case k_floatBitsToInt_IntrinsicKind:
        case k_floatBitsToUint_IntrinsicKind:
        case k_intBitsToFloat_IntrinsicKind:
        case k_uintBitsToFloat_IntrinsicKind: {
            std::string outputType = to_wgsl_type(fContext, call.type());
            return this->assembleSimpleIntrinsic("bitcast<" + outputType + ">", call);
        }

        case k_roundEven_IntrinsicKind:
        case k_round_IntrinsicKind:
            // WGSL has no built-in roundEven(), but its round() is defined as:
            //     "When e lies halfway between integers k and k + 1, the result is k when k is
            //      even, and k + 1 when k is odd."
            // This is equivalent to GLSL's roundEven(). GLSL's round() is allowed to just match
            // roundEven().
            return this->assembleSimpleIntrinsic("round", call);

        case k_reflect_IntrinsicKind:
            if (arguments[0]->type().isScalar()) {
                // I - 2 * N * I * N
                // Manually override the auto const-eval workaround since both I and N are used
                // multiple times in new binary expressions.
                fNeedsConstEvalWorkaround = false;
                std::string I = this->assembleExpression(*arguments[0], Precedence::kMultiplicative,
                                                         kUsedMultipleTimes);
                // We force N into a let when it is constant, ensuring (2*N), (N*I), and (I*N)
                // avoid issues with const eval compilation failures. Technically if we were already
                // lifting I to a let, we could skip lifting N if we knew (2*N) would not overflow,
                // but this keeps logic simpler.
                AssembleMode mode = ConstantFolder::GetConstantValueOrNull(*arguments[1]) ?
                        kForceLet : kUsedMultipleTimes;
                std::string N = this->assembleExpression(*arguments[1], Precedence::kMultiplicative,
                                                         mode);
                return String::printf("(%s - 2 * %s * %s * %s)",
                                      I.c_str(), N.c_str(),
                                      I.c_str(), N.c_str());
            }
            return this->assembleSimpleIntrinsic("reflect", call);

        case k_refract_IntrinsicKind:
            if (arguments[0]->type().isScalar()) {
                // WGSL only implements refract for vectors; rather than reimplementing refract from
                // scratch, we can replace the call with `refract(float2(I,0), float2(N,0), eta).x`.
                std::string I = this->assembleExpression(*arguments[0], Precedence::kSequence);
                std::string N = this->assembleExpression(*arguments[1], Precedence::kSequence);
                std::string Eta = this->assembleExpression(*arguments[2], Precedence::kSequence);
                return String::printf("refract(vec2<%s>(%s, 0), vec2<%s>(%s, 0), %s).x",
                                      to_wgsl_type(fContext, arguments[0]->type()).c_str(),
                                      I.c_str(),
                                      to_wgsl_type(fContext, arguments[1]->type()).c_str(),
                                      N.c_str(),
                                      Eta.c_str());
            }
            return this->assembleSimpleIntrinsic("refract", call);

        case k_sample_IntrinsicKind: {
            // Determine if a bias argument was passed in.
            SkASSERT(arguments.size() == 2 || arguments.size() == 3);
            bool callIncludesBias = (arguments.size() == 3);
            std::string expr;
            const char* close;
            if (fProgram.fConfig->fSettings.fSharpenTextures || callIncludesBias) {
                // We need to supply a bias argument; this is a separate intrinsic in WGSL.
                std::tie(expr, close) = this->assemblePartialSampleCall("textureSampleBias",
                                                                        call.type(),
                                                                        *arguments[0],
                                                                        *arguments[1]);
                expr += ", ";
                if (callIncludesBias) {
                    expr += this->assembleExpression(*arguments[2], Precedence::kAdditive) +
                            " + ";
                }
                expr += skstd::to_string(fProgram.fConfig->fSettings.fSharpenTextures
                                                 ? kSharpenTexturesBias
                                                 : 0.0f);
            } else {
                // No bias is necessary, so we can call `textureSample` directly.
                std::tie(expr, close) = this->assemblePartialSampleCall("textureSample",
                                                                        call.type(),
                                                                        *arguments[0],
                                                                        *arguments[1]);

            }

            return expr + close;
        }
        case k_sampleLod_IntrinsicKind: {
            auto [expr, close] = this->assemblePartialSampleCall("textureSampleLevel",
                                                                 call.type(),
                                                                 *arguments[0],
                                                                 *arguments[1]);
            expr += ", " + this->assembleExpression(*arguments[2], Precedence::kSequence);

            return expr + close;
        }
        case k_sampleGrad_IntrinsicKind: {
            auto [expr, close] = this->assemblePartialSampleCall("textureSampleGrad",
                                                                 call.type(),
                                                                 *arguments[0],
                                                                 *arguments[1]);

            expr += ", " + this->assembleExpression(*arguments[2], Precedence::kSequence);
            expr += ", " + this->assembleExpression(*arguments[3], Precedence::kSequence);
            return expr + close;
        }

        case k_textureRead_IntrinsicKind: {
            // textureLoad takes a texture and coordinates. It does NOT take a sampler.
            // If we are passed a combined sampler, we must extract just the texture.
            std::string expr = "textureLoad(";

            expr += this->assembleTextureFromImageOrSampler(*arguments[0]);

            expr += ", ";
            expr += this->assembleExpression(*arguments[1], Precedence::kSequence);

            // We need to inject an extra argument for the mip-level. We don't plan on using mipmaps
            // in our storage textures, so we can just pass zero.
            expr += ", 0)";

            // WGSL does not support f16 textures while all of SkSL's sample functions return
            // "half4", so add a cast back to f16 if necessary.
            if (type_is_low_precision(call.type(), fContext)) {
                std::string lowPType = to_wgsl_type(fContext, call.type());
                return lowPType + "(" + expr + ")";
            }

            return expr;
        }
        case k_textureSize_IntrinsicKind:
        case k_textureWidth_IntrinsicKind:
        case k_textureHeight_IntrinsicKind: {
            std::string expr = "textureDimensions(";

            // Use our helper to safely extract the texture
            expr += this->assembleTextureFromImageOrSampler(*arguments[0]);

            expr += ")";
            if (kind == k_textureWidth_IntrinsicKind) {
                expr += ".x";
            } else if (kind == k_textureHeight_IntrinsicKind) {
                expr += ".y";
            }
            return expr;
        }
        case k_textureWrite_IntrinsicKind:
            return this->assembleSimpleIntrinsic("textureStore", call,
                                                 /*wgslOnlySupportsHighPrecision=*/true);

        case k_unpackHalf2x16_IntrinsicKind:
            return this->assembleSimpleIntrinsic("unpack2x16float", call);

        case k_unpackSnorm2x16_IntrinsicKind:
            return this->assembleSimpleIntrinsic("unpack2x16snorm", call);

        case k_unpackSnorm4x8_IntrinsicKind:
            return this->assembleSimpleIntrinsic("unpack4x8snorm", call);

        case k_unpackUnorm2x16_IntrinsicKind:
            return this->assembleSimpleIntrinsic("unpack2x16unorm", call);

        case k_unpackUnorm4x8_IntrinsicKind:
            return this->assembleSimpleIntrinsic("unpack4x8unorm", call);

        case k_clamp_IntrinsicKind:
        case k_max_IntrinsicKind:
        case k_min_IntrinsicKind:
        case k_smoothstep_IntrinsicKind:
        case k_step_IntrinsicKind:
            return this->assembleVectorizedIntrinsic(call.function().name(), call);

        case k_abs_IntrinsicKind:
        case k_acos_IntrinsicKind:
        case k_all_IntrinsicKind:
        case k_any_IntrinsicKind:
        case k_asin_IntrinsicKind:
        case k_atomicAdd_IntrinsicKind:
        case k_atomicLoad_IntrinsicKind:
        case k_atomicMax_IntrinsicKind:
        case k_atomicMin_IntrinsicKind:
        case k_atomicStore_IntrinsicKind:
        case k_ceil_IntrinsicKind:
        case k_cos_IntrinsicKind:
        case k_cross_IntrinsicKind:
        case k_degrees_IntrinsicKind:
        case k_distance_IntrinsicKind:
        case k_exp_IntrinsicKind:
        case k_exp2_IntrinsicKind:
        case k_floor_IntrinsicKind:
        case k_fract_IntrinsicKind:
        case k_length_IntrinsicKind:
        case k_log_IntrinsicKind:
        case k_log2_IntrinsicKind:
        case k_radians_IntrinsicKind:
        case k_pow_IntrinsicKind:
        case k_saturate_IntrinsicKind:
        case k_sign_IntrinsicKind:
        case k_sin_IntrinsicKind:
        case k_sqrt_IntrinsicKind:
        case k_storageBarrier_IntrinsicKind:
        case k_tan_IntrinsicKind:
        case k_workgroupBarrier_IntrinsicKind:
        default:
            return this->assembleSimpleIntrinsic(call.function().name(), call);
    }
}

static std::string generate_inverse2x2(const char* scalarName, const char* suffix) {
    return SkSL::String::printf(
            "fn inverse_2x2%s(m: mat2x2<%s>) -> mat2x2<%s> {\n"
                "return mat2x2<%s>(m[1].y, -m[0].y, -m[1].x, m[0].x) * (1/determinant(m));\n"
            "}\n", suffix, scalarName, scalarName, scalarName);
}

static std::string generate_inverse3x3(const char* scalarName, const char* suffix) {
    return SkSL::String::printf(
            "fn inverse_3x3%s(m: mat3x3<%s>) -> mat3x3<%s> {\n"
                "let a00 = m[0].x; let a01 = m[0].y; let a02 = m[0].z;\n"
                "let a10 = m[1].x; let a11 = m[1].y; let a12 = m[1].z;\n"
                "let a20 = m[2].x; let a21 = m[2].y; let a22 = m[2].z;\n"
                "let b01 =  a22*a11 - a12*a21;\n"
                "let b11 = -a22*a10 + a12*a20;\n"
                "let b21 =  a21*a10 - a11*a20;\n"
                "let det = a00*b01 + a01*b11 + a02*b21;\n"
                "return mat3x3<%s>(b01, (-a22*a01 + a02*a21), ( a12*a01 - a02*a11),\n"
                                  "b11, ( a22*a00 - a02*a20), (-a12*a00 + a02*a10),\n"
                                  "b21, (-a21*a00 + a01*a20), ( a11*a00 - a01*a10)) * (1/det);\n"
            "}\n", suffix, scalarName, scalarName, scalarName);
}

static std::string generate_inverse4x4(const char* scalarName, const char* suffix) {
    return SkSL::String::printf(
            "fn inverse_4x4%s(m: mat4x4<%s>) -> mat4x4<%s>{\n"
                "let a00 = m[0].x; let a01 = m[0].y; let a02 = m[0].z; let a03 = m[0].w;\n"
                "let a10 = m[1].x; let a11 = m[1].y; let a12 = m[1].z; let a13 = m[1].w;\n"
                "let a20 = m[2].x; let a21 = m[2].y; let a22 = m[2].z; let a23 = m[2].w;\n"
                "let a30 = m[3].x; let a31 = m[3].y; let a32 = m[3].z; let a33 = m[3].w;\n"
                "let b00 = a00*a11 - a01*a10;\n"
                "let b01 = a00*a12 - a02*a10;\n"
                "let b02 = a00*a13 - a03*a10;\n"
                "let b03 = a01*a12 - a02*a11;\n"
                "let b04 = a01*a13 - a03*a11;\n"
                "let b05 = a02*a13 - a03*a12;\n"
                "let b06 = a20*a31 - a21*a30;\n"
                "let b07 = a20*a32 - a22*a30;\n"
                "let b08 = a20*a33 - a23*a30;\n"
                "let b09 = a21*a32 - a22*a31;\n"
                "let b10 = a21*a33 - a23*a31;\n"
                "let b11 = a22*a33 - a23*a32;\n"
                "let det = b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06;\n"
                "return mat4x4<%s>(a11*b11 - a12*b10 + a13*b09,\n"
                                  "a02*b10 - a01*b11 - a03*b09,\n"
                                  "a31*b05 - a32*b04 + a33*b03,\n"
                                  "a22*b04 - a21*b05 - a23*b03,\n"
                                  "a12*b08 - a10*b11 - a13*b07,\n"
                                  "a00*b11 - a02*b08 + a03*b07,\n"
                                  "a32*b02 - a30*b05 - a33*b01,\n"
                                  "a20*b05 - a22*b02 + a23*b01,\n"
                                  "a10*b10 - a11*b08 + a13*b06,\n"
                                  "a01*b08 - a00*b10 - a03*b06,\n"
                                  "a30*b04 - a31*b02 + a33*b00,\n"
                                  "a21*b02 - a20*b04 - a23*b00,\n"
                                  "a11*b07 - a10*b09 - a12*b06,\n"
                                  "a00*b09 - a01*b07 + a02*b06,\n"
                                  "a31*b01 - a30*b03 - a32*b00,\n"
                                  "a20*b03 - a21*b01 + a22*b00) * (1/det);\n"
            "}\n", suffix, scalarName, scalarName, scalarName);
}

// Generates outer_product_$Cx$R(vec$R<f32}>, vec$C<f32>) -> mat$Cx$R<f32> or its f16 variant.
static std::string gen_outer_product_fn(const char* scalarName, const char* suffix, int c, int r) {
    return String::printf(
            "fn outer_product_%dx%d%s(a: vec%d<%s>, b: vec%d<%s>) -> mat%dx%d<%s> {\n"
                "var m : mat%dx%d<%s>;\n"
                "for (var c = 0; c < %d; c++) { m[c] = a * b[c]; }\n"
                "return m;\n"
            "}\n",
            /* outer_product_$Cx$R$s */ c, r, suffix,
            /* vec$R */ r, scalarName,
            /* vec$C */ c, scalarName,
            /* mat$Cx$R */ c, r, scalarName,
            /* mat$Cx$R */ c, r, scalarName,
            /* c < $C */ c);
}

std::string WGSLCodeGenerator::assembleInversePolyfill(const FunctionCall& call) {
    const ExpressionArray& arguments = call.arguments();
    const Type& type = arguments.front()->type();

    // The `inverse` intrinsic should only accept a single-argument square matrix.
    // Once we implement f16 support, these polyfills will need to be updated to support `hmat`;
    // for the time being, all floats in WGSL are f32, so we don't need to worry about precision.
    SkASSERT(arguments.size() == 1);
    SkASSERT(type.isMatrix());
    SkASSERT(type.rows() == type.columns());

    const bool useF16 = type_is_low_precision(type, fContext);
    WrittenPolyfills* polyfill = useF16 ? &fF16Polyfills : &fF32Polyfills;
    const char* typeName       = useF16 ? "f16"          : "f32";
    const char* suffix         = useF16 ? "h"            : "f";

    const int idx = type.rows() - 2;
    if (!polyfill->fInverse[idx]) {
        using InverseGenFn = std::string(*)(const char*, const char*);
        static constexpr std::array<InverseGenFn, 3> kTemplates{generate_inverse2x2,
                                                                generate_inverse3x3,
                                                                generate_inverse4x4};
        polyfill->fInverse[idx] = true;
        fHeader.writeText(kTemplates[idx](typeName, suffix).c_str());
    }
    return this->assembleSimpleIntrinsic(String::printf("inverse_%dx%d%s",
                                                        type.rows(), type.columns(), suffix), call);
}

std::string WGSLCodeGenerator::assembleOuterProductPolyfill(const FunctionCall& call) {
    // The outer product should take two vector arguments, with the first type's component count
    // defining R and the second type's component count defining C.
    const ExpressionArray& arguments = call.arguments();
    SkASSERT(arguments.size() == 2);
    SkASSERT(arguments[0]->type().isVector() && arguments[1]->type().isVector());
    SkASSERT(call.type().isMatrix());

    const int r = arguments[0]->type().columns();
    const int c = arguments[1]->type().columns();
    SkASSERT(r == call.type().rows() && c == call.type().columns());

    const bool useF16 = type_is_low_precision(call.type(), fContext);
    WrittenPolyfills* polyfill = useF16 ? &fF16Polyfills : &fF32Polyfills;
    const char* typeName       = useF16 ? "f16"          : "f32";
    const char* suffix         = useF16 ? "h"            : "f";

    const int cIdx = c - 2;
    const int rIdx = r - 2;
    if (!polyfill->fOuterProduct[cIdx][rIdx]) {
        polyfill->fOuterProduct[cIdx][rIdx] = true;
        fHeader.writeText(gen_outer_product_fn(typeName, suffix, c, r).c_str());
    }

    return this->assembleSimpleIntrinsic(String::printf("outer_product_%dx%d%s",
                                                        c, r, suffix), call);
}

std::string WGSLCodeGenerator::assembleFunctionCall(const FunctionCall& call,
                                                    Precedence parentPrecedence) {
    const FunctionDeclaration& func = call.function();
    std::string result;

    // Helper for wrapping user and intrinsic function calls that might have side effects.
    auto emitCall = [&](const std::string& expr, bool forceLet=false) {
        if (call.type().isVoid() || parentPrecedence >= Precedence::kStatement) {
            // If this is true, the assembled expression won't be used directly by the caller, so we
            // need to write it out as its own statement to preserve any side effects.
            SkASSERT(parentPrecedence >= Precedence::kSequence);
            this->write(expr);
            this->writeLine(";");
            return std::string(); // Will be unused
        } else if (forceLet) {
            // The function call is used by the caller, but we need to write the actual call *now*
            // before additional statements.
            return this->writeScratchLet(expr);
        } else {
            // Can inline the call's expression into the caller's expression
            return expr;
        }
    };

    // Many intrinsics need to be rewritten in WGSL.
    if (func.isIntrinsic()) {
        return emitCall(this->assembleIntrinsicCall(call, func.intrinsicKind(), parentPrecedence));
    }

    // We implement function out-parameters by declaring them as pointers. SkSL follows GLSL's
    // out-parameter semantics, in which out-parameters are only written back to the original
    // variable after the function's execution is complete (see
    // https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Parameters).
    //
    // In addition, SkSL supports swizzles and array index expressions to be passed into
    // out-parameters; however, WGSL does not allow taking their address into a pointer.
    //
    // We support these by using LValues to create temporary copies and then pass pointers to the
    // copies. Once the function returns, we copy the values back to the LValue.

    // First detect which arguments are passed to out-parameters.
    // TODO: rewrite this method in terms of LValues.
    const ExpressionArray& args = call.arguments();
    SkSpan<Variable* const> params = func.parameters();
    SkASSERT(SkToSizeT(args.size()) == params.size());

    STArray<16, std::unique_ptr<LValue>> writeback;
    STArray<16, std::string> substituteArgument;
    writeback.reserve_exact(args.size());
    substituteArgument.reserve_exact(args.size());

    bool needsWriteback = false;
    for (int index = 0; index < args.size(); ++index) {
        if (params[index]->modifierFlags() & ModifierFlag::kOut) {
            std::unique_ptr<LValue> lvalue = this->makeLValue(*args[index]);
            if (lvalue) {
                if (params[index]->modifierFlags() & ModifierFlag::kIn) {
                    // Load the lvalue's contents into the substitute argument.
                    substituteArgument.push_back(this->writeScratchVar(args[index]->type(),
                                                                       lvalue->load()));
                } else {
                    // Create a substitute argument, but leave it uninitialized.
                    substituteArgument.push_back(this->writeScratchVar(args[index]->type()));
                }
                writeback.push_back(std::move(lvalue));
                needsWriteback = true;
            } else {
                substituteArgument.push_back(std::string());
                writeback.push_back(nullptr);
            }
        } else {
            substituteArgument.push_back(std::string());
            writeback.push_back(nullptr);
        }
    }

    std::string expr = this->assembleName(func.mangledName());
    expr.push_back('(');
    auto separator = SkSL::String::Separator();

    if (std::string funcDepArgs = this->functionDependencyArgs(func); !funcDepArgs.empty()) {
        expr += funcDepArgs;
        separator();
    }

    // Pass the function arguments, or any substitutes as needed.
    for (int index = 0; index < args.size(); ++index) {
        expr += separator();
        if (!substituteArgument[index].empty()) {
            // We need to take the address of the variable and pass it down as a pointer.
            expr += '&' + substituteArgument[index];
        } else if (args[index]->type().isSampler()) {
            // If the argument is a sampler, we need to pass the texture _and_ its associated
            // sampler. (Function parameter lists also convert sampler parameters into a matching
            // texture/sampler parameter pair.)
            expr += this->assembleExpression(*args[index], Precedence::kSequence);
            expr += kTextureSuffix;
            expr += ", ";
            expr += this->assembleExpression(*args[index], Precedence::kSequence);
            expr += kSamplerSuffix;
        } else if (args[index]->type().isUnsizedArray()) {
            // If the array is in the parameter storage space then manually just pass it through
            // since it is already a pointer.
            if (args[index]->is<VariableReference>()) {
                const Variable* v = args[index]->as<VariableReference>().variable();
                // A variable reference to an unsized array should always be a parameter,
                // because unsized arrays coming from uniforms will have the `FieldAccess`
                // expression type.
                SkASSERT(v->storage() == Variable::Storage::kParameter);
                expr += this->assembleName(v->mangledName());
            } else {
                expr += "&(" + this->assembleExpression(*args[index], Precedence::kSequence) + ")";
            }
        } else {
            expr += this->assembleExpression(*args[index], Precedence::kSequence);
        }
    }
    expr += ')';

    // If we have to write substitutions after the function call, we have to force the function call
    // into a scratch let so that variable can be returned as the expression.
    result = emitCall(expr, /*forceLet=*/needsWriteback);

    if (needsWriteback) {
        for (int index = 0; index < args.size(); ++index) {
            if (!substituteArgument[index].empty()) {
                this->writeLine(writeback[index]->store(substituteArgument[index]));
            }
        }
    }

    // Return the result of invoking the function.
    return result;
}

std::string WGSLCodeGenerator::assembleIndexExpression(const IndexExpression& i) {
    // Put the index value into a let-expression.
    std::string idx = this->assembleExpression(*i.index(), Precedence::kExpression,
                                               kUsedMultipleTimes);
    return this->assembleExpression(*i.base(), Precedence::kPostfix) + "[" + idx + "]";
}

std::string WGSLCodeGenerator::assembleLiteral(const Literal& l) {
    const Type& type = l.type();
    if (type.isFloat() || type.isBoolean()) {
        std::string value = l.description(OperatorPrecedence::kExpression);
        if (type_is_low_precision(type, fContext)) {
            SkASSERT(type.isFloat());
            value += "h";
        }
        return value;
    }
    SkASSERT(type.isInteger());
    if (type.matches(*fContext.fTypes.fUInt)) {
        return std::to_string(l.intValue() & 0xffffffff) + "u";
    } else if (type.matches(*fContext.fTypes.fUShort)) {
        return std::to_string(l.intValue() & 0xffff) + "u";
    } else {
        return std::to_string(l.intValue());
    }
}

std::string WGSLCodeGenerator::assembleIncrementExpr(const Type& type) {
    // `type(`
    std::string expr = to_wgsl_type(fContext, type);
    expr.push_back('(');

    // `1, 1, 1...)`
    auto separator = SkSL::String::Separator();
    for (int slots = type.slotCount(); slots > 0; --slots) {
        expr += separator();
        expr += "1";
    }
    expr.push_back(')');
    return expr;
}

std::string WGSLCodeGenerator::assemblePrefixExpression(const PrefixExpression& p,
                                                        Precedence parentPrecedence) {
    // Unary + does nothing, so we omit it from the output.
    Operator op = p.getOperator();
    if (op.kind() == Operator::Kind::PLUS) {
        return this->assembleExpression(*p.operand(), Precedence::kPrefix);
    }

    // Pre-increment/decrement expressions have no direct equivalent in WGSL.
    if (op.kind() == Operator::Kind::PLUSPLUS || op.kind() == Operator::Kind::MINUSMINUS) {
        std::unique_ptr<LValue> lvalue = this->makeLValue(*p.operand());
        if (!lvalue) {
            return "";
        }

        // Generate the new value: `lvalue + type(1, 1, 1...)`.
        std::string newValue =
                lvalue->load() +
                (p.getOperator().kind() == Operator::Kind::PLUSPLUS ? " + " : " - ") +
                this->assembleIncrementExpr(p.operand()->type());
        this->writeLine(lvalue->store(newValue));
        return lvalue->load();
    }

    // WGSL natively supports unary negation/not expressions (!,~,-).
    SkASSERT(op.kind() == OperatorKind::LOGICALNOT ||
             op.kind() == OperatorKind::BITWISENOT ||
             op.kind() == OperatorKind::MINUS);

    // The unary negation operator only applies to scalars and vectors. For other mathematical
    // objects (such as matrices) we can express it as a multiplication by -1.
    std::string expr;
    const bool needsNegation = op.kind() == Operator::Kind::MINUS &&
                               !p.operand()->type().isScalar() && !p.operand()->type().isVector();
    const bool needParens = needsNegation || Precedence::kPrefix >= parentPrecedence;

    if (needParens) {
        expr.push_back('(');
    }

    if (needsNegation) {
        expr += "-1.0 * ";
        expr += this->assembleExpression(*p.operand(), Precedence::kMultiplicative);
    } else {
        expr += p.getOperator().tightOperatorName();
        expr += this->assembleExpression(*p.operand(), Precedence::kPrefix);
    }

    if (needParens) {
        expr.push_back(')');
    }

    return expr;
}

std::string WGSLCodeGenerator::assemblePostfixExpression(const PostfixExpression& p,
                                                         Precedence parentPrecedence) {
    SkASSERT(p.getOperator().kind() == Operator::Kind::PLUSPLUS ||
             p.getOperator().kind() == Operator::Kind::MINUSMINUS);

    // Post-increment/decrement expressions have no direct equivalent in WGSL; they do exist as a
    // standalone statement for convenience, but these aren't the same as SkSL's post-increments.
    std::unique_ptr<LValue> lvalue = this->makeLValue(*p.operand());
    if (!lvalue) {
        return "";
    }

    // If the expression is used, create a let-copy of the original value.
    // (At statement-level precedence, we know the value is unused and can skip this let-copy.)
    std::string originalValue;
    if (parentPrecedence != Precedence::kStatement) {
        originalValue = this->writeScratchLet(lvalue->load());
    }
    // Generate the new value: `lvalue + type(1, 1, 1...)`.
    std::string newValue = lvalue->load() +
                           (p.getOperator().kind() == Operator::Kind::PLUSPLUS ? " + " : " - ") +
                           this->assembleIncrementExpr(p.operand()->type());
    this->writeLine(lvalue->store(newValue));

    return originalValue;
}

std::string WGSLCodeGenerator::assembleSwizzle(const Swizzle& swizzle) {
    return this->assembleExpression(*swizzle.base(), Precedence::kPostfix) + "." +
           Swizzle::MaskString(swizzle.components());
}

std::string WGSLCodeGenerator::writeScratchVar(const Type& type, const std::string& value) {
    std::string scratchVarName = "_skTemp" + std::to_string(fScratchCount++);
    this->write("var ");
    this->write(scratchVarName);
    this->write(": ");
    this->write(to_wgsl_type(fContext, type));
    if (!value.empty()) {
        this->write(" = ");
        this->write(value);
    }
    this->writeLine(";");
    return scratchVarName;
}

std::string WGSLCodeGenerator::writeScratchLet(const std::string& expr,
                                               bool isCompileTimeConstant) {
    std::string scratchVarName = "_skTemp" + std::to_string(fScratchCount++);
    this->write(fAtFunctionScope && !isCompileTimeConstant ? "let " : "const ");
    this->write(scratchVarName);
    this->write(" = ");
    this->write(expr);
    this->writeLine(";");
    return scratchVarName;
}

std::string WGSLCodeGenerator::assembleTernaryExpression(const TernaryExpression& t,
                                                         Precedence parentPrecedence) {
    std::string expr;

    // The trivial case is when neither branch has side effects and evaluate to a scalar or vector
    // type. This can be represented with a call to the WGSL `select` intrinsic. Select doesn't
    // support short-circuiting, so we should only use it when both the true- and false-expressions
    // are trivial to evaluate.
    if ((t.type().isScalar() || t.type().isVector()) &&
        !Analysis::HasSideEffects(*t.test()) &&
        Analysis::IsTrivialExpression(*t.ifTrue()) &&
        Analysis::IsTrivialExpression(*t.ifFalse())) {

        bool needParens = Precedence::kTernary >= parentPrecedence;
        if (needParens) {
            expr.push_back('(');
        }
        expr += "select(";
        expr += this->assembleExpression(*t.ifFalse(), Precedence::kSequence);
        expr += ", ";
        expr += this->assembleExpression(*t.ifTrue(), Precedence::kSequence);
        expr += ", ";

        bool isVector = t.type().isVector();
        if (isVector) {
            // Splat the condition expression into a vector.
            expr += String::printf("vec%d<bool>(", t.type().columns());
        }
        expr += this->assembleExpression(*t.test(), Precedence::kSequence);
        if (isVector) {
            expr.push_back(')');
        }
        expr.push_back(')');
        if (needParens) {
            expr.push_back(')');
        }
    } else {
        // WGSL does not support ternary expressions. Instead, we hoist the expression out into the
        // surrounding block, convert it into an if statement, and write the result to a synthesized
        // variable. Instead of the original expression, we return that variable.
        expr = this->writeScratchVar(t.ifTrue()->type());

        std::string testExpr = this->assembleExpression(*t.test(), Precedence::kExpression);
        this->write("if ");
        this->write(testExpr);
        this->writeLine(" {");

        ++fIndentation;
        std::string trueExpr = this->assembleExpression(*t.ifTrue(), Precedence::kAssignment);
        this->write(expr);
        this->write(" = ");
        this->write(trueExpr);
        this->writeLine(";");
        --fIndentation;

        this->writeLine("} else {");

        ++fIndentation;
        std::string falseExpr = this->assembleExpression(*t.ifFalse(), Precedence::kAssignment);
        this->write(expr);
        this->write(" = ");
        this->write(falseExpr);
        this->writeLine(";");
        --fIndentation;

        this->writeLine("}");
    }
    return expr;
}

std::string WGSLCodeGenerator::variablePrefix(const Variable& v) {
    if (v.storage() == Variable::Storage::kGlobal) {
        // If the field refers to a pipeline IO parameter, then we access it via the synthesized IO
        // structs. We make an explicit exception for `sk_PointSize` which we declare as a
        // placeholder variable in global scope as it is not supported by WebGPU as a pipeline IO
        // parameter (see comments in `writeStageOutputStruct`).
        if (v.modifierFlags() & ModifierFlag::kIn) {
            return "_stageIn.";
        }
        if (v.modifierFlags() & ModifierFlag::kOut) {
            return "(*_stageOut).";
        }

        // If the field refers to an anonymous-interface-block structure, access it via the
        // synthesized `_uniform0` or `_storage1` global.
        if (const InterfaceBlock* ib = v.interfaceBlock()) {
            const Type& ibType = ib->var()->type().componentType();
            if (const std::string* ibName = fInterfaceBlockNameMap.find(&ibType)) {
                return *ibName + '.';
            }
        }

        // If the field refers to an top-level uniform, access it via the synthesized
        // `_globalUniforms` global. (Note that this should only occur in test code; Skia will
        // always put uniforms in an interface block.)
        if (is_in_global_uniforms(v)) {
            return "_globalUniforms.";
        }
    }

    return "";
}

std::string WGSLCodeGenerator::variableReferenceNameForLValue(const VariableReference& r) {
    const Variable& v = *r.variable();

    if (v.storage() == Variable::Storage::kParameter &&
         (v.modifierFlags() & ModifierFlag::kOut || v.type().isUnsizedArray())) {
        // This is an out-parameter or unsized array parameter; it's pointer-typed, so we need to
        // dereference it. We wrap the dereference in parentheses, in case the value is used in an
        // access expression later.
        return "(*" + this->assembleName(v.mangledName()) + ')';
    }

    if (is_in_global_uniforms(v)) {
        // Assemble polyfill access (see assembleFieldAccess)
        SkASSERT(fSyntheticGlobalUniformsBlock);
        FieldPolyfillInfo* polyfillInfo = nullptr;
        const Type& globalStruct = fSyntheticGlobalUniformsBlock->var()->type().componentType();
        for (const Field& f : globalStruct.fields()) {
            if (f.fName == v.name()) {
                polyfillInfo = fFieldPolyfillMap.find(&f);
                break;
            }
        }

        if (polyfillInfo) {
            // We found a global variable declaration that had to be polyfilled, so switch to its
            // replacement expression. This is simpler than assembleFieldAccess() because we don't
            // need to worry about index expressions.
            polyfillInfo->fWasAccessed = true;
            return polyfillInfo->fReplacementName;
        }

        // Fall through for a regular global variable access
    }

    return this->variablePrefix(v) + this->assembleName(v.mangledName());
}

std::string WGSLCodeGenerator::assembleVariableReference(const VariableReference& r) {
    // TODO(b/294274678): Correctly handle RTFlip for built-ins.
    const Variable& v = *r.variable();

    // Insert a conversion expression if this is a built-in variable whose type differs from the
    // SkSL.
    std::string expr;
    std::optional<std::string_view> conversion = needs_builtin_type_conversion(v);
    if (conversion.has_value()) {
        expr += *conversion;
        expr.push_back('(');
    }

    expr += this->variableReferenceNameForLValue(r);

    if (conversion.has_value()) {
        expr.push_back(')');
    }

    return expr;
}

std::string WGSLCodeGenerator::assembleAnyConstructor(const AnyConstructor& c) {
    std::string expr = to_wgsl_type(fContext, c.type());
    expr.push_back('(');
    auto separator = SkSL::String::Separator();
    for (const auto& e : c.argumentSpan()) {
        expr += separator();
        expr += this->assembleExpression(*e, Precedence::kSequence);
    }
    expr.push_back(')');
    return expr;
}

std::string WGSLCodeGenerator::assembleConstructorCompound(const ConstructorCompound& c) {
    if (c.type().isVector()) {
        return this->assembleConstructorCompoundVector(c);
    } else if (c.type().isMatrix()) {
        return this->assembleConstructorCompoundMatrix(c);
    } else {
        fContext.fErrors->error(c.fPosition, "unsupported compound constructor");
        return {};
    }
}

std::string WGSLCodeGenerator::assembleConstructorCompoundVector(const ConstructorCompound& c) {
    // WGSL supports constructing vectors from a mix of scalars and vectors but
    // not matrices (see https://www.w3.org/TR/WGSL/#type-constructor-expr).
    //
    // SkSL supports vec4(mat2x2) which we handle specially.
    if (c.type().columns() == 4 && c.argumentSpan().size() == 1) {
        const Expression& arg = *c.argumentSpan().front();
        if (arg.type().isMatrix()) {
            SkASSERT(arg.type().columns() == 2);
            SkASSERT(arg.type().rows() == 2);

            std::string matrix = this->assembleExpression(arg, Precedence::kPostfix,
                                                          kUsedMultipleTimes);
            return String::printf("%s(%s[0], %s[1])", to_wgsl_type(fContext, c.type()).c_str(),
                                                      matrix.c_str(),
                                                      matrix.c_str());
        }
    }
    return this->assembleAnyConstructor(c);
}

std::string WGSLCodeGenerator::assembleConstructorCompoundMatrix(const ConstructorCompound& ctor) {
    SkASSERT(ctor.type().isMatrix());

    std::string expr = to_wgsl_type(fContext, ctor.type()) + '(';
    auto separator = String::Separator();
    for (const std::unique_ptr<Expression>& arg : ctor.arguments()) {
        SkASSERT(arg->type().isScalar() || arg->type().isVector());

        if (arg->type().isScalar()) {
            expr += separator();
            expr += this->assembleExpression(*arg, Precedence::kSequence);
        } else {
            std::string inner = this->assembleExpression(*arg, Precedence::kSequence,
                                                         kUsedMultipleTimes);
            int numSlots = arg->type().slotCount();
            for (int slot = 0; slot < numSlots; ++slot) {
                String::appendf(&expr, "%s%s[%d]", separator().c_str(), inner.c_str(), slot);
            }
        }
    }
    return expr + ')';
}

std::string WGSLCodeGenerator::assembleConstructorDiagonalMatrix(
        const ConstructorDiagonalMatrix& c) {
    const Type& type = c.type();
    SkASSERT(type.isMatrix());
    SkASSERT(c.argument()->type().isScalar());

    // Evaluate the inner-expression, creating a scratch variable if necessary.
    std::string inner = this->assembleExpression(*c.argument(), Precedence::kAssignment,
                                                 kUsedMultipleTimes);

    // Assemble a diagonal-matrix expression.
    std::string expr = to_wgsl_type(fContext, type) + '(';
    auto separator = String::Separator();
    for (int col = 0; col < type.columns(); ++col) {
        for (int row = 0; row < type.rows(); ++row) {
            expr += separator();
            if (col == row) {
                expr += inner;
            } else {
                expr += "0.0";
            }
        }
    }
    return expr + ')';
}

std::string WGSLCodeGenerator::assembleConstructorMatrixResize(
        const ConstructorMatrixResize& ctor) {
    std::string source = this->assembleExpression(*ctor.argument(), Precedence::kSequence,
                                                  kUsedMultipleTimes);
    int columns = ctor.type().columns();
    int rows = ctor.type().rows();
    int sourceColumns = ctor.argument()->type().columns();
    int sourceRows = ctor.argument()->type().rows();
    auto separator = String::Separator();
    std::string expr = to_wgsl_type(fContext, ctor.type()) + '(';

    for (int c = 0; c < columns; ++c) {
        for (int r = 0; r < rows; ++r) {
            expr += separator();
            if (c < sourceColumns && r < sourceRows) {
                String::appendf(&expr, "%s[%d][%d]", source.c_str(), c, r);
            } else if (r == c) {
                expr += "1.0";
            } else {
                expr += "0.0";
            }
        }
    }

    return expr + ')';
}

std::string WGSLCodeGenerator::assembleConstructorArrayCast(const ConstructorArrayCast& ctor,
                                                            Precedence parentPrecedence) {
    SkASSERT(!ctor.type().isUnsizedArray()); // Can't iterate over unbounded elements

    // Our SkSL -> WGSL conversion only distinguishes f16 and f32, so any other array cast turns
    // into equivalent types in WGSL. Check the component type of the ctor and arg, since those are
    // both array types, which has to be peeled away.
    if (to_wgsl_type(fContext, ctor.type().componentType()) ==
        to_wgsl_type(fContext, ctor.argument()->type().componentType())) {
        return this->assembleExpression(*ctor.argument(), parentPrecedence);
    }

    // Construct a new array of the ctor's type
    std::string expr = to_wgsl_type(fContext, ctor.type());
    expr += "(";

    std::string elemType = to_wgsl_type(fContext, ctor.type().componentType());
    std::string arrayArg = this->assembleExpression(*ctor.argument(),
                                                    Precedence::kPostfix,
                                                    AssembleMode::kUsedMultipleTimes);

    // Each value of the new array is a cast of an element from the ctor's argument.
    int arrayLen = ctor.type().columns();
    auto separator = String::Separator();
    for (int i = 0; i < arrayLen; ++i) {
        expr += separator();
        String::appendf(&expr, "%s(%s[%d])", elemType.c_str(), arrayArg.c_str(), i);
    }

    expr += ")";
    return expr;
}

std::string WGSLCodeGenerator::assembleEqualityExpression(const Type& left,
                                                          const std::string& leftName,
                                                          const Type& right,
                                                          const std::string& rightName,
                                                          Operator op,
                                                          Precedence parentPrecedence) {
    SkASSERT(op.kind() == OperatorKind::EQEQ || op.kind() == OperatorKind::NEQ);

    std::string expr;
    bool isEqual = (op.kind() == Operator::Kind::EQEQ);
    const char* const combiner = isEqual ? " && " : " || ";

    if (left.isMatrix()) {
        // Each matrix column must be compared as if it were an individual vector.
        SkASSERT(right.isMatrix());
        SkASSERT(left.rows() == right.rows());
        SkASSERT(left.columns() == right.columns());
        int columns = left.columns();
        const Type& vecType = left.columnType(fContext);
        const char* separator = "(";
        for (int index = 0; index < columns; ++index) {
            expr += separator;
            std::string suffix = '[' + std::to_string(index) + ']';
            expr += this->assembleEqualityExpression(vecType, leftName + suffix,
                                                     vecType, rightName + suffix,
                                                     op, Precedence::kParentheses);
            separator = combiner;
        }
        return expr + ')';
    }

    if (left.isArray()) {
        SkASSERT(right.matches(left));
        const Type& indexedType = left.componentType();
        const char* separator = "(";
        for (int index = 0; index < left.columns(); ++index) {
            expr += separator;
            std::string suffix = '[' + std::to_string(index) + ']';
            expr += this->assembleEqualityExpression(indexedType, leftName + suffix,
                                                     indexedType, rightName + suffix,
                                                     op, Precedence::kParentheses);
            separator = combiner;
        }
        return expr + ')';
    }

    if (left.isStruct()) {
        // Recursively compare every field in the struct.
        SkASSERT(right.matches(left));
        SkSpan<const Field> fields = left.fields();

        const char* separator = "(";
        for (const Field& field : fields) {
            expr += separator;
            expr += this->assembleEqualityExpression(
                            *field.fType, leftName + '.' + this->assembleName(field.fName),
                            *field.fType, rightName + '.' + this->assembleName(field.fName),
                            op, Precedence::kParentheses);
            separator = combiner;
        }
        return expr + ')';
    }

    if (left.isVector()) {
        // Compare vectors via `all(x == y)` or `any(x != y)`.
        SkASSERT(right.isVector());
        SkASSERT(left.slotCount() == right.slotCount());

        expr += isEqual ? "all(" : "any(";
        expr += leftName;
        expr += operator_name(op);
        expr += rightName;
        return expr + ')';
    }

    // Compare scalars via `x == y`.
    SkASSERT(right.isScalar());
    if (parentPrecedence < Precedence::kSequence) {
        expr = '(';
    }
    expr += leftName;
    expr += operator_name(op);
    expr += rightName;
    if (parentPrecedence < Precedence::kSequence) {
        expr += ')';
    }
    return expr;
}

std::string WGSLCodeGenerator::assembleEqualityExpression(const Expression& left,
                                                          const Expression& right,
                                                          Operator op,
                                                          Precedence parentPrecedence) {
    // WGSL supports scalar and vector comparisons natively. We know the expressions will only
    // be emitted once in that case. Every other case will be poly-filled, resulting in referencing
    // the left and right expressions multiple times.
    AssembleMode mode = !left.type().isScalar() && !left.type().isVector() ?
            kUsedMultipleTimes : kAuto;
    std::string leftName = this->assembleExpression(left, Precedence::kParentheses, mode);
    std::string rightName = this->assembleExpression(right, Precedence::kParentheses, mode);
    return this->assembleEqualityExpression(left.type(), leftName, right.type(), rightName,
                                            op, parentPrecedence);
}

std::string WGSLCodeGenerator::assembleTextureFromImageOrSampler(const Expression& arg) {
    SkASSERT(arg.type().typeKind() == Type::TypeKind::kTexture ||
             arg.type().typeKind() == Type::TypeKind::kSampler);
    std::string expr = this->assembleExpression(arg, Precedence::kSequence);
    if (arg.type().typeKind() == Type::TypeKind::kSampler) {
        expr += kTextureSuffix;
    }
    return expr;
}

void WGSLCodeGenerator::writeProgramElement(const ProgramElement& e) {
    switch (e.kind()) {
        case ProgramElement::Kind::kExtension:
            // TODO(skbug.com/40044196): WGSL supports extensions via the "enable" directive
            // (https://www.w3.org/TR/WGSL/#enable-extensions-sec ). While we could easily emit this
            // directive, we should first ensure that all possible SkSL extension names are
            // converted to their appropriate WGSL extension.
            break;
        case ProgramElement::Kind::kGlobalVar:
            this->writeGlobalVarDeclaration(e.as<GlobalVarDeclaration>());
            break;
        case ProgramElement::Kind::kInterfaceBlock:
            // All interface block declarations are handled explicitly as the "program header" in
            // generateCode().
            break;
        case ProgramElement::Kind::kStructDefinition:
            this->writeStructDefinition(e.as<StructDefinition>());
            break;
        case ProgramElement::Kind::kFunctionPrototype:
            // A WGSL function declaration must contain its body and the function name is in scope
            // for the entire program (see https://www.w3.org/TR/WGSL/#function-declaration and
            // https://www.w3.org/TR/WGSL/#declaration-and-scope).
            //
            // As such, we don't emit function prototypes.
            break;
        case ProgramElement::Kind::kFunction:
            this->writeFunction(e.as<FunctionDefinition>());
            break;
        case ProgramElement::Kind::kModifiers:
            this->writeModifiersDeclaration(e.as<ModifiersDeclaration>());
            break;
        default:
            SkDEBUGFAILF("unsupported program element: %s\n", e.description().c_str());
            break;
    }
}

void WGSLCodeGenerator::writeTextureOrSampler(const Variable& var,
                                              int bindingLocation,
                                              std::string_view suffix,
                                              std::string_view wgslType) {
    if (var.type().dimensions() != SpvDim2D) {
        // Skia currently only uses 2D textures.
        fContext.fErrors->error(var.varDeclaration()->position(), "unsupported texture dimensions");
        return;
    }

    this->write("@group(");
    this->write(std::to_string(std::max(0, var.layout().fSet)));
    this->write(") @binding(");
    this->write(std::to_string(bindingLocation));
    this->write(") var ");
    this->write(this->assembleName(var.mangledName()));
    this->write(suffix);
    this->write(": ");
    this->write(wgslType);
    this->writeLine(";");
}

void WGSLCodeGenerator::writeGlobalVarDeclaration(const GlobalVarDeclaration& d) {
    const VarDeclaration& decl = d.varDeclaration();
    const Variable& var = *decl.var();
    if ((var.modifierFlags() & (ModifierFlag::kIn | ModifierFlag::kOut)) ||
        is_in_global_uniforms(var)) {
        // Pipeline stage I/O parameters and top-level (non-block) uniforms are handled specially
        // in generateCode().
        return;
    }

    const Type::TypeKind varKind = var.type().typeKind();
    if (varKind == Type::TypeKind::kSampler) {
        // If the sampler binding was unassigned, provide a scratch value; this will make
        // golden-output tests pass, but will not actually be usable for drawing.
        int samplerLocation = var.layout().fSampler >= 0 ? var.layout().fSampler
                                                         : 10000 + fScratchCount++;
        this->writeTextureOrSampler(var, samplerLocation, kSamplerSuffix, "sampler");

        // If the texture binding was unassigned, provide a scratch value (for golden-output tests).
        int textureLocation = var.layout().fTexture >= 0 ? var.layout().fTexture
                                                         : 10000 + fScratchCount++;
        this->writeTextureOrSampler(var, textureLocation, kTextureSuffix, "texture_2d<f32>");
        return;
    }

    if (varKind == Type::TypeKind::kTexture) {
        // If a binding location was unassigned, provide a scratch value (for golden-output tests).
        int textureLocation = var.layout().fBinding >= 0 ? var.layout().fBinding
                                                         : 10000 + fScratchCount++;
        // For a texture without an associated sampler, we don't apply a suffix.
        this->writeTextureOrSampler(var, textureLocation, /*suffix=*/"",
                                    to_wgsl_type(fContext, var.type(), &var.layout()));
        return;
    }

    std::string initializer;
    if (decl.value()) {
        // We assume here that the initial-value expression will not emit any helper statements.
        // Initial-value expressions are required to pass IsConstantExpression, which limits the
        // blast radius to constructors, literals, and other constant values/variables.
        initializer += " = ";
        initializer += this->assembleExpression(*decl.value(), Precedence::kAssignment);
    }

    if (var.modifierFlags().isConst()) {
        this->write("const ");
    } else if (var.modifierFlags().isWorkgroup()) {
        this->write("var<workgroup> ");
    } else if (var.modifierFlags().isPixelLocal()) {
        this->write("var<pixel_local> ");
    } else {
        this->write("var<private> ");
    }
    this->write(this->assembleName(var.mangledName()));
    this->write(": " + to_wgsl_type(fContext, var.type(), &var.layout()));
    this->write(initializer);
    this->writeLine(";");
}

void WGSLCodeGenerator::writeStructDefinition(const StructDefinition& s) {
    const Type& type = s.type();
    this->writeLine("struct " + type.displayName() + " {");
    this->writeFields(type.fields(), /*memoryLayout=*/nullptr);
    this->writeLine("};");
}

void WGSLCodeGenerator::writeModifiersDeclaration(const ModifiersDeclaration& modifiers) {
    LayoutFlags flags = modifiers.layout().fFlags;
    flags &= ~(LayoutFlag::kLocalSizeX | LayoutFlag::kLocalSizeY | LayoutFlag::kLocalSizeZ);
    if (flags != LayoutFlag::kNone) {
        fContext.fErrors->error(modifiers.position(), "unsupported declaration");
        return;
    }

    if (modifiers.layout().fLocalSizeX >= 0) {
        fLocalSizeX = modifiers.layout().fLocalSizeX;
    }
    if (modifiers.layout().fLocalSizeY >= 0) {
        fLocalSizeY = modifiers.layout().fLocalSizeY;
    }
    if (modifiers.layout().fLocalSizeZ >= 0) {
        fLocalSizeZ = modifiers.layout().fLocalSizeZ;
    }
}

void WGSLCodeGenerator::writeFields(SkSpan<const Field> fields, const MemoryLayout* memoryLayout) {
    fIndentation++;

    for (size_t index = 0; index < fields.size(); ++index) {
        const Field& field = fields[index];
        if (memoryLayout && !memoryLayout->isSupported(*field.fType)) {
            // Reject types that aren't supported by the memory layout.
            fContext.fErrors->error(field.fPosition, "type '" + std::string(field.fType->name()) +
                                                     "' is not permitted here");
            return;
        }

        // Prepend @size(n) to enforce the offsets from the SkSL layout. (This is effectively
        // a gadget that we can use to insert padding between elements.)
        if (index < fields.size() - 1) {
            int thisFieldOffset = field.fLayout.fOffset;
            int nextFieldOffset = fields[index + 1].fLayout.fOffset;
            if (index == 0 && thisFieldOffset > 0) {
                fContext.fErrors->error(field.fPosition, "field must have an offset of zero");
                return;
            }
            if (thisFieldOffset >= 0 && nextFieldOffset > thisFieldOffset) {
                this->write("@size(");
                this->write(std::to_string(nextFieldOffset - thisFieldOffset));
                this->write(") ");
            }
        }

        this->write(this->assembleName(field.fName));
        this->write(": ");
        if (const FieldPolyfillInfo* info = fFieldPolyfillMap.find(&field)) {
            if (info->fIsArray) {
                // This properly handles arrays of matrices, as well as arrays of other primitives.
                SkASSERT(field.fType->isArray());
                this->write("array<_skArrayElement_");
                this->write(field.fType->abbreviatedName());
                this->write(", ");
                this->write(std::to_string(field.fType->columns()));
                this->write(">");
            } else if (info->fIsMatrix) {
                this->write("_skMatrix");
                this->write(std::to_string(field.fType->columns()));
                this->write(std::to_string(field.fType->rows()));
                this->write(type_is_low_precision(*field.fType, fContext) ? "h" : "f");
            } else {
                SkDEBUGFAILF("need polyfill for %s", info->fReplacementName.c_str());
            }
        } else {
            this->write(to_wgsl_type(fContext, *field.fType, &field.fLayout));
        }
        this->writeLine(",");
    }

    fIndentation--;
}

void WGSLCodeGenerator::writeEnables() {
    this->writeLine("diagnostic(off, derivative_uniformity);");
    this->writeLine("diagnostic(off, chromium.unreachable_code);");

    if (!fContext.fConfig->fSettings.fForceHighPrecision) {
        // Always turn on f16, even if technically a given program might not use half values.
        this->writeLine("enable f16;");
    }
    if (fRequirements.fPixelLocalExtension) {
        this->writeLine("enable chromium_experimental_pixel_local;");
    }
    if (fProgram.fInterface.fUseLastFragColor) {
        this->writeLine("enable chromium_experimental_framebuffer_fetch;");
    }
    if (fProgram.fInterface.fOutputSecondaryColor) {
        this->writeLine("enable dual_source_blending;");
    }
}

bool WGSLCodeGenerator::needsStageInputStruct() const {
    // It is illegal to declare a struct with no members; we can't emit a placeholder empty stage
    // input struct.
    return !fPipelineInputs.empty();
}

void WGSLCodeGenerator::writeStageInputStruct() {
    if (!this->needsStageInputStruct()) {
        return;
    }

    std::string_view structNamePrefix = pipeline_struct_prefix(fProgram.fConfig->fKind);
    SkASSERT(!structNamePrefix.empty());

    this->write("struct ");
    this->write(structNamePrefix);
    this->writeLine("In {");
    fIndentation++;

    for (const Variable* v : fPipelineInputs) {
        if (v->type().isInterfaceBlock()) {
            for (const Field& f : v->type().fields()) {
                this->writePipelineIODeclaration(f.fLayout, *f.fType, f.fModifierFlags, f.fName,
                                                 Delimiter::kComma);
            }
        } else {
            this->writePipelineIODeclaration(v->layout(), v->type(), v->modifierFlags(),
                                             v->mangledName(), Delimiter::kComma);
        }
    }

    fIndentation--;
    this->writeLine("};");
}

bool WGSLCodeGenerator::needsStageOutputStruct() const {
    // It is illegal to declare a struct with no members. However, vertex programs will _always_
    // have an output stage in WGSL, because the spec requires them to emit `@builtin(position)`.
    // So we always synthesize a reference to `sk_Position` even if the program doesn't need it.
    return !fPipelineOutputs.empty() || ProgramConfig::IsVertex(fProgram.fConfig->fKind);
}

void WGSLCodeGenerator::writeStageOutputStruct() {
    if (!this->needsStageOutputStruct()) {
        return;
    }

    std::string_view structNamePrefix = pipeline_struct_prefix(fProgram.fConfig->fKind);
    SkASSERT(!structNamePrefix.empty());

    this->write("struct ");
    this->write(structNamePrefix);
    this->writeLine("Out {");
    fIndentation++;

    bool declaredPositionBuiltin = false;
    bool requiresPointSizeBuiltin = false;
    for (const Variable* v : fPipelineOutputs) {
        if (v->type().isInterfaceBlock()) {
            for (const auto& f : v->type().fields()) {
                this->writePipelineIODeclaration(f.fLayout, *f.fType, f.fModifierFlags, f.fName,
                                                 Delimiter::kComma);
                if (f.fLayout.fBuiltin == SK_POSITION_BUILTIN) {
                    declaredPositionBuiltin = true;
                } else if (f.fLayout.fBuiltin == SK_POINTSIZE_BUILTIN) {
                    // sk_PointSize is explicitly not supported by `builtin_from_sksl_name` so
                    // writePipelineIODeclaration will never write it. We mark it here if the
                    // declaration is needed so we can synthesize it below.
                    requiresPointSizeBuiltin = true;
                }
            }
        } else {
            this->writePipelineIODeclaration(v->layout(), v->type(), v->modifierFlags(),
                                             v->mangledName(), Delimiter::kComma);
        }
    }

    // A vertex program must include the `position` builtin in its entrypoint's return type.
    const bool positionBuiltinRequired = ProgramConfig::IsVertex(fProgram.fConfig->fKind);
    if (positionBuiltinRequired && !declaredPositionBuiltin) {
        this->writeLine("@builtin(position) sk_Position: vec4<f32>,");
    }

    fIndentation--;
    this->writeLine("};");

    // In WebGPU/WGSL, the vertex stage does not support a point-size output and the size
    // of a point primitive is always 1 pixel (see https://github.com/gpuweb/gpuweb/issues/332).
    //
    // There isn't anything we can do to emulate this correctly at this stage so we synthesize a
    // placeholder global variable that has no effect. Programs should not rely on sk_PointSize when
    // using the Dawn backend.
    if (ProgramConfig::IsVertex(fProgram.fConfig->fKind) && requiresPointSizeBuiltin) {
        this->writeLine("/* unsupported */ var<private> sk_PointSize: f32;");
    }
}

void WGSLCodeGenerator::prepareUniformPolyfillsForInterfaceBlock(
        const InterfaceBlock* interfaceBlock,
        std::string_view instanceName,
        MemoryLayout::Standard nativeLayout) {
    SkSL::MemoryLayout std140(MemoryLayout::Standard::k140);
    SkSL::MemoryLayout native(nativeLayout);

    const Type& structType = interfaceBlock->var()->type().componentType();
    for (const Field& field : structType.fields()) {
        const Type* type = field.fType;
        bool needsArrayPolyfill = false;
        bool needsMatrixPolyfill = false;

        auto isPolyfillableMatrixType = [&](const Type* type) {
            return type->isMatrix() && std140.stride(*type) != native.stride(*type);
        };

        if (isPolyfillableMatrixType(type)) {
            // Matrices will be represented as 16-byte aligned arrays in std140, and reconstituted
            // into proper matrices as they are later accessed. We need to synthesize polyfill.
            needsMatrixPolyfill = true;
        } else if (type->isArray() && !type->isUnsizedArray() &&
                   !type->componentType().isOpaque()) {
            const Type* innerType = &type->componentType();
            if (isPolyfillableMatrixType(innerType)) {
                // Use a polyfill when the array contains a matrix that requires polyfill.
                needsArrayPolyfill = true;
                needsMatrixPolyfill = true;
            } else if (native.size(*innerType) < 16) {
                // Use a polyfill when the array elements are smaller than 16 bytes, since std140
                // will pad elements to a 16-byte stride.
                needsArrayPolyfill = true;
            }
        }

        if (needsArrayPolyfill || needsMatrixPolyfill) {
            // Add a polyfill for this matrix type.
            FieldPolyfillInfo info;
            info.fInterfaceBlock = interfaceBlock;
            info.fReplacementName = "_skUnpacked_" + std::string(instanceName) + '_' +
                                    this->assembleName(field.fName);
            info.fIsArray = needsArrayPolyfill;
            info.fIsMatrix = needsMatrixPolyfill;
            fFieldPolyfillMap.set(&field, info);
        }
    }
}

void WGSLCodeGenerator::writeUniformsAndBuffers() {
    for (const ProgramElement* e : fProgram.elements()) {
        // Iterate through the interface blocks.
        if (!e->is<InterfaceBlock>()) {
            continue;
        }
        this->writeInterfaceBlock(e->as<InterfaceBlock>());
    }
}

void WGSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& ib) {
    // Determine if this interface block holds uniforms, buffers, or something else (skip it).
    std::string_view addressSpace;
    std::string_view accessMode;
    MemoryLayout::Standard nativeLayout;
    const bool isPushConstant =
            static_cast<bool>(ib.var()->layout().fFlags & LayoutFlag::kPushConstant);
    if (ib.var()->modifierFlags().isUniform()) {
        if (isPushConstant) {
            addressSpace = "immediate";
        } else {
            addressSpace = "uniform";
        }
        nativeLayout = fContext.fConfig->fSettings.fForceHighPrecision
                ? MemoryLayout::Standard::kWGSLUniform_Base
                : MemoryLayout::Standard::kWGSLUniform_EnableF16;
    } else if (ib.var()->modifierFlags().isBuffer()) {
        addressSpace = "storage";
        nativeLayout = fContext.fConfig->fSettings.fForceHighPrecision
                ? MemoryLayout::Standard::kWGSLStorage_Base
                : MemoryLayout::Standard::kWGSLStorage_EnableF16;
        accessMode = ib.var()->modifierFlags().isReadOnly() ? ", read" : ", read_write";
    } else {
        return;
    }

    // If we have an anonymous interface block, assign a name like `_uniform0` or `_storage1`.
    std::string instanceName;
    if (ib.instanceName().empty()) {
        instanceName = "_" + std::string(addressSpace) + std::to_string(fScratchCount++);
        fInterfaceBlockNameMap[&ib.var()->type().componentType()] = instanceName;
    } else {
        instanceName = std::string(ib.instanceName());
    }

    this->prepareUniformPolyfillsForInterfaceBlock(&ib, instanceName, nativeLayout);

    // Create a struct to hold all of the fields from this InterfaceBlock.
    SkASSERT(!ib.typeName().empty());
    this->write("struct ");
    this->write(ib.typeName());
    this->writeLine(" {");

    // Find the struct type and fields used by this interface block.
    const Type& ibType = ib.var()->type().componentType();
    SkASSERT(ibType.isStruct());

    SkSpan<const Field> ibFields = ibType.fields();
    SkASSERT(!ibFields.empty());

    MemoryLayout layout(MemoryLayout::Standard::k140);
    this->writeFields(ibFields, &layout);
    this->writeLine("};");
    if (!isPushConstant) {
        this->write("@group(");
        this->write(std::to_string(std::max(0, ib.var()->layout().fSet)));
        this->write(") @binding(");
        this->write(std::to_string(std::max(0, ib.var()->layout().fBinding)));
        this->write(") ");
    }
    this->write("var<");
    this->write(addressSpace);
    this->write(accessMode);
    this->write("> ");
    this->write(instanceName);
    this->write(" : ");
    this->write(to_wgsl_type(fContext, ib.var()->type(), &ib.var()->layout()));
    this->writeLine(";");
}

void WGSLCodeGenerator::writeNonBlockUniformsForTests() {
    TArray<Field> globalVarFields;
    Position globalVarPos;
    for (const ProgramElement* e : fProgram.elements()) {
        if (e->is<GlobalVarDeclaration>()) {
            const GlobalVarDeclaration& decls = e->as<GlobalVarDeclaration>();
            const Variable& var = *decls.varDeclaration().var();

            if (is_in_global_uniforms(var)) {
                if (globalVarFields.empty()) {
                    globalVarPos = var.position();
                }
                globalVarFields.push_back(Field(var.position(), var.layout(), ModifierFlag::kNone,
                                                var.name(), &var.type()));
            }
        }
    }

    if (!globalVarFields.empty()) {
        Layout layout{LayoutFlag::kNone, 0, 0, fProgram.fConfig->fSettings.fDefaultUniformBinding, 0,
                fProgram.fConfig->fSettings.fDefaultUniformSet, 0, 0};
        Modifiers modifiers{globalVarPos, layout, ModifierFlag::kUniform};

        // Interface blocks (for SkSL) are normally only allowed in fragment, vertex, or compute
        // programs and not the synthetic SkSL files that are allowed to declare non-block uniforms
        // Arbitrarily pick kFragment to temporarily override the config kind to pass validations.
        ProgramKind orig = fContext.fConfig->fKind;
        fContext.fConfig->fKind = ProgramKind::kFragment;
        fSyntheticGlobalUniformsBlock = InterfaceBlock::Convert(fContext,
                                                                globalVarPos,
                                                                modifiers,
                                                                "_GlobalUniforms",
                                                                std::move(globalVarFields),
                                                                "_globalUniforms",
                                                                /*arraySize=*/0);
        this->writeInterfaceBlock(*fSyntheticGlobalUniformsBlock);
        fContext.fConfig->fKind = orig;
    }
}

std::string WGSLCodeGenerator::functionDependencyArgs(const FunctionDeclaration& f) {
    WGSLFunctionDependencies* deps = fRequirements.fDependencies.find(&f);
    std::string args;
    if (deps && *deps) {
        const char* separator = "";
        if (*deps & WGSLFunctionDependency::kPipelineInputs) {
            args += "_stageIn";
            separator = ", ";
        }
        if (*deps & WGSLFunctionDependency::kPipelineOutputs) {
            args += separator;
            args += "_stageOut";
        }
    }
    return args;
}

bool WGSLCodeGenerator::writeFunctionDependencyParams(const FunctionDeclaration& f) {
    WGSLFunctionDependencies* deps = fRequirements.fDependencies.find(&f);
    if (!deps || !*deps) {
        return false;
    }

    std::string_view structNamePrefix = pipeline_struct_prefix(fProgram.fConfig->fKind);
    if (structNamePrefix.empty()) {
        return false;
    }
    const char* separator = "";
    if (*deps & WGSLFunctionDependency::kPipelineInputs) {
        this->write("_stageIn: ");
        separator = ", ";
        this->write(structNamePrefix);
        this->write("In");
    }
    if (*deps & WGSLFunctionDependency::kPipelineOutputs) {
        this->write(separator);
        this->write("_stageOut: ptr<function, ");
        this->write(structNamePrefix);
        this->write("Out>");
    }
    return true;
}

bool ToWGSL(Program& program,
            const ShaderCaps* caps,
            OutputStream& out,
            PrettyPrint pp,
            IncludeSyntheticCode isc,
            ValidateWGSLProc validateWGSL) {
    TRACE_EVENT0("skia.shaders", "SkSL::ToWGSL");
    SkASSERT(caps != nullptr);

    program.fContext->fErrors->setSource(*program.fSource);
    bool result;
    if (validateWGSL) {
        StringStream wgsl;
        WGSLCodeGenerator cg(program.fContext.get(), caps, &program, &wgsl, pp, isc);
        result = cg.generateCode();
        if (result) {
            std::string_view wgslBytes = wgsl.str();
            std::string warnings;
            result = validateWGSL(*program.fContext->fErrors, wgslBytes, &warnings);
            if (!warnings.empty()) {
                out.writeText("/* Tint reported warnings. */\n\n");
            }
            out.write(wgslBytes.data(), wgslBytes.size());
        }
    } else {
        WGSLCodeGenerator cg(program.fContext.get(), caps, &program, &out, pp, isc);
        result = cg.generateCode();
    }
    program.fContext->fErrors->setSource(std::string_view());

    return result;
}

bool ToWGSL(Program& program, const ShaderCaps* caps, OutputStream& out) {
#if defined(SK_DEBUG)
    constexpr PrettyPrint defaultPrintOpts = PrettyPrint::kYes;
#else
    constexpr PrettyPrint defaultPrintOpts = PrettyPrint::kNo;
#endif
    return ToWGSL(program, caps, out, defaultPrintOpts, IncludeSyntheticCode::kNo, nullptr);
}

bool ToWGSL(Program& program, const ShaderCaps* caps, NativeShader* out) {
    StringStream buffer;
    if (!ToWGSL(program, caps, buffer)) {
        return false;
    }
    out->fText = buffer.str();
    return true;
}

}  // namespace SkSL
