// 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/Dictionary.h"
#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/V8Binding.h"
#include "core/CoreExport.h"
#include "platform/heap/Handle.h"

namespace blink {

class DOMUint8Array;
class Node;
class NodeList;
class TestArrayBuffer;
class TestArrayBufferView;
class TestDictionary;
class TestInterface2;
class TestInterfaceEmpty;
class TestInterfaceGarbageCollected;
class TestInterfaceImplementation;
class TestInterfaceWillBeGarbageCollected;

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

    bool isArrayBuffer() const { return m_type == SpecificTypeArrayBuffer; }
    PassRefPtr<TestArrayBuffer> getAsArrayBuffer() const;
    void setArrayBuffer(PassRefPtr<TestArrayBuffer>);
    static ArrayBufferOrArrayBufferViewOrDictionary fromArrayBuffer(PassRefPtr<TestArrayBuffer>);

    bool isArrayBufferView() const { return m_type == SpecificTypeArrayBufferView; }
    PassRefPtr<TestArrayBufferView> getAsArrayBufferView() const;
    void setArrayBufferView(PassRefPtr<TestArrayBufferView>);
    static ArrayBufferOrArrayBufferViewOrDictionary fromArrayBufferView(PassRefPtr<TestArrayBufferView>);

    bool isDictionary() const { return m_type == SpecificTypeDictionary; }
    Dictionary getAsDictionary() const;
    void setDictionary(Dictionary);
    static ArrayBufferOrArrayBufferViewOrDictionary fromDictionary(Dictionary);

    ArrayBufferOrArrayBufferViewOrDictionary(const ArrayBufferOrArrayBufferViewOrDictionary&);
    ~ArrayBufferOrArrayBufferViewOrDictionary();
    ArrayBufferOrArrayBufferViewOrDictionary& operator=(const ArrayBufferOrArrayBufferViewOrDictionary&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeArrayBuffer,
        SpecificTypeArrayBufferView,
        SpecificTypeDictionary,
    };
    SpecificTypes m_type;

    RefPtr<TestArrayBuffer> m_arrayBuffer;
    RefPtr<TestArrayBufferView> m_arrayBufferView;
    Dictionary m_dictionary;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const ArrayBufferOrArrayBufferViewOrDictionary&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8ArrayBufferOrArrayBufferViewOrDictionary final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, ArrayBufferOrArrayBufferViewOrDictionary&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const ArrayBufferOrArrayBufferViewOrDictionary&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<ArrayBufferOrArrayBufferViewOrDictionary> {
    CORE_EXPORT static ArrayBufferOrArrayBufferViewOrDictionary nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

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

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

    BooleanOrStringOrUnrestrictedDouble(const BooleanOrStringOrUnrestrictedDouble&);
    ~BooleanOrStringOrUnrestrictedDouble();
    BooleanOrStringOrUnrestrictedDouble& operator=(const BooleanOrStringOrUnrestrictedDouble&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeBoolean,
        SpecificTypeString,
        SpecificTypeUnrestrictedDouble,
    };
    SpecificTypes m_type;

    bool m_boolean;
    String m_string;
    double m_unrestrictedDouble;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const BooleanOrStringOrUnrestrictedDouble&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const BooleanOrStringOrUnrestrictedDouble&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<BooleanOrStringOrUnrestrictedDouble> {
    CORE_EXPORT static BooleanOrStringOrUnrestrictedDouble nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

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

    DoubleOrString(const DoubleOrString&);
    ~DoubleOrString();
    DoubleOrString& operator=(const DoubleOrString&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeDouble,
        SpecificTypeString,
    };
    SpecificTypes m_type;

    double m_double;
    String m_string;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const DoubleOrString&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8DoubleOrString final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, DoubleOrString&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const DoubleOrString&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<DoubleOrString> {
    CORE_EXPORT static DoubleOrString nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

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

    LongOrTestDictionary(const LongOrTestDictionary&);
    ~LongOrTestDictionary();
    LongOrTestDictionary& operator=(const LongOrTestDictionary&);
    DECLARE_TRACE();

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

    int m_long;
    TestDictionary m_testDictionary;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const LongOrTestDictionary&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8LongOrTestDictionary final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, LongOrTestDictionary&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const LongOrTestDictionary&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<LongOrTestDictionary> {
    CORE_EXPORT static LongOrTestDictionary nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

class CORE_EXPORT 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() const;
    void setNode(PassRefPtrWillBeRawPtr<Node>);
    static NodeOrNodeList fromNode(PassRefPtrWillBeRawPtr<Node>);

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

    NodeOrNodeList(const NodeOrNodeList&);
    ~NodeOrNodeList();
    NodeOrNodeList& operator=(const NodeOrNodeList&);
    DECLARE_TRACE();

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

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

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const NodeOrNodeList&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const NodeOrNodeList&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<NodeOrNodeList> {
    CORE_EXPORT static NodeOrNodeList nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

    bool isArrayBuffer() const { return m_type == SpecificTypeArrayBuffer; }
    PassRefPtr<TestArrayBuffer> getAsArrayBuffer() const;
    void setArrayBuffer(PassRefPtr<TestArrayBuffer>);
    static StringOrArrayBufferOrArrayBufferView fromArrayBuffer(PassRefPtr<TestArrayBuffer>);

    bool isArrayBufferView() const { return m_type == SpecificTypeArrayBufferView; }
    PassRefPtr<TestArrayBufferView> getAsArrayBufferView() const;
    void setArrayBufferView(PassRefPtr<TestArrayBufferView>);
    static StringOrArrayBufferOrArrayBufferView fromArrayBufferView(PassRefPtr<TestArrayBufferView>);

    StringOrArrayBufferOrArrayBufferView(const StringOrArrayBufferOrArrayBufferView&);
    ~StringOrArrayBufferOrArrayBufferView();
    StringOrArrayBufferOrArrayBufferView& operator=(const StringOrArrayBufferOrArrayBufferView&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeString,
        SpecificTypeArrayBuffer,
        SpecificTypeArrayBufferView,
    };
    SpecificTypes m_type;

    String m_string;
    RefPtr<TestArrayBuffer> m_arrayBuffer;
    RefPtr<TestArrayBufferView> m_arrayBufferView;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const StringOrArrayBufferOrArrayBufferView&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8StringOrArrayBufferOrArrayBufferView final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, StringOrArrayBufferOrArrayBufferView&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const StringOrArrayBufferOrArrayBufferView&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<StringOrArrayBufferOrArrayBufferView> {
    CORE_EXPORT static StringOrArrayBufferOrArrayBufferView nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

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

    StringOrDouble(const StringOrDouble&);
    ~StringOrDouble();
    StringOrDouble& operator=(const StringOrDouble&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeString,
        SpecificTypeDouble,
    };
    SpecificTypes m_type;

    String m_string;
    double m_double;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const StringOrDouble&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const StringOrDouble&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<StringOrDouble> {
    CORE_EXPORT static StringOrDouble nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

    bool isStringSequence() const { return m_type == SpecificTypeStringSequence; }
    const Vector<String>& getAsStringSequence() const;
    void setStringSequence(const Vector<String>&);
    static StringOrStringSequence fromStringSequence(const Vector<String>&);

    StringOrStringSequence(const StringOrStringSequence&);
    ~StringOrStringSequence();
    StringOrStringSequence& operator=(const StringOrStringSequence&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeString,
        SpecificTypeStringSequence,
    };
    SpecificTypes m_type;

    String m_string;
    Vector<String> m_stringSequence;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const StringOrStringSequence&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8StringOrStringSequence final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, StringOrStringSequence&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const StringOrStringSequence&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<StringOrStringSequence> {
    CORE_EXPORT static StringOrStringSequence nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

    bool isTestEnum() const { return m_type == SpecificTypeTestEnum; }
    String getAsTestEnum() const;
    void setTestEnum(String);
    static TestEnumOrDouble fromTestEnum(String);

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

    TestEnumOrDouble(const TestEnumOrDouble&);
    ~TestEnumOrDouble();
    TestEnumOrDouble& operator=(const TestEnumOrDouble&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestEnum,
        SpecificTypeDouble,
    };
    SpecificTypes m_type;

    String m_testEnum;
    double m_double;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const TestEnumOrDouble&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8TestEnumOrDouble final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, TestEnumOrDouble&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const TestEnumOrDouble&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<TestEnumOrDouble> {
    CORE_EXPORT static TestEnumOrDouble nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

    bool isTestInterface2() const { return m_type == SpecificTypeTestInterface2; }
    PassRefPtr<TestInterface2> getAsTestInterface2() const;
    void setTestInterface2(PassRefPtr<TestInterface2>);
    static TestInterface2OrUint8Array fromTestInterface2(PassRefPtr<TestInterface2>);

    bool isUint8Array() const { return m_type == SpecificTypeUint8Array; }
    PassRefPtr<DOMUint8Array> getAsUint8Array() const;
    void setUint8Array(PassRefPtr<DOMUint8Array>);
    static TestInterface2OrUint8Array fromUint8Array(PassRefPtr<DOMUint8Array>);

    TestInterface2OrUint8Array(const TestInterface2OrUint8Array&);
    ~TestInterface2OrUint8Array();
    TestInterface2OrUint8Array& operator=(const TestInterface2OrUint8Array&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterface2,
        SpecificTypeUint8Array,
    };
    SpecificTypes m_type;

    RefPtr<TestInterface2> m_testInterface2;
    RefPtr<DOMUint8Array> m_uint8Array;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterface2OrUint8Array&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8TestInterface2OrUint8Array final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, TestInterface2OrUint8Array&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterface2OrUint8Array&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<TestInterface2OrUint8Array> {
    CORE_EXPORT static TestInterface2OrUint8Array nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

    bool isTestInterfaceGarbageCollected() const { return m_type == SpecificTypeTestInterfaceGarbageCollected; }
    TestInterfaceGarbageCollected* getAsTestInterfaceGarbageCollected() const;
    void setTestInterfaceGarbageCollected(TestInterfaceGarbageCollected*);
    static TestInterfaceGarbageCollectedOrString fromTestInterfaceGarbageCollected(TestInterfaceGarbageCollected*);

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

    TestInterfaceGarbageCollectedOrString(const TestInterfaceGarbageCollectedOrString&);
    ~TestInterfaceGarbageCollectedOrString();
    TestInterfaceGarbageCollectedOrString& operator=(const TestInterfaceGarbageCollectedOrString&);
    DECLARE_TRACE();

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

    Member<TestInterfaceGarbageCollected> m_testInterfaceGarbageCollected;
    String m_string;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceGarbageCollectedOrString&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceGarbageCollectedOrString&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<TestInterfaceGarbageCollectedOrString> {
    CORE_EXPORT static TestInterfaceGarbageCollectedOrString nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

class CORE_EXPORT 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() const;
    void setTestInterface(PassRefPtr<TestInterfaceImplementation>);
    static TestInterfaceOrLong fromTestInterface(PassRefPtr<TestInterfaceImplementation>);

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

    TestInterfaceOrLong(const TestInterfaceOrLong&);
    ~TestInterfaceOrLong();
    TestInterfaceOrLong& operator=(const TestInterfaceOrLong&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterface,
        SpecificTypeLong,
    };
    SpecificTypes m_type;

    RefPtr<TestInterfaceImplementation> m_testInterface;
    int m_long;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceOrLong&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceOrLong&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<TestInterfaceOrLong> {
    CORE_EXPORT static TestInterfaceOrLong nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

class CORE_EXPORT 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() const;
    void setTestInterface(PassRefPtr<TestInterfaceImplementation>);
    static TestInterfaceOrTestInterfaceEmpty fromTestInterface(PassRefPtr<TestInterfaceImplementation>);

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

    TestInterfaceOrTestInterfaceEmpty(const TestInterfaceOrTestInterfaceEmpty&);
    ~TestInterfaceOrTestInterfaceEmpty();
    TestInterfaceOrTestInterfaceEmpty& operator=(const TestInterfaceOrTestInterfaceEmpty&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeTestInterface,
        SpecificTypeTestInterfaceEmpty,
    };
    SpecificTypes m_type;

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

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceOrTestInterfaceEmpty&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceOrTestInterfaceEmpty&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<TestInterfaceOrTestInterfaceEmpty> {
    CORE_EXPORT static TestInterfaceOrTestInterfaceEmpty nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

class CORE_EXPORT 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() const;
    void setTestInterfaceWillBeGarbageCollected(PassRefPtrWillBeRawPtr<TestInterfaceWillBeGarbageCollected>);
    static TestInterfaceWillBeGarbageCollectedOrTestDictionary fromTestInterfaceWillBeGarbageCollected(PassRefPtrWillBeRawPtr<TestInterfaceWillBeGarbageCollected>);

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

    TestInterfaceWillBeGarbageCollectedOrTestDictionary(const TestInterfaceWillBeGarbageCollectedOrTestDictionary&);
    ~TestInterfaceWillBeGarbageCollectedOrTestDictionary();
    TestInterfaceWillBeGarbageCollectedOrTestDictionary& operator=(const TestInterfaceWillBeGarbageCollectedOrTestDictionary&);
    DECLARE_TRACE();

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

    RefPtrWillBeMember<TestInterfaceWillBeGarbageCollected> m_testInterfaceWillBeGarbageCollected;
    TestDictionary m_testDictionary;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceWillBeGarbageCollectedOrTestDictionary&, v8::Local<v8::Object>, v8::Isolate*);
};

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

CORE_EXPORT v8::Local<v8::Value> toV8(const TestInterfaceWillBeGarbageCollectedOrTestDictionary&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<TestInterfaceWillBeGarbageCollectedOrTestDictionary> {
    CORE_EXPORT static TestInterfaceWillBeGarbageCollectedOrTestDictionary nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

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

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

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

    UnrestrictedDoubleOrString(const UnrestrictedDoubleOrString&);
    ~UnrestrictedDoubleOrString();
    UnrestrictedDoubleOrString& operator=(const UnrestrictedDoubleOrString&);
private:
    enum SpecificTypes {
        SpecificTypeNone,
        SpecificTypeUnrestrictedDouble,
        SpecificTypeString,
    };
    SpecificTypes m_type;

    double m_unrestrictedDouble;
    String m_string;

    friend CORE_EXPORT v8::Local<v8::Value> toV8(const UnrestrictedDoubleOrString&, v8::Local<v8::Object>, v8::Isolate*);
};

class V8UnrestrictedDoubleOrString final {
public:
    CORE_EXPORT static void toImpl(v8::Isolate*, v8::Local<v8::Value>, UnrestrictedDoubleOrString&, ExceptionState&);
};

CORE_EXPORT v8::Local<v8::Value> toV8(const UnrestrictedDoubleOrString&, v8::Local<v8::Object>, v8::Isolate*);

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

template <>
struct NativeValueTraits<UnrestrictedDoubleOrString> {
    CORE_EXPORT static UnrestrictedDoubleOrString nativeValue(v8::Isolate*, v8::Local<v8::Value>, ExceptionState&);
};

class V8DoubleOrStringOrNull final {
public:
    static void toImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, DoubleOrString& impl, ExceptionState& exceptionState)
    {
        if (isUndefinedOrNull(v8Value))
            return;
        V8DoubleOrString::toImpl(isolate, v8Value, impl, exceptionState);
    }
};

} // namespace blink

// We need to set canInitializeWithMemset=true because HeapVector supports
// items that can initialize with memset or have a vtable. It is safe to
// set canInitializeWithMemset=true for a union type object in practice.
// See https://codereview.chromium.org/1118993002/#msg5 for more details.
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::ArrayBufferOrArrayBufferViewOrDictionary);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::BooleanOrStringOrUnrestrictedDouble);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::DoubleOrString);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::LongOrTestDictionary);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::NodeOrNodeList);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrArrayBufferOrArrayBufferView);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrDouble);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::StringOrStringSequence);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestEnumOrDouble);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterface2OrUint8Array);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceGarbageCollectedOrString);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceOrLong);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceOrTestInterfaceEmpty);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::TestInterfaceWillBeGarbageCollectedOrTestDictionary);
WTF_ALLOW_MOVE_AND_INIT_WITH_MEM_FUNCTIONS(blink::UnrestrictedDoubleOrString);

#endif // UnionTypeCore_h
