{% from 'utilities.cc.tmpl' import declare_enum_validation_variable %}
{% from 'utilities.cc.tmpl' import v8_value_to_local_cpp_value %}
{#############################################################################}
{% macro assign_and_return_if_hasinstance(member) %}
{% if member.is_array_buffer_or_view_type %}
if (v8Value->Is{{member.type_name}}()) {
{% else %}
if (V8{{member.type_name}}::hasInstance(v8Value, isolate)) {
{% endif %}
{% if member.is_array_buffer_view_or_typed_array %}
  {{member.cpp_local_type}} cppValue = ToNotShared<{{member.cpp_local_type}}>(isolate, v8Value, exceptionState);
  if (exceptionState.HadException())
    return;
{% else %}
  {{member.cpp_local_type}} cppValue = V8{{member.type_name}}::ToImpl(v8::Local<v8::Object>::Cast(v8Value));
{% endif %}
  impl.Set{{member.type_name}}(cppValue);
  return;
}
{% endmacro %}
{#############################################################################}
{% filter format_blink_cpp_source_code %}
{% include 'copyright_block.txt' %}
#include "{{this_include_header_path}}"

{% for filename in cpp_includes %}
#include "{{filename}}"
{% endfor %}

namespace blink {

{{cpp_class}}::{{cpp_class}}() : type_(SpecificType::kNone) {}

{% for member in members %}
{{member.rvalue_cpp_type}} {{cpp_class}}::GetAs{{member.type_name}}() const {
  DCHECK(Is{{member.type_name}}());
  return {{member.cpp_name}}_;
}

void {{cpp_class}}::Set{{member.type_name}}({{member.rvalue_cpp_type}} value) {
  DCHECK(IsNull());
  {% if member.enum_values %}
  NonThrowableExceptionState exceptionState;
  {{declare_enum_validation_variable(member.enum_values) | trim | indent(2)}}
  if (!IsValidEnum(value, validValues, base::size(validValues), "{{member.enum_type}}", exceptionState)) {
    NOTREACHED();
    return;
  }
  {% endif %}
  {% if member.is_array_buffer_view_or_typed_array %}
  {{member.cpp_name}}_ = {{member.cpp_type}}(value.View());
  {% else %}
  {{member.cpp_name}}_ = value;
  {% endif %}
  type_ = SpecificType::{{member.specific_type_enum}};
}

{{cpp_class}} {{cpp_class}}::From{{member.type_name}}({{member.rvalue_cpp_type}} value) {
  {{cpp_class}} container;
  container.Set{{member.type_name}}(value);
  return container;
}

{% endfor %}
{{cpp_class}}::{{cpp_class}}(const {{cpp_class}}&) = default;
{{cpp_class}}::~{{cpp_class}}() = default;
{{cpp_class}}& {{cpp_class}}::operator=(const {{cpp_class}}&) = default;

void {{cpp_class}}::Trace(blink::Visitor* visitor) {
  {% for member in members if member.is_traceable %}
  visitor->Trace({{member.cpp_name}}_);
  {% endfor %}
}

void {{v8_class}}::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, {{cpp_class}}& impl, UnionTypeConversionMode conversionMode, ExceptionState& exceptionState) {
  if (v8Value.IsEmpty())
    return;

  {# The numbers in the following comments refer to the steps described in
     http://heycam.github.io/webidl/#es-union #}
  {# 1. null or undefined #}
  if (conversionMode == UnionTypeConversionMode::kNullable && IsUndefinedOrNull(v8Value))
    return;

  {% if dictionary_type %}
  {# 3. Dictionaries for null or undefined #}
  if (IsUndefinedOrNull(v8Value)) {
    {{v8_value_to_local_cpp_value(dictionary_type) | trim | indent}}
    impl.Set{{dictionary_type.type_name}}(cppValue);
    return;
  }

  {% endif %}
  {# 4. Platform objects (interfaces) #}
  {% for interface in interface_types %}
  {{assign_and_return_if_hasinstance(interface) | trim | indent(2)}}

  {% endfor %}
  {# 8. ArrayBuffer #}
  {% if array_buffer_type %}
  {{assign_and_return_if_hasinstance(array_buffer_type) | trim | indent(2)}}

  {% endif %}
  {# 9., 10. ArrayBufferView #}
  {# FIXME: Individual typed arrays (e.g. Uint8Array) aren\'t supported yet. #}
  {% if array_buffer_view_type %}
  {{assign_and_return_if_hasinstance(array_buffer_view_type) | trim | indent(2)}}

  {% endif %}
  {% if array_or_sequence_type %}
  {# 11.1, 11.2. Sequences and frozen arrays #}
  if (HasCallableIteratorSymbol(isolate, v8Value, exceptionState)) {
    {{v8_value_to_local_cpp_value(array_or_sequence_type) | trim | indent}}
    {% if array_or_sequence_type.enum_values %}
    {{declare_enum_validation_variable(array_or_sequence_type.enum_values) | trim | indent(4)}}
    if (!IsValidEnum(cppValue, validValues, base::size(validValues), "{{array_or_sequence_type.enum_type}}", exceptionState))
      return;
    {% endif %}
    impl.Set{{array_or_sequence_type.type_name}}(cppValue);
    return;
  }

  {% endif %}
  {% if dictionary_type %}
  {# 11.3. Dictionaries #}
  if (v8Value->IsObject()) {
    {{v8_value_to_local_cpp_value(dictionary_type) | trim | indent}}
    impl.Set{{dictionary_type.type_name}}(cppValue);
    return;
  }

  {% endif %}
  {# 11.4. Records #}
  {% if record_type %}
  if (v8Value->IsObject()) {
    {{v8_value_to_local_cpp_value(record_type) | trim | indent}}
    impl.Set{{record_type.type_name}}(cppValue);
    return;
  }

  {% endif %}
  {# TODO(bashi): Support 11.5 Callback interface when we need it #}
  {# 11.6. Objects #}
  {% if object_type %}
  if (IsUndefinedOrNull(v8Value) || v8Value->IsObject()) {
    {{v8_value_to_local_cpp_value(object_type) | trim | indent}}
    impl.Set{{object_type.type_name}}(cppValue);
    return;
  }

  {% endif %}
  {# FIXME: In some cases, we can omit boolean and numeric type checks because
     we have fallback conversions. (step 16 and 17) #}
  {% if boolean_type %}
  {# 12. Boolean #}
  if (v8Value->IsBoolean()) {
    impl.SetBoolean(v8Value.As<v8::Boolean>()->Value());
    return;
  }

  {% endif %}
  {% if numeric_type %}
  {# 13. Number #}
  if (v8Value->IsNumber()) {
    {{v8_value_to_local_cpp_value(numeric_type) | trim | indent}}
    impl.Set{{numeric_type.type_name}}(cppValue);
    return;
  }

  {% endif %}
  {% if string_type %}
  {# 14. String #}
  {
    {{v8_value_to_local_cpp_value(string_type) | trim | indent}}
    {% if string_type.enum_values %}
    {{declare_enum_validation_variable(string_type.enum_values) | trim | indent}}
    if (!IsValidEnum(cppValue, validValues, base::size(validValues), "{{string_type.enum_type}}", exceptionState))
      return;
    {% endif %}
    impl.Set{{string_type.type_name}}(cppValue);
    return;
  }

  {# 15. Number (fallback) #}
  {% elif numeric_type %}
  {
    {{v8_value_to_local_cpp_value(numeric_type) | trim | indent}}
    impl.Set{{numeric_type.type_name}}(cppValue);
    return;
  }

  {# 16. Boolean (fallback) #}
  {% elif boolean_type %}
  {
    impl.SetBoolean(v8Value->BooleanValue(isolate->GetCurrentContext()).ToChecked());
    return;
  }

  {% else %}
  {# 17. TypeError #}
  exceptionState.ThrowTypeError("The provided value is not of type '{{type_string}}'");
  {% endif %}
}

v8::Local<v8::Value> ToV8(const {{cpp_class}}& impl, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) {
  switch (impl.type_) {
    case {{cpp_class}}::SpecificType::kNone:
      {# FIXME: We might want to return undefined in some cases #}
      return v8::Null(isolate);
    {% for member in members %}
    case {{cpp_class}}::SpecificType::{{member.specific_type_enum}}:
      return {{member.cpp_value_to_v8_value}};
    {% endfor %}
    default:
      NOTREACHED();
  }
  return v8::Local<v8::Value>();
}

{{cpp_class}} NativeValueTraits<{{cpp_class}}>::NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState) {
  {{cpp_class}} impl;
  {{v8_class}}::ToImpl(isolate, value, impl, UnionTypeConversionMode::kNotNullable, exceptionState);
  return impl;
}

}  // namespace blink

{% endfilter %}{# format_blink_cpp_source_code #}
