// This file was GENERATED by command:
//     pump.py union_type_conversion_impl.h.pump
// DO NOT EDIT BY HAND!!!

// Copyright 2016 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_MOZJS_45_UNION_TYPE_CONVERSION_IMPL_H_
#define COBALT_SCRIPT_MOZJS_45_UNION_TYPE_CONVERSION_IMPL_H_

#include "cobalt/base/type_id.h"
#include "cobalt/script/mozjs-45/mozjs_exception_state.h"
#include "cobalt/script/mozjs-45/mozjs_global_environment.h"
#include "cobalt/script/mozjs-45/mozjs_user_object_holder.h"
#include "cobalt/script/mozjs-45/mozjs_value_handle.h"
#include "cobalt/script/mozjs-45/type_traits.h"
#include "cobalt/script/union_type.h"

// Conversion to/from JS::Value for IDL union types.

namespace cobalt {
namespace script {
namespace mozjs {

template <typename T1, typename T2>
void ToJSValue(JSContext* context, const script::UnionType2<T1, T2>& in_union,
               JS::MutableHandleValue out_value) {
  if (in_union.template IsType<T1>()) {
    ToJSValue(context, in_union.template AsType<T1>(), out_value);
    return;
  }
  if (in_union.template IsType<T2>()) {
    ToJSValue(context, in_union.template AsType<T2>(), out_value);
    return;
  }
  NOTREACHED();
  out_value.setUndefined();
}

template <typename T1, typename T2>
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::UnionType2<T1, T2>* out_union) {
  DCHECK_EQ(0, conversion_flags);
  // JS -> IDL type conversion procedure described here:
  // http://heycam.github.io/webidl/#es-union

  // TODO: Support Date, RegExp, DOMException, Error, ArrayBuffer, DataView,
  //       TypedArrayName, callback functions, dictionary.

  // 1. If the union type includes a nullable type and |V| is null or undefined,
  // then return the IDL value null.
  if (value.isNull() || value.isUndefined()) {
    // Since the nullability should have been detected by the conversion for
    // base::optional, we should throw, because if we get here it means the
    // union does not include a nullable type, but have been passed a null
    // value.
    exception_state->SetSimpleException(kNotUnionType);
    return;
  }

  // Typedef for readability.
  typedef ::cobalt::script::internal::UnionTypeTraits<T1> UnionTypeTraitsT1;
  typedef ::cobalt::script::internal::UnionTypeTraits<T2> UnionTypeTraitsT2;

  // 2. Let |types| be the flattened member types of the union type.
  // Forward declare all potential types
  T1 t1;
  T2 t2;

  // 4. If |V| is a platform object, then:
  //   1. If |types| includes an interface type that V implements, then return
  //      the IDL value that is a reference to the object |V|.
  //   2. If |types| includes object, then return the IDL value that is a
  //      reference to the object |V|.
  if (value.isObject()) {
    // The specification doesn't dictate what should happen if V implements
    // more than one of the interfaces. For example, if V implements interface
    // B and interface B inherits from interface A, what happens if both A and
    // B are union members? Blink doesn't seem to do anything special for this
    // case. Just choose the first interface in the flattened members that
    // matches.

    JS::RootedObject rooted_object(context);
    bool success = JS_ValueToObject(context, value, &rooted_object);
    DCHECK(success);

    MozjsGlobalEnvironment* global_environment =
        static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
    const WrapperFactory* wrapper_factory =
        global_environment->wrapper_factory();

    if (UnionTypeTraitsT1::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT1::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT2::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 11. If |Type(V)| is Object, then:
  //   1. If |types| includes a sequence type, then
  //     1. Let |method| be the result of GetMethod(V, @@iterator)
  //     2. ReturnIfAbrupt(method)
  //     3. If method is not undefined, return the result of creating a sequence
  //        of that type from |V| and |method|.
  if (value.isObject()) {
    if (UnionTypeTraitsT1::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 12. If |Type(V)| is Boolean, then:
  // 1. If |types| includes a boolean, then return the result of converting |V|
  //      to boolean.
  if (value.isBoolean()) {
    if (UnionTypeTraitsT1::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 13. If |Type(V)| is a Number, then:
  //   1. If |types| includes a numeric type, then return the result of
  //      converting |V| to that numeric type.
  if (value.isNumber()) {
    if (UnionTypeTraitsT1::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 14. If |types| includes a string type, then return the result of converting
  //     |V| to that type.
  if (value.isString()) {
    if (UnionTypeTraitsT1::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 15. If |types| includes a numeric type, then return the result of
  //     converting |V| to that numeric type.
  if (UnionTypeTraitsT1::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType2<T1, T2>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType2<T1, T2>(t2);
    return;
  }

  // 16. If |types| includes a boolean, then return the result of converting |V|
  //     to boolean.
  if (UnionTypeTraitsT1::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType2<T1, T2>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType2<T1, T2>(t2);
    return;
  }

  // 17. If |types| includes an ArrayBufferView type, then return the result of
  //     converting |V| to ArrayBufferView type.
  //     This step has to be before 18 to catch array_buffer_view types.
  if (value.isObject() && JS_IsArrayBufferViewObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 18. If |types| includes any ScriptValue type, then return the result of
  //     converting |V| to that ScriptValue type.
  if (value.isObject() && JS_IsArrayBufferObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType2<T1, T2>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType2<T1, T2>(t2);
      return;
    }
  }

  // 19. Throw a TypeError.
  exception_state->SetSimpleException(kNotUnionType);
}

template <typename T1, typename T2, typename T3>
void ToJSValue(JSContext* context,
               const script::UnionType3<T1, T2, T3>& in_union,
               JS::MutableHandleValue out_value) {
  if (in_union.template IsType<T1>()) {
    ToJSValue(context, in_union.template AsType<T1>(), out_value);
    return;
  }
  if (in_union.template IsType<T2>()) {
    ToJSValue(context, in_union.template AsType<T2>(), out_value);
    return;
  }
  if (in_union.template IsType<T3>()) {
    ToJSValue(context, in_union.template AsType<T3>(), out_value);
    return;
  }
  NOTREACHED();
  out_value.setUndefined();
}

template <typename T1, typename T2, typename T3>
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::UnionType3<T1, T2, T3>* out_union) {
  DCHECK_EQ(0, conversion_flags);
  // JS -> IDL type conversion procedure described here:
  // http://heycam.github.io/webidl/#es-union

  // TODO: Support Date, RegExp, DOMException, Error, ArrayBuffer, DataView,
  //       TypedArrayName, callback functions, dictionary.

  // 1. If the union type includes a nullable type and |V| is null or undefined,
  // then return the IDL value null.
  if (value.isNull() || value.isUndefined()) {
    // Since the nullability should have been detected by the conversion for
    // base::optional, we should throw, because if we get here it means the
    // union does not include a nullable type, but have been passed a null
    // value.
    exception_state->SetSimpleException(kNotUnionType);
    return;
  }

  // Typedef for readability.
  typedef ::cobalt::script::internal::UnionTypeTraits<T1> UnionTypeTraitsT1;
  typedef ::cobalt::script::internal::UnionTypeTraits<T2> UnionTypeTraitsT2;
  typedef ::cobalt::script::internal::UnionTypeTraits<T3> UnionTypeTraitsT3;

  // 2. Let |types| be the flattened member types of the union type.
  // Forward declare all potential types
  T1 t1;
  T2 t2;
  T3 t3;

  // 4. If |V| is a platform object, then:
  //   1. If |types| includes an interface type that V implements, then return
  //      the IDL value that is a reference to the object |V|.
  //   2. If |types| includes object, then return the IDL value that is a
  //      reference to the object |V|.
  if (value.isObject()) {
    // The specification doesn't dictate what should happen if V implements
    // more than one of the interfaces. For example, if V implements interface
    // B and interface B inherits from interface A, what happens if both A and
    // B are union members? Blink doesn't seem to do anything special for this
    // case. Just choose the first interface in the flattened members that
    // matches.

    JS::RootedObject rooted_object(context);
    bool success = JS_ValueToObject(context, value, &rooted_object);
    DCHECK(success);

    MozjsGlobalEnvironment* global_environment =
        static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
    const WrapperFactory* wrapper_factory =
        global_environment->wrapper_factory();

    if (UnionTypeTraitsT1::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT1::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT2::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT3::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 11. If |Type(V)| is Object, then:
  //   1. If |types| includes a sequence type, then
  //     1. Let |method| be the result of GetMethod(V, @@iterator)
  //     2. ReturnIfAbrupt(method)
  //     3. If method is not undefined, return the result of creating a sequence
  //        of that type from |V| and |method|.
  if (value.isObject()) {
    if (UnionTypeTraitsT1::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 12. If |Type(V)| is Boolean, then:
  // 1. If |types| includes a boolean, then return the result of converting |V|
  //      to boolean.
  if (value.isBoolean()) {
    if (UnionTypeTraitsT1::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 13. If |Type(V)| is a Number, then:
  //   1. If |types| includes a numeric type, then return the result of
  //      converting |V| to that numeric type.
  if (value.isNumber()) {
    if (UnionTypeTraitsT1::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 14. If |types| includes a string type, then return the result of converting
  //     |V| to that type.
  if (value.isString()) {
    if (UnionTypeTraitsT1::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 15. If |types| includes a numeric type, then return the result of
  //     converting |V| to that numeric type.
  if (UnionTypeTraitsT1::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType3<T1, T2, T3>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType3<T1, T2, T3>(t2);
    return;
  }

  if (UnionTypeTraitsT3::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t3);
    *out_union = script::UnionType3<T1, T2, T3>(t3);
    return;
  }

  // 16. If |types| includes a boolean, then return the result of converting |V|
  //     to boolean.
  if (UnionTypeTraitsT1::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType3<T1, T2, T3>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType3<T1, T2, T3>(t2);
    return;
  }

  if (UnionTypeTraitsT3::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t3);
    *out_union = script::UnionType3<T1, T2, T3>(t3);
    return;
  }

  // 17. If |types| includes an ArrayBufferView type, then return the result of
  //     converting |V| to ArrayBufferView type.
  //     This step has to be before 18 to catch array_buffer_view types.
  if (value.isObject() && JS_IsArrayBufferViewObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 18. If |types| includes any ScriptValue type, then return the result of
  //     converting |V| to that ScriptValue type.
  if (value.isObject() && JS_IsArrayBufferObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType3<T1, T2, T3>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType3<T1, T2, T3>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType3<T1, T2, T3>(t3);
      return;
    }
  }

  // 19. Throw a TypeError.
  exception_state->SetSimpleException(kNotUnionType);
}

template <typename T1, typename T2, typename T3, typename T4>
void ToJSValue(JSContext* context,
               const script::UnionType4<T1, T2, T3, T4>& in_union,
               JS::MutableHandleValue out_value) {
  if (in_union.template IsType<T1>()) {
    ToJSValue(context, in_union.template AsType<T1>(), out_value);
    return;
  }
  if (in_union.template IsType<T2>()) {
    ToJSValue(context, in_union.template AsType<T2>(), out_value);
    return;
  }
  if (in_union.template IsType<T3>()) {
    ToJSValue(context, in_union.template AsType<T3>(), out_value);
    return;
  }
  if (in_union.template IsType<T4>()) {
    ToJSValue(context, in_union.template AsType<T4>(), out_value);
    return;
  }
  NOTREACHED();
  out_value.setUndefined();
}

template <typename T1, typename T2, typename T3, typename T4>
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::UnionType4<T1, T2, T3, T4>* out_union) {
  DCHECK_EQ(0, conversion_flags);
  // JS -> IDL type conversion procedure described here:
  // http://heycam.github.io/webidl/#es-union

  // TODO: Support Date, RegExp, DOMException, Error, ArrayBuffer, DataView,
  //       TypedArrayName, callback functions, dictionary.

  // 1. If the union type includes a nullable type and |V| is null or undefined,
  // then return the IDL value null.
  if (value.isNull() || value.isUndefined()) {
    // Since the nullability should have been detected by the conversion for
    // base::optional, we should throw, because if we get here it means the
    // union does not include a nullable type, but have been passed a null
    // value.
    exception_state->SetSimpleException(kNotUnionType);
    return;
  }

  // Typedef for readability.
  typedef ::cobalt::script::internal::UnionTypeTraits<T1> UnionTypeTraitsT1;
  typedef ::cobalt::script::internal::UnionTypeTraits<T2> UnionTypeTraitsT2;
  typedef ::cobalt::script::internal::UnionTypeTraits<T3> UnionTypeTraitsT3;
  typedef ::cobalt::script::internal::UnionTypeTraits<T4> UnionTypeTraitsT4;

  // 2. Let |types| be the flattened member types of the union type.
  // Forward declare all potential types
  T1 t1;
  T2 t2;
  T3 t3;
  T4 t4;

  // 4. If |V| is a platform object, then:
  //   1. If |types| includes an interface type that V implements, then return
  //      the IDL value that is a reference to the object |V|.
  //   2. If |types| includes object, then return the IDL value that is a
  //      reference to the object |V|.
  if (value.isObject()) {
    // The specification doesn't dictate what should happen if V implements
    // more than one of the interfaces. For example, if V implements interface
    // B and interface B inherits from interface A, what happens if both A and
    // B are union members? Blink doesn't seem to do anything special for this
    // case. Just choose the first interface in the flattened members that
    // matches.

    JS::RootedObject rooted_object(context);
    bool success = JS_ValueToObject(context, value, &rooted_object);
    DCHECK(success);

    MozjsGlobalEnvironment* global_environment =
        static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
    const WrapperFactory* wrapper_factory =
        global_environment->wrapper_factory();

    if (UnionTypeTraitsT1::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT1::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT2::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT3::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT4::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 11. If |Type(V)| is Object, then:
  //   1. If |types| includes a sequence type, then
  //     1. Let |method| be the result of GetMethod(V, @@iterator)
  //     2. ReturnIfAbrupt(method)
  //     3. If method is not undefined, return the result of creating a sequence
  //        of that type from |V| and |method|.
  if (value.isObject()) {
    if (UnionTypeTraitsT1::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 12. If |Type(V)| is Boolean, then:
  // 1. If |types| includes a boolean, then return the result of converting |V|
  //      to boolean.
  if (value.isBoolean()) {
    if (UnionTypeTraitsT1::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 13. If |Type(V)| is a Number, then:
  //   1. If |types| includes a numeric type, then return the result of
  //      converting |V| to that numeric type.
  if (value.isNumber()) {
    if (UnionTypeTraitsT1::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 14. If |types| includes a string type, then return the result of converting
  //     |V| to that type.
  if (value.isString()) {
    if (UnionTypeTraitsT1::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 15. If |types| includes a numeric type, then return the result of
  //     converting |V| to that numeric type.
  if (UnionTypeTraitsT1::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
    return;
  }

  if (UnionTypeTraitsT3::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t3);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
    return;
  }

  if (UnionTypeTraitsT4::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t4);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
    return;
  }

  // 16. If |types| includes a boolean, then return the result of converting |V|
  //     to boolean.
  if (UnionTypeTraitsT1::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
    return;
  }

  if (UnionTypeTraitsT3::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t3);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
    return;
  }

  if (UnionTypeTraitsT4::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t4);
    *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
    return;
  }

  // 17. If |types| includes an ArrayBufferView type, then return the result of
  //     converting |V| to ArrayBufferView type.
  //     This step has to be before 18 to catch array_buffer_view types.
  if (value.isObject() && JS_IsArrayBufferViewObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 18. If |types| includes any ScriptValue type, then return the result of
  //     converting |V| to that ScriptValue type.
  if (value.isObject() && JS_IsArrayBufferObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType4<T1, T2, T3, T4>(t4);
      return;
    }
  }

  // 19. Throw a TypeError.
  exception_state->SetSimpleException(kNotUnionType);
}

template <typename T1, typename T2, typename T3, typename T4, typename T5>
void ToJSValue(JSContext* context,
               const script::UnionType5<T1, T2, T3, T4, T5>& in_union,
               JS::MutableHandleValue out_value) {
  if (in_union.template IsType<T1>()) {
    ToJSValue(context, in_union.template AsType<T1>(), out_value);
    return;
  }
  if (in_union.template IsType<T2>()) {
    ToJSValue(context, in_union.template AsType<T2>(), out_value);
    return;
  }
  if (in_union.template IsType<T3>()) {
    ToJSValue(context, in_union.template AsType<T3>(), out_value);
    return;
  }
  if (in_union.template IsType<T4>()) {
    ToJSValue(context, in_union.template AsType<T4>(), out_value);
    return;
  }
  if (in_union.template IsType<T5>()) {
    ToJSValue(context, in_union.template AsType<T5>(), out_value);
    return;
  }
  NOTREACHED();
  out_value.setUndefined();
}

template <typename T1, typename T2, typename T3, typename T4, typename T5>
void FromJSValue(JSContext* context, JS::HandleValue value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::UnionType5<T1, T2, T3, T4, T5>* out_union) {
  DCHECK_EQ(0, conversion_flags);
  // JS -> IDL type conversion procedure described here:
  // http://heycam.github.io/webidl/#es-union

  // TODO: Support Date, RegExp, DOMException, Error, ArrayBuffer, DataView,
  //       TypedArrayName, callback functions, dictionary.

  // 1. If the union type includes a nullable type and |V| is null or undefined,
  // then return the IDL value null.
  if (value.isNull() || value.isUndefined()) {
    // Since the nullability should have been detected by the conversion for
    // base::optional, we should throw, because if we get here it means the
    // union does not include a nullable type, but have been passed a null
    // value.
    exception_state->SetSimpleException(kNotUnionType);
    return;
  }

  // Typedef for readability.
  typedef ::cobalt::script::internal::UnionTypeTraits<T1> UnionTypeTraitsT1;
  typedef ::cobalt::script::internal::UnionTypeTraits<T2> UnionTypeTraitsT2;
  typedef ::cobalt::script::internal::UnionTypeTraits<T3> UnionTypeTraitsT3;
  typedef ::cobalt::script::internal::UnionTypeTraits<T4> UnionTypeTraitsT4;
  typedef ::cobalt::script::internal::UnionTypeTraits<T5> UnionTypeTraitsT5;

  // 2. Let |types| be the flattened member types of the union type.
  // Forward declare all potential types
  T1 t1;
  T2 t2;
  T3 t3;
  T4 t4;
  T5 t5;

  // 4. If |V| is a platform object, then:
  //   1. If |types| includes an interface type that V implements, then return
  //      the IDL value that is a reference to the object |V|.
  //   2. If |types| includes object, then return the IDL value that is a
  //      reference to the object |V|.
  if (value.isObject()) {
    // The specification doesn't dictate what should happen if V implements
    // more than one of the interfaces. For example, if V implements interface
    // B and interface B inherits from interface A, what happens if both A and
    // B are union members? Blink doesn't seem to do anything special for this
    // case. Just choose the first interface in the flattened members that
    // matches.

    JS::RootedObject rooted_object(context);
    bool success = JS_ValueToObject(context, value, &rooted_object);
    DCHECK(success);

    MozjsGlobalEnvironment* global_environment =
        static_cast<MozjsGlobalEnvironment*>(JS_GetContextPrivate(context));
    const WrapperFactory* wrapper_factory =
        global_environment->wrapper_factory();

    if (UnionTypeTraitsT1::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT1::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT2::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT3::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT4::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            rooted_object, UnionTypeTraitsT5::GetTypeID())) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 11. If |Type(V)| is Object, then:
  //   1. If |types| includes a sequence type, then
  //     1. Let |method| be the result of GetMethod(V, @@iterator)
  //     2. ReturnIfAbrupt(method)
  //     3. If method is not undefined, return the result of creating a sequence
  //        of that type from |V| and |method|.
  if (value.isObject()) {
    if (UnionTypeTraitsT1::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_sequence_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 12. If |Type(V)| is Boolean, then:
  // 1. If |types| includes a boolean, then return the result of converting |V|
  //      to boolean.
  if (value.isBoolean()) {
    if (UnionTypeTraitsT1::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_boolean_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 13. If |Type(V)| is a Number, then:
  //   1. If |types| includes a numeric type, then return the result of
  //      converting |V| to that numeric type.
  if (value.isNumber()) {
    if (UnionTypeTraitsT1::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_numeric_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 14. If |types| includes a string type, then return the result of converting
  //     |V| to that type.
  if (value.isString()) {
    if (UnionTypeTraitsT1::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_string_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 15. If |types| includes a numeric type, then return the result of
  //     converting |V| to that numeric type.
  if (UnionTypeTraitsT1::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
    return;
  }

  if (UnionTypeTraitsT3::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t3);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
    return;
  }

  if (UnionTypeTraitsT4::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t4);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
    return;
  }

  if (UnionTypeTraitsT5::is_numeric_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t5);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
    return;
  }

  // 16. If |types| includes a boolean, then return the result of converting |V|
  //     to boolean.
  if (UnionTypeTraitsT1::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t1);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
    return;
  }

  if (UnionTypeTraitsT2::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t2);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
    return;
  }

  if (UnionTypeTraitsT3::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t3);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
    return;
  }

  if (UnionTypeTraitsT4::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t4);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
    return;
  }

  if (UnionTypeTraitsT5::is_boolean_type) {
    FromJSValue(context, value, conversion_flags, exception_state, &t5);
    *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
    return;
  }

  // 17. If |types| includes an ArrayBufferView type, then return the result of
  //     converting |V| to ArrayBufferView type.
  //     This step has to be before 18 to catch array_buffer_view types.
  if (value.isObject() && JS_IsArrayBufferViewObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_array_buffer_view_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 18. If |types| includes any ScriptValue type, then return the result of
  //     converting |V| to that ScriptValue type.
  if (value.isObject() && JS_IsArrayBufferObject(&value.toObject())) {
    if (UnionTypeTraitsT1::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t1);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t1);
      return;
    }

    if (UnionTypeTraitsT2::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t2);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t2);
      return;
    }

    if (UnionTypeTraitsT3::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t3);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t3);
      return;
    }

    if (UnionTypeTraitsT4::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t4);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t4);
      return;
    }

    if (UnionTypeTraitsT5::is_script_value_type) {
      FromJSValue(context, value, conversion_flags, exception_state, &t5);
      *out_union = script::UnionType5<T1, T2, T3, T4, T5>(t5);
      return;
    }
  }

  // 19. Throw a TypeError.
  exception_state->SetSimpleException(kNotUnionType);
}

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_MOZJS_45_UNION_TYPE_CONVERSION_IMPL_H_
