/*
 * 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 "Reference.h"
#include "ScalarType.h"
#include "VectorType.h"

#include <android-base/logging.h>
#include <hidl-util/Formatter.h>
#include <iostream>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>

namespace android {

CompoundType::CompoundType(Style style, const std::string& localName, const FQName& fullName,
                           const Location& location, Scope* parent)
    : Scope(localName, fullName, location, parent), mStyle(style) {}

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

void CompoundType::addField(NamedReference<Type>* field) {
    mFields.push_back(field);
}

std::vector<const NamedReference<Type>*> CompoundType::getFields() const {
    return std::vector<const NamedReference<Type>*>(mFields.begin(), mFields.end());
}

std::vector<const Reference<Type>*> CompoundType::getReferences() const {
    std::vector<const Reference<Type>*> ret;
    ret.insert(ret.begin(), mFields.begin(), mFields.end());
    return ret;
}

status_t CompoundType::validate() const {
    for (const auto* field : mFields) {
        const Type& type = field->type();

        if ((type.isVector() && static_cast<const VectorType*>(&type)->isVectorOfBinders())) {
            std::cerr << "ERROR: Struct/union cannot contain vectors of interfaces at "
                      << field->location() << "\n";
            return UNKNOWN_ERROR;
        }

        if (mStyle == STYLE_UNION) {
            if (type.isInterface()) {
                std::cerr << "ERROR: Union cannot contain interfaces at " << field->location()
                          << "\n";
                return UNKNOWN_ERROR;
            }

            if (type.needsEmbeddedReadWrite()) {
                std::cerr << "ERROR: Union must not contain any types that need fixup at "
                          << field->location() << "\n";
                return UNKNOWN_ERROR;
            }
        }
    }

    if (mStyle == STYLE_SAFE_UNION && mFields.size() < 2) {
        std::cerr << "ERROR: Safe union must contain at least two types to be useful at "
                  << location() << "\n";
        return UNKNOWN_ERROR;
    }

    status_t err = validateUniqueNames();
    if (err != OK) return err;

    err = validateSubTypeNames();
    if (err != OK) return err;

    return Scope::validate();
}

status_t CompoundType::validateUniqueNames() const {
    std::unordered_set<std::string> names;

    for (const auto* field : mFields) {
        if (names.find(field->name()) != names.end()) {
            std::cerr << "ERROR: Redefinition of field '" << field->name() << "' at "
                      << field->location() << "\n";
            return UNKNOWN_ERROR;
        }
        names.insert(field->name());
    }

    return OK;
}

void CompoundType::emitInvalidSubTypeNamesError(const std::string& subTypeName,
                                                const Location& location) const {
    std::cerr << "ERROR: Type name '" << subTypeName << "' defined at " << location
              << " conflicts with a member function of "
              << "safe_union " << definedName() << ". Consider renaming or "
              << "moving its definition outside the safe_union scope.\n";
}

status_t CompoundType::validateSubTypeNames() const {
    if (mStyle != STYLE_SAFE_UNION) { return OK; }
    const auto& subTypes = Scope::getSubTypes();

    for (const auto& subType : subTypes) {
        if (subType->definedName() == "getDiscriminator") {
            emitInvalidSubTypeNamesError(subType->definedName(), subType->location());
            return UNKNOWN_ERROR;
        }
    }

    return OK;
}

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

bool CompoundType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
    if (mStyle == STYLE_UNION) {
        return false;
    }
    for (const auto* field : mFields) {
        if (!field->get()->canCheckEquality(visited)) {
            return false;
        }
    }
    return true;
}

std::string CompoundType::typeName() const {
    switch (mStyle) {
        case STYLE_STRUCT: {
            return "struct " + definedName();
        }
        case STYLE_UNION: {
            return "union " + definedName();
        }
        case STYLE_SAFE_UNION: {
            return "safe_union " + definedName();
        }
    }
    CHECK(!"Should not be here");
}

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

    switch (mode) {
        case StorageMode_Stack:
            return base;

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

        case StorageMode_Result:
            return base + (containsInterface()?"":"*");
    }
    CHECK(!"Should not be here");
}

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";
        }
        case STYLE_SAFE_UNION:
        {
            return "TYPE_SAFE_UNION";
        }
    }
    CHECK(!"Should not be here");
}

bool CompoundType::containsInterface() const {
    for (const auto& field : mFields) {
        if (field->type().isCompoundType()) {
            const Type& t = field->type();
            const CompoundType* ct = static_cast<const CompoundType*>(&t);
            if (ct->containsInterface()) {
                return true;
            }
        }
        if (field->type().isInterface()) {
            return true;
        }
    }
    return false;
}

void CompoundType::emitSafeUnionUnknownDiscriminatorError(Formatter& out, const std::string& value,
                                                          bool fatal) const {
    if (fatal) {
        out << "::android::hardware::details::logAlwaysFatal(";
    } else {
        out << "ALOGE(\"%s\", ";
    }
    out << "(\n";
    out.indent(2, [&] {
        out << "\"Unknown union discriminator (value: \" +\n"
            << "std::to_string(" << getUnionDiscriminatorType()->getCppTypeCast(value)
            << ") + \").\").c_str());\n";
    });
}

void CompoundType::emitSafeUnionReaderWriterForInterfaces(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {

    CHECK(mStyle == STYLE_SAFE_UNION);

    out.block([&] {
        const auto discriminatorType = getUnionDiscriminatorType();
        if (isReader) {
            out << discriminatorType->getCppStackType()
                << " _hidl_d_primitive;\n";
        } else {
            out << "const "
                << discriminatorType->getCppStackType()
                << " _hidl_d_primitive = "
                << discriminatorType->getCppTypeCast(name + ".getDiscriminator()")
                << ";\n";
        }

        getUnionDiscriminatorType()->emitReaderWriter(out, "_hidl_d_primitive", parcelObj,
                                                    parcelObjIsPointer, isReader, mode);
        out << "switch (("
            << fullName()
            << "::hidl_discriminator) _hidl_d_primitive) ";

        out.block([&] {
               for (const auto& field : mFields) {
                   out << "case " << fullName() << "::hidl_discriminator::" << field->name()
                       << ": ";

                   const std::string tempFieldName = "_hidl_temp_" + field->name();
                   out.block([&] {
                          if (isReader) {
                              out << field->type().getCppResultType() << " " << tempFieldName
                                  << ";\n";

                              field->type().emitReaderWriter(out, tempFieldName, parcelObj,
                                                             parcelObjIsPointer, isReader, mode);

                              const std::string derefOperator =
                                      field->type().resultNeedsDeref() ? "*" : "";
                              out << name << "." << field->name() << "(std::move(" << derefOperator
                                  << tempFieldName << "));\n";
                          } else {
                              const std::string fieldValue = name + "." + field->name() + "()";
                              out << field->type().getCppArgumentType() << " " << tempFieldName
                                  << " = " << fieldValue << ";\n";

                              field->type().emitReaderWriter(out, tempFieldName, parcelObj,
                                                             parcelObjIsPointer, isReader, mode);
                          }
                          out << "break;\n";
                      }).endl();
               }

               out << "default: ";
               out.block([&] {
                      emitSafeUnionUnknownDiscriminatorError(out, "_hidl_d_primitive",
                                                             !isReader /*fatal*/);
                      if (isReader) {
                          out << "_hidl_err = BAD_VALUE;\n";
                          handleError(out, mode);
                      }
                  }).endl();
           }).endl();
    }).endl();
}

void CompoundType::emitReaderWriter(
        Formatter &out,
        const std::string &name,
        const std::string &parcelObj,
        bool parcelObjIsPointer,
        bool isReader,
        ErrorMode mode) const {

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

    if(containsInterface()){
        if (mStyle == STYLE_SAFE_UNION) {
            emitSafeUnionReaderWriterForInterfaces(out, name, parcelObj,
                                                   parcelObjIsPointer,
                                                   isReader, mode);
            return;
        }

        for (const auto& field : mFields) {
            const std::string tempFieldName = "_hidl_temp_" + field->name();
            const std::string fieldValue = name + "." + field->name();

            out.block([&] {
                if (isReader) {
                    out << field->type().getCppResultType()
                        << " "
                        << tempFieldName
                        << ";\n";
                } else {
                    out << field->type().getCppArgumentType()
                        << " "
                        << tempFieldName
                        << " = "
                        << fieldValue
                        << ";\n";
                }

                field->type().emitReaderWriter(out, tempFieldName, parcelObj,
                                               parcelObjIsPointer, isReader, mode);
                if (isReader) {
                    const std::string derefOperator = field->type().resultNeedsDeref()
                                                      ? "*" : "";
                    out << fieldValue
                        << " = std::move("
                        << derefOperator
                        << tempFieldName
                        << ");\n";
                }
            }).endl();
        }
    } else {
        const std::string parentName = "_hidl_" + name + "_parent";

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

        if (isReader) {
            out << "_hidl_err = " << parcelObjDeref << "readBuffer("
                << "sizeof(*" << name << "), &" << parentName << ", "
                << " const_cast<const void**>(reinterpret_cast<void **>("
                << "&" << name << ")));\n";
            handleError(out, mode);
        } else {
            out << "_hidl_err = "
                << parcelObjDeref
                << "writeBuffer(&"
                << name
                << ", sizeof("
                << name
                << "), &"
                << parentName
                << ");\n";
            handleError(out, mode);
        }

        bool needEmbeddedReadWrite = needsEmbeddedReadWrite();
        CHECK(mStyle != STYLE_UNION || !needEmbeddedReadWrite);

        if (needEmbeddedReadWrite) {
            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 << "(" << getJavaTypeCast(argName) << ")."
        << (isReader ? "readFromParcel" : "writeToParcel") << "(" << parcelObj << ");\n";
}

void CompoundType::emitJavaFieldInitializer(
        Formatter &out, const std::string &fieldName) const {
    const std::string fieldDeclaration = fullJavaName() + " " + fieldName;
    emitJavaFieldDefaultInitialValue(out, fieldDeclaration);
}

void CompoundType::emitJavaFieldDefaultInitialValue(
        Formatter &out, const std::string &declaredFieldName) const {
    out << declaredFieldName
        << " = 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 << "("
            << getJavaTypeCast(fieldName)
            << ").readEmbeddedFromParcel("
            << parcelName
            << ", "
            << blobName
            << ", "
            << offset
            << ");\n";

        return;
    }

    out << fieldName
        << ".writeEmbeddedToBlob("
        << blobName
        << ", "
        << offset
        << ");\n";
}

void CompoundType::emitLayoutAsserts(Formatter& out, const Layout& layout,
                                     const std::string& layoutName) const {
    out << "static_assert(sizeof("
        << fullName()
        << layoutName
        << ") == "
        << layout.size
        << ", \"wrong size\");\n";

    out << "static_assert(__alignof("
        << fullName()
        << layoutName
        << ") == "
        << layout.align
        << ", \"wrong alignment\");\n";
}

void CompoundType::emitSafeUnionTypeDeclarations(Formatter& out) const {
    out << "struct " << definedName() << " final {\n";

    out.indent();

    Scope::emitTypeDeclarations(out);

    bool hasPointer = containsPointer();
    CompoundLayout layout = hasPointer
                            ? CompoundLayout()
                            : getCompoundAlignmentAndSize();

    out << "enum class hidl_discriminator : "
        << getUnionDiscriminatorType()->getCppType(StorageMode_Stack, false)
        << " ";

    out.block([&] {
        for (size_t idx = 0; idx < mFields.size(); idx++) {
            const auto& field = mFields.at(idx);

            field->emitDocComment(out);
            out << field->name()
                << " = "
                << idx
                << ",  // "
                << field->type().getCppStackType(true /*specifyNamespaces*/)
                << "\n";
        }
    });
    out << ";\n\n";

    out << definedName() << "();\n"                                              // Constructor
        << "~" << definedName() << "();\n"                                       // Destructor
        << definedName() << "(" << definedName() << "&&);\n"                     // Move constructor
        << definedName() << "(const " << definedName() << "&);\n"                // Copy constructor
        << definedName() << "& operator=(" << definedName() << "&&);\n"          // Move assignment
        << definedName() << "& operator=(const " << definedName() << "&);\n\n";  // Copy assignment

    for (const auto& field : mFields) {
        // Setter (copy)
        out << "void "
            << field->name()
            << "("
            << field->type().getCppArgumentType()
            << ");\n";

        if (field->type().resolveToScalarType() == nullptr) {
            // Setter (move)
            out << "void "
                << field->name()
                << "("
                << field->type().getCppStackType()
                << "&&);\n";
        }

        // Getter (mutable)
        out << field->type().getCppStackType()
            << "& "
            << field->name()
            << "();\n";

        // Getter (immutable)
        out << field->type().getCppArgumentType()
            << " "
            << field->name()
            << "() const;\n\n";
    }

    out << "// Utility methods\n";
    out << "hidl_discriminator getDiscriminator() const;\n\n";

    out << "constexpr size_t hidl_getUnionOffset() const ";
    out.block([&] {
        out << "return offsetof(" << fullName() << ", hidl_u);\n";
    }).endl().endl();

    out.unindent();
    out << "private:\n";
    out.indent();

    out << "void hidl_destructUnion();\n\n";

    out << "hidl_discriminator hidl_d";
    if (!hasPointer) {
        out << " __attribute__ ((aligned("
            << layout.discriminator.align << "))) ";
    }
    out << ";\n";
    out << "union hidl_union final {\n";
    out.indent();

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

        out << field->type().getCppStackType()
            << " "
            << field->name();

        if (!hasPointer) {
            out << " __attribute__ ((aligned("
                << fieldAlign
                << ")))";
        }
        out << ";\n";
    }

    out << "\n"
        << "hidl_union();\n"
        << "~hidl_union();\n";

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

    if (!hasPointer) {
        out << "\n";

        emitLayoutAsserts(out, layout.innerStruct, "::hidl_union");
        emitLayoutAsserts(out, layout.discriminator, "::hidl_discriminator");
    }

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

    if (!hasPointer) {
        emitLayoutAsserts(out, layout.overall, "");
        out << "\n";
    }
}

void CompoundType::emitFieldHidlDefinition(Formatter& out, const NamedReference<Type>& ref) const {
    if (ref.getDocComment() != nullptr) ref.getDocComment()->emit(out);

    if (ref.definedInline()) {
        // Same check as above, this is for sanity
        CHECK(ref.get()->isCompoundType());
        static_cast<const CompoundType*>(ref.get())->emitInlineHidlDefinition(out);
        out << " " << ref.name() << ";\n";
    } else {
        out << ref.localName() << " " << ref.name() << ";\n";
    }
}

void CompoundType::emitInlineHidlDefinition(Formatter& out) const {
    if (getDocComment() != nullptr) getDocComment()->emit(out);
    out << typeName() << " ";

    std::set<FQName> namesDeclaredInScope;
    for (const NamedReference<Type>* ref : mFields) {
        if (ref->definedInline()) {
            const Type* type = ref->get();
            CHECK(type->isCompoundType()) << " only compound types can be defined inline";
            namesDeclaredInScope.insert(static_cast<const CompoundType*>(type)->fqName());
        }
    }

    std::vector<const NamedType*> preDeclaredTypes;
    for (const NamedType* namedType : getSortedDefinedTypes()) {
        if (namesDeclaredInScope.find(namedType->fqName()) == namesDeclaredInScope.end()) {
            // have to predeclare it
            preDeclaredTypes.push_back(namedType);
        }
    }

    out << "{";
    out.indent([&] {
        size_t preDeclaredTypesIdx = 0;
        size_t fieldIdx = 0;
        while (preDeclaredTypesIdx < preDeclaredTypes.size() && fieldIdx < mFields.size()) {
            out << "\n";
            if (preDeclaredTypes.at(preDeclaredTypesIdx)->location() <
                mFields.at(fieldIdx)->location()) {
                preDeclaredTypes.at(preDeclaredTypesIdx++)->emitHidlDefinition(out);
            } else {
                emitFieldHidlDefinition(out, *mFields.at(fieldIdx++));
            }
        }

        while (preDeclaredTypesIdx < preDeclaredTypes.size()) {
            out << "\n";
            preDeclaredTypes.at(preDeclaredTypesIdx++)->emitHidlDefinition(out);
        }

        while (fieldIdx < mFields.size()) {
            out << "\n";
            emitFieldHidlDefinition(out, *mFields.at(fieldIdx++));
        }
    });
    out << "}";
}

void CompoundType::emitHidlDefinition(Formatter& out) const {
    emitInlineHidlDefinition(out);
    out << ";\n";
}

void CompoundType::emitTypeDeclarations(Formatter& out) const {
    if (mStyle == STYLE_SAFE_UNION) {
        emitSafeUnionTypeDeclarations(out);
        return;
    }

    out << ((mStyle == STYLE_STRUCT) ? "struct" : "union") << " " << definedName() << " final {\n";

    out.indent();

    Scope::emitTypeDeclarations(out);

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

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

        return;
    }

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

            offset += Layout::getPad(offset, fieldAlign);

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

            if (mStyle == STYLE_STRUCT) {
                offset += fieldSize;
            }
        }

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

    CompoundLayout layout = getCompoundAlignmentAndSize();
    emitLayoutAsserts(out, layout.overall, "");
    out << "\n";
}

void CompoundType::emitTypeForwardDeclaration(Formatter& out) const {
    switch (mStyle) {
        case STYLE_UNION: {
            out << "union";
            break;
        }
        case STYLE_STRUCT:
        case STYLE_SAFE_UNION: {
            out << "struct";
            break;
        }
        default: {
            CHECK(!"Should not be here");
        }
    }
    out << " " << definedName() << ";\n";
}

void CompoundType::emitPackageTypeDeclarations(Formatter& out) const {
    Scope::emitPackageTypeDeclarations(out);

    out << "static inline std::string toString(" << getCppArgumentType() << " o);\n";
    out << "static inline void PrintTo(" << getCppArgumentType() << " o, ::std::ostream*);\n";

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

        out << "static inline bool operator!=("
            << getCppArgumentType() << " lhs, " << getCppArgumentType() << " rhs);\n";
    } else {
        out << "// operator== and operator!= are not generated for " << definedName() << "\n";
    }

    out.endl();
}

void CompoundType::emitPackageTypeHeaderDefinitions(Formatter& out) const {
    Scope::emitPackageTypeHeaderDefinitions(out);

    out << "static inline 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";

        if (mStyle == STYLE_SAFE_UNION) {
            out << "\nswitch (o.getDiscriminator()) {\n";
            out.indent();
        }

        for (const NamedReference<Type>* field : mFields) {
            if (mStyle == STYLE_SAFE_UNION) {
                out << "case "
                    << fullName()
                    << "::hidl_discriminator::"
                    << field->name()
                    << ": ";

                out.block([&] {
                    out << "os += \"."
                    << field->name()
                    << " = \";\n"
                    << "os += toString(o."
                    << field->name()
                    << "());\n"
                    << "break;\n";
                }).endl();
            } else {
                out << "os += \"";
                if (field != *(mFields.begin())) {
                    out << ", ";
                }
                out << "." << field->name() << " = \";\n";
                field->type().emitDump(out, "os", "o." + field->name());
            }
        }

        if (mStyle == STYLE_SAFE_UNION) {
            out << "default: ";
            out.block([&] {
                   emitSafeUnionUnknownDiscriminatorError(out, "o.getDiscriminator()",
                                                          true /*fatal*/);
               })
                .endl();

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

    out << "static inline void PrintTo(" << getCppArgumentType() << " o, ::std::ostream* os) ";
    out.block([&] { out << "*os << toString(o);\n"; }).endl().endl();

    if (canCheckEquality()) {
        out << "static inline bool operator==(" << getCppArgumentType() << " "
            << (mFields.empty() ? "/* lhs */" : "lhs") << ", " << getCppArgumentType() << " "
            << (mFields.empty() ? "/* rhs */" : "rhs") << ") ";
        out.block([&] {
            if (mStyle == STYLE_SAFE_UNION) {
                out.sIf("lhs.getDiscriminator() != rhs.getDiscriminator()", [&] {
                    out << "return false;\n";
                }).endl();

                out << "switch (lhs.getDiscriminator()) {\n";
                out.indent();
            }

            for (const auto& field : mFields) {
                if (mStyle == STYLE_SAFE_UNION) {
                    out << "case "
                        << fullName()
                        << "::hidl_discriminator::"
                        << field->name()
                        << ": ";

                    out.block([&] {
                        out << "return (lhs."
                        << field->name()
                        << "() == rhs."
                        << field->name()
                        << "());\n";
                    }).endl();
                } else {
                    out.sIf("lhs." + field->name() + " != rhs." + field->name(), [&] {
                        out << "return false;\n";
                    }).endl();
                }
            }

            if (mStyle == STYLE_SAFE_UNION) {
                out << "default: ";
                out.block([&] {
                       emitSafeUnionUnknownDiscriminatorError(out, "lhs.getDiscriminator()",
                                                              true /*fatal*/);
                   })
                    .endl();

                out.unindent();
                out << "}\n";
            }
            out << "return true;\n";
        }).endl().endl();

        out << "static inline bool operator!=("
            << getCppArgumentType() << " lhs, " << getCppArgumentType() << " rhs)";
        out.block([&] {
            out << "return !(lhs == rhs);\n";
        }).endl().endl();
    } else {
        out << "// operator== and operator!= are not generated for " << definedName() << "\n\n";
    }
}

void CompoundType::emitPackageHwDeclarations(Formatter& out) const {
    Scope::emitPackageHwDeclarations(out);

    if (needsEmbeddedReadWrite()) {
        out << "::android::status_t readEmbeddedFromParcel(\n";

        out.indent(2);

        out << "const " << 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);
    }
}

static void emitSafeUnionFieldConstructor(Formatter& out,
                                          const NamedReference<Type>* field,
                                          const std::string& initializerObjectName) {
    out << "new (&hidl_u."
        << field->name()
        << ") "
        << field->type().getCppStackType()
        << "("
        << initializerObjectName
        << ");\n";
}

static void emitSafeUnionSetterDefinition(Formatter& out,
                                          const NamedReference<Type>* field,
                                          const std::string& parameterName,
                                          bool usesMoveSemantics) {
    out.block([&] {
        out << "if (hidl_d != hidl_discriminator::"
            << field->name()
            << ") ";

        const std::string argumentName = usesMoveSemantics
                                         ? ("std::move(" + parameterName + ")")
                                         : parameterName;
        out.block([&] {
            out << "hidl_destructUnion();\n"
                << "::std::memset(&hidl_u, 0, sizeof(hidl_u));\n\n";

            emitSafeUnionFieldConstructor(out, field, argumentName);
            out << "hidl_d = hidl_discriminator::"
                << field->name()
                << ";\n";
        }).endl();

        out << "else if (&(hidl_u."
            << field->name()
            << ") != &"
            << parameterName
            << ") ";

        out.block([&] {
            out << "hidl_u."
                << field->name()
                << " = "
                << argumentName
                << ";\n";
        }).endl();
    }).endl().endl();
}

static void emitSafeUnionGetterDefinition(Formatter& out, const std::string& fieldName) {
    out.block([&] {
        out << "if (CC_UNLIKELY(hidl_d != hidl_discriminator::"
            << fieldName
            << ")) ";

        out.block([&] {
            out << "LOG_ALWAYS_FATAL(\"Bad safe_union access: safe_union has discriminator %\" "
                << "PRIu64 \" but discriminator %\" PRIu64 \" was accessed.\",\n";
            out.indent(2, [&] {
                out << "static_cast<uint64_t>(hidl_d), "
                    << "static_cast<uint64_t>(hidl_discriminator::" << fieldName << "));";
            }).endl();
        }).endl().endl();

        out << "return hidl_u."
            << fieldName
            << ";\n";
    }).endl().endl();
}

void CompoundType::emitSafeUnionCopyAndAssignDefinition(Formatter& out,
                                                        const std::string& parameterName,
                                                        bool isCopyConstructor,
                                                        bool usesMoveSemantics) const {
    out.block([&] {
        if (!isCopyConstructor) {
            out << "if (this == &"
            << parameterName
            << ") { return *this; }\n\n";
        }

        out << "switch ("
            << parameterName
            << ".hidl_d) ";

        out.block([&] {
               for (const auto& field : mFields) {
                   const std::string parameterFieldName =
                           (parameterName + ".hidl_u." + field->name());

                   const std::string argumentName =
                           usesMoveSemantics ? ("std::move(" + parameterFieldName + ")")
                                             : parameterFieldName;

                   out << "case hidl_discriminator::" << field->name() << ": ";

                   if (isCopyConstructor) {
                       out.block([&] {
                              emitSafeUnionFieldConstructor(out, field, argumentName);
                              out << "break;\n";
                          }).endl();
                   } else {
                       out.block([&] {
                              out << field->name() << "(" << argumentName << ");\n"
                                  << "break;\n";
                          }).endl();
                   }
               }

               out << "default: ";
               out.block([&] {
                      emitSafeUnionUnknownDiscriminatorError(out, parameterName + ".hidl_d",
                                                             true /*fatal*/);
                  }).endl();
           }).endl();

        if (isCopyConstructor) {
            out << "\nhidl_d = "
                << parameterName
                << ".hidl_d;\n";
        } else {
            out << "return *this;\n";
        }
    }).endl().endl();
}

void CompoundType::emitSafeUnionTypeConstructors(Formatter& out) const {

    // Default constructor
    out << fullName() << "::" << definedName() << "() ";

    out.block([&] {
        out << "static_assert(offsetof("
            << fullName()
            << ", hidl_d) == 0, \"wrong offset\");\n";

        const CompoundLayout layout = getCompoundAlignmentAndSize();

        if (!containsPointer()) {
            out << "static_assert(offsetof(" << fullName()
                << ", hidl_u) == " << layout.innerStruct.offset << ", \"wrong offset\");\n";
        }

        out.endl();

        out << "::std::memset(&hidl_u, 0, sizeof(hidl_u));\n";

        // union itself is zero'd when set
        // padding after descriminator
        size_t dpad = layout.innerStruct.offset - layout.discriminator.size;
        emitPaddingZero(out, layout.discriminator.size /*offset*/, dpad /*size*/);

        size_t innerStructEnd = layout.innerStruct.offset + layout.innerStruct.size;
        // final padding of the struct
        size_t fpad = layout.overall.size - innerStructEnd;
        emitPaddingZero(out, innerStructEnd /*offset*/, fpad /*size*/);

        out.endl();

        CHECK(!mFields.empty());
        out << "hidl_d = hidl_discriminator::" << mFields.at(0)->name() << ";\n";
        emitSafeUnionFieldConstructor(out, mFields.at(0), "");
    }).endl().endl();

    // Destructor
    out << fullName() << "::~" << definedName() << "() ";

    out.block([&] {
        out << "hidl_destructUnion();\n";
    }).endl().endl();

    // Move constructor
    out << fullName() << "::" << definedName() << "(" << definedName()
        << "&& other) : " << fullName() << "() ";

    emitSafeUnionCopyAndAssignDefinition(
            out, "other", true /* isCopyConstructor */, true /* usesMoveSemantics */);

    // Copy constructor
    out << fullName() << "::" << definedName() << "(const " << definedName()
        << "& other) : " << fullName() << "() ";

    emitSafeUnionCopyAndAssignDefinition(
        out, "other", true /* isCopyConstructor */, false /* usesMoveSemantics */);

    // Move assignment operator
    out << fullName() << "& (" << fullName() << "::operator=)(" << definedName() << "&& other) ";

    emitSafeUnionCopyAndAssignDefinition(
            out, "other", false /* isCopyConstructor */, true /* usesMoveSemantics */);

    // Copy assignment operator
    out << fullName() << "& (" << fullName() << "::operator=)(const " << definedName()
        << "& other) ";

    emitSafeUnionCopyAndAssignDefinition(
            out, "other", false /* isCopyConstructor */, false /* usesMoveSemantics */);
}

void CompoundType::emitSafeUnionTypeDefinitions(Formatter& out) const {
    emitSafeUnionTypeConstructors(out);

    out << "void "
        << fullName()
        << "::hidl_destructUnion() ";

    out.block([&] {
        out << "switch (hidl_d) ";
        out.block([&] {
               for (const auto& field : mFields) {
                   out << "case hidl_discriminator::" << field->name() << ": ";

                   out.block([&] {
                          out << "::android::hardware::details::destructElement(&(hidl_u."
                              << field->name() << "));\n"
                              << "break;\n";
                      }).endl();
               }

               out << "default: ";
               out.block([&] {
                      emitSafeUnionUnknownDiscriminatorError(out, "hidl_d", true /*fatal*/);
                  }).endl();
           })
                .endl()
                .endl();
    }).endl().endl();

    for (const NamedReference<Type>* field : mFields) {
        // Setter (copy)
        out << "void "
            << fullName()
            << "::"
            << field->name()
            << "("
            << field->type().getCppArgumentType()
            << " o) ";

        emitSafeUnionSetterDefinition(out, field, "o", false /* usesMoveSemantics */);

        if (field->type().resolveToScalarType() == nullptr) {
            // Setter (move)
            out << "void "
                << fullName()
                << "::"
                << field->name()
                << "("
                << field->type().getCppStackType()
                << "&& o) ";

            emitSafeUnionSetterDefinition(out, field, "o", true /* usesMoveSemantics */);
        }

        // Getter (mutable)
        out << field->type().getCppStackType()
            << "& ("
            << fullName()
            << "::"
            << field->name()
            << ")() ";

        emitSafeUnionGetterDefinition(out, field->name());

        // Getter (immutable)
        out << field->type().getCppArgumentType()
            << " ("
            << fullName()
            << "::"
            << field->name()
            << ")() const ";

        emitSafeUnionGetterDefinition(out, field->name());
    }

    // Trivial constructor/destructor for internal union
    out << fullName() << "::hidl_union::hidl_union() {}\n\n"
        << fullName() << "::hidl_union::~hidl_union() {}\n\n";

    // Utility method
    out << fullName() << "::hidl_discriminator ("
        << fullName() << "::getDiscriminator)() const ";

    out.block([&] {
        out << "return hidl_d;\n";
    }).endl().endl();
}

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

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

    if (mStyle == STYLE_SAFE_UNION) {
        emitSafeUnionTypeDefinitions(out);
    }
}

static void emitJavaSafeUnionUnknownDiscriminatorError(Formatter& out, bool fatal) {
    out << "throw new ";

    if (fatal) {
        out << "Error";
    } else {
        out << "IllegalStateException";
    }

    out << "(\"Unknown union discriminator (value: \" + hidl_d + \").\");\n";
}

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

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

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

    out.indent();

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

    if (mStyle == STYLE_SAFE_UNION) {
        out << "public " << definedName() << "() ";
        out.block([&] {
               CHECK(!mFields.empty());
               mFields.at(0)->type().emitJavaFieldDefaultInitialValue(out, "hidl_o");
           })
                .endl()
                .endl();

        const std::string discriminatorStorageType = (
                getUnionDiscriminatorType()->getJavaType(false));

        out << "public static final class hidl_discriminator ";
        out.block([&] {
               for (size_t idx = 0; idx < mFields.size(); idx++) {
                   const auto& field = mFields.at(idx);

                   field->emitDocComment(out);
                   out << "public static final " << discriminatorStorageType << " " << field->name()
                       << " = " << idx << ";  // "
                       << field->type().getJavaType(true /* forInitializer */) << "\n";
               }

               out << "\n"
                   << "public static final String getName(" << discriminatorStorageType
                   << " value) ";

               out.block([&] {
                      out << "switch (value) ";
                      out.block([&] {
                             for (size_t idx = 0; idx < mFields.size(); idx++) {
                                 const auto& field = mFields.at(idx);

                                 out << "case " << idx << ": { return \"" << field->name()
                                     << "\"; }\n";
                             }
                             out << "default: { return \"Unknown\"; }\n";
                         }).endl();
                  })
                       .endl()
                       .endl();

               out << "private hidl_discriminator() {}\n";
           })
                .endl()
                .endl();

        out << "private " << discriminatorStorageType << " hidl_d = 0;\n";
        out << "private Object hidl_o = null;\n";

        for (const auto& field : mFields) {
            // Setter
            out << "public void "
                << field->name()
                << "("
                << field->type().getJavaType(false)
                << " "
                << field->name()
                << ") ";

            out.block([&] {
                out << "hidl_d = hidl_discriminator."
                    << field->name()
                    << ";\n";

                out << "hidl_o = "
                    << field->name()
                    << ";\n";
            }).endl().endl();

            // Getter
            out << "public "
                << field->type().getJavaType(false)
                << " "
                << field->name()
                << "() ";

            out.block([&] {
                out << "if (hidl_d != hidl_discriminator."
                    << field->name()
                    << ") ";

                out.block([&] {
                    out << "String className = (hidl_o != null) ? "
                        << "hidl_o.getClass().getName() : \"null\";\n";

                    out << "throw new IllegalStateException(\n";
                    out.indent(2, [&] {
                        out << "\"Read access to inactive union components is disallowed. \" +\n"
                            << "\"Discriminator value is \" + hidl_d + \" (corresponding \" +\n"
                            << "\"to \" + hidl_discriminator.getName(hidl_d) + \"), and \" +\n"
                            << "\"hidl_o is of type \" + className + \".\");\n";
                    });
                }).endl();

                out << "if (hidl_o != null && !"
                    << field->type().getJavaTypeClass()
                    << ".class.isInstance(hidl_o)) ";

                out.block([&] {
                    out << "throw new Error(\"Union is in a corrupted state.\");\n";
                }).endl();

                out << "return ("
                    << field->type().getJavaTypeCast("hidl_o")
                    << ");\n";
            }).endl().endl();
        }

        out << "// Utility method\n"
            << "public "
            << discriminatorStorageType
            << " getDiscriminator() { return hidl_d; }\n\n";

    } else if (mStyle == STYLE_STRUCT) {
        for (const auto& field : mFields) {
            field->emitDocComment(out);

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

        out << "\n";
    } else {
        LOG(FATAL) << "Java output doesn't support " << mStyle;
    }

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

    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();
            // Though class is final, we use getClass instead of instanceof to be explicit.
            out.sIf("otherObject.getClass() != " + fullJavaName() + ".class", [&] {
                out << "return false;\n";
            }).endl();
            out << fullJavaName() << " other = (" << fullJavaName() << ")otherObject;\n";

            if (mStyle == STYLE_SAFE_UNION) {
                out.sIf("this.hidl_d != other.hidl_d", [&] {
                    out << "return false;\n";
                }).endl();
                out.sIf("!android.os.HidlSupport.deepEquals(this.hidl_o, other.hidl_o)", [&] {
                    out << "return false;\n";
                }).endl();
            } else {
                for (const auto& field : mFields) {
                    std::string condition = (field->type().isScalar() || field->type().isEnum())
                        ? "this." + field->name() + " != other." + field->name()
                        : ("!android.os.HidlSupport.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, [&] {
                if (mStyle == STYLE_SAFE_UNION) {
                    out << "android.os.HidlSupport.deepHashCode(this.hidl_o),\n"
                        << "java.util.Objects.hashCode(this.hidl_d)";
                } else {
                    out.join(mFields.begin(), mFields.end(), ", \n", [&](const auto& field) {
                        out << "android.os.HidlSupport.deepHashCode(this." << field->name() << ")";
                    });
                }
            });
            out << ");\n";
        }).endl().endl();
    } else {
        out << "// equals() is not generated for " << definedName() << "\n";
    }

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

    out << "@Override\npublic final String toString() ";
    out.block([&] {
        out << "java.lang.StringBuilder builder = new java.lang.StringBuilder();\n"
            << "builder.append(\"{\");\n";

        if (mStyle == STYLE_SAFE_UNION) {
            out << "switch (this.hidl_d) {\n";
            out.indent();
        }

        for (const auto& field : mFields) {
            if (mStyle == STYLE_SAFE_UNION) {
                out << "case hidl_discriminator."
                    << field->name()
                    << ": ";

                out.block([&] {
                    out << "builder.append(\""
                        << "."
                        << field->name()
                        << " = \");\n";

                    field->type().emitJavaDump(out, "builder", "this." + field->name() + "()");
                    out << "break;\n";
                }).endl();
            }
            else {
                out << "builder.append(\"";
                if (field != *(mFields.begin())) {
                    out << ", ";
                }
                out << "." << field->name() << " = \");\n";
                field->type().emitJavaDump(out, "builder", "this." + field->name());
            }
        }

        if (mStyle == STYLE_SAFE_UNION) {
            out << "default: ";
            out.block([&] { emitJavaSafeUnionUnknownDiscriminatorError(out, true /*fatal*/); })
                .endl();

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

        out << "builder.append(\"}\");\nreturn builder.toString();\n";
    }).endl().endl();

    CompoundLayout layout = getCompoundAlignmentAndSize();

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

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

        if (mStyle == STYLE_SAFE_UNION) {
            out << "hidl_d = ";
            getUnionDiscriminatorType()->emitJavaReaderWriter(
                    out, "parcel", "hidl_d", true);

            out << "switch (hidl_d) {\n";
            out.indent();
        }

        for (const auto& field : mFields) {
            if (mStyle == STYLE_SAFE_UNION) {
                out << "case hidl_discriminator."
                    << field->name()
                    << ": ";

                out.block([&] {
                    out << "hidl_o = ";
                    field->type().emitJavaReaderWriter(out, "parcel", "hidl_o", true);

                    out << "break;\n";
                }).endl();
            } else {
                out << field->name() << " = ";
                field->type().emitJavaReaderWriter(out, "parcel", field->name(), true);
            }
        }

        if (mStyle == STYLE_SAFE_UNION) {
            out << "default: ";
            out.block([&] { emitJavaSafeUnionUnknownDiscriminatorError(out, false /*fatal*/); })
                .endl();

            out.unindent();
            out << "}\n";
        }
    } else {
        out << "android.os.HwBlob blob = parcel.readBuffer(";
        out << layout.overall.size << " /* size */);\n";
        out << "readEmbeddedFromParcel(parcel, blob, 0 /* parentOffset */);\n";
    }
    out.unindent();
    out << "}\n\n";

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

    size_t vecAlign, vecSize;
    VectorType::getAlignmentAndSizeStatic(&vecAlign, &vecSize);

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

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

    if (containsInterface()) {
        out << "int size = parcel.readInt32();\n";
        out << "for(int i = 0 ; i < size; i ++) {\n";
        out.indent();
        out << fullJavaName() << " tmp = ";
        emitJavaReaderWriter(out, "parcel", "tmp", true);
        out << "_hidl_vec.add(tmp);\n";
        out.unindent();
        out << "}\n";
    } else {
        out << "android.os.HwBlob _hidl_blob = parcel.readBuffer(";
        out << vecSize << " /* sizeof hidl_vec<T> */);\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";
    ////////////////////////////////////////////////////////////////////////////
    if (containsInterface()) {
        out << "// readEmbeddedFromParcel is not generated()\n";
    } else {
        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();

        if (mStyle == STYLE_SAFE_UNION) {
            getUnionDiscriminatorType()->emitJavaFieldReaderWriter(
                out, 0 /* depth */, "parcel", "_hidl_blob", "hidl_d",
                "_hidl_offset + " + std::to_string(layout.discriminator.offset),
                true /* isReader */);

            out << "switch (this.hidl_d) {\n";
            out.indent();
        }

        size_t offset = layout.innerStruct.offset;
        for (const auto& field : mFields) {
            if (mStyle == STYLE_SAFE_UNION) {
                out << "case hidl_discriminator."
                    << field->name()
                    << ": ";

                out.block([&] {
                    field->type().emitJavaFieldDefaultInitialValue(out, "hidl_o");
                    field->type().emitJavaFieldReaderWriter(
                        out, 0 /* depth */, "parcel", "_hidl_blob", "hidl_o",
                        "_hidl_offset + " + std::to_string(offset), true /* isReader */);

                    out << "break;\n";
                }).endl();
            } else {
                size_t fieldAlign, fieldSize;
                field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);

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

        if (mStyle == STYLE_SAFE_UNION) {
            out << "default: ";
            out.block([&] { emitJavaSafeUnionUnknownDiscriminatorError(out, false /*fatal*/); })
                .endl();

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

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

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

    if (containsInterface()) {
        if (mStyle == STYLE_SAFE_UNION) {
            getUnionDiscriminatorType()->emitJavaReaderWriter(
                out, "parcel", "hidl_d", false);

            out << "switch (this.hidl_d) {\n";
            out.indent();
        }

        for (const auto& field : mFields) {
            if (mStyle == STYLE_SAFE_UNION) {
                out << "case hidl_discriminator."
                    << field->name()
                    << ": ";

                out.block([&] {
                    field->type().emitJavaReaderWriter(out, "parcel", field->name() + "()", false);
                    out << "break;\n";
                }).endl();
            } else {
                field->type().emitJavaReaderWriter(out, "parcel", field->name(), false);
            }
        }

        if (mStyle == STYLE_SAFE_UNION) {
            out << "default: ";
            out.block([&] { emitJavaSafeUnionUnknownDiscriminatorError(out, true /*fatal*/); })
                .endl();

            out.unindent();
            out << "}\n";
        }
    } else {
        out << "android.os.HwBlob _hidl_blob = new android.os.HwBlob("
            << layout.overall.size
            << " /* 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<" << definedName()
        << "> _hidl_vec) {\n";
    out.unindent();

    if (containsInterface()) {
        out << "parcel.writeInt32(_hidl_vec.size());\n";
        out << "for(" << fullJavaName() << " tmp: _hidl_vec) ";
        out.block([&] {
            emitJavaReaderWriter(out, "parcel", "tmp", false);
        }).endl();
    } else {
        out << "android.os.HwBlob _hidl_blob = new android.os.HwBlob(" << vecSize
            << " /* 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";
    ////////////////////////////////////////////////////////////////////////////

    if (containsInterface()) {
        out << "// writeEmbeddedToBlob() is not generated\n";
    } else {
        out << "public final void writeEmbeddedToBlob(\n";
        out.indent(2);
        out << "android.os.HwBlob _hidl_blob, long _hidl_offset) {\n";
        out.unindent();

        if (mStyle == STYLE_SAFE_UNION) {
            getUnionDiscriminatorType()->emitJavaFieldReaderWriter(
                out, 0 /* depth */, "parcel", "_hidl_blob", "hidl_d",
                "_hidl_offset + " + std::to_string(layout.discriminator.offset),
                false /* isReader */);

            out << "switch (this.hidl_d) {\n";
            out.indent();
        }

        size_t offset = layout.innerStruct.offset;
        for (const auto& field : mFields) {
            if (mStyle == STYLE_SAFE_UNION) {
                out << "case hidl_discriminator."
                    << field->name()
                    << ": ";

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

                    out << "break;\n";
                }).endl();
            } else {
                size_t fieldAlign, fieldSize;
                field->type().getAlignmentAndSize(&fieldAlign, &fieldSize);

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

        if (mStyle == STYLE_SAFE_UNION) {
            out << "default: ";
            out.block([&] { emitJavaSafeUnionUnknownDiscriminatorError(out, true /*fatal*/); })
                .endl();

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

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

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

    const std::string name = "obj";
    if (isReader) {
        out << "const " << space << definedName() << " &" << name << ",\n";
        out << "const ::android::hardware::Parcel &parcel,\n";
    } else {
        out << "const " << space << definedName() << " &" << 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";

    if (mStyle == STYLE_SAFE_UNION) {
        out << "switch (" << name << ".getDiscriminator()) {\n";
        out.indent();
    }

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

        if (mStyle == STYLE_SAFE_UNION) {
            out << "case " << fullName() << "::hidl_discriminator::"
                << field->name() << ": {\n";
            out.indent();
        }

        const std::string fieldName = (mStyle == STYLE_SAFE_UNION)
                                        ? (name + "." + field->name() + "()")
                                        : (name + "." + field->name());

        const std::string fieldOffset = (mStyle == STYLE_SAFE_UNION)
                                        ? (name + ".hidl_getUnionOffset() " +
                                           "/* safe_union: union offset into struct */")
                                        : ("offsetof(" + fullName() + ", " + field->name() + ")");

        field->type().emitReaderWriterEmbedded(
                out,
                0 /* depth */,
                fieldName,
                field->name() /* sanitizedName */,
                false /* nameIsPointer */,
                "parcel",
                !isReader /* parcelObjIsPointer */,
                isReader,
                ErrorMode_Return,
                "parentHandle",
                "parentOffset + " + fieldOffset);

        if (mStyle == STYLE_SAFE_UNION) {
            out << "break;\n";
            out.unindent();
            out << "}\n";
        }
    }

    if (mStyle == STYLE_SAFE_UNION) {
        out << "default: { break; }\n";
        out.unindent();
        out << "}\n";
    }

    out << "return _hidl_err;\n";

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

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

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

    return false;
}

bool CompoundType::resultNeedsDeref() const {
    return !containsInterface() ;
}

void 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;
            }
            case STYLE_SAFE_UNION:
            {
                out << "sub_safe_union: {\n";
                break;
            }
            default:
            {
                CHECK(!"Should not be here");
            }
        }
        out.indent();
        type->emitVtsTypeDeclarations(out);
        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;
            }
            case STYLE_SAFE_UNION:
            {
                out << "safe_union_value: {\n";
                break;
            }
            default:
            {
                CHECK(!"Should not be here");
            }
        }
        out.indent();
        out << "name: \"" << field->name() << "\"\n";
        field->type().emitVtsAttributeType(out);
        out.unindent();
        out << "}\n";
    }
}

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

bool CompoundType::deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const {
    if (mStyle == STYLE_UNION) {
        return false;
    }

    for (const auto* field : mFields) {
        if (!field->get()->isJavaCompatible(visited)) {
            return false;
        }
    }

    return Scope::deepIsJavaCompatible(visited);
}

bool CompoundType::deepContainsPointer(std::unordered_set<const Type*>* visited) const {
    for (const auto* field : mFields) {
        if (field->get()->containsPointer(visited)) {
            return true;
        }
    }

    return Scope::deepContainsPointer(visited);
}

void CompoundType::getAlignmentAndSize(size_t *align, size_t *size) const {
    CompoundLayout layout = getCompoundAlignmentAndSize();
    *align = layout.overall.align;
    *size = layout.overall.size;
}

CompoundType::CompoundLayout CompoundType::getCompoundAlignmentAndSize() const {
    CompoundLayout compoundLayout;

    // Local aliases for convenience
    Layout& overall = compoundLayout.overall;
    Layout& innerStruct = compoundLayout.innerStruct;
    Layout& discriminator = compoundLayout.discriminator;

    if (mStyle == STYLE_SAFE_UNION) {
        getUnionDiscriminatorType()->getAlignmentAndSize(
            &(discriminator.align), &(discriminator.size));

        innerStruct.offset = discriminator.size;
    }

    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 lPad = Layout::getPad(innerStruct.size, fieldAlign);

        innerStruct.size = (mStyle == STYLE_STRUCT)
                            ? (innerStruct.size + lPad + fieldSize)
                            : std::max(innerStruct.size, fieldSize);

        innerStruct.align = std::max(innerStruct.align, fieldAlign);
    }

    // Pad the inner structure's size
    innerStruct.size += Layout::getPad(innerStruct.size,
                                       innerStruct.align);

    // Compute its final offset
    innerStruct.offset += Layout::getPad(innerStruct.offset,
                                         innerStruct.align);

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

    overall.size = innerStruct.offset + innerStruct.size;

    // Pad the overall structure's size
    overall.align = std::max(innerStruct.align, discriminator.align);
    overall.size += Layout::getPad(overall.size, overall.align);

    if (mStyle != STYLE_SAFE_UNION) {
        CHECK(overall.offset == innerStruct.offset) << overall.offset << " " << innerStruct.offset;
        CHECK(overall.align == innerStruct.align) << overall.align << " " << innerStruct.align;
        CHECK(overall.size == innerStruct.size) << overall.size << " " << innerStruct.size;
    }

    return compoundLayout;
}

void CompoundType::emitPaddingZero(Formatter& out, size_t offset, size_t size) const {
    if (size > 0) {
        out << "::std::memset(reinterpret_cast<uint8_t*>(this) + " << offset << ", 0, " << size
            << ");\n";
    } else {
        out << "// no padding to zero starting at offset " << offset << "\n";
    }
}

std::unique_ptr<ScalarType> CompoundType::getUnionDiscriminatorType() const {
    static const std::vector<std::pair<int, ScalarType::Kind> > scalars {
        {8, ScalarType::Kind::KIND_UINT8},
        {16, ScalarType::Kind::KIND_UINT16},
        {32, ScalarType::Kind::KIND_UINT32},
    };

    size_t numFields = mFields.size();
    auto kind = ScalarType::Kind::KIND_UINT64;

    for (const auto& scalar : scalars) {
        if (numFields <= (1ULL << scalar.first)) {
            kind = scalar.second; break;
        }
    }

    return std::unique_ptr<ScalarType>(new ScalarType(kind, nullptr));
}

size_t CompoundType::Layout::getPad(size_t offset, size_t align) {
    size_t remainder = offset % align;
    return (remainder > 0) ? (align - remainder) : 0;
}

}  // namespace android

