{% from 'utilities.cc.tmpl' import declare_enum_validation_variable, v8_value_to_local_cpp_value %}
{% from 'methods.cc.tmpl' import runtime_timer_scope, runtime_timer_scope_disabled_by_default %}

{##############################################################################}
{% macro attribute_getter(attribute, world_suffix) %}
static void {{attribute.name}}AttributeGetter{{world_suffix}}(
{%- if attribute.is_data_type_property %}
const v8::PropertyCallbackInfo<v8::Value>& info
{%- else %}
const v8::FunctionCallbackInfo<v8::Value>& info
{%- endif %}) {
  {% filter format_remove_duplicates(['ExceptionState exceptionState']) %}
  {% set define_exception_state -%}
  ExceptionState exceptionState(info.GetIsolate(), ExceptionState::kGetterContext, "{{interface_name}}", "{{attribute.name}}");
  {%- endset %}

  {% if attribute.is_lenient_this %}
  // [LenientThis]
  // Make sure that info.Holder() really points to an instance if [LenientThis].
  if (!{{v8_class}}::hasInstance(info.Holder(), info.GetIsolate()))
    return; // Return silently because of [LenientThis].
  {% elif attribute.has_promise_type %}
  // This attribute returns a Promise.
  // Per https://heycam.github.io/webidl/#dfn-attribute-getter, all exceptions
  // must be turned into a Promise rejection.
  {{define_exception_state}}
  ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState);

  // Returning a Promise type requires us to disable some of V8's type checks,
  // so we have to manually check that info.Holder() really points to an
  // instance of the type.
  if (!{{v8_class}}::hasInstance(info.Holder(), info.GetIsolate())) {
    exceptionState.ThrowTypeError("Illegal invocation");
    return;
  }
  {% endif %}

  {% if not attribute.is_static or attribute.is_save_same_object %}
  v8::Local<v8::Object> holder = info.Holder();
  {% endif %}

  {% if attribute.is_save_same_object %}
  // [SaveSameObject]
  {% set same_object_private_key = interface_name + attribute.name[0]|capitalize + attribute.name[1:] %}
  // If you see a compile error that
  //   V8PrivateProperty::GetSameObject{{same_object_private_key}}
  // is not defined, then you need to register your attribute at
  // V8_PRIVATE_PROPERTY_FOR_EACH defined in V8PrivateProperty.h as
  //   X(SameObject, {{same_object_private_key}})
  auto privateSameObject = V8PrivateProperty::GetSameObject{{same_object_private_key}}(info.GetIsolate());
  {
    v8::Local<v8::Value> v8Value;
    if (privateSameObject.GetOrUndefined(holder).ToLocal(&v8Value) && !v8Value->IsUndefined()) {
      V8SetReturnValue(info, v8Value);
      return;
    }
  }
  {% endif %}

  {% if not attribute.is_static %}
  {% set local_dom_window_only = interface_name == 'Window' and not attribute.has_cross_origin_getter %}
  {% if local_dom_window_only %}
  {% if attribute.is_check_security_for_receiver %}
  {{cpp_class}}* uncheckedImpl = {{v8_class}}::ToImpl(holder);
  {% else %}
  // Same-origin attribute getters are never exposed via the cross-origin
  // interceptors. Since same-origin access requires a LocalDOMWindow, it is
  // safe to downcast here.
  LocalDOMWindow* impl = ToLocalDOMWindow({{v8_class}}::ToImpl(holder));
  {% endif %}{# attribute.is_check_security_for_receiver #}
  {% else %}
  {{cpp_class}}* impl = {{v8_class}}::ToImpl(holder);
  {% endif %}{# local_dom_window_only #}
  {% endif %}{# not attribute.is_static #}

  {% if attribute.cached_attribute_validation_method %}
  // [CachedAttribute]
  V8PrivateProperty::Symbol propertySymbol =
      V8PrivateProperty::GetSymbol(info.GetIsolate(),
          "{{cpp_class}}#{{attribute.name.capitalize()}}");
  if (!static_cast<const {{cpp_class}}*>(impl)->{{attribute.cached_attribute_validation_method}}()) {
    v8::Local<v8::Value> v8Value;
    if (propertySymbol.GetOrUndefined(holder).ToLocal(&v8Value) && !v8Value->IsUndefined()) {
      V8SetReturnValue(info, v8Value);
      return;
    }
  }
  {% endif %}

  {% if attribute.is_check_security_for_receiver and not attribute.is_data_type_property %}
  // Perform a security check for the receiver object.
  {{define_exception_state}}
  {% if local_dom_window_only %}
  if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(info.GetIsolate()), uncheckedImpl, exceptionState)) {
  {% else %}
  if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(info.GetIsolate()), impl, exceptionState)) {
  {% endif %}{# local_dom_window_only #}
    V8SetReturnValueNull(info);
    return;
  }
  {% if local_dom_window_only %}
  LocalDOMWindow* impl = ToLocalDOMWindow(uncheckedImpl);
  {% endif %}{# local_dom_window_only #}
  {% endif %}

  {% if attribute.is_check_security_for_return_value %}
  // Perform a security check for the returned object.
  {{define_exception_state}}
  if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(info.GetIsolate()), {{attribute.cpp_value}}, BindingSecurity::ErrorReportOption::kDoNotReport)) {
    UseCounter::Count(CurrentExecutionContext(info.GetIsolate()),
                      WebFeature::kCrossOrigin{{interface_name}}{{attribute.name|blink_capitalize}});
    V8SetReturnValueNull(info);
    return;
  }
  {% endif %}

  {% if attribute.is_call_with_execution_context %}
  {% if attribute.is_static %}
  ExecutionContext* executionContext = ExecutionContext::ForCurrentRealm(info);
  {% else %}
  ExecutionContext* executionContext = ExecutionContext::ForRelevantRealm(info);
  {% endif %}
  {% endif %}

  {% if attribute.is_call_with_script_state %}
  {% if attribute.is_static %}
  ScriptState* scriptState = ScriptState::ForCurrentRealm(info);
  {% else %}
  ScriptState* scriptState = ScriptState::ForRelevantRealm(info);
  {% endif %}
  {% endif %}

  {% if attribute.is_getter_raises_exception %}
  {{define_exception_state}}
  {% endif %}
  {% if attribute.is_explicit_nullable %}
  bool isNull = false;
  {% endif %}

  {% if attribute.cpp_value_original %}
  {{attribute.cpp_type}} {{attribute.cpp_value}}({{attribute.cpp_value_original}});
  {% endif %}

  {% if attribute.use_output_parameter_for_result %}
  {{attribute.cpp_type}} result;
  {{attribute.cpp_value}};
  {% endif %}

  {% if attribute.is_getter_raises_exception %}
  if (UNLIKELY(exceptionState.HadException()))
    return;
  {% endif %}

  {% if attribute.reflect_only %}
  {{release_only_check(attribute.reflect_only, attribute.reflect_missing,
                       attribute.reflect_invalid, attribute.reflect_empty,
                       attribute.cpp_value)
      | trim | indent(2)}}
  {% endif %}

  {% if attribute.cached_attribute_validation_method %}
  // [CachedAttribute]
  v8::Local<v8::Value> v8Value({{attribute.cpp_value_to_v8_value}});
  propertySymbol.Set(holder, v8Value);
  {% endif %}

  {% if attribute.is_explicit_nullable %}
  if (isNull) {
    V8SetReturnValueNull(info);
    return;
  }
  {% endif %}

  {% if attribute.is_keep_alive_for_gc %}
  // Keep the wrapper object for the return value alive as long as |this|
  // object is alive in order to save creation time of the wrapper object.
  if ({{attribute.cpp_value}} && DOMDataStore::SetReturnValue{{world_suffix}}(info.GetReturnValue(), {{attribute.cpp_value_to_script_wrappable}}))
    return;
  v8::Local<v8::Value> v8Value(ToV8({{attribute.cpp_value_to_script_wrappable}}, holder, info.GetIsolate()));
  V8PrivateProperty::GetSymbol(
      info.GetIsolate(), "KeepAlive#{{interface_name}}#{{attribute.name}}")
      .Set(holder, v8Value);
  {% endif %}

  {% if world_suffix %}
  {{attribute.v8_set_return_value_for_main_world}};
  {% else %}
  {{attribute.v8_set_return_value}};
  {% endif %}

  {% if attribute.is_save_same_object %}
  // [SaveSameObject]
  privateSameObject.Set(holder, info.GetReturnValue().Get());
  {% endif %}
  {% endfilter %}{# format_remove_duplicates #}
}
{% endmacro %}


{######################################}
{% macro release_only_check(reflect_only_values, reflect_missing,
                            reflect_invalid, reflect_empty, cpp_value) %}
{# Attribute is limited to only known values: check that the attribute value is
   one of those. If not, set it to the empty string.
   http://www.whatwg.org/specs/web-apps/current-work/#limited-to-only-known-values #}
{% if reflect_empty %}
if ({{cpp_value}}.IsNull()) {
{% if reflect_missing %}
  {{cpp_value}} = "{{reflect_missing}}";
{% else %}
  ;
{% endif %}
} else if ({{cpp_value}}.IsEmpty()) {
  {{cpp_value}} = "{{reflect_empty}}";
{% else %}
if ({{cpp_value}}.IsEmpty()) {
{# FIXME: should use [ReflectEmpty] instead; need to change IDL files #}
{% if reflect_missing %}
  {{cpp_value}} = "{{reflect_missing}}";
{% else %}
  ;
{% endif %}
{% endif %}
{% for value in reflect_only_values %}
} else if (EqualIgnoringASCIICase({{cpp_value}}, "{{value}}")) {
  {{cpp_value}} = "{{value}}";
{% endfor %}
} else {
  {{cpp_value}} = "{{reflect_invalid}}";
}
{% endmacro %}


{##############################################################################}
{% macro attribute_getter_callback(attribute, world_suffix) %}
void {{v8_class_or_partial}}::{{attribute.name}}AttributeGetterCallback{{world_suffix}}(
{%- if attribute.is_data_type_property %}
v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>& info
{%- else %}
const v8::FunctionCallbackInfo<v8::Value>& info
{%- endif %}) {
  {% if attribute.runtime_call_stats.extended_attribute_defined %}
  {{ runtime_timer_scope(attribute.runtime_call_stats.getter_counter) | trim | indent(2) }}
  {% else %}
  {{ runtime_timer_scope_disabled_by_default(attribute.runtime_call_stats.getter_counter) }}
  {% endif %}

  {% if attribute.deprecate_as %}
  Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{attribute.deprecate_as}});
  {% endif %}

  {% if attribute.measure_as %}
  UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{attribute.measure_as('AttributeGetter')}});
  {% endif %}

  {% if world_suffix in attribute.activity_logging_world_list_for_getter %}
  {% if attribute.is_static %}
  ScriptState* scriptState = ScriptState::ForCurrentRealm(info);
  {% else %}
  ScriptState* scriptState = ScriptState::ForRelevantRealm(info);
  {% endif %}
  V8PerContextData* contextData = scriptState->PerContextData();
  if (
  {%- if attribute.activity_logging_world_check -%}
      scriptState->World().IsIsolatedWorld() && {# one space at the end #}
  {%- endif -%}
      contextData && contextData->ActivityLogger()) {
    contextData->ActivityLogger()->LogGetter("{{interface_name}}.{{attribute.name}}");
  }
  {% endif %}

  {% if attribute.has_custom_getter %}
  {{v8_class}}::{{attribute.name}}AttributeGetterCustom(info);
  {% else %}
  {{cpp_class_or_partial}}V8Internal::{{attribute.name}}AttributeGetter{{world_suffix}}(info);
  {% endif %}
}
{% endmacro %}


{##############################################################################}
{% macro constructor_getter_callback(attribute, world_suffix) %}
void {{v8_class_or_partial}}::{{attribute.name}}ConstructorGetterCallback{{world_suffix}}(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
  {{ runtime_timer_scope_disabled_by_default(attribute.runtime_call_stats.constructor_getter_callback_counter) }}
  {% if attribute.deprecate_as %}
  Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{attribute.deprecate_as}});
  {% endif %}

  {% if attribute.measure_as %}
  UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{attribute.measure_as('ConstructorGetter')}});
  {% endif %}

  {% if attribute.is_named_constructor %}
  V8{{attribute.constructor_type}}::NamedConstructorAttributeGetter(property, info);
  {% else %}
  V8ConstructorAttributeGetter(property, info, &V8{{attribute.constructor_type}}::wrapperTypeInfo);
  {% endif %}
}
{% endmacro %}


{##############################################################################}
{% macro attribute_setter(attribute, world_suffix) %}
static void {{attribute.name}}AttributeSetter{{world_suffix}}(
{%- if attribute.has_cross_origin_setter %}
v8::Local<v8::Value> v8Value, const V8CrossOriginSetterInfo& info
{%- elif attribute.is_data_type_property %}
v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
{%- else %}
v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info
{%- endif %}) {
  {% filter format_remove_duplicates(['ExceptionState exceptionState']) %}
  v8::Isolate* isolate = info.GetIsolate();
  ALLOW_UNUSED_LOCAL(isolate);

  v8::Local<v8::Object> holder = info.Holder();
  ALLOW_UNUSED_LOCAL(holder);

  {% set define_exception_state -%}
  ExceptionState exceptionState(isolate, ExceptionState::kSetterContext, "{{interface_name}}", "{{attribute.name}}");
  {%- endset %}

  {% if attribute.is_lenient_this %}
  // [LenientThis]
  // Make sure that info.Holder() really points to an instance if [LenientThis].
  if (!{{v8_class}}::hasInstance(holder, isolate))
    return; // Return silently because of [LenientThis].
  {% endif %}

  {% if not attribute.is_static and not attribute.is_replaceable and not attribute.is_put_forwards %}
  {% set local_dom_window_only = interface_name == 'Window' and not attribute.has_cross_origin_setter %}
  {% if local_dom_window_only %}
  {% if attribute.is_check_security_for_receiver %}
  {{cpp_class}}* uncheckedImpl = {{v8_class}}::ToImpl(holder);
  {% else %}
  // Same-origin attributes setters are never exposed via the cross-origin
  // interceptors. Since same-origin access requires a LocalDOMWindow, it is
  // safe to downcast here.
  LocalDOMWindow* impl = ToLocalDOMWindow({{v8_class}}::ToImpl(holder));
  {% endif %}{# attribute.is_check_security_for_receiver #}
  {% else %}
  {{cpp_class}}* impl = {{v8_class}}::ToImpl(holder);
  {% endif %}{# local_dom_window_only #}
  {% endif %}

  {% if attribute.is_check_security_for_receiver and not attribute.is_data_type_property %}
  // Perform a security check for the receiver object.
  {{define_exception_state}}
  {% if local_dom_window_only %}
  if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(isolate), uncheckedImpl, exceptionState)) {
  {% else %}
  if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(isolate), impl, exceptionState)) {
  {% endif %}{# local_dom_window_only #}
    V8SetReturnValue(info, v8Value);
    return;
  }
  {% if local_dom_window_only %}
  LocalDOMWindow* impl = ToLocalDOMWindow(uncheckedImpl);
  {% endif %}{# local_dom_window_only #}
  {% endif %}

  {% if attribute.is_check_security_for_return_value %}
#error Attribute setter with the security check for the return value is not supported.  Since the return value is the given value to be set, it\'s meaningless to perform the security check for the return value.
  {% endif %}

  {% if attribute.is_put_forwards %}
  // [PutForwards] => {{attribute.name}}.{{attribute.target_attribute_name}}
  {{define_exception_state}}
  v8::Local<v8::Value> target;
  if (!holder->Get(isolate->GetCurrentContext(), V8AtomicString(isolate, "{{attribute.name}}")).ToLocal(&target))
    return;
  if (!target->IsObject()) {
    exceptionState.ThrowTypeError("The attribute value is not an object");
    return;
  }
  bool result;
  if (!target.As<v8::Object>()->Set(isolate->GetCurrentContext(), V8AtomicString(isolate, "{{attribute.target_attribute_name}}"), v8Value).To(&result))
    return;
  if (!result)
    return;
  {% else %}{# attribute.is_put_forwards #}
  {% if attribute.is_custom_element_callbacks or attribute.is_reflect %}
  V0CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
  {% endif %}

  {% if attribute.has_setter_exception_state %}
  {{define_exception_state}}
  {% endif %}
  {% if attribute.is_ce_reactions %}
  CEReactionsScope ce_reactions_scope;
  {% endif %}

  // Prepare the value to be set.
  {% if attribute.idl_type != 'EventHandler' %}
  {{v8_value_to_local_cpp_value(attribute) | trim | indent(2)}}
  {% endif %}

  {% if attribute.has_type_checking_interface %}
  // Type check per: http://heycam.github.io/webidl/#es-interface
  if (!cppValue{% if attribute.is_nullable %} && !IsUndefinedOrNull(v8Value){% endif %}) {
    exceptionState.ThrowTypeError("The provided value is not of type '{{attribute.idl_type}}'.");
    return;
  }
  {% endif %}

  {% if attribute.enum_values %}
  // Type check per: http://heycam.github.io/webidl/#dfn-attribute-setter
  // Returns undefined without setting the value if the value is invalid.
  DummyExceptionStateForTesting dummyExceptionState;
  {{declare_enum_validation_variable(attribute.enum_values) | trim | indent(2)}}
  if (!IsValidEnum(cppValue, validValues, base::size(validValues), "{{attribute.enum_type}}", dummyExceptionState)) {
    ExecutionContext::ForCurrentRealm(info)->AddConsoleMessage(
        ConsoleMessage::Create(kJSMessageSource, kWarningMessageLevel,
                               dummyExceptionState.Message()));
    return;
  }
  {% endif %}

  {% if attribute.is_call_with_execution_context or
        attribute.is_setter_call_with_execution_context %}
  {% if attribute.is_static %}
  ExecutionContext* executionContext = ExecutionContext::ForCurrentRealm(info);
  {% else %}
  ExecutionContext* executionContext = ExecutionContext::ForRelevantRealm(info);
  {% endif %}
  {% endif %}

  {% if attribute.is_call_with_script_state or
  	attribute.is_setter_call_with_script_state %}
  {% if attribute.is_static %}
  ScriptState* scriptState = ScriptState::ForCurrentRealm(info);
  {% else %}
  ScriptState* scriptState = ScriptState::ForRelevantRealm(info);
  {% endif %}
  {% endif %}

  {% if attribute.is_replaceable %}
  v8::Local<v8::String> propertyName = V8AtomicString(isolate, "{{attribute.name}}");
  {% endif %}
  {% if attribute.is_explicit_nullable %}
  bool isNull = IsUndefinedOrNull(v8Value);
  {% endif %}
  {{attribute.cpp_setter}};

  {% if attribute.cached_attribute_validation_method %}
  // [CachedAttribute]
  // Invalidate the cached value.
  V8PrivateProperty::GetSymbol(
      isolate, "{{cpp_class}}#{{attribute.name.capitalize()}}")
      .DeleteProperty(holder, v8::Undefined(isolate));
  {% endif %}
  {% endif %}{# attribute.is_put_forwards #}
  {% endfilter %}{# format_remove_duplicates #}
}
{% endmacro %}


{##############################################################################}
{% macro attribute_setter_callback(attribute, world_suffix) %}
void {{v8_class_or_partial}}::{{attribute.name}}AttributeSetterCallback{{world_suffix}}(
{%- if attribute.is_data_type_property %}
v8::Local<v8::Name>, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
{%- else %}
const v8::FunctionCallbackInfo<v8::Value>& info
{%- endif %}) {
  {% if attribute.is_lenient_setter %}
  // Setter for {{attribute.name}} is no-op because [LenientSetter] is specified.
  {% else %}
  {% if attribute.runtime_call_stats.extended_attribute_defined %}
  {{ runtime_timer_scope(attribute.runtime_call_stats.setter_counter) | trim | indent(2) }}
  {% else %}
  {{ runtime_timer_scope_disabled_by_default(attribute.runtime_call_stats.setter_counter) }}
  {% endif %}

  {% if not attribute.is_data_type_property %}
  v8::Local<v8::Value> v8Value = info[0];
  {% endif %}

  {% if attribute.deprecate_as %}
  Deprecation::CountDeprecation(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{attribute.deprecate_as}});
  {% endif %}

  {% if attribute.measure_as %}
  UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), WebFeature::k{{attribute.measure_as('AttributeSetter')}});
  {% endif %}

  {% if world_suffix in attribute.activity_logging_world_list_for_setter %}
  {% if attribute.is_static %}
  ScriptState* scriptState = ScriptState::ForCurrentRealm(info);
  {% else %}
  ScriptState* scriptState = ScriptState::ForRelevantRealm(info);
  {% endif %}
  V8PerContextData* contextData = scriptState->PerContextData();
  if (
  {%- if attribute.activity_logging_world_check -%}
      scriptState->World().IsIsolatedWorld() && {# one space at the end #}
  {%- endif -%}
      contextData && contextData->ActivityLogger()) {
    contextData->ActivityLogger()->LogSetter("{{interface_name}}.{{attribute.name}}", v8Value);
  }
  {% endif %}

  {% if attribute.has_custom_setter %}
  {{v8_class}}::{{attribute.name}}AttributeSetterCustom(v8Value, info);
  {% elif attribute.has_cross_origin_setter %}
  {{cpp_class_or_partial}}V8Internal::{{attribute.name}}AttributeSetter(v8Value, V8CrossOriginSetterInfo(info.GetIsolate(), info.Holder()));
  {% else %}
  {{cpp_class_or_partial}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(v8Value, info);
  {% endif %}
  {% endif %}{# attribute.is_lenient_setter #}
}
{% endmacro %}


{##############################################################################}
{% macro build_attribute_or_accessor_configuration(attribute, config_type) %}
{% from 'utilities.cc.tmpl' import property_location %}
{% if attribute.constructor_type %}
  {% set getter_callback = '%s::%sConstructorGetterCallback' % (v8_class_or_partial, attribute.name) %}
  {% set setter_callback = 'nullptr' %}
{% else %}{# regular attributes #}
  {% set getter_callback = '%s::%sAttributeGetterCallback' % (v8_class_or_partial, attribute.name) %}
  {% set setter_callback = '%s::%sAttributeSetterCallback' % (v8_class_or_partial, attribute.name)
      if attribute.has_setter else 'nullptr' %}
{% endif %}

{% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
                            ' | '.join(attribute.property_attributes) %}
{% set cached_property_key = 'V8PrivateProperty::k' +
    (attribute.cached_accessor_name if attribute.is_cached_accessor
     else 'NoCachedAccessor') %}
{% set holder_check = 'V8DOMConfiguration::kDoNotCheckHolder'
    if attribute.is_lenient_this or attribute.has_promise_type
    else 'V8DOMConfiguration::kCheckHolder' %}
{% set getter_side_effect_type = 'V8DOMConfiguration::kHasNoSideEffect'
    if attribute.getter_has_no_side_effect else 'V8DOMConfiguration::kHasSideEffect' %}
{% set getter_behavior = 'V8DOMConfiguration::kAlwaysCallGetter'
    if not attribute.is_lazy_data_attribute else 'V8DOMConfiguration::kReplaceWithDataProperty' %}
{% if attribute.is_per_world_bindings %}
  {% set getter_callback_for_main_world = '%sForMainWorld' % getter_callback %}
  {% set setter_callback_for_main_world =
      '%sForMainWorld' % setter_callback if attribute.has_setter else 'nullptr' %}
{% endif %}
{% set config_pre = {
    'main' : [
        '"%s"' % attribute.name,
        getter_callback_for_main_world,
        setter_callback_for_main_world,
    ],
    'non_main' : [
        '"%s"' % attribute.name,
        getter_callback,
        setter_callback,
    ],
} %}
{% set accessor_only_fields = [] if config_type == 'attribute' else [cached_property_key] %}
{% set config_post = [
    property_attribute,
    property_location(attribute),
    holder_check,
    getter_side_effect_type,
    getter_behavior,
] %}

{% if attribute.is_per_world_bindings %}
  {% set main_config_list = config_pre["main"] + accessor_only_fields +
      config_post + ['V8DOMConfiguration::kMainWorld'] %}
  {% set non_main_config_list = config_pre["non_main"] + accessor_only_fields +
      config_post + ['V8DOMConfiguration::kNonMainWorlds'] %}
  {# Emit for main world then non-main.#}
{ {{main_config_list | join(', ')}} },
{ {{non_main_config_list | join(', ')}} }
{%- else -%}
  {% set all_worlds_config_list = config_pre["non_main"] + accessor_only_fields +
      config_post + ['V8DOMConfiguration::kAllWorlds'] %}
  {# Emit only for all worlds #}
{ {{all_worlds_config_list | join(', ')}} }
{%- endif -%}
{% endmacro %}


{##############################################################################}
{% macro attribute_configuration(attribute) %}
{{build_attribute_or_accessor_configuration(attribute, 'attribute')}}
{% endmacro %}


{##############################################################################}
{% macro accessor_configuration(attribute) %}
{{build_attribute_or_accessor_configuration(attribute, 'accessor')}}
{% endmacro %}


{##############################################################################}
{# This macro installs |attributes_to_install| on v8::Object/v8::Function, not on v8::ObjectTemplate/v8::FunctionTemplate. #}
{% macro install_conditional_attributes(attributes_to_install) %}
{% for exposed_test, exposed_attribute_list in attributes_to_install | groupby('exposed_test') %}
{% filter exposed(exposed_test) %}
{% for secure_context_test, secure_context_attribute_list in exposed_attribute_list | groupby('secure_context_test') %}
{% filter secure_context(secure_context_test) %}
{% for feature_name, attribute_list in secure_context_attribute_list | groupby('runtime_enabled_feature_name') %}
{% filter runtime_enabled(feature_name) %}
static const V8DOMConfiguration::AccessorConfiguration accessor_configurations[] = {
    {% for attribute in attribute_list | sort %}
    {{accessor_configuration(attribute) | trim | indent(4)}},
    {% endfor %}
};
V8DOMConfiguration::InstallAccessors(
    isolate, world, instanceObject, prototypeObject, interfaceObject,
    signature, accessor_configurations,
    base::size(accessor_configurations));
{% endfilter %}{# runtime_enabled #}
{% endfor %}{# secure_context_attribute_list grouped by runtime_enabled #}
{% endfilter %}{# secure_context #}
{% endfor %}{# exposed_attribute_list grouped by secure_context_text #}
{% endfilter %}{# exposed #}
{% endfor %}{# attributes grouped by exposed_test #}
{% endmacro %}


{##############################################################################}
{% macro install_conditional_interface_objects(attributes_to_install) %}
{% for exposed_test, exposed_attribute_list in attributes_to_install | groupby('exposed_test') %}
{% filter exposed(exposed_test) %}
{% for secure_context_test, secure_context_attribute_list in exposed_attribute_list | groupby('secure_context_test') %}
{% filter secure_context(secure_context_test) %}
{% for feature_name, attribute_list in secure_context_attribute_list | groupby('runtime_enabled_feature_name') %}
{% filter runtime_enabled(feature_name) %}
static const V8DOMConfiguration::AttributeConfiguration attribute_configurations[] = {
    {% for attribute in attribute_list | sort %}
    {{attribute_configuration(attribute) | trim | indent(4)}},
    {% endfor %}
};
V8DOMConfiguration::InstallAttributes(
    isolate, world, instanceObject, prototypeObject,
    attribute_configurations, base::size(attribute_configurations));
{% endfilter %}{# runtime_enabled #}
{% endfor %}{# secure_context_attribute_list grouped by runtime_enabled #}
{% endfilter %}{# secure_context #}
{% endfor %}{# exposed_attribute_list grouped by secure_context_text #}
{% endfilter %}{# exposed #}
{% endfor %}{# attributes grouped by exposed_test #}
{% endmacro %}
