// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_
#define COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_

#include <cmath>

#include <limits>
#include <string>
#include <vector>

#include "base/logging.h"
#include "base/optional.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "cobalt/base/compiler.h"
#include "cobalt/base/enable_if.h"
#include "cobalt/base/token.h"
#include "cobalt/script/sequence.h"
#include "cobalt/script/v8c/algorithm_helpers.h"
#include "cobalt/script/v8c/helpers.h"
#include "cobalt/script/v8c/type_traits.h"
#include "cobalt/script/v8c/union_type_conversion_forward.h"
#include "cobalt/script/v8c/v8c_array_buffer.h"
#include "cobalt/script/v8c/v8c_array_buffer_view.h"
#include "cobalt/script/v8c/v8c_callback_interface_holder.h"
#include "cobalt/script/v8c/v8c_data_view.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "cobalt/script/v8c/v8c_typed_arrays.h"
#include "cobalt/script/v8c/v8c_user_object_holder.h"
#include "cobalt/script/v8c/v8c_value_handle.h"
#include "cobalt/script/value_handle.h"
#include "nb/memory_scope.h"
#include "v8/include/v8.h"

namespace cobalt {
namespace script {
namespace v8c {

// Flags that can be used as a bitmask for special conversion behaviour.
enum ConversionFlags {
  kNoConversionFlags = 0,
  kConversionFlagRestricted = 1 << 0,
  kConversionFlagNullable = 1 << 1,
  kConversionFlagTreatNullAsEmptyString = 1 << 2,
  kConversionFlagTreatUndefinedAsEmptyString = 1 << 3,
  kConversionFlagClamped = 1 << 4,
  kConversionFlagObjectOnly = 1 << 5,

  // Valid conversion flags for numeric values.
  kConversionFlagsNumeric = kConversionFlagRestricted | kConversionFlagClamped,

  // Valid conversion flags for string types.
  kConversionFlagsString = kConversionFlagTreatNullAsEmptyString |
                           kConversionFlagTreatUndefinedAsEmptyString,

  // Valid conversion flags for objects.
  kConversionFlagsObject = kConversionFlagNullable,

  // Valid conversion flags for ValueHandles.
  kConversionFlagsValueHandle =
      kConversionFlagObjectOnly | kConversionFlagNullable,

  // Valid conversion flags for callback functions.
  kConversionFlagsCallbackFunction = kConversionFlagNullable,

  // Valid conversion flags for callback interfaces.
  kConversionFlagsCallbackInterface = kConversionFlagNullable,
};

// std::string -> JSValue
inline void ToJSValue(v8::Isolate* isolate, const std::string& in_string,
                      v8::Local<v8::Value>* out_value) {
  v8::MaybeLocal<v8::String> maybe_string = v8::String::NewFromUtf8(
      isolate, in_string.data(), v8::NewStringType::kNormal, in_string.size());
  v8::Local<v8::Value> string;
  if (!maybe_string.ToLocal(&string)) {
    *out_value = v8::Null(isolate);
    return;
  }

  *out_value = string;
}

// JSValue -> std::string
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 std::string* out_string);

// std::vector<uint8_t> -> JSValue
// Note that this conversion is specifically for the Web IDL type ByteString.
// Ideally, conversion requests would be explicit in what type they wanted to
// convert to, however it is currently solely based on input type.
inline void ToJSValue(v8::Isolate* isolate, const std::vector<uint8_t>& in_data,
                      v8::Local<v8::Value>* out_value) {
  v8::MaybeLocal<v8::String> maybe_string = v8::String::NewFromOneByte(
      isolate, in_data.data(), v8::NewStringType::kNormal, in_data.size());
  v8::Local<v8::Value> string;
  if (!maybe_string.ToLocal(&string)) {
    *out_value = v8::Null(isolate);
    return;
  }

  *out_value = string;
}

// base::Token -> JSValue
inline void ToJSValue(v8::Isolate* isolate, const base::Token& token,
                      v8::Local<v8::Value>* out_value) {
  ToJSValue(isolate, std::string(token.c_str()), out_value);
}

// bool -> JSValue
inline void ToJSValue(v8::Isolate* isolate, bool in_boolean,
                      v8::Local<v8::Value>* out_value) {
  *out_value = v8::Boolean::New(isolate, in_boolean);
}

// JSValue -> bool
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        bool* out_boolean) {
  DCHECK_EQ(conversion_flags, kNoConversionFlags)
      << "No conversion flags supported.";
  DCHECK(out_boolean);
  v8::MaybeLocal<v8::Boolean> maybe_boolean = value->ToBoolean(isolate);
  v8::Local<v8::Boolean> boolean;
  if (!maybe_boolean.ToLocal(&boolean)) {
    // TODO: Handle this failure case.  It apparently can't happen in
    // SpiderMonkey.
    NOTIMPLEMENTED();
    return;
  }
  *out_boolean = boolean->Value();
}

// signed integers <= 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) <= 4),
                             T>::type* = NULL) {
  *out_value = v8::Integer::New(isolate, static_cast<int32_t>(in_number));
}

template <typename T>
inline const double UpperBound() {
  return std::numeric_limits<T>::max();
}

template <typename T>
inline const double LowerBound() {
  return std::numeric_limits<T>::min();
}

// The below specializations of UpperBound<T> and LowerBound<T> for 64
// bit integers use the (2^(53) - 1) and similar bounds specified in
// step 1 of ConvertToInt, see:
// https://heycam.github.io/webidl/#abstract-opdef-converttoint
template <>
inline const double UpperBound<int64_t>() {
  const double kInt64UpperBound = static_cast<double>((1ll << 53) - 1);
  return kInt64UpperBound;
}

template <>
inline const double LowerBound<int64_t>() {
  const double kInt64LowerBound = static_cast<double>(-(1ll << 53) + 1);
  return kInt64LowerBound;
}

template <>
inline const double UpperBound<uint64_t>() {
  const double kUInt64UpperBound = static_cast<double>((1ll << 53) - 1);
  return kUInt64UpperBound;
}

// TODO: Consider just having this return a value.  Or just inline in it now
// that we removed the code duplication across integer conversions.
template <typename T>
void ClampedValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                  v8::Local<v8::Value>* clamped_value) {
  v8::MaybeLocal<v8::Number> maybe_number =
      value->ToNumber(isolate->GetCurrentContext());
  v8::Local<v8::Number> number;
  if (!maybe_number.ToLocal(&number)) {
    return;
  }
  double value_of_number = number->Value();
  if (value_of_number > UpperBound<T>()) {
    value_of_number = UpperBound<T>();
  } else if (value_of_number < LowerBound<T>()) {
    value_of_number = LowerBound<T>();
  }
  *clamped_value = v8::Number::New(isolate, value_of_number);
}

namespace internal {

// A small helper metafunction for integer-like FromJSValue conversions to
// pick the right type to feed to V8, which can only be the output types
// observed here.
template <typename T>
struct IntegralTypeToOutType {
  static_assert(std::numeric_limits<T>::is_specialized &&
                    std::numeric_limits<T>::is_integer,
                "");
  using type = typename std::conditional<
      std::numeric_limits<T>::is_signed,
      typename std::conditional<(sizeof(T) <= 4), int32_t, int64_t>::type,
      typename std::conditional<(sizeof(T) <= 4), uint32_t,
                                uint64_t>::type>::type;
};

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      int32_t* out) {
  v8::Maybe<int32_t> maybe_result =
      value->Int32Value(isolate->GetCurrentContext());
  if (!maybe_result.To(out)) {
    return false;
  }
  return true;
}

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      int64_t* out) {
  v8::Maybe<int64_t> maybe_result =
      value->IntegerValue(isolate->GetCurrentContext());
  if (!maybe_result.To(out)) {
    return false;
  }
  *out = maybe_result.FromJust();
  return true;
}

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      uint32_t* out) {
  v8::Maybe<uint32_t> maybe_result =
      value->Uint32Value(isolate->GetCurrentContext());
  if (!maybe_result.To(out)) {
    return false;
  }
  *out = maybe_result.FromJust();
  return true;
}

inline bool ToOutType(v8::Isolate* isolate, v8::Local<v8::Value> value,
                      uint64_t* out) {
  // V8 doesn't have anything for uint64_t (TODO: why?  More spec compliant?
  // less spec compliant?...), so this one is different.
  v8::Maybe<double> maybe_result =
      value->NumberValue(isolate->GetCurrentContext());
  if (maybe_result.IsNothing()) {
    return false;
  }
  *out = static_cast<uint64_t>(maybe_result.FromJust());
  return true;
}

}  // namespace internal

// JSValue -> integer-like
template <typename T>
inline void FromJSValue(
    v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
    ExceptionState* exception_state, T* out_number,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer,
                             T>::type* = NULL) {
  DCHECK(out_number);

  if (UNLIKELY(value->IsSymbol())) {
    exception_state->SetSimpleException(
        kTypeError, "Cannot convert a Symbol value to a number");
    return;
  }

  // Convert a JavaScript value to an integer type as specified by the
  // ECMAScript standard.
  using OutType = typename internal::IntegralTypeToOutType<T>::type;
  OutType out;
  bool success;
  if (UNLIKELY(conversion_flags & kConversionFlagClamped)) {
    v8::Local<v8::Value> clamped_value;
    ClampedValue<T>(isolate, value, &clamped_value);
    DCHECK(!clamped_value.IsEmpty());
    success = internal::ToOutType(isolate, clamped_value, &out);
  } else {
    success = internal::ToOutType(isolate, value, &out);
  }

  // It is possible for |JS::To{Uint,Int}{32,64}| to fail in certain edge
  // cases, such as application JavaScript setting up infinite recursion that
  // gets triggered by the conversion.
  if (!success) {
    // TODO: Still need to handle infinite recursion edge case here, see
    // mozjs-45 version of this function.
    exception_state->SetSimpleException(
        std::numeric_limits<T>::is_signed ? kNotInt64Type : kNotUint64Type);
    return;
  }
  *out_number = static_cast<T>(out);
}

// signed integers > 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) > 4),
                             T>::type* = NULL) {
  *out_value = v8::Number::New(isolate, in_number);
}

// unsigned integers <= 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 !std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) <= 4),
                             T>::type* = NULL) {
  *out_value = v8::Integer::NewFromUnsigned(isolate, in_number);
}

// TODO: Don't specialize template on these..., have them share an impl w/
// double unsigned integers > 4 bytes -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 std::numeric_limits<T>::is_integer &&
                                 !std::numeric_limits<T>::is_signed &&
                                 (sizeof(T) > 4),
                             T>::type* = NULL) {
  *out_value = v8::Number::New(isolate, in_number);
}

// double -> JSValue
template <typename T>
inline void ToJSValue(
    v8::Isolate* isolate, T in_number, v8::Local<v8::Value>* out_value,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 !std::numeric_limits<T>::is_integer,
                             T>::type* = NULL) {
  *out_value = v8::Number::New(isolate, in_number);
}

// JSValue -> double
template <typename T>
inline void FromJSValue(
    v8::Isolate* isolate, v8::Local<v8::Value> value, int conversion_flags,
    ExceptionState* exception_state, T* out_number,
    typename base::enable_if<std::numeric_limits<T>::is_specialized &&
                                 !std::numeric_limits<T>::is_integer,
                             T>::type* = NULL) {
  DCHECK_EQ(conversion_flags & ~kConversionFlagsNumeric, 0)
      << "Unexpected conversion flags found.";

  v8::MaybeLocal<v8::Number> maybe_value_as_number =
      value->ToNumber(isolate->GetCurrentContext());
  v8::Local<v8::Number> value_as_number;
  if (!maybe_value_as_number.ToLocal(&value_as_number)) {
    NOTIMPLEMENTED();
    return;
  }
  double value_as_double = value_as_number->Value();
  if ((conversion_flags & kConversionFlagRestricted) &&
      !std::isfinite(value_as_double)) {
    exception_state->SetSimpleException(kNotFinite);
    return;
  }
  *out_number = value_as_double;
}

// optional<T> -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
                      const base::Optional<T>& in_optional,
                      v8::Local<v8::Value>* out_value) {
  if (in_optional) {
    ToJSValue(isolate, in_optional.value(), out_value);
  } else {
    *out_value = v8::Null(isolate);
  }
}

// JSValue -> optional<T>
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        base::Optional<T>* out_optional) {
  if (value->IsNullOrUndefined()) {
    *out_optional = base::nullopt;
  } else {
    *out_optional = T();
    FromJSValue(isolate, value, conversion_flags & ~kConversionFlagNullable,
                exception_state, &(out_optional->value()));
  }
}

// JSValue -> optional<std::string>
template <>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        base::Optional<std::string>* out_optional) {
  if (value->IsNull()) {
    *out_optional = base::nullopt;
  } else if (value->IsUndefined() &&
             !(conversion_flags & kConversionFlagTreatUndefinedAsEmptyString)) {
    // If TreatUndefinedAs=EmptyString is set, skip the default conversion
    // of undefined to null.
    *out_optional = base::nullopt;
  } else {
    *out_optional = std::string();
    FromJSValue(isolate, value, conversion_flags & ~kConversionFlagNullable,
                exception_state, &(out_optional->value()));
  }
}

// ValueHandle -> JSValue
void ToJSValue(v8::Isolate* isolate,
               const ValueHandleHolder* value_handle_holder,
               v8::Local<v8::Value>* out_value);

// base::Time -> JSValue
void ToJSValue(v8::Isolate* isolate, const base::Time& time,
               v8::Local<v8::Value>* out_value);

// JSValue -> base::Time
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 base::Time* out_time);

// JSValue -> ValueHandle
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 V8cValueHandleHolder* out_holder);

// object -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate, const scoped_refptr<T>& in_object,
                      v8::Local<v8::Value>* out_value) {
  if (!in_object) {
    *out_value = v8::Null(isolate);
    return;
  }

  V8cGlobalEnvironment* global_environment =
      V8cGlobalEnvironment::GetFromIsolate(isolate);
  *out_value = global_environment->wrapper_factory()->GetWrapper(in_object);
}

// raw object pointer -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate, T* in_object,
                      v8::Local<v8::Value>* out_value) {
  ToJSValue(isolate, scoped_refptr<T>(in_object), out_value);
}

// JSValue -> object
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        scoped_refptr<T>* out_object) {
  DCHECK_EQ(conversion_flags & ~kConversionFlagsObject, 0)
      << "Unexpected conversion flags found.";

  if (value->IsNullOrUndefined()) {
    if (!(conversion_flags & kConversionFlagNullable)) {
      exception_state->SetSimpleException(kNotNullableType);
    }
    return;
  }
  if (!value->IsObject()) {
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }

  V8cGlobalEnvironment* global_environment =
      V8cGlobalEnvironment::GetFromIsolate(isolate);
  WrapperFactory* wrapper_factory = global_environment->wrapper_factory();
  v8::Local<v8::Object> object = value.As<v8::Object>();

  // Note that |DoesObjectImplementInterface| handles the case in which
  // |object| has no |WrapperPrivate|.
  if (!wrapper_factory->DoesObjectImplementInterface(object,
                                                     base::GetTypeId<T>())) {
    exception_state->SetSimpleException(kDoesNotImplementInterface);
    return;
  }

  WrapperPrivate* wrapper_private =
      WrapperPrivate::GetFromWrapperObject(object);
  DCHECK(wrapper_private);
  *out_object = wrapper_private->wrappable<T>();
}

// CallbackInterface -> JSValue
template <typename T>
inline void ToJSValue(v8::Isolate* isolate,
                      const ScriptValue<T>* callback_interface,
                      v8::Local<v8::Value>* out_value) {
  if (!callback_interface) {
    *out_value = v8::Null(isolate);
    return;
  }

  typedef typename CallbackInterfaceTraits<T>::V8cCallbackInterfaceClass
      V8cCallbackInterfaceClass;
  // Downcast to V8cUserObjectHolder<T> so we can get the underlying JSObject.
  typedef V8cUserObjectHolder<V8cCallbackInterfaceClass>
      V8cUserObjectHolderClass;
  const V8cUserObjectHolderClass* user_object_holder =
      base::polymorphic_downcast<const V8cUserObjectHolderClass*>(
          callback_interface);

  // Shouldn't be NULL. If the callback was NULL then NULL should have been
  // passed as an argument into this function.
  // Downcast to the corresponding V8cCallbackInterface type, from which we
  // can get the implementing object.
  const V8cCallbackInterfaceClass* v8c_callback_interface =
      base::polymorphic_downcast<const V8cCallbackInterfaceClass*>(
          user_object_holder->GetValue());
  DCHECK(v8c_callback_interface);
  *out_value = v8c_callback_interface->NewLocal(isolate);
}

// JSValue -> CallbackInterface
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* out_exception,
                        V8cCallbackInterfaceHolder<T>* out_callback_interface) {
  typedef T V8cCallbackInterfaceClass;
  DCHECK_EQ(conversion_flags & ~kConversionFlagsCallbackFunction, 0)
      << "No conversion flags supported.";
  if (value->IsNull()) {
    if (!(conversion_flags & kConversionFlagNullable)) {
      out_exception->SetSimpleException(kNotNullableType);
    }
    // If it is a nullable type, just return.
    return;
  }

  // https://www.w3.org/TR/WebIDL/#es-user-objects
  // Any user object can be considered to implement a user interface. Actually
  // checking if the correct properties exist will happen when the operation
  // on the callback interface is run.
  if (!value->IsObject()) {
    out_exception->SetSimpleException(kNotObjectType);
    return;
  }

  *out_callback_interface = V8cCallbackInterfaceHolder<T>(isolate, value);
}

// Sequence -> JSValue
template <typename T>
void ToJSValue(v8::Isolate* isolate, const script::Sequence<T>& sequence,
               v8::Local<v8::Value>* out_value) {
  // 1. Let n be the length of S.
  using size_type = typename script::Sequence<T>::size_type;
  size_type count = sequence.size();

  // 2. Let A be a new Array object created as if by the expression [].
  v8::Local<v8::Array> array = v8::Array::New(isolate);

  // 3. Initialize i to be 0.
  // 4. While i < n:
  for (size_type index = 0; index < count; ++index) {
    // 4.1. Let V be the value in S at index i.
    // 4.2. Let E be the result of converting V to an ECMAScript value.
    v8::Local<v8::Value> element;
    ToJSValue(isolate, sequence.at(index), &element);

    // 4.3. Let P be the result of calling ToString(i).
    // 4.4. Call CreateDataProperty(A, P, E).
    v8::Maybe<bool> set_result =
        array->Set(isolate->GetCurrentContext(), index, element);

    // 4.5. Set i to i + 1.
  }

  // 5. Return A.
  *out_value = array;
}

// JSValue -> Sequence
template <typename T>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::Sequence<T>* out_sequence) {
  DCHECK_EQ(0, conversion_flags);
  DCHECK(out_sequence);

  // JS -> IDL type conversion procedure described here:
  // https://heycam.github.io/webidl/#es-sequence

  // 1. If Type(V) is not Object, throw a TypeError.
  if (!value->IsObject()) {
    exception_state->SetSimpleException(kNotObjectType);
    return;
  }

  // 2. Let method be ? GetMethod(V, @@iterator).
  // 3. If method is undefined, throw a TypeError.
  v8::Local<v8::Object> iterable = value.As<v8::Object>();

  v8::Local<v8::Object> iterator;
  V8cExceptionState* v8c_exception_state =
      base::polymorphic_downcast<V8cExceptionState*>(exception_state);
  if (!GetIterator(isolate, iterable, v8c_exception_state).ToLocal(&iterator)) {
    DCHECK(v8c_exception_state->is_exception_set());
    return;
  }

  v8::Local<v8::String> next_key = NewInternalString(isolate, "next");
  v8::Local<v8::String> value_key = NewInternalString(isolate, "value");
  v8::Local<v8::String> done_key = NewInternalString(isolate, "done");
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  // 4. Return the result of creating a sequence from V and method.
  // https://heycam.github.io/webidl/#create-sequence-from-iterable
  for (;;) {
    // Let next be ? IteratorStep(iter).
    v8::Local<v8::Value> next;
    if (!iterator->Get(context, next_key).ToLocal(&next)) {
      exception_state->SetSimpleException(kTypeError, "");
      return;
    }
    if (!next->IsFunction()) {
      exception_state->SetSimpleException(kTypeError,
                                          "Iterator.next should be callable.");
      return;
    }

    v8::Local<v8::Value> next_result;
    if (!next.As<v8::Function>()
             ->Call(context, iterator, 0, nullptr)
             .ToLocal(&next_result)) {
      return;
    }
    if (!next_result->IsObject()) {
      exception_state->SetSimpleException(
          kTypeError, "Iterator.next did not return an object.");
      return;
    }

    // Let nextItem be ? IteratorValue(next).
    v8::Local<v8::Object> result_object = next_result.As<v8::Object>();
    v8::Local<v8::Value> next_item;
    v8::Local<v8::Value> done;
    if (!result_object->Get(context, value_key).ToLocal(&next_item) ||
        !result_object->Get(context, done_key).ToLocal(&done)) {
      return;
    }

    if (done->BooleanValue(isolate)) {
      break;
    }

    // Initialize S_i to the result of converting nextItem to an IDL value
    // of type T.
    T idl_next_item;
    FromJSValue(isolate, next_item, conversion_flags, exception_state,
                &idl_next_item);
    if (v8c_exception_state->is_exception_set()) {
      return;
    }
    out_sequence->push_back(idl_next_item);
  }
}

template <typename T>
void ToJSValue(v8::Isolate* isolate,
               const ScriptValue<Promise<T>>* promise_holder,
               v8::Local<v8::Value>* out_value);

template <typename T>
void ToJSValue(v8::Isolate* isolate, ScriptValue<Promise<T>>* promise_holder,
               v8::Local<v8::Value>* out_value);

// script::Handle<T> -> JSValue
template <typename T>
void ToJSValue(v8::Isolate* isolate, const Handle<T>& local,
               v8::Local<v8::Value>* out_value) {
  TRACK_MEMORY_SCOPE("Javascript");
  ToJSValue(isolate, local.GetScriptValue(), out_value);
}

// script::Handle<JSValue> -> object
template <typename T>
inline void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                        int conversion_flags, ExceptionState* exception_state,
                        Handle<T>* out_object) {
  DCHECK_EQ(conversion_flags & ~kConversionFlagsObject, 0)
      << "Unexpected conversion flags found.";

  if (value->IsNullOrUndefined()) {
    if (!(conversion_flags & kConversionFlagNullable)) {
      exception_state->SetSimpleException(kNotNullableType);
    }
    return;
  }

  typename TypeTraits<T>::ConversionType temporary_holder;
  FromJSValue(isolate, value, conversion_flags, exception_state,
              &temporary_holder);
  *out_object = std::move(Handle<T>(temporary_holder));
}

}  // namespace v8c
}  // namespace script
}  // namespace cobalt

// Union type conversion is generated by a pump script.
#include "cobalt/script/v8c/union_type_conversion_impl.h"

#endif  // COBALT_SCRIPT_V8C_CONVERSION_HELPERS_H_
