text: /*
   * Copyright 2017 Google Inc.
   *
   * Use of this source code is governed by a BSD-style license that can be
   * found in the LICENSE file.
   */
  
  #ifndef SKSL_SWITCHSTATEMENT
  #define SKSL_SWITCHSTATEMENT
  
  #include "include/private/SkSLStatement.h"
  #include "src/sksl/ir/SkSLSwitchCase.h"
  
  #include <memory>
  #include <vector>
  
  namespace SkSL {
  
  class Expression;
  class SymbolTable;
  
  /**
   * A 'switch' statement.
   */
  class SwitchStatement final : public Statement {
  public:
      static constexpr Kind kStatementKind = Kind::kSwitch;
  
      SwitchStatement(int offset, bool isStatic, std::unique_ptr<Expression> value,
                      StatementArray cases, std::shared_ptr<SymbolTable> symbols)
          : INHERITED(offset, kStatementKind)
          , fIsStatic(isStatic)
          , fValue(std::move(value))
          , fCases(std::move(cases))
          , fSymbols(std::move(symbols)) {}
  
      // Create a `switch` statement with an array of case-values and case-statements.
      // Coerces case values to the proper type and reports an error if cases are duplicated.
      // Reports errors via the ErrorReporter.
      static std::unique_ptr<Statement> Convert(const Context& context,
                                                int offset,
                                                bool isStatic,
                                                std::unique_ptr<Expression> value,
                                                ExpressionArray caseValues,
                                                StatementArray caseStatements,
                                                std::shared_ptr<SymbolTable> symbolTable);
  
      // Create a `switch` statement with an array of SwitchCases. The array of SwitchCases must
      // already contain non-overlapping, correctly-typed case values. Reports errors via ASSERT.
      static std::unique_ptr<Statement> Make(const Context& context,
                                             int offset,
                                             bool isStatic,
                                             std::unique_ptr<Expression> value,
                                             StatementArray cases,
                                             std::shared_ptr<SymbolTable> symbolTable);
  
      // Returns a block containing all of the statements that will be run if the given case matches
      // (which, owing to the statements being owned by unique_ptrs, means the switch itself will be
      // disassembled by this call and must then be discarded).
      // Returns null (and leaves the switch unmodified) if no such simple reduction is possible, such
      // as when break statements appear inside conditionals.
      static std::unique_ptr<Statement> BlockForCase(StatementArray* cases,
                                                     SwitchCase* caseToCapture,
                                                     std::shared_ptr<SymbolTable> symbolTable);
  
      std::unique_ptr<Expression>& value() {
          return fValue;
      }
  
      const std::unique_ptr<Expression>& value() const {
          return fValue;
      }
  
      StatementArray& cases() {
          return fCases;
      }
  
      const StatementArray& cases() const {
          return fCases;
      }
  
      bool isStatic() const {
          return fIsStatic;
      }
  
      const std::shared_ptr<SymbolTable>& symbols() const {
          return fSymbols;
      }
  
      std::unique_ptr<Statement> clone() const override;
  
      String description() const override;
  
  private:
      bool fIsStatic;
      std::unique_ptr<Expression> fValue;
      StatementArray fCases;  // every Statement inside fCases must be a SwitchCase
      std::shared_ptr<SymbolTable> fSymbols;
  
      using INHERITED = Statement;
  };
  
  }  // namespace SkSL
  
  #endif
  