// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_JS_COLLECTION_H_
#define V8_OBJECTS_JS_COLLECTION_H_

#include "src/objects/js-collection-iterator.h"
#include "src/objects/objects.h"

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

class OrderedHashSet;
class OrderedHashMap;

#include "torque-generated/src/objects/js-collection-tq.inc"

class JSCollection
    : public TorqueGeneratedJSCollection<JSCollection, JSObject> {
 public:
  static const int kAddFunctionDescriptorIndex = 3;

  TQ_OBJECT_CONSTRUCTORS(JSCollection)
};

// The JSSet describes EcmaScript Harmony sets
class JSSet : public TorqueGeneratedJSSet<JSSet, JSCollection> {
 public:
  static void Initialize(Handle<JSSet> set, Isolate* isolate);
  static void Clear(Isolate* isolate, Handle<JSSet> set);
  void Rehash(Isolate* isolate);

  // Dispatched behavior.
  DECL_PRINTER(JSSet)
  DECL_VERIFIER(JSSet)

  TQ_OBJECT_CONSTRUCTORS(JSSet)
};

class JSSetIterator
    : public OrderedHashTableIterator<JSSetIterator, OrderedHashSet> {
 public:
  // Dispatched behavior.
  DECL_PRINTER(JSSetIterator)
  DECL_VERIFIER(JSSetIterator)

  DECL_CAST(JSSetIterator)

  OBJECT_CONSTRUCTORS(JSSetIterator,
                      OrderedHashTableIterator<JSSetIterator, OrderedHashSet>);
};

// The JSMap describes EcmaScript Harmony maps
class JSMap : public TorqueGeneratedJSMap<JSMap, JSCollection> {
 public:
  static void Initialize(Handle<JSMap> map, Isolate* isolate);
  static void Clear(Isolate* isolate, Handle<JSMap> map);
  void Rehash(Isolate* isolate);

  // Dispatched behavior.
  DECL_PRINTER(JSMap)
  DECL_VERIFIER(JSMap)

  TQ_OBJECT_CONSTRUCTORS(JSMap)
};

class JSMapIterator
    : public OrderedHashTableIterator<JSMapIterator, OrderedHashMap> {
 public:
  // Dispatched behavior.
  DECL_PRINTER(JSMapIterator)
  DECL_VERIFIER(JSMapIterator)

  DECL_CAST(JSMapIterator)

  // Returns the current value of the iterator. This should only be called when
  // |HasMore| returns true.
  inline Object CurrentValue();

  OBJECT_CONSTRUCTORS(JSMapIterator,
                      OrderedHashTableIterator<JSMapIterator, OrderedHashMap>);
};

// Base class for both JSWeakMap and JSWeakSet
class JSWeakCollection
    : public TorqueGeneratedJSWeakCollection<JSWeakCollection, JSObject> {
 public:
  static void Initialize(Handle<JSWeakCollection> collection, Isolate* isolate);
  V8_EXPORT_PRIVATE static void Set(Handle<JSWeakCollection> collection,
                                    Handle<Object> key, Handle<Object> value,
                                    int32_t hash);
  static bool Delete(Handle<JSWeakCollection> collection, Handle<Object> key,
                     int32_t hash);
  static Handle<JSArray> GetEntries(Handle<JSWeakCollection> holder,
                                    int max_entries);

  static const int kAddFunctionDescriptorIndex = 3;

  // Iterates the function object according to the visiting policy.
  class BodyDescriptorImpl;

  // Visit the whole object.
  using BodyDescriptor = BodyDescriptorImpl;

  static const int kHeaderSizeOfAllWeakCollections = kHeaderSize;

  TQ_OBJECT_CONSTRUCTORS(JSWeakCollection)
};

// The JSWeakMap describes EcmaScript Harmony weak maps
class JSWeakMap : public TorqueGeneratedJSWeakMap<JSWeakMap, JSWeakCollection> {
 public:
  // Dispatched behavior.
  DECL_PRINTER(JSWeakMap)
  DECL_VERIFIER(JSWeakMap)

  STATIC_ASSERT(kHeaderSize == kHeaderSizeOfAllWeakCollections);
  TQ_OBJECT_CONSTRUCTORS(JSWeakMap)
};

// The JSWeakSet describes EcmaScript Harmony weak sets
class JSWeakSet : public TorqueGeneratedJSWeakSet<JSWeakSet, JSWeakCollection> {
 public:
  // Dispatched behavior.
  DECL_PRINTER(JSWeakSet)
  DECL_VERIFIER(JSWeakSet)

  STATIC_ASSERT(kHeaderSize == kHeaderSizeOfAllWeakCollections);
  TQ_OBJECT_CONSTRUCTORS(JSWeakSet)
};

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_JS_COLLECTION_H_
