Broke DSLWriter into two separate classes

As DSLWriter evolved, it ended up performing two unrelated duties:

1. Holding per-thread state which is referenced throughout SkSL
   (including non-DSL code)
2. DSL-specific utility functions

There's no reason for those to be contained in the same class, and
there's also no reason the per-thread state should be held in a
DSL-specific class. This breaks out an SkSL::ThreadContext class to hold
the state info, leaving the DSL utility functions behind in DSLWriter
(which should perhaps be renamed, but that's a job for a future CL).

Change-Id: Iccd45314bd9b37d4a1d3e27920e32a50c0b07d7c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/456736
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/dsl/priv/DSLWriter.h b/src/sksl/dsl/priv/DSLWriter.h
index 9a57576..a3efcf4 100644
--- a/src/sksl/dsl/priv/DSLWriter.h
+++ b/src/sksl/dsl/priv/DSLWriter.h
@@ -8,214 +8,33 @@
 #ifndef SKSL_DSLWRITER
 #define SKSL_DSLWRITER
 
-#include "include/core/SkSpan.h"
 #include "include/core/SkStringView.h"
-#include "include/private/SkSLModifiers.h"
-#include "include/private/SkSLStatement.h"
-#include "include/sksl/DSLExpression.h"
-#include "include/sksl/DSLStatement.h"
-#include "src/sksl/SkSLMangler.h"
-#include "src/sksl/SkSLOperators.h"
-#include "src/sksl/SkSLParsedModule.h"
-#include "src/sksl/ir/SkSLExpressionStatement.h"
-#include "src/sksl/ir/SkSLProgram.h"
+#include "include/core/SkTypes.h"
 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
 #include "src/gpu/GrFragmentProcessor.h"
+#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
 #endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
-#include <list>
-#include <stack>
 
-class AutoDSLContext;
+#include <memory>
 
 namespace SkSL {
 
-class Compiler;
-class Context;
-class IRGenerator;
-class ProgramElement;
-class SymbolTable;
-class Type;
 class Variable;
+class Statement;
 
 namespace dsl {
 
 class DSLGlobalVar;
 class DSLParameter;
+class DSLStatement;
+class DSLVarBase;
 class DSLVar;
 
 /**
- * Thread-safe class that tracks per-thread state associated with DSL output. This class is for
- * internal use only.
+ * Various utility methods needed by DSL code.
  */
 class DSLWriter {
 public:
-    DSLWriter(SkSL::Compiler* compiler,  SkSL::ProgramKind kind,
-              const SkSL::ProgramSettings& settings, SkSL::ParsedModule module, bool isModule);
-
-    ~DSLWriter();
-
-    /**
-     * Returns true if the DSL has been started.
-     */
-    static bool IsActive();
-
-    /**
-     * Returns the Compiler used by DSL operations in the current thread.
-     */
-    static SkSL::Compiler& Compiler() { return *Instance().fCompiler; }
-
-    /**
-     * Returns the IRGenerator used by DSL operations in the current thread.
-     */
-    static SkSL::IRGenerator& IRGenerator();
-
-    /**
-     * Returns the Context used by DSL operations in the current thread.
-     */
-    static SkSL::Context& Context();
-
-    /**
-     * Returns the Settings used by DSL operations in the current thread.
-     */
-    static SkSL::ProgramSettings& Settings();
-
-    /**
-     * Returns the Program::Inputs used by the current thread.
-     */
-    static SkSL::Program::Inputs& Inputs();
-
-    /**
-     * Returns the collection to which DSL program elements in this thread should be appended.
-     */
-    static std::vector<std::unique_ptr<SkSL::ProgramElement>>& ProgramElements() {
-        return Instance().fProgramElements;
-    }
-
-    static std::vector<const ProgramElement*>& SharedElements() {
-        return Instance().fSharedElements;
-    }
-
-    /**
-     * Returns the SymbolTable of the current thread's IRGenerator.
-     */
-    static const std::shared_ptr<SkSL::SymbolTable>& SymbolTable();
-
-    /**
-     * Returns the current memory pool.
-     */
-    static std::unique_ptr<Pool>& MemoryPool() { return Instance().fPool; }
-
-    /**
-     * Returns the current modifiers pool.
-     */
-    static std::unique_ptr<ModifiersPool>& GetModifiersPool() { return Instance().fModifiersPool; }
-
-    /**
-     * Returns the current ProgramConfig.
-     */
-    static std::unique_ptr<ProgramConfig>& GetProgramConfig() { return Instance().fConfig; }
-
-    static bool IsModule() { return GetProgramConfig()->fIsBuiltinCode; }
-
-    static void Reset();
-
-    /**
-     * Returns the final pointer to a pooled Modifiers object that should be used to represent the
-     * given modifiers.
-     */
-    static const SkSL::Modifiers* Modifiers(const SkSL::Modifiers& modifiers);
-
-    /**
-     * Returns the SkSL variable corresponding to a DSL var.
-     */
-    static const SkSL::Variable* Var(DSLVarBase& var);
-
-    /**
-     * Creates an SkSL variable corresponding to a DSLParameter.
-     */
-    static std::unique_ptr<SkSL::Variable> CreateParameterVar(DSLParameter& var);
-
-
-    /**
-     * Returns the SkSL declaration corresponding to a DSLVar.
-     */
-    static std::unique_ptr<SkSL::Statement> Declaration(DSLVarBase& var);
-
-    /**
-     * For use in testing only: marks the variable as having been declared, so that it can be
-     * destroyed without generating errors.
-     */
-    static void MarkDeclared(DSLVarBase& var);
-
-    /**
-     * Returns the (possibly mangled) final name that should be used for an entity with the given
-     * raw name.
-     */
-    static skstd::string_view Name(skstd::string_view name);
-
-#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
-    /**
-     * Returns the fragment processor for which DSL output is being generated for the current
-     * thread.
-     */
-    static GrFragmentProcessor::ProgramImpl* CurrentProcessor() {
-        SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
-        return Instance().fStack.top().fProcessor;
-    }
-
-    /**
-     * Returns the EmitArgs for fragment processor output in the current thread.
-     */
-    static GrFragmentProcessor::ProgramImpl::EmitArgs* CurrentEmitArgs() {
-        SkASSERTF(!Instance().fStack.empty(), "This feature requires a FragmentProcessor");
-        return Instance().fStack.top().fEmitArgs;
-    }
-
-    static bool InFragmentProcessor() {
-        return !Instance().fStack.empty();
-    }
-
-    /**
-     * Pushes a new processor / emitArgs pair for the current thread.
-     */
-    static void StartFragmentProcessor(GrFragmentProcessor::ProgramImpl* processor,
-                                       GrFragmentProcessor::ProgramImpl::EmitArgs* emitArgs);
-
-    /**
-     * Pops the processor / emitArgs pair associated with the current thread.
-     */
-    static void EndFragmentProcessor();
-
-    static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
-#else
-    static bool InFragmentProcessor() {
-        return false;
-    }
-#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
-
-    /**
-     * Adds a new declaration into an existing declaration statement. This either turns the original
-     * declaration into an unscoped block or, if it already was, appends a new statement to the end
-     * of it.
-     */
-    static void AddVarDeclaration(DSLStatement& existing, DSLVar& additional);
-
-    /**
-     * Returns the ErrorReporter associated with the current thread. This object will be notified
-     * when any DSL errors occur.
-     */
-    static ErrorReporter& GetErrorReporter() {
-        return *Context().fErrors;
-    }
-
-    static void SetErrorReporter(ErrorReporter* errorReporter);
-
-    /**
-     * Notifies the current ErrorReporter that a DSL error has occurred. The default error handler
-     * prints the message to stderr and aborts.
-     */
-    static void ReportError(skstd::string_view msg, PositionInfo info = PositionInfo::Capture());
-
     /**
      * Returns whether name mangling is enabled. Mangling is important for the DSL because its
      * variables normally all go into the same symbol table; for instance if you were to translate
@@ -234,52 +53,52 @@
      * with x1 and x2 ending up in the same symbol table. This is fine as long as their effective
      * names are different, so mangling prevents this situation from causing problems.
      */
-    static bool ManglingEnabled() {
-        return Instance().fSettings.fDSLMangling;
-    }
+    static bool ManglingEnabled();
+
+    static skstd::string_view Name(skstd::string_view name);
+
+    /**
+     * Returns the SkSL variable corresponding to a DSL var.
+     */
+    static const SkSL::Variable* Var(DSLVarBase& var);
+
+    /**
+     * Creates an SkSL variable corresponding to a DSLParameter.
+     */
+    static std::unique_ptr<SkSL::Variable> CreateParameterVar(DSLParameter& var);
+
+    /**
+     * Returns the SkSL declaration corresponding to a DSLVar.
+     */
+    static std::unique_ptr<SkSL::Statement> Declaration(DSLVarBase& var);
+
+    /**
+     * For use in testing only: marks the variable as having been declared, so that it can be
+     * destroyed without generating errors.
+     */
+    static void MarkDeclared(DSLVarBase& var);
 
     /**
      * Returns whether DSLVars should automatically be marked declared upon creation. This is used
      * to simplify testing.
      */
-    static bool MarkVarsDeclared() {
-        return Instance().fSettings.fDSLMarkVarsDeclared;
-    }
+    static bool MarkVarsDeclared();
 
     /**
-     * Forwards any pending errors to the DSL ErrorReporter.
+     * Adds a new declaration into an existing declaration statement. This either turns the original
+     * declaration into an unscoped block or, if it already was, appends a new statement to the end
+     * of it.
      */
-    static void ReportErrors(PositionInfo pos);
+    static void AddVarDeclaration(DSLStatement& existing, DSLVar& additional);
 
-    static DSLWriter& Instance();
+    /**
+     * Clears any elements or symbols which have been output.
+     */
+    static void Reset();
 
-    static void SetInstance(std::unique_ptr<DSLWriter> instance);
-
-private:
-    class DefaultErrorReporter : public ErrorReporter {
-        void handleError(skstd::string_view msg, PositionInfo pos) override;
-    };
-
-    std::unique_ptr<SkSL::ProgramConfig> fConfig;
-    std::unique_ptr<SkSL::ModifiersPool> fModifiersPool;
-    SkSL::Compiler* fCompiler;
-    std::unique_ptr<Pool> fPool;
-    SkSL::ProgramConfig* fOldConfig;
-    SkSL::ModifiersPool* fOldModifiersPool;
-    std::vector<std::unique_ptr<SkSL::ProgramElement>> fProgramElements;
-    std::vector<const SkSL::ProgramElement*> fSharedElements;
-    DefaultErrorReporter fDefaultErrorReporter;
-    ErrorReporter& fOldErrorReporter;
-    ProgramSettings fSettings;
-    Mangler fMangler;
 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
-    struct StackFrame {
-        GrFragmentProcessor::ProgramImpl* fProcessor;
-        GrFragmentProcessor::ProgramImpl::EmitArgs* fEmitArgs;
-        SkSL::StatementArray fSavedDeclarations;
-    };
-    std::stack<StackFrame, std::list<StackFrame>> fStack;
-#endif // !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
+    static GrGLSLUniformHandler::UniformHandle VarUniformHandle(const DSLGlobalVar& var);
+#endif
 
     friend class DSLCore;
     friend class DSLVar;