// Copyright 2015 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_PROPERTY_DESCRIPTOR_H_
#define V8_PROPERTY_DESCRIPTOR_H_


#include "src/handles.h"
#include "src/property-details.h"


namespace v8 {
namespace internal {

class Isolate;
class Object;
class PropertyDescriptorObject;

class PropertyDescriptor {
 public:
  PropertyDescriptor()
      : enumerable_(false),
        has_enumerable_(false),
        configurable_(false),
        has_configurable_(false),
        writable_(false),
        has_writable_(false) {}

  // ES6 6.2.4.1
  static bool IsAccessorDescriptor(PropertyDescriptor* desc) {
    return desc->has_get() || desc->has_set();
  }

  // ES6 6.2.4.2
  static bool IsDataDescriptor(PropertyDescriptor* desc) {
    return desc->has_value() || desc->has_writable();
  }

  // ES6 6.2.4.3
  static bool IsGenericDescriptor(PropertyDescriptor* desc) {
    return !IsAccessorDescriptor(desc) && !IsDataDescriptor(desc);
  }

  // ES6 6.2.4.4
  Handle<Object> ToObject(Isolate* isolate);

  Handle<PropertyDescriptorObject> ToPropertyDescriptorObject(Isolate* isolate);

  // ES6 6.2.4.5
  static bool ToPropertyDescriptor(Isolate* isolate, Handle<Object> obj,
                                   PropertyDescriptor* desc);

  // ES6 6.2.4.6
  static void CompletePropertyDescriptor(Isolate* isolate,
                                         PropertyDescriptor* desc);

  bool is_empty() const {
    return !has_enumerable() && !has_configurable() && !has_writable() &&
           !has_value() && !has_get() && !has_set();
  }

  bool IsRegularAccessorProperty() const {
    return has_configurable() && has_enumerable() && !has_value() &&
           !has_writable() && has_get() && has_set();
  }

  bool IsRegularDataProperty() const {
    return has_configurable() && has_enumerable() && has_value() &&
           has_writable() && !has_get() && !has_set();
  }

  bool enumerable() const { return enumerable_; }
  void set_enumerable(bool enumerable) {
    enumerable_ = enumerable;
    has_enumerable_ = true;
  }
  bool has_enumerable() const { return has_enumerable_; }

  bool configurable() const { return configurable_; }
  void set_configurable(bool configurable) {
    configurable_ = configurable;
    has_configurable_ = true;
  }
  bool has_configurable() const { return has_configurable_; }

  Handle<Object> value() const { return value_; }
  void set_value(Handle<Object> value) { value_ = value; }
  bool has_value() const { return !value_.is_null(); }

  bool writable() const { return writable_; }
  void set_writable(bool writable) {
    writable_ = writable;
    has_writable_ = true;
  }
  bool has_writable() const { return has_writable_; }

  Handle<Object> get() const { return get_; }
  void set_get(Handle<Object> get) { get_ = get; }
  bool has_get() const { return !get_.is_null(); }

  Handle<Object> set() const { return set_; }
  void set_set(Handle<Object> set) { set_ = set; }
  bool has_set() const { return !set_.is_null(); }

  Handle<Object> name() const { return name_; }
  void set_name(Handle<Object> name) { name_ = name; }

  PropertyAttributes ToAttributes() {
    return static_cast<PropertyAttributes>(
        (has_enumerable() && !enumerable() ? DONT_ENUM : NONE) |
        (has_configurable() && !configurable() ? DONT_DELETE : NONE) |
        (has_writable() && !writable() ? READ_ONLY : NONE));
  }

 private:
  bool enumerable_ : 1;
  bool has_enumerable_ : 1;
  bool configurable_ : 1;
  bool has_configurable_ : 1;
  bool writable_ : 1;
  bool has_writable_ : 1;
  Handle<Object> value_;
  Handle<Object> get_;
  Handle<Object> set_;
  Handle<Object> name_;

  // Some compilers (Xcode 5.1, ARM GCC 4.9) insist on having a copy
  // constructor for std::vector<PropertyDescriptor>, so we can't
  // DISALLOW_COPY_AND_ASSIGN(PropertyDescriptor); here.
};

}  // namespace internal
}  // namespace v8

#endif  // V8_PROPERTY_DESCRIPTOR_H_
