/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "CompoundType.h"

#include "ArrayType.h"
#include "VectorType.h"
#include <hidl-util/Formatter.h>
#include <android-base/logging.h>

namespace android {

CompoundType::CompoundType(Style style, const char *localName, const Location &location)
    : Scope(localName, location),
      mStyle(style),
      mFields(NULL) {
}

CompoundType::Style CompoundType::style() const {
    return mStyle;
}

bool CompoundType::setFields(
        std::vector<CompoundField *> *fields, std::string *errorMsg) {
    mFields = fields;

    for (const auto &field : *fields) {
        const Type &type = field->type();

        if (type.isBinder()
                || (type.isVector()
                    && static_cast<const VectorType *>(
                        &type)->isVectorOfBinders())) {
            *errorMsg =
                "Structs/Unions must not contain references to interfaces.";

            return false;
        }

        if (mStyle == STYLE_UNION) {
            if (type.needsEmbeddedReadWrite()) {
                // Can't have those in a union.

                *errorMsg =
                    "Unions must not contain any types that need fixup.";

                return false;
            }
        }
    }

    return true;
}

bool CompoundType::isCompoundType() const {
    return true;
}

bool CompoundType::canCheckEquality() const {
    if (mStyle == STYLE_UNION) {
        return false;
    }
    for (const auto &field : *mFields) {
        if (!field->type().canCheckEquality()) {
            return false;
        }
    }
    return true;
}


std::string CompoundType::getCppType(
        StorageMode mode,
        bool specifyNamespaces) const {
    const std::string base =
        specifyNamespaces ? fullName() : partialCppName();

    switch (mode) {
        case StorageMode_Stack:
            return base;

        case StorageMode_Argument:
            return "const " + base + "&";

        case StorageMode_Result:
            return "const " + base + "*";
    }
}

std::string CompoundType::getJavaType(bool /* forInitializer */) const {
    return fullJavaName();
}

std::string CompoundType::getVtsType() const {
    switch (mStyle) {
        case STYLE_STRUCT:
        {
            return "TYPE_STRUCT";
        }
        case STYLE_UNION:
        {
            return "TYPE_UNION";
        }
    }
}

void CompoundType::emitReaderWriter(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {
    const std::string parentName = "_hidl_" + name + "_parent";

    out << "size_t " << parentName << ";\n\n";

    const std::string parcelObjDeref =
        parcelObj + (parcelObjIsPointer ? "->" : ".");

    if (isReader) {
        out << "_hidl_err = "
            << parcelObjDeref
            << "readBuffer("
            << "&"
            << parentName
            << ", "
            << " reinterpret_cast<const void **>("
            << "&" << name
            << "));\n";

        handleError(out, mode);
    } else {
        out << "_hidl_err = "
            << parcelObjDeref
            << "writeBuffer(&"
            << name
            << ", sizeof("
            << name
            << "), &"
            << parentName
            << ");\n";

        handleError(out, mode);
    }

    if (mStyle != STYLE_STRUCT || !needsEmbeddedReadWrite()) {
        return;
    }

    emitReaderWriterEmbedded(
            out,
            0 /* depth */,
            name,
            name, /* sanitizedName */
            isReader /* nameIsPointer */,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            parentName,
            "0 /* parentOffset */");
}

void CompoundType::emitReaderWriterEmbedded(
        Formatter &out,
        size_t /* depth */,
        const std::string &name,
        const std::string & /*sanitizedName */,
        bool nameIsPointer,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode,
        const std::string &parentName,
        const std::string &offsetText) const {
    emitReaderWriterEmbeddedForTypeName(
            out,
            name,
            nameIsPointer,
            parcelObj,
            parcelObjIsPointer,
            isReader,
            mode,
            parentName,
            offsetText,
            fullName(),
            "" /* childName */,
            "" /* namespace */);
}

void CompoundType::emitJavaReaderWriter(
        Formatter &out,
        const std::string &parcelObj,
        const std::string &argName,
        bool isReader) const {
    if (isReader) {
        out << "new " << fullJavaName() << "();\n";
    }

    out << argName
        << "."
        << (isReader ? "readFromParcel" : "writeToParcel")
        << "("
        << parcelObj
        << ");\n";
}

void CompoundType::emitJavaFieldInitializer(
        Formatter &out, const std::string &fieldName) const {
    out << "final "
        << fullJavaName()
        << " "
        << fieldName
        << " = new "
        << fullJavaName()
        << "();\n";
}

void CompoundType::emitJavaFieldReaderWriter(
        Formatter &out,
        size_t /* depth */,
        const std::string &parcelName,
        const std::string &blobName,
        const std::string &fieldName,
        const std::string &offset,
        bool isReader) const {
    if (isReader) {
        out << fieldName
            << ".readEmbeddedFromParcel("
            << parcelName
            << ", "
            << blobName
            << ", "
            << offset
            << ");\n";

        return;
    }

    out << fieldName
        << ".writeEmbeddedToBlob("
        << blobName
        << ", "
        << offset
        << ");\n";
}
void CompoundType::emitResolveReferences(
            Formatter &out,
            const std::string &name,
            bool nameIsPointer,
            const std::string &parcelObj,
            bool parcelObjIsPointer,
            bool isReader,
            ErrorMode mode) const {
    emitResolveReferencesEmbedded(
        out,
        0 /* depth */,
        name,
        name /* sanitizedName */,
        nameIsPointer,
        parcelObj,
        parcelObjIsPointer,
        isReader,
        mode,
        "_hidl_" + name + "_parent",
        "0 /* parentOffset */");
}

void CompoundType::emitResolveReferencesEmbedded(
            Formatter &out,
            size_t /* depth */,
            const std::string &name,
            const std::string &/* sanitizedName */,
            bool nameIsPointer,
            const std::string &parcelObj,
            bool parcelObjIsPointer,
            bool isReader,
            ErrorMode mode,
            const std::string &parentName,
            const std::string &offsetText) const {
    CHECK(needsResolveReferences());

    const std::string parcelObjDeref =
        parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;

    const std::string parcelObjPointer =
        parcelObjIsPointer ? parcelObj : ("&" + parcelObj);

    const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
    const std::string namePointer = nameIsPointer ? name : ("&" + name);

    out << "_hidl_err = ";

    if (isReader) {
        out << "readEmbeddedReferenceFromParcel(\n";
    } else {
        out << "writeEmbeddedReferenceToParcel(\n";
    }

    out.indent(2, [&]{
        if (isReader) {
            out << "const_cast<"
                << fullName()
                << " *"
                << ">("
                << namePointer
                << "),\n"
                << parcelObjDeref;
        } else {
            out << nameDerefed
                << ",\n"
                << parcelObjPointer;
        }

        out << ",\n"
            << parentName
            << ",\n"
            << offsetText
            << ");\n\n";
    });

    handleError(out, mode);
}

status_t CompoundType::emitTypeDeclarations(Formatter &out) const {
    out << ((mStyle == STYLE_STRUCT) ? "struct" : "union")
        << " "
        << localName()
        << " final {\n";

    out.indent();

    Scope::emitTypeDeclarations(out);

    if (!isJavaCompatible()) {
        for (const auto &field : *mFields) {
            out << field->type().getCppStackType()
                << " "
                << field->name()
                << ";\n";
        }

        out.unindent();
        out << "};\n\n";

        return OK;
    }

    for (int pass = 0; pass < 2; ++pass) {
        size_t offset = 0;
        for (const auto &field : *mFields) {
            size_t fieldAlign, fieldSize;
            field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);

            size_t pad = offset % fieldAlign;
            if (pad > 0) {
                offset += fieldAlign - pad;
            }

            if (pass == 0) {
                out << field->type().getCppStackType()
                    << " "
                    << field->name()
                    << " __attribute__ ((aligned("
                    << fieldAlign
                    << ")));\n";
            } else {
                out << "static_assert(offsetof("
                    << fullName()
                    << ", "
                    << field->name()
                    << ") == "
                    << offset
                    << ", \"wrong offset\");\n";
            }

            offset += fieldSize;
        }

        if (pass == 0) {
            out.unindent();
            out << "};\n\n";
        }
    }

    size_t structAlign, structSize;
    getAlignmentAndSize(&structAlign, &structSize);

    out << "static_assert(sizeof("
        << fullName()
        << ") == "
        << structSize
        << ", \"wrong size\");\n";

    out << "static_assert(__alignof("
        << fullName()
        << ") == "
        << structAlign
        << ", \"wrong alignment\");\n\n";

    return OK;
}


status_t CompoundType::emitGlobalTypeDeclarations(Formatter &out) const {
    Scope::emitGlobalTypeDeclarations(out);

    out << "std::string toString("
        << getCppArgumentType()
        << ");\n";

    if (!canCheckEquality()) {
        return OK;
    }

    out << "inline bool operator==("
        << getCppArgumentType() << " " << (mFields->empty() ? "/* lhs */" : "lhs") << ", "
        << getCppArgumentType() << " " << (mFields->empty() ? "/* rhs */" : "rhs") << ") ";
    out.block([&] {
        for (const auto &field : *mFields) {
            out.sIf("lhs." + field->name() + " != rhs." + field->name(), [&] {
                out << "return false;\n";
            }).endl();
        }
        out << "return true;\n";
    }).endl().endl();

    out << "inline bool operator!=("
        << getCppArgumentType() << " lhs," << getCppArgumentType() << " rhs)";
    out.block([&] {
        out << "return !(lhs == rhs);\n";
    }).endl().endl();

    return OK;
}

status_t CompoundType::emitGlobalHwDeclarations(Formatter &out) const  {
    if (needsEmbeddedReadWrite()) {
        out << "::android::status_t readEmbeddedFromParcel(\n";

        out.indent(2);

        out << fullName() << " *obj,\n"
            << "const ::android::hardware::Parcel &parcel,\n"
            << "size_t parentHandle,\n"
            << "size_t parentOffset);\n\n";

        out.unindent(2);

        out << "::android::status_t writeEmbeddedToParcel(\n";

        out.indent(2);

        out << "const " << fullName() << " &obj,\n"
            << "::android::hardware::Parcel *parcel,\n"
            << "size_t parentHandle,\n"
            << "size_t parentOffset);\n\n";

        out.unindent(2);
    }

    if(needsResolveReferences()) {
        out << "::android::status_t readEmbeddedReferenceFromParcel(\n";
        out.indent(2);
        out << fullName() << " *obj,\n"
            << "const ::android::hardware::Parcel &parcel,\n"
            << "size_t parentHandle, size_t parentOffset);\n\n";
        out.unindent(2);
        out << "::android::status_t writeEmbeddedReferenceToParcel(\n";
        out.indent(2);
        out << "const " << fullName() << " &obj,\n"
            << "::android::hardware::Parcel *,\n"
            << "size_t parentHandle, size_t parentOffset);\n\n";
        out.unindent(2);
    }

    return OK;
}

status_t CompoundType::emitTypeDefinitions(
        Formatter &out, const std::string prefix) const {
    std::string space = prefix.empty() ? "" : (prefix + "::");
    status_t err = Scope::emitTypeDefinitions(out, space + localName());

    if (err != OK) {
        return err;
    }

    if (needsEmbeddedReadWrite()) {
        emitStructReaderWriter(out, prefix, true /* isReader */);
        emitStructReaderWriter(out, prefix, false /* isReader */);
    }

    if (needsResolveReferences()) {
        emitResolveReferenceDef(out, prefix, true /* isReader */);
        emitResolveReferenceDef(out, prefix, false /* isReader */);
    }

    out << "std::string toString("
        << getCppArgumentType()
        << (mFields->empty() ? "" : " o")
        << ") ";

    out.block([&] {
        // include toString for scalar types
        out << "using ::android::hardware::details::toString;\n"
            << "std::string os;\n";
        out << "os += \"{\";\n";

        for (const CompoundField *field : *mFields) {
            out << "os += \"";
            if (field != *(mFields->begin())) {
                out << ", ";
            }
            out << "." << field->name() << " = \";\n";
            field->type().emitDump(out, "os", "o." + field->name());
        }

        out << "os += \"}\"; return os;\n";
    }).endl().endl();

    return OK;
}

status_t CompoundType::emitJavaTypeDeclarations(
        Formatter &out, bool atTopLevel) const {
    out << "public final ";

    if (!atTopLevel) {
        out << "static ";
    }

    out << "class "
        << localName()
        << " {\n";

    out.indent();

    Scope::emitJavaTypeDeclarations(out, false /* atTopLevel */);

    for (const auto &field : *mFields) {
        out << "public ";

        field->type().emitJavaFieldInitializer(out, field->name());
    }

    if (!mFields->empty()) {
        out << "\n";
    }

    ////////////////////////////////////////////////////////////////////////////

    if (canCheckEquality()) {
        out << "@Override\npublic final boolean equals(Object otherObject) ";
        out.block([&] {
            out.sIf("this == otherObject", [&] {
                out << "return true;\n";
            }).endl();
            out.sIf("otherObject == null", [&] {
                out << "return false;\n";
            }).endl();
            // Class is final, so we only need to check instanceof, not getClass
            out.sIf("!(otherObject instanceof " + fullJavaName() + ")", [&] {
                out << "return false;\n";
            }).endl();
            out << fullJavaName() << " other = (" << fullJavaName() << ")otherObject;\n";
            for (const auto &field : *mFields) {
                std::string condition = field->type().isScalar()
                    ? "this." + field->name() + " != other." + field->name()
                    : ("!java.util.Objects.deepEquals(this." + field->name()
                            + ", other." + field->name() + ")");
                out.sIf(condition, [&] {
                    out << "return false;\n";
                }).endl();
            }
            out << "return true;\n";
        }).endl().endl();

        out << "@Override\npublic final int hashCode() ";
        out.block([&] {
            out << "return java.util.Objects.hash(\n";
            out.indent(2, [&] {
                bool first = true;
                for (const auto &field : *mFields) {
                    if (!first) {
                        out << ", \n";
                    }
                    first = false;
                    if (field->type().isArray()) {
                        const ArrayType &type = static_cast<const ArrayType &>(field->type());
                        if (type.countDimensions() == 1 &&
                            type.getElementType()->resolveToScalarType() != nullptr) {
                            out << "java.util.Arrays.hashCode(this." << field->name() << ")";
                        } else {
                            out << "java.util.Arrays.deepHashCode(this." << field->name() << ")";
                        }
                    } else {
                        out << "this." << field->name();
                    }
                }
            });
            out << ");\n";
        }).endl().endl();
    }

    ////////////////////////////////////////////////////////////////////////////

    out << "@Override\npublic final String toString() ";
    out.block([&] {
        out << "java.lang.StringBuilder builder = new java.lang.StringBuilder();\n"
            << "builder.append(\"{\");\n";
        for (const auto &field : *mFields) {
            out << "builder.append(\"";
            if (field != *(mFields->begin())) {
                out << ", ";
            }
            out << "." << field->name() << " = \");\n";
            field->type().emitJavaDump(out, "builder", "this." + field->name());
        }
        out << "builder.append(\"}\");\nreturn builder.toString();\n";
    }).endl().endl();

    ////////////////////////////////////////////////////////////////////////////

    out << "public final void readFromParcel(android.os.HwParcel parcel) {\n";
    out.indent();
    out << "android.os.HwBlob blob = parcel.readBuffer();\n";
    out << "readEmbeddedFromParcel(parcel, blob, 0 /* parentOffset */);\n";
    out.unindent();
    out << "}\n\n";

    ////////////////////////////////////////////////////////////////////////////

    out << "public static final java.util.ArrayList<"
        << localName()
        << "> readVectorFromParcel(android.os.HwParcel parcel) {\n";
    out.indent();

    out << "java.util.ArrayList<"
        << localName()
        << "> _hidl_vec = new java.util.ArrayList();\n";

    out << "android.os.HwBlob _hidl_blob = parcel.readBuffer();\n\n";

    VectorType::EmitJavaFieldReaderWriterForElementType(
            out,
            0 /* depth */,
            this,
            "parcel",
            "_hidl_blob",
            "_hidl_vec",
            "0",
            true /* isReader */);

    out << "\nreturn _hidl_vec;\n";

    out.unindent();
    out << "}\n\n";

    ////////////////////////////////////////////////////////////////////////////

    out << "public final void readEmbeddedFromParcel(\n";
    out.indent(2);
    out << "android.os.HwParcel parcel, android.os.HwBlob _hidl_blob, long _hidl_offset) {\n";
    out.unindent();

    size_t offset = 0;
    for (const auto &field : *mFields) {
        size_t fieldAlign, fieldSize;
        field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);

        size_t pad = offset % fieldAlign;
        if (pad > 0) {
            offset += fieldAlign - pad;
        }

        field->type().emitJavaFieldReaderWriter(
                out,
                0 /* depth */,
                "parcel",
                "_hidl_blob",
                field->name(),
                "_hidl_offset + " + std::to_string(offset),
                true /* isReader */);

        offset += fieldSize;
    }

    out.unindent();
    out << "}\n\n";

    ////////////////////////////////////////////////////////////////////////////

    size_t structAlign, structSize;
    getAlignmentAndSize(&structAlign, &structSize);

    out << "public final void writeToParcel(android.os.HwParcel parcel) {\n";
    out.indent();

    out << "android.os.HwBlob _hidl_blob = new android.os.HwBlob("
        << structSize
        << " /* size */);\n";

    out << "writeEmbeddedToBlob(_hidl_blob, 0 /* parentOffset */);\n"
        << "parcel.writeBuffer(_hidl_blob);\n";

    out.unindent();
    out << "}\n\n";

    ////////////////////////////////////////////////////////////////////////////

    out << "public static final void writeVectorToParcel(\n";
    out.indent(2);
    out << "android.os.HwParcel parcel, java.util.ArrayList<"
        << localName()
        << "> _hidl_vec) {\n";
    out.unindent();

    out << "android.os.HwBlob _hidl_blob = new android.os.HwBlob(24 /* sizeof(hidl_vec<T>) */);\n";

    VectorType::EmitJavaFieldReaderWriterForElementType(
            out,
            0 /* depth */,
            this,
            "parcel",
            "_hidl_blob",
            "_hidl_vec",
            "0",
            false /* isReader */);

    out << "\nparcel.writeBuffer(_hidl_blob);\n";

    out.unindent();
    out << "}\n\n";

    ////////////////////////////////////////////////////////////////////////////

    out << "public final void writeEmbeddedToBlob(\n";
    out.indent(2);
    out << "android.os.HwBlob _hidl_blob, long _hidl_offset) {\n";
    out.unindent();

    offset = 0;
    for (const auto &field : *mFields) {
        size_t fieldAlign, fieldSize;
        field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);

        size_t pad = offset % fieldAlign;
        if (pad > 0) {
            offset += fieldAlign - pad;
        }

        field->type().emitJavaFieldReaderWriter(
                out,
                0 /* depth */,
                "parcel",
                "_hidl_blob",
                field->name(),
                "_hidl_offset + " + std::to_string(offset),
                false /* isReader */);

        offset += fieldSize;
    }

    out.unindent();
    out << "}\n";

    out.unindent();
    out << "};\n\n";

    return OK;
}

void CompoundType::emitStructReaderWriter(
        Formatter &out, const std::string &prefix, bool isReader) const {

    std::string space = prefix.empty() ? "" : (prefix + "::");

    out << "::android::status_t "
        << (isReader ? "readEmbeddedFromParcel"
                     : "writeEmbeddedToParcel")
        << "(\n";

    out.indent(2);

    bool useName = false;
    for (const auto &field : *mFields) {
        if (field->type().useNameInEmitReaderWriterEmbedded(isReader)) {
            useName = true;
            break;
        }
    }
    std::string name = useName ? "obj" : "/* obj */";
    // if not useName, then obj  should not be used at all,
    // then the #error should not be emitted.
    std::string error = useName ? "" : "\n#error\n";

    if (isReader) {
        out << space << localName() << " *" << name << ",\n";
        out << "const ::android::hardware::Parcel &parcel,\n";
    } else {
        out << "const " << space << localName() << " &" << name << ",\n";
        out << "::android::hardware::Parcel *parcel,\n";
    }

    out << "size_t parentHandle,\n"
        << "size_t parentOffset)";

    out << " {\n";

    out.unindent(2);
    out.indent();

    out << "::android::status_t _hidl_err = ::android::OK;\n\n";

    for (const auto &field : *mFields) {
        if (!field->type().needsEmbeddedReadWrite()) {
            continue;
        }

        field->type().emitReaderWriterEmbedded(
                out,
                0 /* depth */,
                name + (isReader ? "->" : ".") + field->name() + error,
                field->name() /* sanitizedName */,
                false /* nameIsPointer */,
                "parcel",
                !isReader /* parcelObjIsPointer */,
                isReader,
                ErrorMode_Return,
                "parentHandle",
                "parentOffset + offsetof("
                    + fullName()
                    + ", "
                    + field->name()
                    + ")");
    }

    out << "return _hidl_err;\n";

    out.unindent();
    out << "}\n\n";
}

void CompoundType::emitResolveReferenceDef(
        Formatter &out, const std::string prefix, bool isReader) const {
    out << "::android::status_t ";
    const std::string space(prefix.empty() ? "" : (prefix + "::"));

    bool useParent = false;
    for (const auto &field : *mFields) {
        if (field->type().useParentInEmitResolveReferencesEmbedded()) {
            useParent = true;
            break;
        }
    }

    std::string parentHandleName = useParent ? "parentHandle" : "/* parentHandle */";
    std::string parentOffsetName = useParent ? "parentOffset" : "/* parentOffset */";

    if (isReader) {
        out << "readEmbeddedReferenceFromParcel(\n";
        out.indent(2);
        out << space + localName() + " *obj,\n"
            << "const ::android::hardware::Parcel &parcel,\n"
            << "size_t " << parentHandleName << ", "
            << "size_t " << parentOffsetName << ")\n";
        out.unindent(2);
    } else {
        out << "writeEmbeddedReferenceToParcel(\n";
        out.indent(2);
        out << "const " << space + localName() + " &obj,\n"
            << "::android::hardware::Parcel *parcel,\n"
            << "size_t " << parentHandleName << ", "
            << "size_t " << parentOffsetName << ")\n";
        out.unindent(2);
    }

    out << " {\n";

    out.indent();

    out << "::android::status_t _hidl_err = ::android::OK;\n\n";

    const std::string nameDeref(isReader ? "obj->" : "obj.");
    // if not useParent, then parentName and offsetText
    // should not be used at all, then the #error should not be emitted.
    std::string error = useParent ? "" : "\n#error\n";

    for (const auto &field : *mFields) {
        if (!field->type().needsResolveReferences()) {
            continue;
        }

        field->type().emitResolveReferencesEmbedded(
            out,
            0 /* depth */,
            nameDeref + field->name(),
            field->name() /* sanitizedName */,
            false,    // nameIsPointer
            "parcel", // const std::string &parcelObj,
            !isReader, // bool parcelObjIsPointer,
            isReader, // bool isReader,
            ErrorMode_Return,
            parentHandleName + error,
            parentOffsetName
                + " + offsetof("
                + fullName()
                + ", "
                + field->name()
                + ")"
                + error);
    }

    out << "return _hidl_err;\n";

    out.unindent();
    out << "}\n\n";
}

bool CompoundType::needsEmbeddedReadWrite() const {
    if (mStyle != STYLE_STRUCT) {
        return false;
    }

    for (const auto &field : *mFields) {
        if (field->type().needsEmbeddedReadWrite()) {
            return true;
        }
    }

    return false;
}

bool CompoundType::needsResolveReferences() const {
    if (mStyle != STYLE_STRUCT) {
        return false;
    }

    for (const auto &field : *mFields) {
        if (field->type().needsResolveReferences()) {
            return true;
        }
    }

    return false;
}

bool CompoundType::resultNeedsDeref() const {
    return true;
}

status_t CompoundType::emitVtsTypeDeclarations(Formatter &out) const {
    out << "name: \"" << fullName() << "\"\n";
    out << "type: " << getVtsType() << "\n";

    // Emit declaration for each subtype.
    for (const auto &type : getSubTypes()) {
        switch (mStyle) {
            case STYLE_STRUCT:
            {
                out << "sub_struct: {\n";
                break;
            }
            case STYLE_UNION:
            {
                out << "sub_union: {\n";
                break;
            }
        }
        out.indent();
        status_t status(type->emitVtsTypeDeclarations(out));
        if (status != OK) {
            return status;
        }
        out.unindent();
        out << "}\n";
    }

    // Emit declaration for each field.
    for (const auto &field : *mFields) {
        switch (mStyle) {
            case STYLE_STRUCT:
            {
                out << "struct_value: {\n";
                break;
            }
            case STYLE_UNION:
            {
                out << "union_value: {\n";
                break;
            }
        }
        out.indent();
        out << "name: \"" << field->name() << "\"\n";
        status_t status = field->type().emitVtsAttributeType(out);
        if (status != OK) {
            return status;
        }
        out.unindent();
        out << "}\n";
    }

    return OK;
}

status_t CompoundType::emitVtsAttributeType(Formatter &out) const {
    out << "type: " << getVtsType() << "\n";
    out << "predefined_type: \"" << fullName() << "\"\n";
    return OK;
}

bool CompoundType::isJavaCompatible() const {
    if (mStyle != STYLE_STRUCT || !Scope::isJavaCompatible()) {
        return false;
    }

    for (const auto &field : *mFields) {
        if (!field->type().isJavaCompatible()) {
            return false;
        }
    }

    return true;
}

void CompoundType::getAlignmentAndSize(size_t *align, size_t *size) const {
    *align = 1;

    size_t offset = 0;
    for (const auto &field : *mFields) {
        // Each field is aligned according to its alignment requirement.
        // The surrounding structure's alignment is the maximum of its
        // fields' aligments.

        size_t fieldAlign, fieldSize;
        field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);

        size_t pad = offset % fieldAlign;
        if (pad > 0) {
            offset += fieldAlign - pad;
        }

        offset += fieldSize;

        if (fieldAlign > (*align)) {
            *align = fieldAlign;
        }
    }

    // Final padding to account for the structure's alignment.
    size_t pad = offset % (*align);
    if (pad > 0) {
        offset += (*align) - pad;
    }

    *size = offset;

    if (*size == 0) {
        // An empty struct still occupies a byte of space in C++.
        *size = 1;
    }
}

////////////////////////////////////////////////////////////////////////////////

CompoundField::CompoundField(const char *name, Type *type)
    : mName(name),
      mType(type) {
}

std::string CompoundField::name() const {
    return mName;
}

const Type &CompoundField::type() const {
    return *mType;
}

}  // namespace android

