/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// This IDL file is for testing the front end, not code generator,
// as typedefs are resolved during IR construction (after parsing,
// before code generation), and thus the code generator never sees them.

typedef boolean                    BooleanType;
typedef float                      Float;
typedef unsigned long long         ULongLong;
typedef [Clamp] long               LongWithClamp;
typedef TestInterfaceEmpty         TestInterfaceEmptyType;
typedef sequence<long>             LongSequence;
typedef DOMString                  String;
typedef FrozenArray<DOMString>     FrozenStringArray;
typedef TestCallbackInterface      TestCallbackInterfaceType;
typedef TestInterfaceConstructor   T;
typedef (TestInterface or TestInterfaceEmpty) TestInterfaceOrTestInterfaceEmpty;
typedef (DOMString or double) DOMStringOrDouble;
typedef record<ByteString, long>   SomeRecordType;
typedef record<USVString, TestObject> RecordWithOilpanValueType;
typedef (sequence<sequence<ByteString>> or record<ByteString, ByteString>) UnionWithRecord;
typedef (Node or (sequence<long> or Event) or (XMLHttpRequest or DOMString)? or record<DOMString, (ByteString or NodeList)>) NestedUnionType;
typedef (ULongLong or (BooleanType or TestCallbackInterfaceType)) UnionWithTypedef;

[
    Constructor(String stringArg)
] interface TestTypedefs {
    attribute ULongLong uLongLongAttribute;
    attribute LongWithClamp longWithClampAttribute;
    attribute T tAttribute;
    attribute DOMStringOrDouble? domStringOrDoubleOrNullAttribute;

    void voidMethodLongSequenceArg(optional LongSequence longSequenceArg);

    void voidMethodFloatArgStringArg(Float floatArg, String stringArg);
    void voidMethodTestCallbackInterfaceTypeArg(TestCallbackInterfaceType testCallbackInterfaceTypeArg);

    ULongLong uLongLongMethodTestInterfaceEmptyTypeSequenceArg(sequence<TestInterfaceEmptyType> testInterfaceEmptyTypeSequenceArg);
    TestInterfaceOrTestInterfaceEmpty testInterfaceOrTestInterfaceEmptyMethod();
    DOMStringOrDouble domStringOrDoubleMethod();

    FrozenStringArray arrayOfStringsMethodArrayOfStringsArg(FrozenStringArray frozenStringArrayArg);

    void methodTakingRecord(SomeRecordType arg);
    void methodTakingOilpanValueRecord(RecordWithOilpanValueType arg);
    double unionWithRecordMethod(UnionWithRecord arg);
    record<DOMString, boolean> methodThatReturnsRecord();

    void voidMethodNestedUnionType(NestedUnionType arg);

    void voidMethodUnionWithTypedef(UnionWithTypedef arg);
};
