// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file has been auto-generated by code_generator_v8.py. DO NOT MODIFY!

#include "V8TestInterface5.h"

#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/GeneratedCodeHelper.h"
#include "bindings/core/v8/ScriptState.h"
#include "bindings/core/v8/ScriptValue.h"
#include "bindings/core/v8/V8DOMConfiguration.h"
#include "bindings/core/v8/V8Iterator.h"
#include "bindings/core/v8/V8ObjectConstructor.h"
#include "bindings/core/v8/V8TestInterfaceEmpty.h"
#include "bindings/modules/v8/BooleanOrString.h"
#include "bindings/modules/v8/DoubleOrString.h"
#include "bindings/modules/v8/V8TestInterface5.h"
#include "core/dom/Document.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/GetPtr.h"
#include "wtf/RefPtr.h"

namespace blink {

// Suppress warning: global constructors, because struct WrapperTypeInfo is trivial
// and does not depend on another global objects.
#if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
const WrapperTypeInfo V8TestInterface5::wrapperTypeInfo = { gin::kEmbedderBlink, V8TestInterface5::domTemplate, V8TestInterface5::trace, V8TestInterface5::traceWrappers, V8TestInterface5::visitDOMWrapper, V8TestInterface5::preparePrototypeAndInterfaceObject, "TestInterface5", &V8TestInterfaceEmpty::wrapperTypeInfo, WrapperTypeInfo::WrapperTypeObjectPrototype, WrapperTypeInfo::ObjectClassId, WrapperTypeInfo::InheritFromActiveScriptWrappable, WrapperTypeInfo::NotInheritFromEventTarget, WrapperTypeInfo::Dependent };
#if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
#pragma clang diagnostic pop
#endif

// This static member must be declared by DEFINE_WRAPPERTYPEINFO in TestInterface5Implementation.h.
// For details, see the comment of DEFINE_WRAPPERTYPEINFO in
// bindings/core/v8/ScriptWrappable.h.
const WrapperTypeInfo& TestInterface5Implementation::s_wrapperTypeInfo = V8TestInterface5::wrapperTypeInfo;

// [ActiveScriptWrappable]
static_assert(
    std::is_base_of<ActiveScriptWrappable, TestInterface5Implementation>::value,
    "TestInterface5Implementation does not inherit from ActiveScriptWrappable, but specifying "
    "[ActiveScriptWrappable] extended attribute in the IDL file.  "
    "Be consistent.");
static_assert(
    !std::is_same<decltype(&TestInterface5Implementation::hasPendingActivity),
                  decltype(&ScriptWrappable::hasPendingActivity)>::value,
    "TestInterface5Implementation is not overriding hasPendingActivity(), but is specifying "
    "[ActiveScriptWrappable] extended attribute in the IDL file.  "
    "Be consistent.");

namespace TestInterface5ImplementationV8Internal {

static void testInterfaceAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValueFast(info, WTF::getPtr(impl->testInterfaceAttribute()), impl);
}

void testInterfaceAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::testInterfaceAttributeAttributeGetter(info);
}

static void testInterfaceAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "testInterfaceAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    TestInterface5Implementation* cppValue = V8TestInterface5::toImplWithTypeCheck(info.GetIsolate(), v8Value);
    if (!cppValue) {
        exceptionState.throwTypeError("The provided value is not of type 'TestInterface5'.");
        return;
    }
    impl->setTestInterfaceAttribute(cppValue);
}

void testInterfaceAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::testInterfaceAttributeAttributeSetter(v8Value, info);
}

static void doubleAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValue(info, impl->doubleAttribute());
}

void doubleAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::doubleAttributeAttributeGetter(info);
}

static void doubleAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "doubleAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    double cppValue = toRestrictedDouble(info.GetIsolate(), v8Value, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setDoubleAttribute(cppValue);
}

void doubleAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::doubleAttributeAttributeSetter(v8Value, info);
}

static void floatAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValue(info, impl->floatAttribute());
}

void floatAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::floatAttributeAttributeGetter(info);
}

static void floatAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "floatAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    float cppValue = toRestrictedFloat(info.GetIsolate(), v8Value, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setFloatAttribute(cppValue);
}

void floatAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::floatAttributeAttributeSetter(v8Value, info);
}

static void unrestrictedDoubleAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValue(info, impl->unrestrictedDoubleAttribute());
}

void unrestrictedDoubleAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::unrestrictedDoubleAttributeAttributeGetter(info);
}

static void unrestrictedDoubleAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "unrestrictedDoubleAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    double cppValue = toDouble(info.GetIsolate(), v8Value, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setUnrestrictedDoubleAttribute(cppValue);
}

void unrestrictedDoubleAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::unrestrictedDoubleAttributeAttributeSetter(v8Value, info);
}

static void unrestrictedFloatAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValue(info, impl->unrestrictedFloatAttribute());
}

void unrestrictedFloatAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::unrestrictedFloatAttributeAttributeGetter(info);
}

static void unrestrictedFloatAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "unrestrictedFloatAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    float cppValue = toFloat(info.GetIsolate(), v8Value, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setUnrestrictedFloatAttribute(cppValue);
}

void unrestrictedFloatAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::unrestrictedFloatAttributeAttributeSetter(v8Value, info);
}

static void staticStringAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8SetReturnValueString(info, TestInterface5Implementation::staticStringAttribute(), info.GetIsolate());
}

void staticStringAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::staticStringAttributeAttributeGetter(info);
}

static void staticStringAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    V8StringResource<> cppValue = v8Value;
    if (!cppValue.prepare())
        return;
    TestInterface5Implementation::setStaticStringAttribute(cppValue);
}

void staticStringAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::staticStringAttributeAttributeSetter(v8Value, info);
}

static void alwaysExposedAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValueInt(info, impl->alwaysExposedAttribute());
}

void alwaysExposedAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::alwaysExposedAttributeAttributeGetter(info);
}

static void alwaysExposedAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "alwaysExposedAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setAlwaysExposedAttribute(cppValue);
}

void alwaysExposedAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::alwaysExposedAttributeAttributeSetter(v8Value, info);
}

static void workerExposedAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValueInt(info, impl->workerExposedAttribute());
}

void workerExposedAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::workerExposedAttributeAttributeGetter(info);
}

static void workerExposedAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "workerExposedAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setWorkerExposedAttribute(cppValue);
}

void workerExposedAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::workerExposedAttributeAttributeSetter(v8Value, info);
}

static void windowExposedAttributeAttributeGetter(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    v8SetReturnValueInt(info, impl->windowExposedAttribute());
}

void windowExposedAttributeAttributeGetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::windowExposedAttributeAttributeGetter(info);
}

static void windowExposedAttributeAttributeSetter(v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Object> holder = info.Holder();
    ExceptionState exceptionState(ExceptionState::SetterContext, "windowExposedAttribute", "TestInterface5", holder, info.GetIsolate());
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(holder);
    int cppValue = toInt32(info.GetIsolate(), v8Value, NormalConversion, exceptionState);
    if (exceptionState.hadException())
        return;
    impl->setWindowExposedAttribute(cppValue);
}

void windowExposedAttributeAttributeSetterCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Local<v8::Value> v8Value = info[0];
    TestInterface5ImplementationV8Internal::windowExposedAttributeAttributeSetter(v8Value, info);
}

static void voidMethodTestInterfaceEmptyArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    if (UNLIKELY(info.Length() < 1)) {
        V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToExecute("voidMethodTestInterfaceEmptyArg", "TestInterface5", ExceptionMessages::notEnoughArguments(1, info.Length())));
        return;
    }

    TestInterfaceEmpty* testInterfaceEmptyArg;
    testInterfaceEmptyArg = V8TestInterfaceEmpty::toImplWithTypeCheck(info.GetIsolate(), info[0]);
    if (!testInterfaceEmptyArg) {
        V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToExecute("voidMethodTestInterfaceEmptyArg", "TestInterface5", "parameter 1 is not of type 'TestInterfaceEmpty'."));

        return;
    }

    impl->voidMethodTestInterfaceEmptyArg(testInterfaceEmptyArg);
}

static void voidMethodTestInterfaceEmptyArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodTestInterfaceEmptyArgMethod(info);
}

static void voidMethodDoubleArgFloatArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "voidMethodDoubleArgFloatArg");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    if (UNLIKELY(info.Length() < 2)) {
        exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
        return;
    }

    double doubleArg;
    float floatArg;
    doubleArg = toRestrictedDouble(info.GetIsolate(), info[0], exceptionState);
    if (exceptionState.hadException())
        return;

    floatArg = toRestrictedFloat(info.GetIsolate(), info[1], exceptionState);
    if (exceptionState.hadException())
        return;

    impl->voidMethodDoubleArgFloatArg(doubleArg, floatArg);
}

static void voidMethodDoubleArgFloatArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodDoubleArgFloatArgMethod(info);
}

static void voidMethodUnrestrictedDoubleArgUnrestrictedFloatArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "voidMethodUnrestrictedDoubleArgUnrestrictedFloatArg");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    if (UNLIKELY(info.Length() < 2)) {
        exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(2, info.Length()));
        return;
    }

    double unrestrictedDoubleArg;
    float unrestrictedFloatArg;
    unrestrictedDoubleArg = toDouble(info.GetIsolate(), info[0], exceptionState);
    if (exceptionState.hadException())
        return;

    unrestrictedFloatArg = toFloat(info.GetIsolate(), info[1], exceptionState);
    if (exceptionState.hadException())
        return;

    impl->voidMethodUnrestrictedDoubleArgUnrestrictedFloatArg(unrestrictedDoubleArg, unrestrictedFloatArg);
}

static void voidMethodUnrestrictedDoubleArgUnrestrictedFloatArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodUnrestrictedDoubleArgUnrestrictedFloatArgMethod(info);
}

static void voidMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    impl->voidMethod();
}

static void voidMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodMethod(info);
}

static void voidMethodMethodForMainWorld(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    impl->voidMethod();
}

static void voidMethodMethodCallbackForMainWorld(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodMethodForMainWorld(info);
}

static void alwaysExposedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    impl->alwaysExposedMethod();
}

static void alwaysExposedMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::alwaysExposedMethodMethod(info);
}

static void workerExposedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    impl->workerExposedMethod();
}

static void workerExposedMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::workerExposedMethodMethod(info);
}

static void windowExposedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    impl->windowExposedMethod();
}

static void windowExposedMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::windowExposedMethodMethod(info);
}

static void alwaysExposedStaticMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation::alwaysExposedStaticMethod();
}

static void alwaysExposedStaticMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::alwaysExposedStaticMethodMethod(info);
}

static void workerExposedStaticMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation::workerExposedStaticMethod();
}

static void workerExposedStaticMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::workerExposedStaticMethodMethod(info);
}

static void windowExposedStaticMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation::windowExposedStaticMethod();
}

static void windowExposedStaticMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::windowExposedStaticMethodMethod(info);
}

static void windowAndServiceWorkerExposedMethodMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    impl->windowAndServiceWorkerExposedMethod();
}

static void windowAndServiceWorkerExposedMethodMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::windowAndServiceWorkerExposedMethodMethod(info);
}

static void voidMethodBooleanOrDOMStringArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "voidMethodBooleanOrDOMStringArg");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    if (UNLIKELY(info.Length() < 1)) {
        exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
        return;
    }

    BooleanOrString arg;
    V8BooleanOrString::toImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::NotNullable, exceptionState);
    if (exceptionState.hadException())
        return;

    impl->voidMethodBooleanOrDOMStringArg(arg);
}

static void voidMethodBooleanOrDOMStringArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodBooleanOrDOMStringArgMethod(info);
}

static void voidMethodDoubleOrDOMStringArgMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "voidMethodDoubleOrDOMStringArg");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    if (UNLIKELY(info.Length() < 1)) {
        exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
        return;
    }

    DoubleOrString arg;
    V8DoubleOrString::toImpl(info.GetIsolate(), info[0], arg, UnionTypeConversionMode::NotNullable, exceptionState);
    if (exceptionState.hadException())
        return;

    impl->voidMethodDoubleOrDOMStringArg(arg);
}

static void voidMethodDoubleOrDOMStringArgMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::voidMethodDoubleOrDOMStringArgMethod(info);
}

static void keysMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "keys");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    ScriptState* scriptState = ScriptState::forReceiverObject(info);

    Iterator* result = impl->keysForBinding(scriptState, exceptionState);
    if (exceptionState.hadException()) {
        return;
    }
    v8SetReturnValue(info, result);
}

static void keysMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::keysMethod(info);
}

static void valuesMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "values");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    ScriptState* scriptState = ScriptState::forReceiverObject(info);

    Iterator* result = impl->valuesForBinding(scriptState, exceptionState);
    if (exceptionState.hadException()) {
        return;
    }
    v8SetReturnValue(info, result);
}

static void valuesMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::valuesMethod(info);
}

static void entriesMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "entries");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    ScriptState* scriptState = ScriptState::forReceiverObject(info);

    Iterator* result = impl->entriesForBinding(scriptState, exceptionState);
    if (exceptionState.hadException()) {
        return;
    }
    v8SetReturnValue(info, result);
}

static void entriesMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::entriesMethod(info);
}

static void forEachMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "forEach");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    ScriptState* scriptState = ScriptState::forReceiverObject(info);

    if (UNLIKELY(info.Length() < 1)) {
        exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, info.Length()));
        return;
    }

    ScriptValue callback;
    ScriptValue thisArg;
    if (!info[0]->IsFunction()) {
        exceptionState.throwTypeError("The callback provided as parameter 1 is not a function.");

        return;
    }
    callback = ScriptValue(ScriptState::current(info.GetIsolate()), info[0]);

    thisArg = ScriptValue(ScriptState::current(info.GetIsolate()), info[1]);

    impl->forEachForBinding(scriptState, ScriptValue(scriptState, info.Holder()), callback, thisArg, exceptionState);
    if (exceptionState.hadException()) {
        return;
    }
}

static void forEachMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::forEachMethod(info);
}

static void toStringMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    v8SetReturnValueString(info, impl->toString(), info.GetIsolate());
}

static void toStringMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::toStringMethod(info);
}

static void iteratorMethod(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionContext, "TestInterface5", "iterator");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    ScriptState* scriptState = ScriptState::forReceiverObject(info);

    Iterator* result = impl->iterator(scriptState, exceptionState);
    if (exceptionState.hadException()) {
        return;
    }
    v8SetReturnValue(info, result);
}

static void iteratorMethodCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::iteratorMethod(info);
}

static void namedPropertyGetter(const AtomicString& name, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());
    String result = impl->anonymousNamedGetter(name);
    if (result.isNull())
        return;
    v8SetReturnValueString(info, result, info.GetIsolate());
}

void namedPropertyGetterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    if (!name->IsString())
        return;
    const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>());

    TestInterface5ImplementationV8Internal::namedPropertyGetter(propertyName, info);
}

static void namedPropertySetter(const AtomicString& name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());
    V8StringResource<> propertyValue = v8Value;
    if (!propertyValue.prepare())
        return;

    bool result = impl->anonymousNamedSetter(name, propertyValue);
    if (!result)
        return;
    v8SetReturnValue(info, v8Value);
}

void namedPropertySetterCallback(v8::Local<v8::Name> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    if (!name->IsString())
        return;
    const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>());

    TestInterface5ImplementationV8Internal::namedPropertySetter(propertyName, v8Value, info);
}

static void namedPropertyDeleter(const AtomicString& name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    DeleteResult result = impl->anonymousNamedDeleter(name);
    if (result == DeleteUnknownProperty)
        return;
    v8SetReturnValue(info, result == DeleteSuccess);
}

void namedPropertyDeleterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
    if (!name->IsString())
        return;
    const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>());

    TestInterface5ImplementationV8Internal::namedPropertyDeleter(propertyName, info);
}

static void namedPropertyQuery(const AtomicString& name, const v8::PropertyCallbackInfo<v8::Integer>& info)
{
    const CString& nameInUtf8 = name.utf8();
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::GetterContext, "TestInterface5", nameInUtf8.data());

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    bool result = impl->namedPropertyQuery(name, exceptionState);
    if (!result)
        return;
    v8SetReturnValueInt(info, v8::None);
}

void namedPropertyQueryCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
{
    if (!name->IsString())
        return;
    const AtomicString& propertyName = toCoreAtomicString(name.As<v8::String>());

    TestInterface5ImplementationV8Internal::namedPropertyQuery(propertyName, info);
}

static void namedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
{
    ExceptionState exceptionState(info.GetIsolate(), ExceptionState::EnumerationContext, "TestInterface5");

    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    Vector<String> names;
    impl->namedPropertyEnumerator(names, exceptionState);
    if (exceptionState.hadException())
        return;
    v8SetReturnValue(info, toV8(names, info.Holder(), info.GetIsolate()).As<v8::Array>());
}

void namedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array>& info)
{
    TestInterface5ImplementationV8Internal::namedPropertyEnumerator(info);
}

static void indexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    String result = impl->anonymousIndexedGetter(index);
    if (result.isNull())
        return;
    v8SetReturnValueString(info, result, info.GetIsolate());
}

void indexedPropertyGetterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::indexedPropertyGetter(index, info);
}

static void indexedPropertySetter(uint32_t index, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());
    V8StringResource<> propertyValue = v8Value;
    if (!propertyValue.prepare())
        return;

    bool result = impl->anonymousIndexedSetter(index, propertyValue);
    if (!result)
        return;
    v8SetReturnValue(info, v8Value);
}

void indexedPropertySetterCallback(uint32_t index, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
{
    TestInterface5ImplementationV8Internal::indexedPropertySetter(index, v8Value, info);
}

static void indexedPropertyDeleter(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
    TestInterface5Implementation* impl = V8TestInterface5::toImpl(info.Holder());

    DeleteResult result = impl->anonymousIndexedDeleter(index);
    if (result == DeleteUnknownProperty)
        return;
    v8SetReturnValue(info, result == DeleteSuccess);
}

void indexedPropertyDeleterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
{
    TestInterface5ImplementationV8Internal::indexedPropertyDeleter(index, info);
}

} // namespace TestInterface5ImplementationV8Internal

void V8TestInterface5::visitDOMWrapper(v8::Isolate* isolate, ScriptWrappable* scriptWrappable, const v8::Persistent<v8::Object>& wrapper)
{
    TestInterface5Implementation* impl = scriptWrappable->toImpl<TestInterface5Implementation>();
    TestInterface5Implementation* referencedName = impl->referencedName();
    if (referencedName) {
        DOMWrapperWorld::setWrapperReferencesInAllWorlds(wrapper, referencedName, isolate);
    }
}

// Suppress warning: global constructors, because AttributeConfiguration is trivial
// and does not depend on another global objects.
#if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wglobal-constructors"
#endif
const V8DOMConfiguration::AttributeConfiguration V8TestInterface5Attributes[] = {
    {"testInterfaceConstructorAttribute", v8ConstructorAttributeGetter, 0, 0, 0, const_cast<WrapperTypeInfo*>(&V8TestInterface5::wrapperTypeInfo), static_cast<v8::AccessControl>(v8::DEFAULT), static_cast<v8::PropertyAttribute>(v8::DontEnum), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInstance, V8DOMConfiguration::CheckHolder},
};
#if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
#pragma clang diagnostic pop
#endif

const V8DOMConfiguration::AccessorConfiguration V8TestInterface5Accessors[] = {
    {"testInterfaceAttribute", TestInterface5ImplementationV8Internal::testInterfaceAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::testInterfaceAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
    {"doubleAttribute", TestInterface5ImplementationV8Internal::doubleAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::doubleAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
    {"floatAttribute", TestInterface5ImplementationV8Internal::floatAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::floatAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
    {"unrestrictedDoubleAttribute", TestInterface5ImplementationV8Internal::unrestrictedDoubleAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::unrestrictedDoubleAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
    {"unrestrictedFloatAttribute", TestInterface5ImplementationV8Internal::unrestrictedFloatAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::unrestrictedFloatAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
    {"staticStringAttribute", TestInterface5ImplementationV8Internal::staticStringAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::staticStringAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInterface, V8DOMConfiguration::CheckHolder},
    {"alwaysExposedAttribute", TestInterface5ImplementationV8Internal::alwaysExposedAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::alwaysExposedAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder},
};

const V8DOMConfiguration::MethodConfiguration V8TestInterface5Methods[] = {
    {"voidMethodTestInterfaceEmptyArg", TestInterface5ImplementationV8Internal::voidMethodTestInterfaceEmptyArgMethodCallback, 0, 1, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"voidMethodDoubleArgFloatArg", TestInterface5ImplementationV8Internal::voidMethodDoubleArgFloatArgMethodCallback, 0, 2, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"voidMethodUnrestrictedDoubleArgUnrestrictedFloatArg", TestInterface5ImplementationV8Internal::voidMethodUnrestrictedDoubleArgUnrestrictedFloatArgMethodCallback, 0, 2, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"voidMethod", TestInterface5ImplementationV8Internal::voidMethodMethodCallback, TestInterface5ImplementationV8Internal::voidMethodMethodCallbackForMainWorld, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"alwaysExposedMethod", TestInterface5ImplementationV8Internal::alwaysExposedMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"alwaysExposedStaticMethod", TestInterface5ImplementationV8Internal::alwaysExposedStaticMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInterface},
    {"voidMethodBooleanOrDOMStringArg", TestInterface5ImplementationV8Internal::voidMethodBooleanOrDOMStringArgMethodCallback, 0, 1, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"voidMethodDoubleOrDOMStringArg", TestInterface5ImplementationV8Internal::voidMethodDoubleOrDOMStringArgMethodCallback, 0, 1, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"keys", TestInterface5ImplementationV8Internal::keysMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"values", TestInterface5ImplementationV8Internal::valuesMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"entries", TestInterface5ImplementationV8Internal::entriesMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"forEach", TestInterface5ImplementationV8Internal::forEachMethodCallback, 0, 1, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
    {"toString", TestInterface5ImplementationV8Internal::toStringMethodCallback, 0, 0, static_cast<v8::PropertyAttribute>(v8::DontEnum), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype},
};

static void installV8TestInterface5Template(v8::Isolate* isolate, const DOMWrapperWorld& world, v8::Local<v8::FunctionTemplate> interfaceTemplate)
{
    // Initialize the interface object's template.
    V8DOMConfiguration::initializeDOMInterfaceTemplate(isolate, interfaceTemplate, V8TestInterface5::wrapperTypeInfo.interfaceName, V8TestInterfaceEmpty::domTemplate(isolate, world), V8TestInterface5::internalFieldCount);
    v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interfaceTemplate);
    ALLOW_UNUSED_LOCAL(signature);
    v8::Local<v8::ObjectTemplate> instanceTemplate = interfaceTemplate->InstanceTemplate();
    ALLOW_UNUSED_LOCAL(instanceTemplate);
    v8::Local<v8::ObjectTemplate> prototypeTemplate = interfaceTemplate->PrototypeTemplate();
    ALLOW_UNUSED_LOCAL(prototypeTemplate);
    // Register DOM constants, attributes and operations.
    if (RuntimeEnabledFeatures::featureNameEnabled()) {
        const V8DOMConfiguration::ConstantConfiguration V8TestInterface5Constants[] = {
            {"UNSIGNED_LONG", 0, 0, V8DOMConfiguration::ConstantTypeUnsignedLong},
            {"CONST_JAVASCRIPT", 1, 0, V8DOMConfiguration::ConstantTypeShort},
        };
        V8DOMConfiguration::installConstants(isolate, interfaceTemplate, prototypeTemplate, V8TestInterface5Constants, WTF_ARRAY_LENGTH(V8TestInterface5Constants));
        V8DOMConfiguration::installAttributes(isolate, world, instanceTemplate, prototypeTemplate, V8TestInterface5Attributes, WTF_ARRAY_LENGTH(V8TestInterface5Attributes));
        V8DOMConfiguration::installAccessors(isolate, world, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, V8TestInterface5Accessors, WTF_ARRAY_LENGTH(V8TestInterface5Accessors));
        V8DOMConfiguration::installMethods(isolate, world, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, V8TestInterface5Methods, WTF_ARRAY_LENGTH(V8TestInterface5Methods));
    }

    // Indexed properties
    v8::IndexedPropertyHandlerConfiguration indexedPropertyHandlerConfig(TestInterface5ImplementationV8Internal::indexedPropertyGetterCallback, TestInterface5ImplementationV8Internal::indexedPropertySetterCallback, 0, TestInterface5ImplementationV8Internal::indexedPropertyDeleterCallback, indexedPropertyEnumerator<TestInterface5Implementation>, v8::Local<v8::Value>(), v8::PropertyHandlerFlags::kNone);
    instanceTemplate->SetHandler(indexedPropertyHandlerConfig);
    // Named properties
    v8::NamedPropertyHandlerConfiguration namedPropertyHandlerConfig(TestInterface5ImplementationV8Internal::namedPropertyGetterCallback, TestInterface5ImplementationV8Internal::namedPropertySetterCallback, TestInterface5ImplementationV8Internal::namedPropertyQueryCallback, TestInterface5ImplementationV8Internal::namedPropertyDeleterCallback, TestInterface5ImplementationV8Internal::namedPropertyEnumeratorCallback, v8::Local<v8::Value>(), static_cast<v8::PropertyHandlerFlags>(int(v8::PropertyHandlerFlags::kOnlyInterceptStrings) | int(v8::PropertyHandlerFlags::kNonMasking)));
    instanceTemplate->SetHandler(namedPropertyHandlerConfig);

    // Iterator (@@iterator)
    const V8DOMConfiguration::SymbolKeyedMethodConfiguration symbolKeyedIteratorConfiguration = { v8::Symbol::GetIterator, TestInterface5ImplementationV8Internal::iteratorMethodCallback, 0, v8::DontDelete, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype };
    V8DOMConfiguration::installMethod(isolate, world, prototypeTemplate, signature, symbolKeyedIteratorConfiguration);

    instanceTemplate->SetCallAsFunctionHandler(V8TestInterface5::legacyCallCustom);
}

v8::Local<v8::FunctionTemplate> V8TestInterface5::domTemplate(v8::Isolate* isolate, const DOMWrapperWorld& world)
{
    return V8DOMConfiguration::domClassTemplate(isolate, world, const_cast<WrapperTypeInfo*>(&wrapperTypeInfo), installV8TestInterface5Template);
}

bool V8TestInterface5::hasInstance(v8::Local<v8::Value> v8Value, v8::Isolate* isolate)
{
    return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, v8Value);
}

v8::Local<v8::Object> V8TestInterface5::findInstanceInPrototypeChain(v8::Local<v8::Value> v8Value, v8::Isolate* isolate)
{
    return V8PerIsolateData::from(isolate)->findInstanceInPrototypeChain(&wrapperTypeInfo, v8Value);
}

TestInterface5Implementation* V8TestInterface5::toImplWithTypeCheck(v8::Isolate* isolate, v8::Local<v8::Value> value)
{
    return hasInstance(value, isolate) ? toImpl(v8::Local<v8::Object>::Cast(value)) : nullptr;
}

void V8TestInterface5::preparePrototypeAndInterfaceObject(v8::Local<v8::Context> context, const DOMWrapperWorld& world, v8::Local<v8::Object> prototypeObject, v8::Local<v8::Function> interfaceObject, v8::Local<v8::FunctionTemplate> interfaceTemplate)
{
    v8::Isolate* isolate = context->GetIsolate();
    ExecutionContext* executionContext = toExecutionContext(context);
    v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interfaceTemplate);
    if (executionContext && (executionContext->isWorkerGlobalScope())) {
        const V8DOMConfiguration::AccessorConfiguration accessorConfiguration = {"workerExposedAttribute", TestInterface5ImplementationV8Internal::workerExposedAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::workerExposedAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder};
        V8DOMConfiguration::installAccessor(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, accessorConfiguration);
    }
    if (executionContext && (executionContext->isDocument())) {
        const V8DOMConfiguration::AccessorConfiguration accessorConfiguration = {"windowExposedAttribute", TestInterface5ImplementationV8Internal::windowExposedAttributeAttributeGetterCallback, TestInterface5ImplementationV8Internal::windowExposedAttributeAttributeSetterCallback, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::None), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder};
        V8DOMConfiguration::installAccessor(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, accessorConfiguration);
    }
    v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interfaceTemplate);
    ExecutionContext* executionContext = toExecutionContext(prototypeObject->CreationContext());
    ASSERT(executionContext);
    if (executionContext && (executionContext->isWorkerGlobalScope())) {
        const V8DOMConfiguration::MethodConfiguration workerExposedMethodMethodConfiguration = {"workerExposedMethod", TestInterface5ImplementationV8Internal::workerExposedMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype};
        V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, workerExposedMethodMethodConfiguration);
    }
    if (executionContext && (executionContext->isDocument())) {
        const V8DOMConfiguration::MethodConfiguration windowExposedMethodMethodConfiguration = {"windowExposedMethod", TestInterface5ImplementationV8Internal::windowExposedMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype};
        V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, windowExposedMethodMethodConfiguration);
    }
    if (executionContext && (executionContext->isWorkerGlobalScope())) {
        const V8DOMConfiguration::MethodConfiguration workerExposedStaticMethodMethodConfiguration = {"workerExposedStaticMethod", TestInterface5ImplementationV8Internal::workerExposedStaticMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInterface};
        V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, workerExposedStaticMethodMethodConfiguration);
    }
    if (executionContext && (executionContext->isDocument())) {
        const V8DOMConfiguration::MethodConfiguration windowExposedStaticMethodMethodConfiguration = {"windowExposedStaticMethod", TestInterface5ImplementationV8Internal::windowExposedStaticMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnInterface};
        V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, windowExposedStaticMethodMethodConfiguration);
    }
    if (executionContext && (executionContext->isDocument() || executionContext->isServiceWorkerGlobalScope())) {
        const V8DOMConfiguration::MethodConfiguration windowAndServiceWorkerExposedMethodMethodConfiguration = {"windowAndServiceWorkerExposedMethod", TestInterface5ImplementationV8Internal::windowAndServiceWorkerExposedMethodMethodCallback, 0, 0, v8::None, V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype};
        V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, windowAndServiceWorkerExposedMethodMethodConfiguration);
    }
}

} // namespace blink
