$$ This is a pump file for generating file templates.  Pump is a python
$$ script that is part of the Google Test suite of utilities.  Description
$$ can be found here:
$$
$$ http://code.google.com/p/googletest/wiki/PumpManual
$$

$$ Maximum number of different member types in a union.
$var MAX_MEMBERS = 5
// 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_UNION_TYPE_CONVERSION_IMPL_H_
#define COBALT_SCRIPT_V8C_UNION_TYPE_CONVERSION_IMPL_H_

#include "cobalt/base/type_id.h"
#include "cobalt/script/union_type.h"
#include "cobalt/script/v8c/type_traits.h"
#include "cobalt/script/v8c/v8c_exception_state.h"
#include "cobalt/script/v8c/v8c_global_environment.h"
#include "cobalt/script/v8c/v8c_user_object_holder.h"
#include "cobalt/script/v8c/v8c_value_handle.h"

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

namespace cobalt {
namespace script {
namespace v8c {

$range NUM_MEMBERS 2..MAX_MEMBERS
$for NUM_MEMBERS [[

$range TYPE 1..NUM_MEMBERS

template <$for TYPE , [[typename T$(TYPE)]]>
void ToJSValue(
    v8::Isolate* isolate,
    const script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>& in_union,
    v8::Local<v8::Value>* out_value) {
$for TYPE [[

  if (in_union.template IsType<T$(TYPE)>()) {
    ToJSValue(isolate, in_union.template AsType<T$(TYPE)>(), out_value);
    return;
  }
]]

  NOTREACHED();
  *out_value = v8::Undefined(isolate);
}

template <$for TYPE , [[typename T$(TYPE)]]>
void FromJSValue(v8::Isolate* isolate, v8::Local<v8::Value> value,
                 int conversion_flags, ExceptionState* exception_state,
                 script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>* out_union) {
  DCHECK_EQ(0, conversion_flags);
  // JS -> IDL type conversion procedure described here:
  // https://www.w3.org/TR/WebIDL-1/#es-union
  // ( Draft: http://heycam.github.io/webidl/#es-union )

  // TODO: Support Date, RegExp, web::DOMException, Error, callback functions.

  // 1. If the union type includes a nullable type and |V| is null or undefined,
  // then return the IDL value null.
  if (value->IsNullOrUndefined()) {
    // 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.

$for TYPE [[
  typedef ::cobalt::script::internal::UnionTypeTraits<T$(TYPE)> UnionTypeTraitsT$(TYPE);

]]

  // 2. Let |types| be the flattened member types of the union type.
  // Forward declare all potential types

$for TYPE [[
  T$(TYPE) t$(TYPE);

]]

  // 3. 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.

    v8::Local<v8::Object> object = value.As<v8::Object>();

    V8cGlobalEnvironment* global_environment = V8cGlobalEnvironment::GetFromIsolate(isolate);
    const WrapperFactory* wrapper_factory = global_environment->wrapper_factory();

$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_interface_type &&
        wrapper_factory->DoesObjectImplementInterface(
            object, UnionTypeTraitsT$(TYPE)::GetTypeID())) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

  // 4. If |V| object, then
  //   1. If |types| includes object, then return the IDL value that is a reference to
  //      the object V.
  // Not implemented

  // 5. If V is a web::DOMException platform object, then:
  //   1. If types includes web::DOMException or Error, then return the result of converting
  //      V to that type.
  // Not implemented

  // 6. If V is a native Error object (that is, it has an [[ErrorData]] internal slot),
  //    then:
  //   1. If types includes Error, then return the result of converting V to Error.
  //   2. If types includes object, then return the IDL value that is a reference to
  //      the object V.
  // Not implemented

  // 7. If V is an object with an [[ArrayBufferData]] internal slot, then:
  //   1. If types includes ArrayBuffer, then return the result of converting V to
  //      ArrayBuffer.
  //   2. If types includes object, then return the IDL value that is a reference
  //      to the object V.
  // Not implemented

  // 8. If V is an object with a [[DataView]] internal slot, then:
  //   1. If types includes DataView, then return the result of converting V to DataView.
  //   2. If types includes object, then return the IDL value that is a reference to
  //      the object V.
  //   Note: Only ArrayBufferView is implemented, other DataViews are not.
  // https://www.w3.org/TR/WebIDL-1/#idl-DataView
  if (value->IsArrayBufferView()) {
$for TYPE [[

      if (UnionTypeTraitsT$(TYPE)::is_array_buffer_view_type) {
        FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
        *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
        return;
      }

]]
  }

  // 9. If V is an object with a [[TypedArrayName]] internal slot, then:
  //   1. If types includes a typed array type whose name is the value of V’s [[TypedArrayName]]
  //      internal slot, then return the result of converting V to that type.
  //   2. If types includes object, then return the IDL value that is a reference to the object V.
  // Not implemented

  // 10. If IsCallable(V) is true, then
  //   1. If types includes a callback function type, then return the result of converting V to
  //      that callback function type.
  //   2. If types includes object, then return the IDL value that is a reference to the object V.
  // Not implemented

  // 11. If |V| is null or undefined object, then:
  //   1. If types includes a dictionary type, then return the result of converting V to
  //      that dictionary type.
  if (value->IsObject()) {
$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_dictionary_type) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

  // 12. 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()) {
$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_sequence_type) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

  // 13. If |Type(V)| is Boolean, then:
  //   1. If |types| includes a boolean, then return the result of converting |V|
  //      to boolean.
  if (value->IsBoolean()) {
$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_boolean_type) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

  // 14. 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()) {
$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_numeric_type) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

  // 15. If |types| includes a string type, then return the result of converting
  //     |V| to that type.
  if (value->IsString()) {
$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_string_type) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

  // 16. If |types| includes a numeric type, then return the result of
  //     converting |V| to that numeric type.
$for TYPE [[

  if (UnionTypeTraitsT$(TYPE)::is_numeric_type) {
    FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
    *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
    return;
  }

]]

  // 17. If |types| includes a boolean, then return the result of converting |V|
  //     to boolean.
$for TYPE [[

  if (UnionTypeTraitsT$(TYPE)::is_boolean_type) {
    FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
    *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
    return;
  }

]]

  // Note: non-spec fallback
  //     If |types| includes any ScriptValue type, then return the result of
  //     converting |V| to that ScriptValue type.
  if (value->IsArrayBuffer()) {
$for TYPE [[

    if (UnionTypeTraitsT$(TYPE)::is_script_value_type) {
      FromJSValue(isolate, value, conversion_flags, exception_state, &t$(TYPE));
      *out_union = script::UnionType$(NUM_MEMBERS)<$for TYPE , [[T$(TYPE)]]>(t$(TYPE));
      return;
    }

]]
  }

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

]]  $$ for NUM_MEMBERS

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

#endif  // COBALT_SCRIPT_V8C_UNION_TYPE_CONVERSION_IMPL_H_
