//===--- SyntaxArena.cpp - SyntaxArena implementation -----------*- 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
//
//===----------------------------------------------------------------------===//

#include "swift/Syntax/SyntaxArena.h"
#include "swift/Syntax/RawSyntax.h"
#include "llvm/ADT/FoldingSet.h"

using namespace swift;
using namespace swift::syntax;

namespace {
class RawSyntaxCacheNode;
}

/// Implementation detail of SyntaxArena.
struct SyntaxArena::Implementation {
  /// Allocator.
  llvm::BumpPtrAllocator Allocator;

  /// List of pointers to the allocated RawSyntax
  std::vector<RawSyntax *> AllocatedRawSyntaxList;

  /// Cached Tokens.
  llvm::FoldingSet<RawSyntaxCacheNode> CachedTokens;

  Implementation() = default;
  void *Allocate(size_t size, size_t alignment) {
    return Allocator.Allocate(size, alignment);
  }

  void *AllocateRawSyntax(size_t size, size_t alignment) {
    void *data = Allocator.Allocate(size, alignment);
    /// Remember the allocated pointers so that we can destruct them.
    AllocatedRawSyntaxList.push_back(static_cast<RawSyntax *>(data));
    return data;
  }

  ~Implementation() {
    // Destruct all allocated RawSyntax. They might contain heap allocated
    // propeties and/or children.
    for (auto *N : AllocatedRawSyntaxList)
      N->~RawSyntax();
  }
};

SyntaxArena::SyntaxArena() : Impl(*new Implementation()){};
SyntaxArena::~SyntaxArena() { delete &Impl; }

llvm::BumpPtrAllocator &SyntaxArena::getAllocator() const {
  return Impl.Allocator;
}

void *SyntaxArena::Allocate(size_t size, size_t alignment) {
  return Impl.Allocate(size, alignment);
}

void *SyntaxArena::AllocateRawSyntax(size_t size, size_t alignment) {
  return Impl.AllocateRawSyntax(size, alignment);
}

namespace {

/// Cache node for RawSyntax.
class RawSyntaxCacheNode : public llvm::FoldingSetNode {

  friend llvm::FoldingSetTrait<RawSyntaxCacheNode>;

  /// Associated RawSyntax.
  RawSyntax *Obj;
  /// FoldingSet node identifier of the associated RawSyntax.
  llvm::FoldingSetNodeIDRef IDRef;

public:
  RawSyntaxCacheNode(RawSyntax *Obj, const llvm::FoldingSetNodeIDRef IDRef)
      : Obj(Obj), IDRef(IDRef) {}

  /// Retrieve assciated RawSyntax.
  RawSyntax *get() { return Obj; }

  // Only allow allocation of Node using the allocator in SyntaxArena.
  void *operator new(size_t Bytes, SyntaxArena &Arena,
                     unsigned Alignment = alignof(RawSyntaxCacheNode)) {
    return Arena.Allocate(Bytes, Alignment);
  }

  void *operator new(size_t Bytes) throw() = delete;
  void operator delete(void *Data) throw() = delete;
};

} // namespace

namespace llvm {

/// FoldingSet traits for RawSyntax wrapper.
template <> struct FoldingSetTrait<RawSyntaxCacheNode> {

  static inline void Profile(RawSyntaxCacheNode &X, FoldingSetNodeID &ID) {
    ID.AddNodeID(X.IDRef);
  }

  static inline bool Equals(RawSyntaxCacheNode &X, const FoldingSetNodeID &ID,
                            unsigned, FoldingSetNodeID &) {
    return ID == X.IDRef;
  }
  static inline unsigned ComputeHash(RawSyntaxCacheNode &X,
                                     FoldingSetNodeID &) {
    return X.IDRef.ComputeHash();
  }
};

} // namespace llvm

/// Retrive "token" RawSyntax from the given Arena.
RC<RawSyntax> RawSyntax::getToken(SyntaxArena &Arena, tok TokKind,
                                  OwnedString Text,
                                  llvm::ArrayRef<TriviaPiece> LeadingTrivia,
                                  llvm::ArrayRef<TriviaPiece> TrailingTrivia) {

  // Determine whether this token is worth to cache.
  if (
      // Is string_literal with >16 length.
      (TokKind == tok::string_literal && Text.size() > 16) ||
      // Has leading comment trivia et al.
      any_of(LeadingTrivia,
             [](const syntax::TriviaPiece &T) { return T.getText().size(); }) ||
      // Has trailing comment trivia et al.
      any_of(TrailingTrivia,
             [](const syntax::TriviaPiece &T) { return T.getText().size(); })) {

    // Do not use cache.
    return RawSyntax::make(TokKind, Text, LeadingTrivia, TrailingTrivia,
                           SourcePresence::Present, &Arena);
  }

  // This node is cacheable. Get or create.
  auto &CachedTokens = Arena.Impl.CachedTokens;

  llvm::FoldingSetNodeID ID;
  RawSyntax::Profile(ID, TokKind, Text, LeadingTrivia, TrailingTrivia);

  void *insertPos = nullptr;
  if (auto existing = CachedTokens.FindNodeOrInsertPos(ID, insertPos))
    // Found in the cache. Just return it.
    return existing->get();

  // Could not found in the cache. Create it.
  auto Raw = RawSyntax::make(TokKind, Text, LeadingTrivia, TrailingTrivia,
                             SourcePresence::Present, &Arena);
  auto IDRef = ID.Intern(Arena.getAllocator());
  auto CacheNode = new (Arena) RawSyntaxCacheNode(Raw.get(), IDRef);
  CachedTokens.InsertNode(CacheNode, insertPos);
  return Raw;
}
