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

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

#include "src/sksl/SkSLAnalysis.h"
#include "src/sksl/SkSLCPPUniformCTypes.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/codegen/SkSLHCodeGenerator.h"
#include "src/sksl/ir/SkSLEnum.h"

#include <algorithm>

#if defined(SKSL_STANDALONE) || GR_TEST_UTILS

namespace SkSL {

static bool needs_uniform_var(const Variable& var) {
    return (var.modifiers().fFlags & Modifiers::kUniform_Flag) &&
            var.type().typeKind() != Type::TypeKind::kSampler;
}

CPPCodeGenerator::CPPCodeGenerator(const Context* context, const Program* program,
                                   ErrorReporter* errors, String name, OutputStream* out)
    : INHERITED(context, program, errors, out)
    , fName(std::move(name))
    , fFullName(String::printf("Gr%s", fName.c_str()))
    , fSectionAndParameterHelper(program, *errors) {
    fLineEnding = "\n";
    fTextureFunctionOverride = "sample";
}

void CPPCodeGenerator::writef(const char* s, va_list va) {
    static constexpr int BUFFER_SIZE = 1024;
    va_list copy;
    va_copy(copy, va);
    char buffer[BUFFER_SIZE];
    int length = std::vsnprintf(buffer, BUFFER_SIZE, s, va);
    if (length < BUFFER_SIZE) {
        fOut->write(buffer, length);
    } else {
        std::unique_ptr<char[]> heap(new char[length + 1]);
        vsprintf(heap.get(), s, copy);
        fOut->write(heap.get(), length);
    }
    va_end(copy);
}

void CPPCodeGenerator::writef(const char* s, ...) {
    va_list va;
    va_start(va, s);
    this->writef(s, va);
    va_end(va);
}

void CPPCodeGenerator::writeHeader() {
}

bool CPPCodeGenerator::usesPrecisionModifiers() const {
    return false;
}

String CPPCodeGenerator::getTypeName(const Type& type) {
    return type.name();
}

void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
                                             Precedence parentPrecedence) {
    const Expression& left = *b.left();
    const Expression& right = *b.right();
    Operator op = b.getOperator();
    if (op.kind() == Token::Kind::TK_PERCENT) {
        // need to use "%%" instead of "%" b/c the code will be inside of a printf
        Precedence precedence = op.getBinaryPrecedence();
        if (precedence >= parentPrecedence) {
            this->write("(");
        }
        this->writeExpression(left, precedence);
        this->write(" %% ");
        this->writeExpression(right, precedence);
        if (precedence >= parentPrecedence) {
            this->write(")");
        }
    } else {
        INHERITED::writeBinaryExpression(b, parentPrecedence);
    }
}

static String default_value(const Type& type) {
    if (type.isBoolean()) {
        return "false";
    }
    switch (type.typeKind()) {
        case Type::TypeKind::kScalar: return "0";
        case Type::TypeKind::kVector: return type.name() + "(0)";
        case Type::TypeKind::kMatrix: return type.name() + "(1)";
        default: SK_ABORT("unsupported default_value type");
    }
}

static String default_value(const Variable& var) {
    if (var.modifiers().fLayout.fCType == SkSL::Layout::CType::kSkPMColor4f) {
        return "{SK_FloatNaN, SK_FloatNaN, SK_FloatNaN, SK_FloatNaN}";
    }
    return default_value(var.type());
}

static bool is_private(const Variable& var) {
    const Modifiers& modifiers = var.modifiers();
    return !(modifiers.fFlags & Modifiers::kUniform_Flag) &&
           !(modifiers.fFlags & Modifiers::kIn_Flag) &&
           var.storage() == Variable::Storage::kGlobal &&
           modifiers.fLayout.fBuiltin == -1;
}

static bool is_uniform_in(const Variable& var) {
    const Modifiers& modifiers = var.modifiers();
    return (modifiers.fFlags & Modifiers::kUniform_Flag) &&
           (modifiers.fFlags & Modifiers::kIn_Flag) &&
           var.type().typeKind() != Type::TypeKind::kSampler;
}

String CPPCodeGenerator::formatRuntimeValue(const Type& type,
                                            const Layout& layout,
                                            const String& cppCode,
                                            std::vector<String>* formatArgs) {
    if (type.isArray()) {
        String result("[");
        const char* separator = "";
        for (int i = 0; i < type.columns(); i++) {
            result += separator + this->formatRuntimeValue(type.componentType(), layout,
                                                           "(" + cppCode + ")[" + to_string(i) +
                                                           "]", formatArgs);
            separator = ",";
        }
        result += "]";
        return result;
    }
    if (type.isFloat()) {
        formatArgs->push_back(cppCode);
        return "%f";
    }
    if (type == *fContext.fTypes.fInt) {
        formatArgs->push_back(cppCode);
        return "%d";
    }
    if (type == *fContext.fTypes.fBool) {
        formatArgs->push_back("(" + cppCode + " ? \"true\" : \"false\")");
        return "%s";
    }
    if (type == *fContext.fTypes.fFloat2 || type == *fContext.fTypes.fHalf2) {
        formatArgs->push_back(cppCode + ".fX");
        formatArgs->push_back(cppCode + ".fY");
        return type.name() + "(%f, %f)";
    }
    if (type == *fContext.fTypes.fFloat3 || type == *fContext.fTypes.fHalf3) {
        formatArgs->push_back(cppCode + ".fX");
        formatArgs->push_back(cppCode + ".fY");
        formatArgs->push_back(cppCode + ".fZ");
        return type.name() + "(%f, %f, %f)";
    }
    if (type == *fContext.fTypes.fFloat4 || type == *fContext.fTypes.fHalf4) {
        switch (layout.fCType) {
            case Layout::CType::kSkPMColor:
                formatArgs->push_back("SkGetPackedR32(" + cppCode + ") / 255.0");
                formatArgs->push_back("SkGetPackedG32(" + cppCode + ") / 255.0");
                formatArgs->push_back("SkGetPackedB32(" + cppCode + ") / 255.0");
                formatArgs->push_back("SkGetPackedA32(" + cppCode + ") / 255.0");
                break;
            case Layout::CType::kSkPMColor4f:
                formatArgs->push_back(cppCode + ".fR");
                formatArgs->push_back(cppCode + ".fG");
                formatArgs->push_back(cppCode + ".fB");
                formatArgs->push_back(cppCode + ".fA");
                break;
            case Layout::CType::kSkV4:
                formatArgs->push_back(cppCode + ".x");
                formatArgs->push_back(cppCode + ".y");
                formatArgs->push_back(cppCode + ".z");
                formatArgs->push_back(cppCode + ".w");
                break;
            case Layout::CType::kSkRect:
            case Layout::CType::kDefault:
                formatArgs->push_back(cppCode + ".left()");
                formatArgs->push_back(cppCode + ".top()");
                formatArgs->push_back(cppCode + ".right()");
                formatArgs->push_back(cppCode + ".bottom()");
                break;
            default:
                SkASSERT(false);
        }
        return type.name() + "(%f, %f, %f, %f)";
    }
    if (type.isMatrix()) {
        SkASSERT(type.componentType() == *fContext.fTypes.fFloat ||
                 type.componentType() == *fContext.fTypes.fHalf);

        String format = type.name() + "(";
        for (int c = 0; c < type.columns(); ++c) {
            for (int r = 0; r < type.rows(); ++r) {
                formatArgs->push_back(String::printf("%s.rc(%d, %d)", cppCode.c_str(), r, c));
                format += "%f, ";
            }
        }

        // Replace trailing ", " with ")".
        format.pop_back();
        format.back() = ')';
        return format;
    }
    if (type.isEnum()) {
        formatArgs->push_back("(int) " + cppCode);
        return "%d";
    }
    if (type == *fContext.fTypes.fInt4 ||
        type == *fContext.fTypes.fShort4) {
        formatArgs->push_back(cppCode + ".left()");
        formatArgs->push_back(cppCode + ".top()");
        formatArgs->push_back(cppCode + ".right()");
        formatArgs->push_back(cppCode + ".bottom()");
        return type.name() + "(%d, %d, %d, %d)";
    }

    SkDEBUGFAILF("unsupported runtime value type '%s'\n", String(type.name()).c_str());
    return "";
}

void CPPCodeGenerator::writeRuntimeValue(const Type& type, const Layout& layout,
                                         const String& cppCode) {
    this->write(this->formatRuntimeValue(type, layout, cppCode, &fFormatArgs));
}

void CPPCodeGenerator::writeVarInitializer(const Variable& var, const Expression& value) {
    if (is_private(var)) {
        this->writeRuntimeValue(var.type(), var.modifiers().fLayout, var.name());
    } else {
        this->writeExpression(value, Precedence::kTopLevel);
    }
}

String CPPCodeGenerator::getSamplerHandle(const Variable& var) {
    int samplerCount = 0;
    for (const auto param : fSectionAndParameterHelper.getParameters()) {
        if (&var == param) {
            return "args.fTexSamplers[" + to_string(samplerCount) + "]";
        }
        if (param->type().typeKind() == Type::TypeKind::kSampler) {
            ++samplerCount;
        }
    }
    SK_ABORT("should have found sampler in parameters\n");
}

void CPPCodeGenerator::writeIntLiteral(const IntLiteral& i) {
    this->write(to_string(i.value()));
}

void CPPCodeGenerator::writeSwizzle(const Swizzle& swizzle) {
    if (fCPPMode) {
        // no support for multiple swizzle components yet
        SkASSERT(swizzle.components().size() == 1);
        this->writeExpression(*swizzle.base(), Precedence::kPostfix);
        switch (swizzle.components()[0]) {
            case 0: this->write(".left()");   break;
            case 1: this->write(".top()");    break;
            case 2: this->write(".right()");  break;
            case 3: this->write(".bottom()"); break;
        }
    } else {
        INHERITED::writeSwizzle(swizzle);
    }
}

void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
    if (fCPPMode) {
        this->write(ref.variable()->name());
        return;
    }
    switch (ref.variable()->modifiers().fLayout.fBuiltin) {
        case SK_MAIN_COORDS_BUILTIN:
            this->write("%s");
            fFormatArgs.push_back(String("args.fSampleCoord"));
            fAccessSampleCoordsDirectly = true;
            break;
        default:
            const Variable& var = *ref.variable();
            if (var.type().typeKind() == Type::TypeKind::kSampler) {
                this->write("%s");
                fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerVariable(" +
                                      this->getSamplerHandle(*ref.variable()) + ")");
                return;
            }
            if (var.modifiers().fFlags & Modifiers::kUniform_Flag) {
                this->write("%s");
                String name = var.name();
                String varCode = String::printf("args.fUniformHandler->getUniformCStr(%sVar)",
                                                HCodeGenerator::FieldName(name.c_str()).c_str());
                String code;
                if (var.modifiers().fLayout.fWhen.fLength) {
                    code = String::printf("%sVar.isValid() ? %s : \"%s\"",
                                          HCodeGenerator::FieldName(name.c_str()).c_str(),
                                          varCode.c_str(),
                                          default_value(var.type()).c_str());
                } else {
                    code = varCode;
                }
                fFormatArgs.push_back(code);
            } else if (SectionAndParameterHelper::IsParameter(var)) {
                String name(var.name());
                this->writeRuntimeValue(var.type(), var.modifiers().fLayout,
                                        String::printf("_outer.%s", name.c_str()).c_str());
            } else {
                this->write(var.name());
            }
    }
}

void CPPCodeGenerator::writeIfStatement(const IfStatement& s) {
    if (s.isStatic()) {
        this->write("@");
    }
    INHERITED::writeIfStatement(s);
}

void CPPCodeGenerator::writeReturnStatement(const ReturnStatement& s) {
    INHERITED::writeReturnStatement(s);
}

void CPPCodeGenerator::writeSwitchStatement(const SwitchStatement& s) {
    if (s.isStatic()) {
        this->write("@");
    }
    INHERITED::writeSwitchStatement(s);
}

int CPPCodeGenerator::getChildFPIndex(const Variable& var) const {
    int index = 0;
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<GlobalVarDeclaration>()) {
            const VarDeclaration& decl =
                                  p->as<GlobalVarDeclaration>().declaration()->as<VarDeclaration>();
            if (&decl.var() == &var) {
                return index;
            } else if (decl.var().type().isFragmentProcessor()) {
                ++index;
            }
        }
    }
    SkDEBUGFAIL("child fragment processor not found");
    return 0;
}

String CPPCodeGenerator::getSampleVarName(const char* prefix, int sampleCounter) {
    return String::printf("%s%d", prefix, sampleCounter);
}

void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
    const FunctionDeclaration& function = c.function();
    const ExpressionArray& arguments = c.arguments();
    if (function.isBuiltin() && function.name() == "sample" &&
        arguments[0]->type().typeKind() != Type::TypeKind::kSampler) {
        int sampleCounter = fSampleCounter++;

        // Validity checks that are detected by function definition in sksl_fp.inc
        SkASSERT(arguments.size() >= 1 && arguments.size() <= 3);
        SkASSERT(arguments[0]->type().isFragmentProcessor());

        // Actually fail during compilation if arguments with valid types are
        // provided that are not variable references, since sample() is a
        // special function that impacts code emission.
        if (!arguments[0]->is<VariableReference>()) {
            fErrors.error(arguments[0]->fOffset,
                    "sample()'s fragmentProcessor argument must be a variable reference\n");
            return;
        }
        const Variable& child = *arguments[0]->as<VariableReference>().variable();

        // Start a new extra emit code section so that the emitted child processor can depend on
        // sksl variables defined in earlier sksl code.
        this->newExtraEmitCodeBlock();

        // inputColor is an optional argument that always appears last
        String inputColor;
        if (arguments.back()->type().name() == "half4") {
            // Use the invokeChild() variant that accepts an input color, so convert the 2nd
            // argument's expression into C++ code that produces sksl stored in an SkString.
            String inputColorName = this->getSampleVarName("_input", sampleCounter);
            addExtraEmitCodeLine(convertSKSLExpressionToCPP(*arguments.back(), inputColorName));

            // invokeChild() needs a char* and a pre-pended comma
            inputColor = ", " + inputColorName + ".c_str()";
        }

        // If coords are present, they're float2. They appear right after the fp.
        String inputCoord;
        if (arguments.size() > 1) {
            if (arguments[1]->type().name() == "float2") {
                // Invoking child with explicit coordinates at this call site
                inputCoord = this->getSampleVarName("_coords", sampleCounter);
                addExtraEmitCodeLine(convertSKSLExpressionToCPP(*arguments[1], inputCoord));
                inputCoord.append(".c_str()");
            }
        }
        if (!inputCoord.empty()) {
            inputCoord = ", " + inputCoord;
        }

        // Write the output handling after the possible input handling
        String childName = this->getSampleVarName("_sample", sampleCounter);
        String childIndexStr = to_string(this->getChildFPIndex(child));
        addExtraEmitCodeLine("SkString " + childName + " = this->invokeChild(" + childIndexStr +
                             inputColor + ", args" + inputCoord + ");");

        this->write("%s");
        fFormatArgs.push_back(childName + ".c_str()");
        return;
    }
    if (function.isBuiltin()) {
        INHERITED::writeFunctionCall(c);
    } else {
        this->write("%s");
        fFormatArgs.push_back((String(function.name()) + "_name.c_str()").c_str());
        this->write("(");
        const char* separator = "";
        for (const auto& arg : arguments) {
            this->write(separator);
            separator = ", ";
            this->writeExpression(*arg, Precedence::kSequence);
        }
        this->write(")");
    }
    if (function.isBuiltin() && function.name() == "sample") {
        this->write(".%s");
        SkASSERT(arguments.size() >= 1);
        SkASSERT(arguments[0]->is<VariableReference>());
        String sampler =
                this->getSamplerHandle(*arguments[0]->as<VariableReference>().variable());
        fFormatArgs.push_back("fragBuilder->getProgramBuilder()->samplerSwizzle(" + sampler +
                              ").asString().c_str()");
    }
}

static const char* glsltype_string(const Context& context, const Type& type) {
    // If a new GrSL type is added, this function will need to be updated.
    static_assert(kGrSLTypeCount == 49);

    if (type == *context.fTypes.fVoid    ) { return "kVoid_GrSLType";     }
    if (type == *context.fTypes.fBool    ) { return "kBool_GrSLType";     }
    if (type == *context.fTypes.fBool2   ) { return "kBool2_GrSLType";    }
    if (type == *context.fTypes.fBool3   ) { return "kBool3_GrSLType";    }
    if (type == *context.fTypes.fBool4   ) { return "kBool4_GrSLType";    }
    if (type == *context.fTypes.fShort   ) { return "kShort_GrSLType";    }
    if (type == *context.fTypes.fShort2  ) { return "kShort2_GrSLType";   }
    if (type == *context.fTypes.fShort3  ) { return "kShort3_GrSLType";   }
    if (type == *context.fTypes.fShort4  ) { return "kShort4_GrSLType";   }
    if (type == *context.fTypes.fUShort  ) { return "kUShort_GrSLType";   }
    if (type == *context.fTypes.fUShort2 ) { return "kUShort2_GrSLType";  }
    if (type == *context.fTypes.fUShort3 ) { return "kUShort3_GrSLType";  }
    if (type == *context.fTypes.fUShort4 ) { return "kUShort4_GrSLType";  }
    if (type == *context.fTypes.fFloat   ) { return "kFloat_GrSLType";    }
    if (type == *context.fTypes.fFloat2  ) { return "kFloat2_GrSLType";   }
    if (type == *context.fTypes.fFloat3  ) { return "kFloat3_GrSLType";   }
    if (type == *context.fTypes.fFloat4  ) { return "kFloat4_GrSLType";   }
    if (type == *context.fTypes.fFloat2x2) { return "kFloat2x2_GrSLType"; }
    if (type == *context.fTypes.fFloat3x3) { return "kFloat3x3_GrSLType"; }
    if (type == *context.fTypes.fFloat4x4) { return "kFloat4x4_GrSLType"; }
    if (type == *context.fTypes.fHalf    ) { return "kHalf_GrSLType";     }
    if (type == *context.fTypes.fHalf2   ) { return "kHalf2_GrSLType";    }
    if (type == *context.fTypes.fHalf3   ) { return "kHalf3_GrSLType";    }
    if (type == *context.fTypes.fHalf4   ) { return "kHalf4_GrSLType";    }
    if (type == *context.fTypes.fHalf2x2 ) { return "kHalf2x2_GrSLType";  }
    if (type == *context.fTypes.fHalf3x3 ) { return "kHalf3x3_GrSLType";  }
    if (type == *context.fTypes.fHalf4x4 ) { return "kHalf4x4_GrSLType";  }
    if (type == *context.fTypes.fInt     ) { return "kInt_GrSLType";      }
    if (type == *context.fTypes.fInt2    ) { return "kInt2_GrSLType";     }
    if (type == *context.fTypes.fInt3    ) { return "kInt3_GrSLType";     }
    if (type == *context.fTypes.fInt4    ) { return "kInt4_GrSLType";     }
    if (type == *context.fTypes.fUInt    ) { return "kUint_GrSLType";     }
    if (type == *context.fTypes.fUInt2   ) { return "kUint2_GrSLType";    }
    if (type == *context.fTypes.fUInt3   ) { return "kUint3_GrSLType";    }
    if (type == *context.fTypes.fUInt4   ) { return "kUint4_GrSLType";    }
    if (type.isEnum())                     { return "kInt_GrSLType";      }

    SkDEBUGFAILF("unsupported type: %s", type.description().c_str());
    return nullptr;
}

void CPPCodeGenerator::prepareHelperFunction(const FunctionDeclaration& decl) {
    if (decl.isBuiltin() || decl.isMain()) {
        return;
    }

    String funcName = decl.name();
    this->addExtraEmitCodeLine(
            String::printf("SkString %s_name = fragBuilder->getMangledFunctionName(\"%s\");",
                           funcName.c_str(),
                           funcName.c_str()));

    String args = String::printf("const GrShaderVar %s_args[] = { ", funcName.c_str());
    const char* separator = "";
    for (const Variable* param : decl.parameters()) {
        String paramName = param->name();
        args.appendf("%sGrShaderVar(\"%s\", %s)", separator, paramName.c_str(),
                                                  glsltype_string(fContext, param->type()));
        separator = ", ";
    }
    args += " };";

    this->addExtraEmitCodeLine(args.c_str());
}

void CPPCodeGenerator::prototypeHelperFunction(const FunctionDeclaration& decl) {
    String funcName = decl.name();
    this->addExtraEmitCodeLine(String::printf(
            "fragBuilder->emitFunctionPrototype(%s, %s_name.c_str(), {%s_args, %zu});",
            glsltype_string(fContext, decl.returnType()),
            funcName.c_str(),
            funcName.c_str(),
            decl.parameters().size()));
}

void CPPCodeGenerator::writeFunction(const FunctionDefinition& f) {
    const FunctionDeclaration& decl = f.declaration();
    if (decl.isBuiltin()) {
        return;
    }
    fFunctionHeader.clear();
    OutputStream* oldOut = fOut;
    StringStream buffer;
    fOut = &buffer;
    if (decl.isMain()) {
        fInMain = true;
        for (const std::unique_ptr<Statement>& s : f.body()->as<Block>().children()) {
            this->writeStatement(*s);
            this->writeLine();
        }
        fInMain = false;

        fOut = oldOut;
        this->write(fFunctionHeader);
        this->write(buffer.str());
    } else {
        for (const std::unique_ptr<Statement>& s : f.body()->as<Block>().children()) {
            this->writeStatement(*s);
            this->writeLine();
        }

        fOut = oldOut;
        String funcName = decl.name();

        String funcImpl;
        if (!fFormatArgs.empty()) {
            this->addExtraEmitCodeLine("const String " + funcName + "_impl = String::printf(" +
                                       assembleCodeAndFormatArgPrintf(buffer.str()).c_str() + ");");
            funcImpl = String::printf(" %s_impl.c_str()", funcName.c_str());
        } else {
            funcImpl = "\nR\"SkSL(" + buffer.str() + ")SkSL\"";
        }

        this->addExtraEmitCodeLine(String::printf(
                "fragBuilder->emitFunction(%s, %s_name.c_str(), {%s_args, %zu},%s);",
                glsltype_string(fContext, decl.returnType()),
                funcName.c_str(),
                funcName.c_str(),
                decl.parameters().size(),
                funcImpl.c_str()));
    }
}

void CPPCodeGenerator::writeSetting(const Setting& s) {
    this->writef("sk_Caps.%s", s.name().c_str());
}

bool CPPCodeGenerator::writeSection(const char* name, const char* prefix) {
    const Section* s = fSectionAndParameterHelper.getSection(name);
    if (s) {
        this->writef("%s%s", prefix, s->text().c_str());
        return true;
    }
    return false;
}

void CPPCodeGenerator::writeProgramElement(const ProgramElement& p) {
    switch (p.kind()) {
        case ProgramElement::Kind::kSection:
            return;
        case ProgramElement::Kind::kGlobalVar: {
            const GlobalVarDeclaration& decl = p.as<GlobalVarDeclaration>();
            const Variable& var = decl.declaration()->as<VarDeclaration>().var();
            if (var.modifiers().fFlags & (Modifiers::kIn_Flag | Modifiers::kUniform_Flag) ||
                -1 != var.modifiers().fLayout.fBuiltin) {
                return;
            }
            break;
        }
        case ProgramElement::Kind::kFunctionPrototype: {
            // Function prototypes are handled at the C++ level (in writeEmitCode).
            // We don't want prototypes to be emitted inside the FP's main() function.
            return;
        }
        default:
            break;
    }
    INHERITED::writeProgramElement(p);
}

void CPPCodeGenerator::addUniform(const Variable& var) {
    if (!needs_uniform_var(var)) {
        return;
    }
    if (var.modifiers().fLayout.fWhen.fLength) {
        this->writef("        if (%s) {\n    ", String(var.modifiers().fLayout.fWhen).c_str());
    }
    String name(var.name());
    if (!var.type().isArray()) {
        this->writef("        %sVar = args.fUniformHandler->addUniform(&_outer, "
                     "kFragment_GrShaderFlag, %s, \"%s\");\n",
                     HCodeGenerator::FieldName(name.c_str()).c_str(),
                     glsltype_string(fContext, var.type()),
                     name.c_str());
    } else {
        this->writef("        %sVar = args.fUniformHandler->addUniformArray(&_outer, "
                     "kFragment_GrShaderFlag, %s, \"%s\", %d);\n",
                     HCodeGenerator::FieldName(name.c_str()).c_str(),
                     glsltype_string(fContext, var.type().componentType()),
                     name.c_str(),
                     var.type().columns());
    }
    if (var.modifiers().fLayout.fWhen.fLength) {
        this->write("        }\n");
    }
}

void CPPCodeGenerator::writeInputVars() {
}

void CPPCodeGenerator::writePrivateVars() {
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<GlobalVarDeclaration>()) {
            const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
            const Variable& var = global.declaration()->as<VarDeclaration>().var();
            if (is_private(var)) {
                if (var.type().isFragmentProcessor()) {
                    fErrors.error(global.fOffset,
                                  "fragmentProcessor variables must be declared 'in'");
                    return;
                }
                this->writef("%s %s = %s;\n",
                             HCodeGenerator::FieldType(fContext, var.type(),
                                                       var.modifiers().fLayout).c_str(),
                             String(var.name()).c_str(),
                             default_value(var).c_str());
            } else if (var.modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
                // An auto-tracked uniform in variable, so add a field to hold onto the prior
                // state. Note that tracked variables must be uniform in's and that is validated
                // before writePrivateVars() is called.
                const UniformCTypeMapper* mapper = UniformCTypeMapper::Get(fContext, var);
                SkASSERT(mapper);

                String name = HCodeGenerator::FieldName(String(var.name()).c_str());
                // The member statement is different if the mapper reports a default value
                if (mapper->defaultValue().size() > 0) {
                    this->writef("%s %sPrev = %s;\n",
                                    Layout::CTypeToStr(mapper->ctype()), name.c_str(),
                                    mapper->defaultValue().c_str());
                } else {
                    this->writef("%s %sPrev;\n",
                                    Layout::CTypeToStr(mapper->ctype()), name.c_str());
                }
            }
        }
    }
}

void CPPCodeGenerator::writePrivateVarValues() {
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<GlobalVarDeclaration>()) {
            const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
            const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
            if (is_private(decl.var()) && decl.value()) {
                this->writef("%s = ", String(decl.var().name()).c_str());
                fCPPMode = true;
                this->writeExpression(*decl.value(), Precedence::kAssignment);
                fCPPMode = false;
                this->write(";\n");
            }
        }
    }
}

static bool is_accessible(const Variable& var) {
    const Type& type = var.type();
    return !type.isFragmentProcessor() &&
           Type::TypeKind::kSampler != type.typeKind() &&
           Type::TypeKind::kOther != type.typeKind();
}

void CPPCodeGenerator::newExtraEmitCodeBlock() {
    // This should only be called when emitting SKSL for emitCode(), which can be detected if the
    // cpp buffer is not null, and the cpp buffer is not the current output.
    SkASSERT(fCPPBuffer && fCPPBuffer != fOut);

    // Start a new block as an empty string
    fExtraEmitCodeBlocks.push_back("");
    // Mark its location in the output buffer, uses ${\d} for the token since ${} will not occur in
    // valid sksl and makes detection trivial.
    this->writef("${%zu}", fExtraEmitCodeBlocks.size() - 1);
}

void CPPCodeGenerator::addExtraEmitCodeLine(const String& toAppend) {
    SkASSERT(fExtraEmitCodeBlocks.size() > 0);
    String& currentBlock = fExtraEmitCodeBlocks[fExtraEmitCodeBlocks.size() - 1];
    // Automatically add indentation and newline
    currentBlock += "        " + toAppend + "\n";
}

void CPPCodeGenerator::flushEmittedCode() {
    if (fCPPBuffer == nullptr) {
        // Not actually within writeEmitCode() so nothing to flush
        return;
    }

    StringStream* skslBuffer = static_cast<StringStream*>(fOut);

    String sksl = skslBuffer->str();
    // Empty the accumulation buffer since its current contents are consumed.
    skslBuffer->reset();

    // Switch to the cpp buffer
    fOut = fCPPBuffer;

    // Iterate through the sksl, keeping track of where the last statement ended (e.g. the latest
    // encountered ';', '{', or '}'). If an extra emit code block token is encountered then the
    // code from 0 to last statement end is sent to writeCodeAppend, the extra code block is
    // appended to the cpp buffer, and then the sksl string is trimmed to start where the last
    // statement left off (minus the encountered token).
    size_t i = 0;
    int flushPoint = -1;
    int tokenStart = -1;
    while (i < sksl.size()) {
        if (tokenStart >= 0) {
            // Looking for the end of the token
            if (sksl[i] == '}') {
                // Must append the sksl from 0 to flushPoint (inclusive) then the extra code
                // accumulated in the block with index parsed from chars [tokenStart+2, i-1]
                String toFlush = String(sksl.c_str(), flushPoint + 1);
                // writeCodeAppend automatically removes the format args that it consumed, so
                // fFormatArgs will be in a valid state for any future sksl
                this->writeCodeAppend(toFlush);

                SKSL_INT codeBlock;
                SkAssertResult(
                        stoi(StringFragment(sksl.c_str() + tokenStart + 2, i - tokenStart - 2),
                             &codeBlock));
                SkASSERT((size_t)codeBlock < fExtraEmitCodeBlocks.size());
                if (fExtraEmitCodeBlocks[codeBlock].size() > 0) {
                    this->write(fExtraEmitCodeBlocks[codeBlock].c_str());
                }

                // Now reset the sksl buffer to start after the flush point, but remove the token.
                String compacted = String(sksl.c_str() + flushPoint + 1,
                                          tokenStart - flushPoint - 1);
                if (i < sksl.size() - 1) {
                    compacted += String(sksl.c_str() + i + 1, sksl.size() - i - 1);
                }
                sksl = compacted;

                // And reset iteration
                i = -1;
                flushPoint = -1;
                tokenStart = -1;
            }
        } else {
            // Looking for the start of extra emit block tokens, and tracking when statements end
            if (sksl[i] == ';' || sksl[i] == '{' || sksl[i] == '}') {
                flushPoint = i;
            } else if (i < sksl.size() - 1 && sksl[i] == '$' && sksl[i + 1] == '{') {
                // found an extra emit code block token
                tokenStart = i++;
            }
        }
        i++;
    }

    // Once we've gone through the sksl string to this point, there are no remaining extra emit
    // code blocks to interleave, so append the remainder as usual.
    this->writeCodeAppend(sksl);

    // After appending, switch back to the emptied sksl buffer and reset the extra code blocks
    fOut = skslBuffer;
    fExtraEmitCodeBlocks.clear();
}

String CPPCodeGenerator::assembleCodeAndFormatArgPrintf(const String& code) {
    // Count % format specifiers.
    size_t argCount = 0;
    for (size_t index = 0; index < code.size(); ++index) {
        if ('%' == code[index]) {
            if (index == code.size() - 1) {
                SkDEBUGFAIL("found a dangling format specifier at the end of a string");
                break;
            }
            if (code[index + 1] == '%') {
                // %% indicates a literal % sign, not a format argument. Skip over the next
                // character to avoid mistakenly counting that one as an argument.
                ++index;
            } else {
                // Count the format argument that we found.
                ++argCount;
            }
        }
    }

    // Assemble the printf arguments.
    String result = String::printf("R\"SkSL(%s)SkSL\"\n", code.c_str());
    for (size_t i = 0; i < argCount; ++i) {
        result += ", ";
        result += fFormatArgs[i].c_str();
    }

    // argCount is equal to the number of fFormatArgs that were consumed, so they should be
    // removed from the list.
    if (argCount > 0) {
        fFormatArgs.erase(fFormatArgs.begin(), fFormatArgs.begin() + argCount);
    }

    return result;
}

void CPPCodeGenerator::writeCodeAppend(const String& code) {
    if (!code.empty()) {
        this->write("        fragBuilder->codeAppendf(\n");
        this->write(assembleCodeAndFormatArgPrintf(code));
        this->write(");\n");
    }
}

String CPPCodeGenerator::convertSKSLExpressionToCPP(const Expression& e,
                                                    const String& cppVar) {
    // To do this conversion, we temporarily switch the sksl output stream
    // to an empty stringstream and reset the format args to empty.
    OutputStream* oldSKSL = fOut;
    StringStream exprBuffer;
    fOut = &exprBuffer;

    std::vector<String> oldArgs(fFormatArgs);
    fFormatArgs.clear();

    // Convert the argument expression into a format string and args
    this->writeExpression(e, Precedence::kTopLevel);
    std::vector<String> newArgs(fFormatArgs);
    String expr = exprBuffer.str();

    // After generating, restore the original output stream and format args
    fFormatArgs = oldArgs;
    fOut = oldSKSL;

    // The sksl written to exprBuffer is not processed by flushEmittedCode(), so any extra emit code
    // block tokens won't get handled. So we need to strip them from the expression and stick them
    // to the end of the original sksl stream.
    String exprFormat = "";
    int tokenStart = -1;
    for (size_t i = 0; i < expr.size(); i++) {
        if (tokenStart >= 0) {
            if (expr[i] == '}') {
                // End of the token, so append the token to fOut
                fOut->write(expr.c_str() + tokenStart, i - tokenStart + 1);
                tokenStart = -1;
            }
        } else {
            if (i < expr.size() - 1 && expr[i] == '$' && expr[i + 1] == '{') {
                tokenStart = i++;
            } else {
                exprFormat += expr[i];
            }
        }
    }

    // Now build the final C++ code snippet from the format string and args
    String cppExpr;
    if (newArgs.empty()) {
        // This was a static expression, so we can simplify the input
        // color declaration in the emitted code to just a static string
        cppExpr = "SkString " + cppVar + "(\"" + exprFormat + "\");";
    } else if (newArgs.size() == 1 && exprFormat == "%s") {
        // If the format expression is simply "%s", we can avoid an expensive call to printf.
        // This happens fairly often in codegen so it is worth simplifying.
        cppExpr = "SkString " + cppVar + "(" + newArgs[0] + ");";
    } else {
        // String formatting must occur dynamically, so have the C++ declaration
        // use SkStringPrintf with the format args that were accumulated
        // when the expression was written.
        cppExpr = "SkString " + cppVar + " = SkStringPrintf(\"" + exprFormat + "\"";
        for (size_t i = 0; i < newArgs.size(); i++) {
            cppExpr += ", " + newArgs[i];
        }
        cppExpr += ");";
    }
    return cppExpr;
}

bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
    this->write("    void emitCode(EmitArgs& args) override {\n"
                "        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;\n");
    this->writef("        const %s& _outer = args.fFp.cast<%s>();\n"
                 "        (void) _outer;\n",
                 fFullName.c_str(), fFullName.c_str());
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<GlobalVarDeclaration>()) {
            const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
            const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
            String nameString(decl.var().name());
            const char* name = nameString.c_str();
            if (SectionAndParameterHelper::IsParameter(decl.var()) &&
                is_accessible(decl.var())) {
                this->writef("        auto %s = _outer.%s;\n"
                             "        (void) %s;\n",
                             name, name, name);
            }
        }
    }
    this->writePrivateVarValues();
    for (const auto u : uniforms) {
        this->addUniform(*u);
    }
    this->writeSection(kEmitCodeSection);

    // Save original buffer as the CPP buffer for flushEmittedCode()
    fCPPBuffer = fOut;
    StringStream skslBuffer;
    fOut = &skslBuffer;

    this->newExtraEmitCodeBlock();

    // Generate mangled names and argument lists for helper functions.
    std::unordered_set<const FunctionDeclaration*> definedHelpers;
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<FunctionDefinition>()) {
            const FunctionDeclaration* decl = &p->as<FunctionDefinition>().declaration();
            definedHelpers.insert(decl);
            this->prepareHelperFunction(*decl);
        }
    }

    // Emit prototypes for defined helper functions that originally had prototypes in the FP file.
    // (If a function was prototyped but never defined, we skip it, since it wasn't prepared above.)
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<FunctionPrototype>()) {
            const FunctionDeclaration* decl = &p->as<FunctionPrototype>().declaration();
            if (definedHelpers.find(decl) != definedHelpers.end()) {
                this->prototypeHelperFunction(*decl);
            }
        }
    }

    bool result = INHERITED::generateCode();
    this->flushEmittedCode();

    // Then restore the original CPP buffer and close the function
    fOut = fCPPBuffer;
    fCPPBuffer = nullptr;
    this->write("    }\n");
    return result;
}

void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
    const char* fullName = fFullName.c_str();
    const Section* section = fSectionAndParameterHelper.getSection(kSetDataSection);
    const char* pdman = section ? section->argument().c_str() : "pdman";
    this->writef("    void onSetData(const GrGLSLProgramDataManager& %s, "
                                    "const GrFragmentProcessor& _proc) override {\n",
                 pdman);
    bool wroteProcessor = false;
    for (const Variable* u : uniforms) {
        if (is_uniform_in(*u)) {
            if (!wroteProcessor) {
                this->writef("        const %s& _outer = _proc.cast<%s>();\n", fullName, fullName);
                wroteProcessor = true;
                this->writef("        {\n");
            }

            const UniformCTypeMapper* mapper = UniformCTypeMapper::Get(fContext, *u);
            SkASSERT(mapper);

            String nameString(u->name());
            const char* name = nameString.c_str();

            // Switches for setData behavior in the generated code
            bool conditionalUniform = u->modifiers().fLayout.fWhen != "";
            bool isTracked = u->modifiers().fLayout.fFlags & Layout::kTracked_Flag;
            bool needsValueDeclaration = isTracked || !mapper->canInlineUniformValue();

            String uniformName = HCodeGenerator::FieldName(name) + "Var";

            String indent = "        "; // 8 by default, 12 when nested for conditional uniforms
            if (conditionalUniform) {
                // Add a pre-check to make sure the uniform was emitted
                // before trying to send any data to the GPU
                this->writef("        if (%s.isValid()) {\n", uniformName.c_str());
                indent += "    ";
            }

            String valueVar = "";
            if (needsValueDeclaration) {
                valueVar.appendf("%sValue", name);
                // Use AccessType since that will match the return type of _outer's public API.
                String valueType = HCodeGenerator::AccessType(fContext, u->type(),
                                                              u->modifiers().fLayout);
                this->writef("%s%s %s = _outer.%s;\n",
                             indent.c_str(), valueType.c_str(), valueVar.c_str(), name);
            } else {
                // Not tracked and the mapper only needs to use the value once
                // so send it a safe expression instead of the variable name
                valueVar.appendf("(_outer.%s)", name);
            }

            if (isTracked) {
                String prevVar = HCodeGenerator::FieldName(name) + "Prev";
                this->writef("%sif (%s) {\n"
                             "%s    %s;\n"
                             "%s    %s;\n"
                             "%s}\n", indent.c_str(),
                        mapper->dirtyExpression(valueVar, prevVar).c_str(), indent.c_str(),
                        mapper->saveState(valueVar, prevVar).c_str(), indent.c_str(),
                        mapper->setUniform(pdman, uniformName, valueVar).c_str(), indent.c_str());
            } else {
                this->writef("%s%s;\n", indent.c_str(),
                        mapper->setUniform(pdman, uniformName, valueVar).c_str());
            }

            if (conditionalUniform) {
                // Close the earlier precheck block
                this->writef("        }\n");
            }
        }
    }
    if (wroteProcessor) {
        this->writef("        }\n");
    }
    if (section) {
        int samplerIndex = 0;
        for (const ProgramElement* p : fProgram.elements()) {
            if (p->is<GlobalVarDeclaration>()) {
                const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
                const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
                const Variable& variable = decl.var();
                String nameString(variable.name());
                const char* name = nameString.c_str();
                if (variable.type().typeKind() == Type::TypeKind::kSampler) {
                    this->writef("        const GrSurfaceProxyView& %sView = "
                                 "_outer.textureSampler(%d).view();\n",
                                 name, samplerIndex);
                    this->writef("        GrTexture& %s = *%sView.proxy()->peekTexture();\n",
                                 name, name);
                    this->writef("        (void) %s;\n", name);
                    ++samplerIndex;
                } else if (needs_uniform_var(variable)) {
                    this->writef("        UniformHandle& %s = %sVar;\n"
                                    "        (void) %s;\n",
                                    name, HCodeGenerator::FieldName(name).c_str(), name);
                } else if (SectionAndParameterHelper::IsParameter(variable) &&
                           !variable.type().isFragmentProcessor()) {
                    if (!wroteProcessor) {
                        this->writef("        const %s& _outer = _proc.cast<%s>();\n", fullName,
                                     fullName);
                        wroteProcessor = true;
                    }

                    if (!variable.type().isFragmentProcessor()) {
                        this->writef("        auto %s = _outer.%s;\n"
                                        "        (void) %s;\n",
                                        name, name, name);
                    }
                }
            }
        }
        this->writeSection(kSetDataSection);
    }
    this->write("    }\n");
}

void CPPCodeGenerator::writeOnTextureSampler() {
    bool foundSampler = false;
    for (const auto& param : fSectionAndParameterHelper.getParameters()) {
        if (param->type().typeKind() == Type::TypeKind::kSampler) {
            if (!foundSampler) {
                this->writef(
                        "const GrFragmentProcessor::TextureSampler& %s::onTextureSampler(int "
                        "index) const {\n",
                        fFullName.c_str());
                this->writef("    return IthTextureSampler(index, %s",
                             HCodeGenerator::FieldName(String(param->name()).c_str()).c_str());
                foundSampler = true;
            } else {
                this->writef(", %s",
                             HCodeGenerator::FieldName(String(param->name()).c_str()).c_str());
            }
        }
    }
    if (foundSampler) {
        this->write(");\n}\n");
    }
}

void CPPCodeGenerator::writeClone() {
    if (!this->writeSection(kCloneSection)) {
        if (fSectionAndParameterHelper.getSection(kFieldsSection)) {
            fErrors.error(/*offset=*/0, "fragment processors with custom @fields must also have a "
                                        "custom @clone");
        }
        this->writef("%s::%s(const %s& src)\n"
                     ": INHERITED(k%s_ClassID, src.optimizationFlags())", fFullName.c_str(),
                     fFullName.c_str(), fFullName.c_str(), fFullName.c_str());
        for (const Variable* param : fSectionAndParameterHelper.getParameters()) {
            String fieldName = HCodeGenerator::FieldName(String(param->name()).c_str());
            if (!param->type().isFragmentProcessor()) {
                this->writef("\n, %s(src.%s)",
                             fieldName.c_str(),
                             fieldName.c_str());
            }
        }
        this->writef(" {\n");
        this->writef("        this->cloneAndRegisterAllChildProcessors(src);\n");
        int samplerCount = 0;
        for (const auto& param : fSectionAndParameterHelper.getParameters()) {
            if (param->type().typeKind() == Type::TypeKind::kSampler) {
                ++samplerCount;
            }
        }
        if (samplerCount) {
            this->writef("     this->setTextureSamplerCnt(%d);", samplerCount);
        }
        if (fAccessSampleCoordsDirectly) {
            this->writef("    this->setUsesSampleCoordsDirectly();\n");
        }
        this->write("}\n");
        this->writef("std::unique_ptr<GrFragmentProcessor> %s::clone() const {\n",
                     fFullName.c_str());
        this->writef("    return std::make_unique<%s>(*this);\n",
                     fFullName.c_str());
        this->write("}\n");
    }
}

void CPPCodeGenerator::writeDumpInfo() {
    this->writef("#if GR_TEST_UTILS\n"
                 "SkString %s::onDumpInfo() const {\n", fFullName.c_str());

    if (!this->writeSection(kDumpInfoSection)) {
        if (fSectionAndParameterHelper.getSection(kFieldsSection)) {
            fErrors.error(/*offset=*/0, "fragment processors with custom @fields must also have a "
                                        "custom @dumpInfo");
        }

        String formatString;
        std::vector<String> argumentList;

        for (const Variable* param : fSectionAndParameterHelper.getParameters()) {
            // dumpInfo() doesn't need to log child FPs.
            if (param->type().isFragmentProcessor()) {
                continue;
            }

            // Add this field onto the format string and argument list.
            String fieldName = HCodeGenerator::FieldName(String(param->name()).c_str());
            String runtimeValue = this->formatRuntimeValue(param->type(),
                                                           param->modifiers().fLayout,
                                                           param->name(),
                                                           &argumentList);
            formatString.appendf("%s%s=%s",
                                 formatString.empty() ? "" : ", ",
                                 fieldName.c_str(),
                                 runtimeValue.c_str());
        }

        if (!formatString.empty()) {
            // Emit the finished format string and associated arguments.
            this->writef("    return SkStringPrintf(\"(%s)\"", formatString.c_str());

            for (const String& argument : argumentList) {
                this->writef(", %s", argument.c_str());
            }

            this->write(");");
        } else {
            // No fields to dump at all; just return an empty string.
            this->write("    return SkString();");
        }
    }

    this->write("\n"
                "}\n"
                "#endif\n");
}

void CPPCodeGenerator::writeTest() {
    const Section* test = fSectionAndParameterHelper.getSection(kTestCodeSection);
    if (test) {
        this->writef(
                "GR_DEFINE_FRAGMENT_PROCESSOR_TEST(%s);\n"
                "#if GR_TEST_UTILS\n"
                "std::unique_ptr<GrFragmentProcessor> %s::TestCreate(GrProcessorTestData* %s) {\n",
                fFullName.c_str(),
                fFullName.c_str(),
                test->argument().c_str());
        this->writeSection(kTestCodeSection);
        this->write("}\n"
                    "#endif\n");
    }
}

static int bits_needed(uint32_t v) {
    int bits = 1;
    while (v >= (1u << bits)) {
        bits++;
    }
    return bits;
}

void CPPCodeGenerator::writeGetKey() {
    auto bitsForEnum = [&](const Type& type) {
        for (const ProgramElement* e : fProgram.elements()) {
            if (!e->is<Enum>() || type.name() != e->as<Enum>().typeName()) {
                continue;
            }
            SKSL_INT minVal = 0, maxVal = 0;
            auto gatherEnumRange = [&](StringFragment, SKSL_INT value) {
                minVal = std::min(minVal, value);
                maxVal = std::max(maxVal, value);
            };
            e->as<Enum>().foreach(gatherEnumRange);
            if (minVal < 0) {
                // Found a negative value in the enum, just use 32 bits
                return 32;
            }
            SkASSERT(SkTFitsIn<uint32_t>(maxVal));
            return bits_needed(maxVal);
        }
        SK_ABORT("Didn't find declaring element for enum type!");
        return 32;
    };

    this->writef("void %s::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
                                                "GrProcessorKeyBuilder* b) const {\n",
                 fFullName.c_str());
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<GlobalVarDeclaration>()) {
            const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
            const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
            const Variable& var = decl.var();
            const Type& varType = var.type();
            String nameString(var.name());
            const char* name = nameString.c_str();
            if (var.modifiers().fLayout.fFlags & Layout::kKey_Flag) {
                if (var.modifiers().fFlags & Modifiers::kUniform_Flag) {
                    fErrors.error(var.fOffset, "layout(key) may not be specified on uniforms");
                }
                if (is_private(var)) {
                    this->writef(
                            "%s %s =",
                            HCodeGenerator::FieldType(fContext, varType, var.modifiers().fLayout)
                                    .c_str(),
                            String(var.name()).c_str());
                    if (decl.value()) {
                        fCPPMode = true;
                        this->writeExpression(*decl.value(), Precedence::kAssignment);
                        fCPPMode = false;
                    } else {
                        this->writef("%s", default_value(var).c_str());
                    }
                    this->write(";\n");
                }
                if (var.modifiers().fLayout.fWhen.fLength) {
                    this->writef("if (%s) {", String(var.modifiers().fLayout.fWhen).c_str());
                }
                if (varType == *fContext.fTypes.fHalf4) {
                    this->writef("    uint16_t red = SkFloatToHalf(%s.fR);\n",
                                 HCodeGenerator::FieldName(name).c_str());
                    this->writef("    uint16_t green = SkFloatToHalf(%s.fG);\n",
                                 HCodeGenerator::FieldName(name).c_str());
                    this->writef("    uint16_t blue = SkFloatToHalf(%s.fB);\n",
                                 HCodeGenerator::FieldName(name).c_str());
                    this->writef("    uint16_t alpha = SkFloatToHalf(%s.fA);\n",
                                 HCodeGenerator::FieldName(name).c_str());
                    this->writef("    b->add32(((uint32_t)red << 16) | green, \"%s.rg\");\n", name);
                    this->writef("    b->add32(((uint32_t)blue << 16) | alpha, \"%s.ba\");\n",
                                 name);
                } else if (varType == *fContext.fTypes.fHalf ||
                           varType == *fContext.fTypes.fFloat) {
                    this->writef("    b->add32(sk_bit_cast<uint32_t>(%s), \"%s\");\n",
                                 HCodeGenerator::FieldName(name).c_str(), name);
                } else if (varType.isBoolean()) {
                    this->writef("    b->addBool(%s, \"%s\");\n",
                                 HCodeGenerator::FieldName(name).c_str(), name);
                } else if (varType.isEnum()) {
                    this->writef("    b->addBits(%d, (uint32_t) %s, \"%s\");\n",
                                 bitsForEnum(varType), HCodeGenerator::FieldName(name).c_str(),
                                 name);
                } else if (varType.isInteger()) {
                    this->writef("    b->add32((uint32_t) %s, \"%s\");\n",
                                 HCodeGenerator::FieldName(name).c_str(), name);
                } else {
                    SK_ABORT("NOT YET IMPLEMENTED: automatic key handling for %s\n",
                             varType.displayName().c_str());
                }
                if (var.modifiers().fLayout.fWhen.fLength) {
                    this->write("}");
                }
            }
        }
    }
    this->write("}\n");
}

bool CPPCodeGenerator::generateCode() {
    std::vector<const Variable*> uniforms;
    for (const ProgramElement* p : fProgram.elements()) {
        if (p->is<GlobalVarDeclaration>()) {
            const GlobalVarDeclaration& global = p->as<GlobalVarDeclaration>();
            const VarDeclaration& decl = global.declaration()->as<VarDeclaration>();
            if ((decl.var().modifiers().fFlags & Modifiers::kUniform_Flag) &&
                        decl.var().type().typeKind() != Type::TypeKind::kSampler) {
                uniforms.push_back(&decl.var());
            }

            if (is_uniform_in(decl.var())) {
                // Validate the "uniform in" declarations to make sure they are fully supported,
                // instead of generating surprising C++
                const UniformCTypeMapper* mapper =
                        UniformCTypeMapper::Get(fContext, decl.var());
                if (mapper == nullptr) {
                    fErrors.error(decl.fOffset, String(decl.var().name())
                            + "'s type is not supported for use as a 'uniform in'");
                    return false;
                }
            } else {
                // If it's not a uniform_in, it's an error to be tracked
                if (decl.var().modifiers().fLayout.fFlags & Layout::kTracked_Flag) {
                    fErrors.error(decl.fOffset, "Non-'in uniforms' cannot be tracked");
                    return false;
                }
            }
        }
    }
    const char* baseName = fName.c_str();
    const char* fullName = fFullName.c_str();
    this->writef("%s\n", HCodeGenerator::GetHeader(fProgram, fErrors).c_str());
    this->writef(kFragmentProcessorHeader, fullName);
    this->writef("#include \"%s.h\"\n\n", fullName);
    this->writeSection(kCppSection);
    this->writef("#include \"src/core/SkUtils.h\"\n"
                 "#include \"src/gpu/GrTexture.h\"\n"
                 "#include \"src/gpu/glsl/GrGLSLFragmentProcessor.h\"\n"
                 "#include \"src/gpu/glsl/GrGLSLFragmentShaderBuilder.h\"\n"
                 "#include \"src/gpu/glsl/GrGLSLProgramBuilder.h\"\n"
                 "#include \"src/sksl/SkSLCPP.h\"\n"
                 "#include \"src/sksl/SkSLUtil.h\"\n"
                 "class GrGLSL%s : public GrGLSLFragmentProcessor {\n"
                 "public:\n"
                 "    GrGLSL%s() {}\n",
                 baseName, baseName);
    bool result = this->writeEmitCode(uniforms);
    this->write("private:\n");
    this->writeSetData(uniforms);
    this->writePrivateVars();
    for (const auto& u : uniforms) {
        if (needs_uniform_var(*u) && !(u->modifiers().fFlags & Modifiers::kIn_Flag)) {
            this->writef("    UniformHandle %sVar;\n",
                         HCodeGenerator::FieldName(String(u->name()).c_str()).c_str());
        }
    }
    for (const auto& param : fSectionAndParameterHelper.getParameters()) {
        if (needs_uniform_var(*param)) {
            this->writef("    UniformHandle %sVar;\n",
                         HCodeGenerator::FieldName(String(param->name()).c_str()).c_str());
        }
    }
    this->writef("};\n"
                 "std::unique_ptr<GrGLSLFragmentProcessor> %s::onMakeProgramImpl() const {\n"
                 "    return std::make_unique<GrGLSL%s>();\n"
                 "}\n",
                 fullName, baseName);
    this->writeGetKey();
    this->writef("bool %s::onIsEqual(const GrFragmentProcessor& other) const {\n"
                 "    const %s& that = other.cast<%s>();\n"
                 "    (void) that;\n",
                 fullName, fullName, fullName);
    for (const auto& param : fSectionAndParameterHelper.getParameters()) {
        if (param->type().isFragmentProcessor()) {
            continue;
        }
        String nameString(param->name());
        const char* name = nameString.c_str();
        this->writef("    if (%s != that.%s) return false;\n",
                     HCodeGenerator::FieldName(name).c_str(),
                     HCodeGenerator::FieldName(name).c_str());
    }
    this->write("    return true;\n"
                "}\n");
    this->writeClone();
    this->writeDumpInfo();
    this->writeOnTextureSampler();
    this->writeTest();
    this->writeSection(kCppEndSection);

    result &= 0 == fErrors.errorCount();
    return result;
}

}  // namespace SkSL

#endif // defined(SKSL_STANDALONE) || GR_TEST_UTILS
