//===--- Trivia.h - Swift Syntax Trivia 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 a data structure representing "trivia" in the Swift
// language, such as formatting text like whitespace, or other pieces of
// syntax that don't affect program behavior, like comments.
//
// All source trivia except for comments are kind of "run-length encoded".
// For example, a token might follow 2 newlines and 2 spaces, like so:
//
// func foo() {
//   var x = 2
// }
//
// Here, the 'var' keyword would have the following "leading" trivia:
// [ Newlines(2), Spaces(2) ]
//
// and the following "trailing" trivia:
// [ Spaces(1) ]
//
// Every terminal token in the tree has "leading" and "trailing" trivia.
//
// There is one basic rule to follow when attaching trivia:
//
// 1. A token owns all of its trailing trivia up to, but not including,
//    the next newline character.
//
// 2. Looking backward in the text, a token owns all of the leading trivia
//    up to and including the first contiguous sequence of newlines characters.
//
// For this example again:
//
// func foo() {
//   var x = 2
// }
//
// 'func'
// - Has no leading trivia.
// - Takes up the space after because of rule 1.
// - Leading: [] Trailing: [ Space(1) ]
//
// 'foo'
// - Has no leading trivia. 'func' ate it as its trailing trivia.
// - Has no trailing trivia, because it is butted up against the next '('.
// - Leading: [] Trailing: []
//
// '('
// - Has no leading or trailing trivia.
// - Leading: [] Trailing: []
//
// ')'
// - Has no leading trivia.
// - Takes up the space after because of rule 1.
// - Leading: [] Trailing: [ Space(1) ]
//
// '{'
// - Has no leading trivia. ')' ate it as its trailing trivia.
// - Has no trailing trivia. Because of Rule 1, it doesn't take the newline.
// - Leading: [] Trailing: []
//
// 'var'
// - Takes the newline and preceding two spaces because of Rule 2.
// - Takes the single space that follows because of Rule 1.
// - Leading: [ Newline(1), Space(2) ] Trailing: [ Space(1) ]
//
// ... and so on.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SYNTAX_TRIVIA_H
#define SWIFT_SYNTAX_TRIVIA_H

#include "swift/Basic/OwnedString.h"
#include "llvm/Support/raw_ostream.h"

#include <deque>

namespace swift {
namespace syntax {

class AbsolutePosition;

/// The kind of source trivia, such as spaces, newlines, or comments.
enum class TriviaKind {
  /// A space ' ' character.
  Space,

  /// A tab '\t' character.
  Tab,

  /// A vertical tab '\v' character.
  VerticalTab,

  /// A form-feed '\f' character.
  Formfeed,

  /// A newline '\n' character.
  Newline,

  /// A developer line comment, starting with '//'
  LineComment,

  /// A developer block comment, starting with '/*' and ending with '*/'.
  BlockComment,

  /// A documentation line comment, starting with '///'.
  DocLineComment,

  /// A documentation block comment, starting with '/**' and ending with '*/.
  DocBlockComment,

  /// A backtick '`' character, used to escape identifiers.
  Backtick,
};

/// A contiguous stretch of a single kind of trivia. The constituent part of
/// a `Trivia` collection.
///
/// For example, four spaces would be represented by
/// { TriviaKind::Space, 4, "" }.
///
/// All trivia except for comments don't need to store text, since they can be
/// reconstituted using their Kind and Count.
///
/// In general, you should deal with the actual Trivia collection instead
/// of individual pieces whenever possible.
struct TriviaPiece {
  TriviaKind Kind;
  unsigned Count;
  OwnedString Text;

  TriviaPiece(const TriviaKind Kind, const unsigned Count,
              const OwnedString Text)
      : Kind(Kind), Count(Count), Text(Text) {}

  /// Return a piece of trivia for some number of space characters in a row.
  static TriviaPiece spaces(unsigned Count) {
    return TriviaPiece {TriviaKind::Space, Count, OwnedString{}};
  }

  /// Return a piece of trivia for some number of tab characters in a row.
  static TriviaPiece tabs(unsigned Count) {
    return TriviaPiece {TriviaKind::Tab, Count, OwnedString{}};
  }

  /// Return a piece of trivia for some number of newline characters
  /// in a row.
  static TriviaPiece newlines(unsigned Count) {
    return TriviaPiece {TriviaKind::Newline, Count, OwnedString{}};
  }

  /// Return a piece of trivia for a single line of ('//') developer comment.
  static TriviaPiece lineComment(const OwnedString Text) {
    return TriviaPiece {TriviaKind::LineComment, 1, Text};
  }

  /// Return a piece of trivia for a block comment ('/* ... */')
  static TriviaPiece blockComment(const OwnedString Text) {
    return TriviaPiece {TriviaKind::BlockComment, 1, Text};
  }

  /// Return a piece of trivia for a single line of ('///') doc comment.
  static TriviaPiece docLineComment(const OwnedString Text) {
    return TriviaPiece {TriviaKind::DocLineComment, 1, Text};
  }

  /// Return a piece of trivia for a documentation block comment ('/** ... */')
  static TriviaPiece docBlockComment(const OwnedString Text) {
    return TriviaPiece {TriviaKind::DocBlockComment, 1, Text};
  }

  /// Return a piece of trivia for a single backtick '`' for escaping
  /// an identifier.
  static TriviaPiece backtick() {
    return TriviaPiece {TriviaKind::Backtick, 1, OwnedString{}};
  }

  void accumulateAbsolutePosition(AbsolutePosition &Pos) const;

  /// Print a debug representation of this trivia piece to the provided output
  /// stream and indentation level.
  void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const;

  /// Print this piece of trivia to the provided output stream.
  void print(llvm::raw_ostream &OS) const;

  bool operator==(const TriviaPiece &Other) const {
    return Kind == Other.Kind &&
           Count == Other.Count &&
           Text.str().compare(Other.Text.str()) == 0;
  }

  bool operator!=(const TriviaPiece &Other) const {
    return !(*this == Other);
  }
};

using TriviaList = std::deque<TriviaPiece>;

/// A collection of leading or trailing trivia. This is the main data structure
/// for thinking about trivia.
struct Trivia {
  TriviaList Pieces;

  /// Get the begin iterator of the pieces.
  TriviaList::const_iterator begin() const {
    return Pieces.begin();
  }

  /// Get the end iterator of the pieces.
  TriviaList::const_iterator end() const {
    return Pieces.end();
  }

  /// Add a piece to the end of the collection.
  void push_back(const TriviaPiece &Piece) {
    Pieces.push_back(Piece);
  }

  /// Add a piece to the beginning of the collection.
  void push_front(const TriviaPiece &Piece) {
    Pieces.push_front(Piece);
  }

  /// Return a reference to the first piece.
  ///
  /// Precondition: !empty()
  const TriviaPiece &front() const {
    assert(!empty());
    return Pieces.front();
  }

  /// Return a reference to the last piece.
  ///
  /// Precondition: !empty()
  const TriviaPiece &back() const  {
    assert(!empty());
    return Pieces.back();
  }

  /// Remove the last piece from the Trivia collection.
  ///
  /// Precondition: !empty()
  void pop_back() {
    assert(!empty());
    Pieces.pop_back();
  }

  /// Returns true if there are no pieces in this Trivia collection.
  bool empty() const {
    return Pieces.empty();
  }

  /// Return the number of pieces in this Trivia collection.
  size_t size() const {
    return Pieces.size();
  }

  /// Dump a debug representation of this Trivia collection to standard error.
  void dump() const;

  /// Dump a debug representation of this Trivia collection to the provided
  /// stream and indentation level.
  void dump(llvm::raw_ostream &OS, unsigned Indent = 0) const;

  /// Print all of the pieces to the provided output stream in source order.
  void print(llvm::raw_ostream &OS) const;

  /// Return a new Trivia collection by appending pieces from `Other`.
  Trivia appending(const Trivia &Other) const;
  Trivia operator+(const Trivia &Other) const;

  /// Look for the first TriviaPiece with the DesiredKind. If not found,
  /// returns the end iterator.
  TriviaList::const_iterator find(const TriviaKind DesiredKind) const;

  /// Returns true if the Trivia collection contains a piece of the given Kind.
  bool contains(const TriviaKind Kind) const {
    return find(Kind) != end();
  }

  bool operator==(const Trivia &Other) const {
    if (Pieces.size() != Other.size()) {
      return false;
    }

    for (size_t i = 0; i < Pieces.size(); ++i) {
      if (Pieces[i] != Other.Pieces[i]) {
        return false;
      }
    }

    return true;
  }

  bool operator!=(const Trivia &Other) const {
    return !(*this == Other);
  }

  /// Return a collection of trivia of some number of space characters in a row.
  static Trivia spaces(unsigned Count) {
    if (Count == 0) {
      return {};
    }
    return {{ TriviaPiece {TriviaKind::Space, Count, OwnedString{}} }};
  }

  /// Return a collection of trivia of some number of tab characters in a row.
  static Trivia tabs(unsigned Count) {
    if (Count == 0) {
      return {};
    }
    return {{ TriviaPiece {TriviaKind::Tab, Count, OwnedString{}} }};
  }

  /// Return a collection of trivia of some number of newline characters
  // in a row.
  static Trivia newlines(unsigned Count) {
    if (Count == 0) {
      return {};
    }
    return {{ TriviaPiece {TriviaKind::Newline, Count, OwnedString{}} }};
  }

  /// Return a collection of trivia with a single line of ('//')
  // developer comment.
  static Trivia lineComment(const OwnedString Text) {
    assert(Text.str().startswith("//"));
    return {{ TriviaPiece {TriviaKind::LineComment, 1, Text} }};
  }

  /// Return a collection of trivia with a block comment ('/* ... */')
  static Trivia blockComment(const OwnedString Text) {
    assert(Text.str().startswith("/*"));
    assert(Text.str().endswith("*/"));
    return {{ TriviaPiece {TriviaKind::BlockComment, 1, Text} }};
  }

  /// Return a collection of trivia with a single line of ('///') doc comment.
  static Trivia docLineComment(const OwnedString Text) {
    assert(Text.str().startswith("///"));
    return {{ TriviaPiece {TriviaKind::DocLineComment, 1, Text} }};
  }

  /// Return a collection of trivia with a documentation block
  // comment ('/** ... */')
  static Trivia docBlockComment(const OwnedString Text) {
    assert(Text.str().startswith("/**"));
    assert(Text.str().endswith("*/"));
    return {{ TriviaPiece {TriviaKind::DocBlockComment, 1, Text} }};
  }

  /// Return a piece of trivia for a single backtick '`' for escaping
  /// an identifier.
  static Trivia backtick() {
    return {{ TriviaPiece {TriviaKind::Backtick, 1, OwnedString{}} }};
  }
};
}
}
#endif // SWIFT_SYNTAX_TRIVIA_H
