//===--- SyntaxData.h - Swift Syntax Data 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 SyntaxData interface, the type for the instance
// data for Syntax nodes.
//
// Effectively, these provide two main things to a Syntax node - parental
// relationships and caching for its children.
//
// A SyntaxData contains at least a strong reference to the RawSyntax,
// from which most information comes, and additionally a weak reference to
// its parent and the "index" at which it occurs in its parent. These were
// originally intended to have the important public APIs for structured
// editing but now contain no significant or public API; for those, see the
// Syntax type. These are purely to contain data, hence the name.
//
// Conceptually, SyntaxData add the characteristic of specific identity in a
// piece of Swift source code. While the RawSyntax for the integer literal
// token '1' can be reused anywhere a '1' occurs and has identical formatting,
// a SyntaxData represents *a* specific '1' at a particular location in
// Swift source.
//
// These are effectively internal implementation. For all public APIs, look
// for the type without "Data" in its name. For example, a StructDeclSyntaxData
// expresses its API through the wrapping StructDeclSyntax type.
//
//===----------------------------------------------------------------------===//


#ifndef SWIFT_SYNTAX_SYNTAXDATA_H
#define SWIFT_SYNTAX_SYNTAXDATA_H

#include "swift/Syntax/AtomicCache.h"
#include "swift/Syntax/RawSyntax.h"
#include "swift/Syntax/References.h"
#include "llvm/ADT/DenseMap.h"

#include <atomic>

namespace swift {
namespace syntax {

/// The class for holding parented syntax.
///
/// This structure should not contain significant public
/// API or internal modification API.
///
/// This is only for holding a strong reference to the RawSyntax, a weak
/// reference to the parent, and, in subclasses, lazily created strong
/// references to non-terminal child nodes.
class SyntaxData final
    : public llvm::ThreadSafeRefCountedBase<SyntaxData>,
      private llvm::TrailingObjects<SyntaxData, AtomicCache<SyntaxData>> {
  friend TrailingObjects;

  using RootDataPair = std::pair<RC<SyntaxData>, RC<SyntaxData>>;

  /// The shared raw syntax representing this syntax data node.
  const RC<RawSyntax> Raw;

  /// The parent of this syntax.
  ///
  /// WARNING! Do not access this directly. Use getParent(),
  /// which enforces nullptr checking.
  const SyntaxData *Parent;

  /// The index into the parent's child layout.
  ///
  /// If there is no parent, this is 0.
  const CursorIndex IndexInParent;

  /// Cache the absolute position of this node.
  Optional<AbsolutePosition> PositionCache;

  size_t numTrailingObjects(OverloadToken<AtomicCache<SyntaxData>>) const {
    return Raw->getNumChildren();
  }

  SyntaxData(RC<RawSyntax> Raw, const SyntaxData *Parent = nullptr,
             CursorIndex IndexInParent = 0)
      : Raw(Raw), Parent(Parent), IndexInParent(IndexInParent) {
    auto *I = getTrailingObjects<AtomicCache<SyntaxData>>();
    for (auto *E = I + getNumChildren(); I != E; ++I)
      ::new (static_cast<void *>(I)) AtomicCache<SyntaxData>();
  }

  /// With a new RawSyntax node, create a new node from this one and
  /// recursively rebuild the parental chain up to the root.
  ///
  /// DO NOT expose this as public API.
  RootDataPair replaceSelf(const RC<RawSyntax> NewRaw) const {
    if (hasParent()) {
      auto NewRootAndParent = Parent->replaceChild(NewRaw, IndexInParent);
      auto NewMe = NewRootAndParent.second->getChild(IndexInParent);
      return { NewRootAndParent.first, NewMe.get() };
    } else {
      auto NewMe = make(NewRaw, nullptr, IndexInParent);
      return { NewMe, NewMe.get() };
    }
  }

  /// Create the data for a child node with the raw syntax in our layout
  /// at the provided index.
  /// DO NOT expose this as public API.
  RC<SyntaxData> realizeSyntaxNode(CursorIndex Index) const {
    if (auto &RawChild = Raw->getChild(Index))
      return SyntaxData::make(RawChild, this, Index);
    return nullptr;
  }

  /// Replace a child in the raw syntax and recursively rebuild the
  /// parental chain up to the root.
  ///
  /// DO NOT expose this as public API.
  template <typename CursorType>
  RootDataPair replaceChild(const RC<RawSyntax> RawChild,
                            CursorType ChildCursor) const {
    auto NewRaw = Raw->replaceChild(ChildCursor, RawChild);
    return replaceSelf(NewRaw);
  }

  ArrayRef<AtomicCache<SyntaxData>> getChildren() const {
    return {getTrailingObjects<AtomicCache<SyntaxData>>(), getNumChildren()};
  }

public:
  /// Disable sized deallocation for SyntaxData, because it has tail-allocated
  /// data.
  void operator delete(void *p) { ::operator delete(p); }

  /// Get the node immediately before this current node that does contain a
  /// non-missing token. Return nullptr if we cannot find such node.
  RC<SyntaxData> getPreviousNode() const;

  /// Get the node immediately after this current node that does contain a
  /// non-missing token. Return nullptr if we cannot find such node.
  RC<SyntaxData> getNextNode() const;

  /// Get the first non-missing token node in this tree. Return nullptr if this
  /// node does not contain non-missing tokens.
  RC<SyntaxData> getFirstToken() const;

  /// Get the last non-missing token node in this tree. Return nullptr if this
  /// node does not contain non-missing tokens.
  RC<SyntaxData> getLastToken() const;

  ~SyntaxData() {
    for (auto &I : getChildren())
      I.~AtomicCache<SyntaxData>();
  }

  /// Constructs a SyntaxNode by replacing `self` and recursively building
  /// the parent chain up to the root.
  template <typename SyntaxNode>
  SyntaxNode replaceSelf(const RC<RawSyntax> NewRaw) const {
    auto NewRootAndData = replaceSelf(NewRaw);
    return { NewRootAndData.first, NewRootAndData.second.get() };
  }

  /// Replace a child in the raw syntax and recursively rebuild the
  /// parental chain up to the root.
  ///
  /// DO NOT expose this as public API.
  template <typename SyntaxNode, typename CursorType>
  SyntaxNode replaceChild(const RC<RawSyntax> RawChild,
                          CursorType ChildCursor) const {
    auto NewRootAndParent = replaceChild(RawChild, ChildCursor);
    return SyntaxNode {
      NewRootAndParent.first,
      NewRootAndParent.second.get()
    };
  }


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

  /// Returns the raw syntax node for this syntax node.
  const RC<RawSyntax> &getRaw() const {
    return Raw;
  }

  /// Returns the kind of syntax node this is.
  SyntaxKind getKind() const {
    return Raw->getKind();
  }

  /// Return the parent syntax if there is one.
  const SyntaxData * getParent() const {
    return Parent;
  }

  /// Returns true if this syntax node has a parent.
  bool hasParent() const {
    return Parent != nullptr;
  }

  /// Returns the child index of this node in its parent, if it has a parent,
  /// otherwise 0.
  size_t getIndexInParent() const {
    return IndexInParent;
  }

  /// Returns the number of children this SyntaxData represents.
  size_t getNumChildren() const {
    return Raw->getLayout().size();
  }

  /// Gets the child at the index specified by the provided cursor,
  /// lazily creating it if necessary.
  template <typename CursorType>
  RC<SyntaxData> getChild(CursorType Cursor) const {
    return getChild((size_t)cursorIndex(Cursor));
  }

  /// Gets the child at the specified index in this data's children array.
  /// Why do we need this?
  /// - SyntaxData nodes should have pointer identity.
  /// - We only want to construct parented, realized child nodes as
  ///   SyntaxData when asked.
  ///
  /// For example, if we have a ReturnStmtSyntax, and ask for its returned
  /// expression for the first time with getExpression(), two nodes can race
  /// to create and set the cached expression.
  ///
  /// Looking at an example - say we have a SyntaxData.
  ///
  /// SyntaxData = {
  ///   RC<RawSyntax> Raw = {
  ///     RC<RawTokenSyntax> { SyntaxKind::Token, tok::return_kw, "return" },
  ///     RC<RawSyntax> { SyntaxKind::SomeExpression, ... }
  ///   }
  ///   llvm::SmallVector<AtomicCache<SyntaxData>, 10> Children {
  ///     AtomicCache<SyntaxData> { RC<SyntaxData> = nullptr; },
  ///     AtomicCache<SyntaxData> { RC<SyntaxData> = nullptr; },
  ///   }
  /// }
  ///
  /// If we wanted to safely create the 0th child, an instance of TokenSyntax,
  /// then we ask the AtomicCache in that position to realize its value and
  /// cache it. This is safe because AtomicCache only ever mutates its cache
  /// one time -- the first initialization that wins a compare_exchange_strong.
  RC<SyntaxData> getChild(size_t Index) const {
    if (!getRaw()->getChild(Index))
      return nullptr;
    return getChildren()[Index].getOrCreate([&]() {
      return realizeSyntaxNode(Index);
    });
  }

  /// Calculate the absolute position of this node, use cache if the cache
  /// is populated.
  AbsolutePosition getAbsolutePosition() const;

  /// Calculate the absolute end position of this node, use cache of the immediate
  /// next node if populated.
  AbsolutePosition getAbsoluteEndPositionAfterTrailingTrivia() const;

  /// Get the absolute position without skipping the leading trivia of this
  /// node.
  AbsolutePosition getAbsolutePositionBeforeLeadingTrivia() const;

  /// Returns true if the data node represents type syntax.
  bool isType() const;

  /// Returns true if the data node represents statement syntax.
  bool isStmt() const;

  /// Returns true if the data node represents declaration syntax.
  bool isDecl() const;

  /// Returns true if the data node represents expression syntax.
  bool isExpr() const;

  /// Returns true if the data node represents pattern syntax.
  bool isPattern() const;

  /// Returns true if this syntax is of some "unknown" kind.
  bool isUnknown() const;

  /// Dump a debug description of the syntax data for debugging to
  /// standard error.
  void dump(llvm::raw_ostream &OS) const;

  LLVM_ATTRIBUTE_DEPRECATED(void dump() const LLVM_ATTRIBUTE_USED,
                            "Only meant for use in the debugger");
};

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

// DenseMapInfo for RC<SyntaxData>, used for a Syntax Node -> lib/AST mapping.
namespace llvm {
  using SD = swift::syntax::SyntaxData;
  using RCSD = swift::RC<SD>;
  template <> struct DenseMapInfo<RCSD> {
    static inline RCSD getEmptyKey() {
      return SD::make(nullptr, nullptr, 0);
    }
    static inline RCSD getTombstoneKey() {
        return SD::make(nullptr, nullptr, 0);
    }
    static unsigned getHashValue(const RCSD Value) {
      unsigned H = 0;
      H ^= DenseMapInfo<uintptr_t>::getHashValue(reinterpret_cast<const uintptr_t>(Value->getRaw().get()));
      H ^= DenseMapInfo<uintptr_t>::getHashValue(reinterpret_cast<const uintptr_t>(Value->getParent()));
      H ^= DenseMapInfo<swift::syntax::CursorIndex>::getHashValue(Value->getIndexInParent());
      return H;
    }
    static bool isEqual(const RCSD LHS, const RCSD RHS) {
      return LHS->getRaw().get() == RHS->getRaw().get() &&
             LHS->getParent() == RHS->getParent() &&
             LHS->getIndexInParent() == RHS->getIndexInParent();
    }
  };
}

#endif // SWIFT_SYNTAX_SYNTAXDATA_H
