%{
  # -*- mode: C++ -*-
  from gyb_syntax_support import *
  from gyb_syntax_support.Trivia import TRIVIAS
  # Ignore the following admonition; it applies to the resulting .h file only
}%
//// Automatically Generated From Trivia.h.gyb.
//// Do Not Edit Directly!
//===--- Trivia.h - Swift Syntax Trivia Interface ---------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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 "swift/Basic/JSONSerialization.h"
#include "swift/Basic/ByteTreeSerialization.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/YAMLTraits.h"

#include <vector>

namespace swift {
namespace syntax {

class AbsolutePosition;

/// The kind of source trivia, such as spaces, newlines, or comments.
enum class TriviaKind {
% for trivia in TRIVIAS:
  // ${trivia.comment}
  ${trivia.name},
% end
};

bool isCommentTriviaKind(TriviaKind kind);

/// 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.
class TriviaPiece {
  TriviaKind Kind;
  unsigned Count;
  OwnedString Text;

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

  friend struct json::ObjectTraits<TriviaPiece>;
  friend struct llvm::yaml::MappingTraits<TriviaPiece>;

public:

% for trivia in TRIVIAS:
% if trivia.is_collection():
  static TriviaPiece ${trivia.lower_name}s(unsigned Count) {
    return {TriviaKind::${trivia.name}, Count};
  }
  static TriviaPiece ${trivia.lower_name}() {
    return ${trivia.lower_name}s(1);
  }
% else:
  static TriviaPiece ${trivia.lower_name}(const OwnedString Text) {
    return {TriviaKind::${trivia.name}, Text};
  }
% end
% end

  static TriviaPiece fromText(TriviaKind kind, StringRef text);

  /// Return kind of the trivia.
  TriviaKind getKind() const { return Kind; }

  /// Return the text of the trivia.
  StringRef getText() const { return Text.str(); }

  /// Return the text of the trivia.
  unsigned getCount() const { return Count; }

  /// Return textual length of the trivia.
  size_t getTextLength() const {
    switch (Kind) {
% for trivia in TRIVIAS:
  case TriviaKind::${trivia.name}:
%   if trivia.is_collection():
      return Count * ${trivia.characters_len()};
%   else:
      return Text.size();
%   end
% end
    }
    llvm_unreachable("unhandled kind");
  }

  bool isComment() const {
    return isCommentTriviaKind(getKind());
  }

  void accumulateAbsolutePosition(AbsolutePosition &Pos) const;
  
  /// Try to compose this and Next to one TriviaPiece.
  /// It returns true if it is succeeded.
  bool trySquash(const TriviaPiece &Next);

  /// 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);
  }

  void Profile(llvm::FoldingSetNodeID &ID) const {
    ID.AddInteger(unsigned(Kind));
    switch (Kind) {
% for trivia in TRIVIAS:
  case TriviaKind::${trivia.name}:
%   if trivia.is_collection():
      ID.AddInteger(Count);
%   else:
      ID.AddString(Text.str());
%   end
    break;
% end
    }
  }
};

using TriviaList = std::vector<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.insert(Pieces.begin(), Piece);
  }

  /// Clear pieces.
  void clear() {
    Pieces.clear();
  }

  /// 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();
  }

  size_t getTextLength() const {
    size_t Len = 0;
    for (auto &P : Pieces)
      Len += P.getTextLength();
    return Len;
  }
  
  /// Append Next TriviaPiece or compose last TriviaPiece and
  /// Next TriviaPiece to one last TriviaPiece if it can.
  void appendOrSquash(const TriviaPiece &Next);

  /// 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);
  }

% for trivia in TRIVIAS:
%   if trivia.is_collection():
  static Trivia ${trivia.lower_name}s(unsigned Count) {
    if (Count == 0) {
      return {};
    }
    return {{TriviaPiece::${trivia.lower_name}s(Count)}};
  }
  static Trivia ${trivia.lower_name}() {
    return {{TriviaPiece::${trivia.lower_name}s(1)}};
  }
%   else:
  static Trivia ${trivia.lower_name}(const OwnedString Text) {
    assert(checkTriviaText(Text.str(), TriviaKind::${trivia.name}));
    return {{TriviaPiece::${trivia.lower_name}(Text)}};
  }
%   end
% end

private:
  static bool checkTriviaText(StringRef Text, TriviaKind Kind) {
    switch(Kind) {
    case TriviaKind::LineComment:
      return Text.startswith("//");
    case TriviaKind::BlockComment:
      return Text.startswith("/*") && Text.endswith("*/");
    case TriviaKind::DocLineComment:
      return Text.startswith("///");
    case TriviaKind::DocBlockComment:
      return Text.startswith("/**") && Text.endswith("*/");
    case TriviaKind::GarbageText:
      return !Text.empty();
% for trivia in TRIVIAS:
%   if trivia.is_collection():
    case TriviaKind::${trivia.name}: return true;
%   end
% end
  }
  }
};
} // namespace syntax

namespace byteTree {

template <>
struct WrapperTypeTraits<syntax::TriviaKind> {
  static uint8_t numericValue(const syntax::TriviaKind &Kind) {
    switch (Kind) {
% for trivia in TRIVIAS:
  case syntax::TriviaKind::${trivia.name}: return ${trivia.serialization_code};
% end
    }
    llvm_unreachable("unhandled kind");
  }

  static void write(ByteTreeWriter &Writer, const syntax::TriviaKind &Kind,
                    unsigned Index) {
    Writer.write(numericValue(Kind), Index);
  }
};

template <>
struct ObjectTraits<syntax::TriviaPiece> {
  static unsigned numFields(const syntax::TriviaPiece &Trivia,
                            UserInfoMap &UserInfo) {
    return 2;
  }

  static void write(ByteTreeWriter &Writer, const syntax::TriviaPiece &Trivia,
                    UserInfoMap &UserInfo) {
    Writer.write(Trivia.getKind(), /*Index=*/0);
    // Write the trivia's text or count depending on its kind
    switch (Trivia.getKind()) {
% for trivia in TRIVIAS:
    case syntax::TriviaKind::${trivia.name}:
% if trivia.is_collection():
      Writer.write(static_cast<uint32_t>(Trivia.getCount()), /*Index=*/1);
% else:
      Writer.write(Trivia.getText(), /*Index=*/1);
% end
      break;
% end
    }
  }
};

} // end namespace byteTree

namespace json {
/// Serialization traits for TriviaPiece.
/// - All trivia pieces will have a "kind" key that contains the serialized
///   name of the trivia kind.
/// - Comment trivia will have the associated text of the comment under the
///   "value" key.
/// - All other trivia will have the associated integer count of their
///   occurrences under the "value" key.
template<>
struct ObjectTraits<syntax::TriviaPiece> {
  static void mapping(Output &out, syntax::TriviaPiece &value) {
    auto kind = value.getKind();
    out.mapRequired("kind", kind);
    switch (kind) {
% for trivia in TRIVIAS:
    case syntax::TriviaKind::${trivia.name}: {
% if trivia.is_collection():
      auto count = value.getCount();
      out.mapRequired("value", count);
% else:
      auto text = value.getText();
      out.mapRequired("value", text);
% end
      break;
    }
% end
    }
  }
};

/// Serialization traits for TriviaKind.
template <>
struct ScalarReferenceTraits<syntax::TriviaKind> {
  static StringRef stringRef(const syntax::TriviaKind &value) {
    switch (value) {
% for trivia in TRIVIAS:
    case syntax::TriviaKind::${trivia.name}:
      return "\"${trivia.name}\"";
% end
    }
    llvm_unreachable("unhandled kind");
  }

  static bool mustQuote(StringRef) {
    // The string is already quoted. This is more efficient since it does not
    // check for characters that need to be escaped
    return false;
  }
};
} // namespace json
} // namespace swift

namespace llvm {
namespace yaml {

/// Deserialization traits for TriviaPiece.
/// - All trivia pieces will have a "kind" key that contains the serialized
///   name of the trivia kind.
/// - Comment trivia will have the associated text of the comment under the
///   "value" key.
/// - All other trivia will have the associated integer count of their
///   occurrences under the "value" key.
template<>
struct MappingTraits<swift::syntax::TriviaPiece> {
  static swift::syntax::TriviaPiece mapping(IO &in) {
    swift::syntax::TriviaKind kind;
    in.mapRequired("kind", kind);
    switch (kind) {
% for trivia in TRIVIAS:
    case swift::syntax::TriviaKind::${trivia.name}: {
% if trivia.is_collection():

/// FIXME: This is a workaround for existing bug from llvm yaml parser
/// which would raise error when deserializing number with trailing character
/// like "1\n". See https://bugs.llvm.org/show_bug.cgi?id=15505
      StringRef str;
      in.mapRequired("value", str);
      unsigned count = std::atoi(str.data());
      return swift::syntax::TriviaPiece(kind, count);
% else:
      StringRef text;
      in.mapRequired("value", text);
      return swift::syntax::TriviaPiece(
          kind, swift::OwnedString::makeRefCounted(text));
% end
      break;
    }
% end
    }
  }
};

/// Deserialization traits for TriviaKind.
template <>
struct ScalarEnumerationTraits<swift::syntax::TriviaKind> {
  static void enumeration(IO &in, swift::syntax::TriviaKind &value) {
% for trivia in TRIVIAS:
    in.enumCase(value, "${trivia.name}", swift::syntax::TriviaKind::${trivia.name});
% end
  }
};


} // namespace yaml
} // namespace llvm
#endif // SWIFT_SYNTAX_TRIVIA_H
