/*
 * 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\n";

    if (canCheckEquality()) {
        out << "bool operator==("
            << getCppArgumentType() << ", " << getCppArgumentType() << ");\n\n";

        out << "bool operator!=("
            << getCppArgumentType() << ", " << getCppArgumentType() << ");\n\n";
    } else {
        out << "// operator== and operator!= are not generated for " << localName() << "\n\n";
    }

    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::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();

    if (canCheckEquality()) {
        out << "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 << "bool operator!=("
            << getCppArgumentType() << " lhs," << getCppArgumentType() << " rhs)";
        out.block([&] {
            out << "return !(lhs == rhs);\n";
        }).endl().endl();
    } else {
        out << "// operator== and operator!= are not generated for " << localName() << "\n";
    }

    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();
    } else {
        out << "// equals() is not generated for " << localName() << "\n";
    }

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

    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

