/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "JSTestDerivedDictionary.h"

#include "Document.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertCallbacks.h"
#include "JSDOMConvertNumbers.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMGlobalObject.h"
#include "JSVoidCallback.h"
#include "Settings.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/ObjectConstructor.h>


namespace WebCore {
using namespace JSC;

template<> TestDerivedDictionary convertDictionary<TestDerivedDictionary>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    bool isNullOrUndefined = value.isUndefinedOrNull();
    auto* object = isNullOrUndefined ? nullptr : value.getObject();
    if (UNLIKELY(!isNullOrUndefined && !object)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    TestDerivedDictionary result;
    JSValue boolMemberValue;
    if (isNullOrUndefined)
        boolMemberValue = jsUndefined();
    else {
        boolMemberValue = object->get(&state, Identifier::fromString(vm, "boolMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!boolMemberValue.isUndefined()) {
        result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue callbackMemberValue;
    if (isNullOrUndefined)
        callbackMemberValue = jsUndefined();
    else {
        callbackMemberValue = object->get(&state, Identifier::fromString(vm, "callbackMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!callbackMemberValue.isUndefined()) {
        result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue partialBooleanMemberValue;
    if (isNullOrUndefined)
        partialBooleanMemberValue = jsUndefined();
    else {
        partialBooleanMemberValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialBooleanMemberValue.isUndefined()) {
        result.partialBooleanMember = convert<IDLBoolean>(state, partialBooleanMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#if ENABLE(Conditional15)
    JSValue partialBooleanMemberWithConditionalValue;
    if (isNullOrUndefined)
        partialBooleanMemberWithConditionalValue = jsUndefined();
    else {
        partialBooleanMemberWithConditionalValue = object->get(&state, Identifier::fromString(vm, "partialBooleanMemberWithConditional"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialBooleanMemberWithConditionalValue.isUndefined()) {
        result.partialBooleanMemberWithConditional = convert<IDLBoolean>(state, partialBooleanMemberWithConditionalValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
#endif
    JSValue partialCallbackMemberValue;
    if (isNullOrUndefined)
        partialCallbackMemberValue = jsUndefined();
    else {
        partialCallbackMemberValue = object->get(&state, Identifier::fromString(vm, "partialCallbackMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialCallbackMemberValue.isUndefined()) {
        result.partialCallbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, partialCallbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue partialRequiredLongMemberValue;
    if (isNullOrUndefined)
        partialRequiredLongMemberValue = jsUndefined();
    else {
        partialRequiredLongMemberValue = object->get(&state, Identifier::fromString(vm, "partialRequiredLongMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialRequiredLongMemberValue.isUndefined()) {
        result.partialRequiredLongMember = convert<IDLLong>(state, partialRequiredLongMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    } else {
        throwRequiredMemberTypeError(state, throwScope, "partialRequiredLongMember", "TestDerivedDictionary", "long");
        return { };
    }
    JSValue partialStringMemberValue;
    if (isNullOrUndefined)
        partialStringMemberValue = jsUndefined();
    else {
        partialStringMemberValue = object->get(&state, Identifier::fromString(vm, "partialStringMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialStringMemberValue.isUndefined()) {
        result.partialStringMember = convert<IDLDOMString>(state, partialStringMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue partialStringMemberWithEnabledBySettingValue;
    if (isNullOrUndefined)
        partialStringMemberWithEnabledBySettingValue = jsUndefined();
    else {
        partialStringMemberWithEnabledBySettingValue = object->get(&state, Identifier::fromString(vm, "partialStringMemberWithEnabledBySetting"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialStringMemberWithEnabledBySettingValue.isUndefined()) {
        result.partialStringMemberWithEnabledBySetting = convert<IDLDOMString>(state, partialStringMemberWithEnabledBySettingValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue partialUnsignedLongMemberWithImplementedAsValue;
    if (isNullOrUndefined)
        partialUnsignedLongMemberWithImplementedAsValue = jsUndefined();
    else {
        partialUnsignedLongMemberWithImplementedAsValue = object->get(&state, Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!partialUnsignedLongMemberWithImplementedAsValue.isUndefined()) {
        result.partialUnsignedLongMember = convert<IDLUnsignedLong>(state, partialUnsignedLongMemberWithImplementedAsValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue stringMemberValue;
    if (isNullOrUndefined)
        stringMemberValue = jsUndefined();
    else {
        stringMemberValue = object->get(&state, Identifier::fromString(vm, "stringMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!stringMemberValue.isUndefined()) {
        result.stringMember = convert<IDLDOMString>(state, stringMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue derivedBoolMemberValue;
    if (isNullOrUndefined)
        derivedBoolMemberValue = jsUndefined();
    else {
        derivedBoolMemberValue = object->get(&state, Identifier::fromString(vm, "derivedBoolMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!derivedBoolMemberValue.isUndefined()) {
        result.derivedBoolMember = convert<IDLBoolean>(state, derivedBoolMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    return result;
}

JSC::JSObject* convertDictionaryToJS(JSC::ExecState& state, JSDOMGlobalObject& globalObject, const TestDerivedDictionary& dictionary)
{
    auto& vm = state.vm();

    auto result = constructEmptyObject(&state, globalObject.objectPrototype());

    if (!IDLBoolean::isNullValue(dictionary.boolMember)) {
        auto boolMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.boolMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "boolMember"), boolMemberValue);
    }
    if (!IDLCallbackFunction<JSVoidCallback>::isNullValue(dictionary.callbackMember)) {
        auto callbackMemberValue = toJS<IDLCallbackFunction<JSVoidCallback>>(state, globalObject, IDLCallbackFunction<JSVoidCallback>::extractValueFromNullable(dictionary.callbackMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "callbackMember"), callbackMemberValue);
    }
    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMember)) {
        auto partialBooleanMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMember"), partialBooleanMemberValue);
    }
#if ENABLE(Conditional15)
    if (!IDLBoolean::isNullValue(dictionary.partialBooleanMemberWithConditional)) {
        auto partialBooleanMemberWithConditionalValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.partialBooleanMemberWithConditional));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialBooleanMemberWithConditional"), partialBooleanMemberWithConditionalValue);
    }
#endif
    if (!IDLCallbackFunction<JSVoidCallback>::isNullValue(dictionary.partialCallbackMember)) {
        auto partialCallbackMemberValue = toJS<IDLCallbackFunction<JSVoidCallback>>(state, globalObject, IDLCallbackFunction<JSVoidCallback>::extractValueFromNullable(dictionary.partialCallbackMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialCallbackMember"), partialCallbackMemberValue);
    }
    auto partialRequiredLongMemberValue = toJS<IDLLong>(dictionary.partialRequiredLongMember);
    result->putDirect(vm, JSC::Identifier::fromString(vm, "partialRequiredLongMember"), partialRequiredLongMemberValue);
    if (!IDLDOMString::isNullValue(dictionary.partialStringMember)) {
        auto partialStringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialStringMember"), partialStringMemberValue);
    }
    if (downcast<Document>(jsCast<JSDOMGlobalObject*>(&globalObject)->scriptExecutionContext())->settings().testSettingEnabled()) {
        if (!IDLDOMString::isNullValue(dictionary.partialStringMemberWithEnabledBySetting)) {
            auto partialStringMemberWithEnabledBySettingValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.partialStringMemberWithEnabledBySetting));
            result->putDirect(vm, JSC::Identifier::fromString(vm, "partialStringMemberWithEnabledBySetting"), partialStringMemberWithEnabledBySettingValue);
        }
    }
    if (!IDLUnsignedLong::isNullValue(dictionary.partialUnsignedLongMember)) {
        auto partialUnsignedLongMemberWithImplementedAsValue = toJS<IDLUnsignedLong>(IDLUnsignedLong::extractValueFromNullable(dictionary.partialUnsignedLongMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "partialUnsignedLongMemberWithImplementedAs"), partialUnsignedLongMemberWithImplementedAsValue);
    }
    if (!IDLDOMString::isNullValue(dictionary.stringMember)) {
        auto stringMemberValue = toJS<IDLDOMString>(state, IDLDOMString::extractValueFromNullable(dictionary.stringMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "stringMember"), stringMemberValue);
    }
    if (!IDLBoolean::isNullValue(dictionary.derivedBoolMember)) {
        auto derivedBoolMemberValue = toJS<IDLBoolean>(IDLBoolean::extractValueFromNullable(dictionary.derivedBoolMember));
        result->putDirect(vm, JSC::Identifier::fromString(vm, "derivedBoolMember"), derivedBoolMemberValue);
    }
    return result;
}

} // namespace WebCore
