//===--- StmtSyntax.h - Swift Statement Syntax Interface --------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the interface for statement-specific syntax nodes,
// such as for if- and while- statements.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SYNTAX_STMTSYNTAX_H
#define SWIFT_SYNTAX_STMTSYNTAX_H

#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/References.h"
#include "swift/Syntax/Syntax.h"
#include "swift/Syntax/SyntaxData.h"
#include "swift/Syntax/UnknownSyntax.h"

using llvm::Optional;

namespace swift {
namespace syntax {

class ExprSyntax;
class ExprSyntaxData;

#pragma mark - statement Data

class StmtSyntaxData : public SyntaxData {
protected:
  StmtSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                 CursorIndex IndexInParent = 0)
    : SyntaxData(Raw, Parent, IndexInParent) {}
public:
  static bool classof(const SyntaxData *S) {
    return S->isStmt();
  }
};

#pragma mark - statement API

/// statement -> expression ';'?
///            | declaration ';'?
///            | loop-statement ';'?
///            | branch-statement ';'?
///            | labeled-statement ';'?
///            | control-transfer-statement ';'?
///            | defer-statement ';'?
///            | do-statement ';'?
///            | compiler-control-statement ';'?
class StmtSyntax : public Syntax {
  friend class Syntax;
protected:
  StmtSyntax(const RC<SyntaxData> Root, const StmtSyntaxData *Data);
public:
  using DataType = StmtSyntaxData;
  static bool classof(const Syntax *S) {
    return S->isStmt();
  }
};

#pragma mark - unknown-statement Data

class UnknownStmtSyntaxData : public UnknownSyntaxData {
  UnknownStmtSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                        CursorIndex IndexInParent = 0);
public:
  static RC<UnknownStmtSyntaxData> make(RC<RawSyntax> Raw,
                                        const SyntaxData *Parent = nullptr,
                                        CursorIndex IndexInParent = 0);

  static bool classof(const SyntaxData *S) {
    return S->getKind() == SyntaxKind::UnknownStmt;
  }
};

#pragma mark - unknown-statement API

class UnknownStmtSyntax : public UnknownSyntax {
  friend class SyntaxData;
  friend class UnknownStmtSyntaxData;
  friend class LegacyASTTransformer;

  using DataType = UnknownStmtSyntaxData;

  UnknownStmtSyntax(const RC<SyntaxData> Root,
                    const UnknownStmtSyntaxData *Data);

public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::UnknownStmt;
  }
};

#pragma mark -
#pragma mark code-block Data

class CodeBlockStmtSyntaxData final : public StmtSyntaxData {
  friend class SyntaxData;
  friend class CodeBlockStmtSyntax;
  friend struct SyntaxFactory;

  CodeBlockStmtSyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
                          CursorIndex IndexInParent = 0);
  static RC<CodeBlockStmtSyntaxData> make(RC<RawSyntax> Raw,
                                          const SyntaxData *Parent = nullptr,
                                          CursorIndex IndexInParent = 0);
  static RC<CodeBlockStmtSyntaxData> makeBlank();
public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::CodeBlockStmt;
  }
};

#pragma mark -
#pragma mark code-block API

/// code-block -> '{' statements? '}'
class CodeBlockStmtSyntax : public StmtSyntax {
  enum class Cursor {
    LeftBrace,
    Elements,
    RightBrace,
  };
  friend struct SyntaxFactory;
  friend class CodeBlockStmtSyntaxData;
  friend class FunctionDeclSyntax;

  CodeBlockStmtSyntax(const RC<SyntaxData> Root, CodeBlockStmtSyntaxData *Data);

public:
  /// Returns the left brace of the code block.
  RC<TokenSyntax> getLeftBraceToken() const;

  /// Returns a new `CodeBlockSyntax` with the specified left brace token.
  CodeBlockStmtSyntax withLeftBraceToken(RC<TokenSyntax> NewLeftBrace) const;

  /// Return the n-th element in the code block.
  Syntax getElement(size_t n) const;

  /// Return a new `CodeBlockSyntax` with the added statement at the end,
  /// before the right brace token.
  CodeBlockStmtSyntax withAddedElement(Syntax AdditionalElement) const;

  /// Returns a new `CodeBlockSyntax` with `NewElements` substituted into
  /// the body.
  CodeBlockStmtSyntax
  withElements(const std::vector<Syntax> NewElements) const;

  /// Returns the right brace of the code block.
  RC<TokenSyntax> getRightBraceToken() const;

  /// Returns a new `CodeBlockSyntax` with the specified right brace token.
  CodeBlockStmtSyntax withRightBraceToken(RC<TokenSyntax> NewRightBraces) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::CodeBlockStmt;
  }
};

#pragma mark -
#pragma mark statements Data

using StmtListSyntaxData =
  SyntaxCollectionData<SyntaxKind::StmtList, StmtSyntax>;

#pragma mark -
#pragma mark statements API

/// statements -> statement
///             | statement statements
class StmtListSyntax final
    : public SyntaxCollection<SyntaxKind::StmtList, StmtSyntax> {
  friend struct SyntaxFactory;
  friend class Syntax;
  friend class SyntaxData;
  friend class FunctionDeclSyntax;

  using DataType = StmtListSyntaxData;

  StmtListSyntax(const RC<SyntaxData> Root, const DataType *Data)
    : SyntaxCollection(Root, Data) {}

public:
  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::StmtList;
  }
};

#pragma mark -
#pragma mark fallthrough-statement Data

class FallthroughStmtSyntaxData final : public StmtSyntaxData {
  friend class SyntaxData;
  friend class FallthroughStmtSyntax;
  friend struct SyntaxFactory;

  FallthroughStmtSyntaxData(RC<RawSyntax> Raw,
                            const SyntaxData *Parent = nullptr,
                            CursorIndex IndexInParent = 0);
  static RC<FallthroughStmtSyntaxData> make(RC<RawSyntax> Raw,
                                            const SyntaxData *Parent = nullptr,
                                            CursorIndex IndexInParent = 0);
  static RC<FallthroughStmtSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::FallthroughStmt;
  }
};

#pragma mark -
#pragma mark fallthrough-statement API

/// fallthrough-statement -> 'fallthrough'
class FallthroughStmtSyntax : public StmtSyntax {
  friend struct SyntaxFactory;
  friend class SyntaxData;
  friend class FallthroughStmtSyntaxData;

  using DataType = FallthroughStmtSyntaxData;

  enum class Cursor : CursorIndex {
    FallthroughKeyword,
  };

  FallthroughStmtSyntax(const RC<SyntaxData> Root,
                        const FallthroughStmtSyntaxData *Data);

  static FallthroughStmtSyntax make(RC<RawSyntax> Raw,
                                    const SyntaxData *Parent = nullptr,
                                    CursorIndex IndexInParent = 0);
  static FallthroughStmtSyntax makeBlank();

public:

  /// Get the 'fallthrough' keyword associated comprising this
  /// fallthrough statement.
  RC<TokenSyntax> getFallthroughKeyword() const;

  /// Return a new FallthroughStmtSyntax with the given fallthrough
  /// keyword.
  FallthroughStmtSyntax
  withFallthroughKeyword(RC<TokenSyntax> NewFallthroughKeyword) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::FallthroughStmt;
  }
};

#pragma mark - break-statement Data

class BreakStmtSyntaxData : public StmtSyntaxData {
  friend class SyntaxData;
  friend class BreakStmtSyntax;
  friend struct SyntaxFactory;
  BreakStmtSyntaxData(RC<RawSyntax> Raw,
                            const SyntaxData *Parent = nullptr,
                            CursorIndex IndexInParent = 0);
  static RC<BreakStmtSyntaxData> make(RC<RawSyntax> Raw,
                                      const SyntaxData *Parent = nullptr,
                                      CursorIndex IndexInParent = 0);
  static RC<BreakStmtSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::BreakStmt;
  }

};

#pragma mark - break-statement API

/// break-statement -> 'break' label-name?
/// label-name -> identifier
class BreakStmtSyntax : public StmtSyntax {
  friend struct SyntaxFactory;
  friend class BreakStmtSyntaxData;
  friend class SyntaxData;

  using DataType = BreakStmtSyntaxData;

  enum class Cursor : CursorIndex {
    BreakKeyword,
    Label
  };

  BreakStmtSyntax(const RC<SyntaxData> Root,
                  BreakStmtSyntaxData *Data);

  static BreakStmtSyntax make(RC<RawSyntax> Raw,
                                    const SyntaxData *Parent = nullptr,
                                    CursorIndex IndexInParent = 0);
  static BreakStmtSyntax makeBlank();
public:

  /// Return the 'break' keyword associated with this break statement.
  RC<TokenSyntax> getBreakKeyword() const;

  /// Return a new `BreakStmtSyntax` with the given 'break' keyword.
  BreakStmtSyntax withBreakKeyword(RC<TokenSyntax> NewBreakKeyword) const;

  /// Return the destination label of this break statement. If it doesn't
  /// have one, the token is marked as missing.
  RC<TokenSyntax> getLabel() const;

  /// Return a new `BreakStmtSyntax` with the given destination label.
  BreakStmtSyntax withLabel(RC<TokenSyntax> NewLabel) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::BreakStmt;
  }
};

#pragma mark - continue-statement Data

class ContinueStmtSyntaxData : public StmtSyntaxData {
  friend class SyntaxData;
  friend class ContinueStmtSyntax;
  friend struct SyntaxFactory;
  ContinueStmtSyntaxData(RC<RawSyntax> Raw,
                      const SyntaxData *Parent = nullptr,
                      CursorIndex IndexInParent = 0);
  static RC<ContinueStmtSyntaxData> make(RC<RawSyntax> Raw,
                                      const SyntaxData *Parent = nullptr,
                                      CursorIndex IndexInParent = 0);
  static RC<ContinueStmtSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::ContinueStmt;
  }

};

#pragma mark - continue-statement API

/// continue-statement -> 'continue' label-name?
/// label-name -> identifier
class ContinueStmtSyntax : public StmtSyntax {
  friend struct SyntaxFactory;
  friend class ContinueStmtSyntaxData;
  friend class SyntaxData;

  using DataType = ContinueStmtSyntaxData;

  enum class Cursor : CursorIndex {
    ContinueKeyword,
    Label
  };

  ContinueStmtSyntax(const RC<SyntaxData> Root,
                     ContinueStmtSyntaxData *Data);

  static ContinueStmtSyntax make(RC<RawSyntax> Raw,
                                 const SyntaxData *Parent = nullptr,
                                 CursorIndex IndexInParent = 0);
  static ContinueStmtSyntax makeBlank();
public:

  /// Return the 'continue' keyword associated with this continue statement.
  RC<TokenSyntax> getContinueKeyword() const;

  /// Return a new `ContinueStmtSyntax` with the given 'continue' keyword.
  ContinueStmtSyntax withContinueKeyword(RC<TokenSyntax> NewBreakKeyword) const;

  /// Return the destination label of this break statement. If it doesn't
  /// have one, the token is marked as continue.
  RC<TokenSyntax> getLabel() const;

  /// Return a new `ContinueStmtSyntax` with the given destination label.
  ContinueStmtSyntax withLabel(RC<TokenSyntax> NewLabel) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::ContinueStmt;
  }
};

#pragma mark - return-statement Data

class ReturnStmtSyntaxData : public StmtSyntaxData {
  friend class SyntaxData;
  friend class ReturnStmtSyntax;
  friend struct SyntaxFactory;

  RC<ExprSyntaxData> CachedExpression;

  ReturnStmtSyntaxData(RC<RawSyntax> Raw,
                       const SyntaxData *Parent = nullptr,
                       CursorIndex IndexInParent = 0);
  static RC<ReturnStmtSyntaxData> make(RC<RawSyntax> Raw,
                                       const SyntaxData *Parent = nullptr,
                                       CursorIndex IndexInParent = 0);
  static RC<ReturnStmtSyntaxData> makeBlank();

public:
  static bool classof(const SyntaxData *SD) {
    return SD->getKind() == SyntaxKind::ReturnStmt;
  }
  
};

#pragma mark - return-statement API

/// return-statement -> 'return' expression? ';'?
class ReturnStmtSyntax : public StmtSyntax {
  friend struct SyntaxFactory;
  friend class ReturnStmtSyntaxData;
  friend class SyntaxData;
  friend class Syntax;

  using DataType = ReturnStmtSyntaxData;

  enum class Cursor : CursorIndex {
    ReturnKeyword,
    Expression
  };

  ReturnStmtSyntax(const RC<SyntaxData> Root,
                   const ReturnStmtSyntaxData *Data);

  static ReturnStmtSyntax make(RC<RawSyntax> Raw,
                               const SyntaxData *Parent = nullptr,
                               CursorIndex IndexInParent = 0);
  static ReturnStmtSyntax makeBlank();
public:

  /// Return the 'return' keyword associated with this return statement.
  RC<TokenSyntax> getReturnKeyword() const;

  /// Return a new `ReturnStmtSyntax` with the given 'return' keyword.
  ReturnStmtSyntax withReturnKeyword(RC<TokenSyntax> NewReturnKeyword) const;

  /// Return the expression of this return statement.
  Optional<ExprSyntax> getExpression() const;

  /// Return a new `ReturnStmtSyntax` with the given destination label.
  ReturnStmtSyntax withExpression(ExprSyntax NewExpression) const;

  static bool classof(const Syntax *S) {
    return S->getKind() == SyntaxKind::ReturnStmt;
  }
};

} // end namespace syntax
} // end namespace swift

#endif
