// 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!

#ifndef UnionTypeCore_h
#define UnionTypeCore_h

#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/V8Binding.h"
#include "platform/heap/Handle.h"

namespace blink {

class Node;
class NodeList;
class TestDictionary;
class TestInterface;
class TestInterfaceEmpty;
class TestInterfaceGarbageCollected;
class TestInterfaceWillBeGarbageCollected;

class BooleanOrStringOrUnrestrictedDouble final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    BooleanOrStringOrUnrestrictedDouble();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isBoolean() const { return m_type == SpecificTypeBoolean; }
    bool getAsBoolean();
    void setBoolean(bool);

    bool isString() const { return m_type == SpecificTypeString; }
    String getAsString();
    void setString(String);

    bool isUnrestrictedDouble() const { return m_type == SpecificTypeUnrestrictedDouble; }
    double getAsUnrestrictedDouble();
    void setUnrestrictedDouble(double);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeBoolean,
        SpecificTypeString,
        SpecificTypeUnrestrictedDouble,
    };
    SpecificTypes m_type;

    bool m_boolean;
    String m_string;
    double m_unrestrictedDouble;
};

class V8BooleanOrStringOrUnrestrictedDouble final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, BooleanOrStringOrUnrestrictedDouble&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(BooleanOrStringOrUnrestrictedDouble&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, BooleanOrStringOrUnrestrictedDouble& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

class NodeOrNodeList final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    NodeOrNodeList();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isNode() const { return m_type == SpecificTypeNode; }
    PassRefPtrWillBeRawPtr<Node> getAsNode();
    void setNode(PassRefPtrWillBeRawPtr<Node>);

    bool isNodeList() const { return m_type == SpecificTypeNodeList; }
    PassRefPtrWillBeRawPtr<NodeList> getAsNodeList();
    void setNodeList(PassRefPtrWillBeRawPtr<NodeList>);

    void trace(Visitor*);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeNode,
        SpecificTypeNodeList,
    };
    SpecificTypes m_type;

    RefPtrWillBeMember<Node> m_node;
    RefPtrWillBeMember<NodeList> m_nodeList;
};

class V8NodeOrNodeList final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, NodeOrNodeList&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(NodeOrNodeList&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, NodeOrNodeList& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

class StringOrDouble final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    StringOrDouble();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isString() const { return m_type == SpecificTypeString; }
    String getAsString();
    void setString(String);

    bool isDouble() const { return m_type == SpecificTypeDouble; }
    double getAsDouble();
    void setDouble(double);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeString,
        SpecificTypeDouble,
    };
    SpecificTypes m_type;

    String m_string;
    double m_double;
};

class V8StringOrDouble final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, StringOrDouble&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(StringOrDouble&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, StringOrDouble& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

class TestInterfaceGarbageCollectedOrString final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    TestInterfaceGarbageCollectedOrString();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isTestInterfaceGarbageCollected() const { return m_type == SpecificTypeTestInterfaceGarbageCollected; }
    RawPtr<TestInterfaceGarbageCollected> getAsTestInterfaceGarbageCollected();
    void setTestInterfaceGarbageCollected(RawPtr<TestInterfaceGarbageCollected>);

    bool isString() const { return m_type == SpecificTypeString; }
    String getAsString();
    void setString(String);

    void trace(Visitor*);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterfaceGarbageCollected,
        SpecificTypeString,
    };
    SpecificTypes m_type;

    Member<TestInterfaceGarbageCollected> m_testInterfaceGarbageCollected;
    String m_string;
};

class V8TestInterfaceGarbageCollectedOrString final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, TestInterfaceGarbageCollectedOrString&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(TestInterfaceGarbageCollectedOrString&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceGarbageCollectedOrString& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

class TestInterfaceOrLong final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    TestInterfaceOrLong();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isTestInterface() const { return m_type == SpecificTypeTestInterface; }
    PassRefPtr<TestInterfaceImplementation> getAsTestInterface();
    void setTestInterface(PassRefPtr<TestInterfaceImplementation>);

    bool isLong() const { return m_type == SpecificTypeLong; }
    int getAsLong();
    void setLong(int);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterface,
        SpecificTypeLong,
    };
    SpecificTypes m_type;

    RefPtr<TestInterfaceImplementation> m_testInterface;
    int m_long;
};

class V8TestInterfaceOrLong final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, TestInterfaceOrLong&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(TestInterfaceOrLong&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceOrLong& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

class TestInterfaceOrTestInterfaceEmpty final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    TestInterfaceOrTestInterfaceEmpty();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isTestInterface() const { return m_type == SpecificTypeTestInterface; }
    PassRefPtr<TestInterfaceImplementation> getAsTestInterface();
    void setTestInterface(PassRefPtr<TestInterfaceImplementation>);

    bool isTestInterfaceEmpty() const { return m_type == SpecificTypeTestInterfaceEmpty; }
    PassRefPtr<TestInterfaceEmpty> getAsTestInterfaceEmpty();
    void setTestInterfaceEmpty(PassRefPtr<TestInterfaceEmpty>);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterface,
        SpecificTypeTestInterfaceEmpty,
    };
    SpecificTypes m_type;

    RefPtr<TestInterfaceImplementation> m_testInterface;
    RefPtr<TestInterfaceEmpty> m_testInterfaceEmpty;
};

class V8TestInterfaceOrTestInterfaceEmpty final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, TestInterfaceOrTestInterfaceEmpty&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(TestInterfaceOrTestInterfaceEmpty&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceOrTestInterfaceEmpty& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

class TestInterfaceWillBeGarbageCollectedOrTestDictionary final {
    ALLOW_ONLY_INLINE_ALLOCATION();
public:
    TestInterfaceWillBeGarbageCollectedOrTestDictionary();
    bool isNull() const { return m_type == SpecificTypeNone; }

    bool isTestInterfaceWillBeGarbageCollected() const { return m_type == SpecificTypeTestInterfaceWillBeGarbageCollected; }
    PassRefPtrWillBeRawPtr<TestInterfaceWillBeGarbageCollected> getAsTestInterfaceWillBeGarbageCollected();
    void setTestInterfaceWillBeGarbageCollected(PassRefPtrWillBeRawPtr<TestInterfaceWillBeGarbageCollected>);

    bool isTestDictionary() const { return m_type == SpecificTypeTestDictionary; }
    TestDictionary getAsTestDictionary();
    void setTestDictionary(TestDictionary);

    void trace(Visitor*);

private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterfaceWillBeGarbageCollected,
        SpecificTypeTestDictionary,
    };
    SpecificTypes m_type;

    RefPtrWillBeMember<TestInterfaceWillBeGarbageCollected> m_testInterfaceWillBeGarbageCollected;
    TestDictionary m_testDictionary;
};

class V8TestInterfaceWillBeGarbageCollectedOrTestDictionary final {
public:
    static void toImpl(v8::Isolate*, v8::Handle<v8::Value>, TestInterfaceWillBeGarbageCollectedOrTestDictionary&, ExceptionState&);
};

v8::Handle<v8::Value> toV8(TestInterfaceWillBeGarbageCollectedOrTestDictionary&, v8::Handle<v8::Object>, v8::Isolate*);

template <class CallbackInfo>
inline void v8SetReturnValue(const CallbackInfo& callbackInfo, TestInterfaceWillBeGarbageCollectedOrTestDictionary& impl)
{
    v8SetReturnValue(callbackInfo, toV8(impl, callbackInfo.Holder(), callbackInfo.GetIsolate()));
}

} // namespace blink

#endif // UnionTypeCore_h
