// 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 <utility>
#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/promise.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;
}

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

// 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)) {
    // When these situations happen, there must be an error in the idl
    // declaration.
    DCHECK(false);
    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.
    // V8 does not provide APIs to determine if it is throwing exception and
    // neither does v8 provide API to alert that we might enter infinite
    // exception handling.
    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) {
  // https://webidl.spec.whatwg.org/#es-sequence
  // 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);
  }
}

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

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

// JSValue -> Promise
template <typename T>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::Promise<T>* out_promise);

// 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_
