Home | History | Annotate | Download | only in hidl
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "EnumType.h"
     18 
     19 #include <hidl-util/Formatter.h>
     20 #include <inttypes.h>
     21 #include <iostream>
     22 #include <unordered_map>
     23 
     24 #include "Annotation.h"
     25 #include "Location.h"
     26 #include "ScalarType.h"
     27 
     28 namespace android {
     29 
     30 EnumType::EnumType(const char* localName, const FQName& fullName, const Location& location,
     31                    const Reference<Type>& storageType, Scope* parent)
     32     : Scope(localName, fullName, location, parent), mValues(), mStorageType(storageType) {}
     33 
     34 const Type *EnumType::storageType() const {
     35     return mStorageType.get();
     36 }
     37 
     38 const std::vector<EnumValue *> &EnumType::values() const {
     39     return mValues;
     40 }
     41 
     42 void EnumType::forEachValueFromRoot(const std::function<void(EnumValue*)> f) const {
     43     std::vector<const EnumType*> chain = typeChain();
     44     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
     45         const auto& type = *it;
     46         for (EnumValue* v : type->values()) {
     47             f(v);
     48         }
     49     }
     50 }
     51 
     52 void EnumType::addValue(EnumValue* value) {
     53     CHECK(value != nullptr);
     54     mValues.push_back(value);
     55 }
     56 
     57 status_t EnumType::resolveInheritance() {
     58     const EnumType* prevType = nullptr;
     59     EnumValue* prevValue = nullptr;
     60 
     61     for (const auto* type : superTypeChain()) {
     62         if (!type->values().empty()) {
     63             prevType = type;
     64             prevValue = type->values().back();
     65             break;
     66         }
     67     }
     68 
     69     for (auto* value : mValues) {
     70         value->autofill(prevType, prevValue, mStorageType->resolveToScalarType());
     71         prevType = this;
     72         prevValue = value;
     73     }
     74 
     75     return Scope::resolveInheritance();
     76 }
     77 
     78 std::vector<const Reference<Type>*> EnumType::getReferences() const {
     79     return {&mStorageType};
     80 }
     81 
     82 std::vector<const ConstantExpression*> EnumType::getConstantExpressions() const {
     83     std::vector<const ConstantExpression*> ret;
     84     for (const auto* value : mValues) {
     85         ret.push_back(value->constExpr());
     86     }
     87     return ret;
     88 }
     89 
     90 status_t EnumType::validate() const {
     91     CHECK(getSubTypes().empty());
     92 
     93     if (!isElidableType() || !mStorageType->isValidEnumStorageType()) {
     94         std::cerr << "ERROR: Invalid enum storage type (" << (mStorageType)->typeName()
     95                   << ") specified at " << mStorageType.location() << "\n";
     96         return UNKNOWN_ERROR;
     97     }
     98 
     99     status_t err = validateUniqueNames();
    100     if (err != OK) return err;
    101 
    102     return Scope::validate();
    103 }
    104 
    105 status_t EnumType::validateUniqueNames() const {
    106     std::unordered_map<std::string, const EnumType*> registeredValueNames;
    107     for (const auto* type : superTypeChain()) {
    108         for (const auto* enumValue : type->mValues) {
    109             // No need to check super value uniqueness
    110             registeredValueNames[enumValue->name()] = type;
    111         }
    112     }
    113 
    114     for (const auto* value : mValues) {
    115         auto registered = registeredValueNames.find(value->name());
    116 
    117         if (registered != registeredValueNames.end()) {
    118             const EnumType* definedInType = registered->second;
    119 
    120             if (definedInType == this) {
    121                 // Defined in this enum
    122                 std::cerr << "ERROR: Redefinition of value '" << value->name() << "'";
    123             } else {
    124                 // Defined in super enum
    125                 std::cerr << "ERROR: Redefinition of value '" << value->name()
    126                           << "' defined in enum '" << definedInType->fullName() << "'";
    127             }
    128             std::cerr << " at " << value->location() << "\n";
    129             return UNKNOWN_ERROR;
    130         }
    131 
    132         registeredValueNames[value->name()] = this;
    133     }
    134 
    135     return OK;
    136 }
    137 
    138 bool EnumType::isElidableType() const {
    139     return mStorageType->isElidableType();
    140 }
    141 
    142 const ScalarType *EnumType::resolveToScalarType() const {
    143     return mStorageType->resolveToScalarType();
    144 }
    145 
    146 std::string EnumType::typeName() const {
    147     return "enum " + localName();
    148 }
    149 
    150 bool EnumType::isEnum() const {
    151     return true;
    152 }
    153 
    154 bool EnumType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) const {
    155     return true;
    156 }
    157 
    158 std::string EnumType::getCppType(StorageMode,
    159                                  bool /* specifyNamespaces */) const {
    160     return fullName();
    161 }
    162 
    163 std::string EnumType::getJavaType(bool forInitializer) const {
    164     return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
    165 }
    166 
    167 std::string EnumType::getJavaSuffix() const {
    168     return mStorageType->resolveToScalarType()->getJavaSuffix();
    169 }
    170 
    171 std::string EnumType::getJavaWrapperType() const {
    172     return mStorageType->resolveToScalarType()->getJavaWrapperType();
    173 }
    174 
    175 std::string EnumType::getVtsType() const {
    176     return "TYPE_ENUM";
    177 }
    178 
    179 std::string EnumType::getBitfieldCppType(StorageMode /* mode */, bool specifyNamespaces) const {
    180     const std::string space = specifyNamespaces ? "::android::hardware::" : "";
    181     return space + "hidl_bitfield<" + (specifyNamespaces ? fullName() : localName()) + ">";
    182 }
    183 
    184 std::string EnumType::getBitfieldJavaType(bool forInitializer) const {
    185     return resolveToScalarType()->getJavaType(forInitializer);
    186 }
    187 
    188 std::string EnumType::getBitfieldJavaWrapperType() const {
    189     return resolveToScalarType()->getJavaWrapperType();
    190 }
    191 
    192 LocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
    193     std::vector<const EnumType*> chain = typeChain();
    194     for (auto it = chain.begin(); it != chain.end(); ++it) {
    195         const auto &type = *it;
    196         for(EnumValue *v : type->values()) {
    197             if(v->name() == name) {
    198                 return v;
    199             }
    200         }
    201     }
    202     return nullptr;
    203 }
    204 
    205 void EnumType::emitReaderWriter(
    206         Formatter &out,
    207         const std::string &name,
    208         const std::string &parcelObj,
    209         bool parcelObjIsPointer,
    210         bool isReader,
    211         ErrorMode mode) const {
    212     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    213     CHECK(scalarType != NULL);
    214 
    215     scalarType->emitReaderWriterWithCast(
    216             out,
    217             name,
    218             parcelObj,
    219             parcelObjIsPointer,
    220             isReader,
    221             mode,
    222             true /* needsCast */);
    223 }
    224 
    225 void EnumType::emitJavaFieldReaderWriter(
    226         Formatter &out,
    227         size_t depth,
    228         const std::string &parcelName,
    229         const std::string &blobName,
    230         const std::string &fieldName,
    231         const std::string &offset,
    232         bool isReader) const {
    233     return mStorageType->emitJavaFieldReaderWriter(
    234             out, depth, parcelName, blobName, fieldName, offset, isReader);
    235 }
    236 
    237 void EnumType::emitTypeDeclarations(Formatter& out) const {
    238     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    239     CHECK(scalarType != nullptr);
    240 
    241     const std::string storageType = scalarType->getCppStackType();
    242 
    243     out << "enum class "
    244         << localName()
    245         << " : "
    246         << storageType
    247         << " {\n";
    248 
    249     out.indent();
    250 
    251     std::vector<const EnumType*> chain = typeChain();
    252 
    253     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
    254         const auto &type = *it;
    255 
    256         for (const auto &entry : type->values()) {
    257             entry->emitDocComment(out);
    258 
    259             out << entry->name();
    260 
    261             std::string value = entry->cppValue(scalarType->getKind());
    262             CHECK(!value.empty()); // use autofilled values for c++.
    263             out << " = " << value;
    264 
    265             out << ",";
    266 
    267             std::string comment = entry->comment();
    268             if (!comment.empty()) {
    269                 out << " // " << comment;
    270             }
    271 
    272             out << "\n";
    273         }
    274     }
    275 
    276     out.unindent();
    277     out << "};\n\n";
    278 }
    279 
    280 void EnumType::emitTypeForwardDeclaration(Formatter& out) const {
    281     const ScalarType* scalarType = mStorageType->resolveToScalarType();
    282     const std::string storageType = scalarType->getCppStackType();
    283 
    284     out << "enum class " << localName() << " : " << storageType << ";\n";
    285 }
    286 
    287 void EnumType::emitIteratorDeclaration(Formatter& out) const {
    288     size_t elementCount = 0;
    289     for (const auto* type : typeChain()) {
    290         elementCount += type->mValues.size();
    291     }
    292 
    293     out << "template<> struct hidl_enum_iterator<" << getCppStackType() << ">\n";
    294     out.block([&] {
    295         out << "const " << getCppStackType() << "* begin() { return static_begin(); }\n";
    296         out << "const " << getCppStackType() << "* end() { return begin() + " << elementCount
    297             << "; }\n";
    298         out << "private:\n";
    299         out << "static const " << getCppStackType() << "* static_begin() ";
    300         out.block([&] {
    301             out << "static const " << getCppStackType() << " kVals[" << elementCount << "] ";
    302             out.block([&] {
    303                 auto enumerators = typeChain();
    304                 std::reverse(enumerators.begin(), enumerators.end());
    305                 for (const auto* type : enumerators) {
    306                     for (const auto* enumValue : type->mValues) {
    307                         out << fullName() << "::" << enumValue->name() << ",\n";
    308                     }
    309                 }
    310             }) << ";\n";
    311             out << "return &kVals[0];\n";
    312         });
    313     }) << ";\n\n";
    314 }
    315 
    316 void EnumType::emitEnumBitwiseOperator(
    317         Formatter &out,
    318         bool lhsIsEnum,
    319         bool rhsIsEnum,
    320         const std::string &op) const {
    321     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    322     CHECK(scalarType != nullptr);
    323 
    324     const std::string storageType = scalarType->getCppStackType();
    325 
    326     out << "constexpr "
    327         << storageType
    328         << " operator"
    329         << op
    330         << "(const "
    331         << (lhsIsEnum ? fullName() : storageType)
    332         << " lhs, const "
    333         << (rhsIsEnum ? fullName() : storageType)
    334         << " rhs) {\n";
    335 
    336     out.indent([&] {
    337         out << "return static_cast<"
    338             << storageType
    339             << ">(";
    340 
    341         if (lhsIsEnum) {
    342             out << "static_cast<"
    343                 << storageType
    344                 << ">(lhs)";
    345         } else {
    346             out << "lhs";
    347         }
    348         out << " " << op << " ";
    349         if (rhsIsEnum) {
    350             out << "static_cast<"
    351                 << storageType
    352                 << ">(rhs)";
    353         } else {
    354             out << "rhs";
    355         }
    356         out << ");\n";
    357     });
    358 
    359     out << "}\n\n";
    360 }
    361 
    362 void EnumType::emitBitFieldBitwiseAssignmentOperator(
    363         Formatter &out,
    364         const std::string &op) const {
    365     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    366     CHECK(scalarType != nullptr);
    367 
    368     const std::string storageType = scalarType->getCppStackType();
    369 
    370     out << "constexpr " << storageType << " &operator" << op << "=("
    371         << storageType << "& v, const " << fullName() << " e) {\n";
    372 
    373     out.indent([&] {
    374         out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
    375         out << "return v;\n";
    376     });
    377 
    378     out << "}\n\n";
    379 }
    380 
    381 void EnumType::emitGlobalTypeDeclarations(Formatter& out) const {
    382     out << "namespace android {\n";
    383     out << "namespace hardware {\n";
    384 
    385     emitIteratorDeclaration(out);
    386 
    387     out << "}  // namespace hardware\n";
    388     out << "}  // namespace android\n";
    389 }
    390 
    391 void EnumType::emitPackageTypeDeclarations(Formatter& out) const {
    392     emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
    393     emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
    394     emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "|");
    395     emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
    396     emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
    397     emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "&");
    398 
    399     emitBitFieldBitwiseAssignmentOperator(out, "|");
    400     emitBitFieldBitwiseAssignmentOperator(out, "&");
    401 
    402     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    403     CHECK(scalarType != NULL);
    404 
    405     out << "template<typename>\n"
    406         << "static inline std::string toString(" << resolveToScalarType()->getCppArgumentType()
    407         << " o);\n";
    408     out << "template<>\n"
    409         << "inline std::string toString<" << getCppStackType() << ">("
    410         << scalarType->getCppArgumentType() << " o) ";
    411     out.block([&] {
    412         // include toHexString for scalar types
    413         out << "using ::android::hardware::details::toHexString;\n"
    414             << "std::string os;\n"
    415             << getBitfieldCppType(StorageMode_Stack) << " flipped = 0;\n"
    416             << "bool first = true;\n";
    417         forEachValueFromRoot([&](EnumValue* value) {
    418             std::string valueName = fullName() + "::" + value->name();
    419             out.sIf("(o & " + valueName + ")" +
    420                     " == static_cast<" + scalarType->getCppStackType() +
    421                     ">(" + valueName + ")", [&] {
    422                 out << "os += (first ? \"\" : \" | \");\n"
    423                     << "os += \"" << value->name() << "\";\n"
    424                     << "first = false;\n"
    425                     << "flipped |= " << valueName << ";\n";
    426             }).endl();
    427         });
    428         // put remaining bits
    429         out.sIf("o != flipped", [&] {
    430             out << "os += (first ? \"\" : \" | \");\n";
    431             scalarType->emitHexDump(out, "os", "o & (~flipped)");
    432         });
    433         out << "os += \" (\";\n";
    434         scalarType->emitHexDump(out, "os", "o");
    435         out << "os += \")\";\n";
    436 
    437         out << "return os;\n";
    438     }).endl().endl();
    439 
    440     out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
    441 
    442     out.block([&] {
    443         out << "using ::android::hardware::details::toHexString;\n";
    444         forEachValueFromRoot([&](EnumValue* value) {
    445             out.sIf("o == " + fullName() + "::" + value->name(), [&] {
    446                 out << "return \"" << value->name() << "\";\n";
    447             }).endl();
    448         });
    449         out << "std::string os;\n";
    450         scalarType->emitHexDump(out, "os",
    451             "static_cast<" + scalarType->getCppStackType() + ">(o)");
    452         out << "return os;\n";
    453     }).endl().endl();
    454 }
    455 
    456 void EnumType::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
    457     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    458     CHECK(scalarType != NULL);
    459 
    460     out << "public "
    461         << (atTopLevel ? "" : "static ")
    462         << "final class "
    463         << localName()
    464         << " {\n";
    465 
    466     out.indent();
    467 
    468     const std::string typeName =
    469         scalarType->getJavaType(false /* forInitializer */);
    470 
    471     std::vector<const EnumType*> chain = typeChain();
    472 
    473     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
    474         const auto &type = *it;
    475 
    476         for (const auto &entry : type->values()) {
    477             entry->emitDocComment(out);
    478 
    479             out << "public static final "
    480                 << typeName
    481                 << " "
    482                 << entry->name()
    483                 << " = ";
    484 
    485             // javaValue will make the number signed.
    486             std::string value = entry->javaValue(scalarType->getKind());
    487             CHECK(!value.empty()); // use autofilled values for java.
    488             out << value;
    489 
    490             out << ";";
    491 
    492             std::string comment = entry->comment();
    493             if (!comment.empty()) {
    494                 out << " // " << comment;
    495             }
    496 
    497             out << "\n";
    498         }
    499     }
    500 
    501     out << "public static final String toString("
    502         << typeName << " o) ";
    503     out.block([&] {
    504         forEachValueFromRoot([&](EnumValue* value) {
    505             out.sIf("o == " + value->name(), [&] {
    506                 out << "return \"" << value->name() << "\";\n";
    507             }).endl();
    508         });
    509         out << "return \"0x\" + ";
    510         scalarType->emitConvertToJavaHexString(out, "o");
    511         out << ";\n";
    512     }).endl();
    513 
    514     auto bitfieldType = getBitfieldJavaType(false /* forInitializer */);
    515     auto bitfieldWrapperType = getBitfieldJavaWrapperType();
    516     out << "\n"
    517         << "public static final String dumpBitfield("
    518         << bitfieldType << " o) ";
    519     out.block([&] {
    520         out << "java.util.ArrayList<String> list = new java.util.ArrayList<>();\n";
    521         out << bitfieldType << " flipped = 0;\n";
    522         forEachValueFromRoot([&](EnumValue* value) {
    523             if (value->constExpr()->castSizeT() == 0) {
    524                 out << "list.add(\"" << value->name() << "\"); // " << value->name() << " == 0\n";
    525                 return;  // continue to next value
    526             }
    527             out.sIf("(o & " + value->name() + ") == " + value->name(), [&] {
    528                 out << "list.add(\"" << value->name() << "\");\n";
    529                 out << "flipped |= " << value->name() << ";\n";
    530             }).endl();
    531         });
    532         // put remaining bits
    533         out.sIf("o != flipped", [&] {
    534             out << "list.add(\"0x\" + ";
    535             scalarType->emitConvertToJavaHexString(out, "o & (~flipped)");
    536             out << ");\n";
    537         }).endl();
    538         out << "return String.join(\" | \", list);\n";
    539     }).endl().endl();
    540 
    541     out.unindent();
    542     out << "};\n\n";
    543 }
    544 
    545 void EnumType::emitVtsTypeDeclarations(Formatter& out) const {
    546     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    547 
    548     out << "name: \"" << fullName() << "\"\n";
    549     out << "type: " << getVtsType() << "\n";
    550     out << "enum_value: {\n";
    551     out.indent();
    552 
    553     out << "scalar_type: \""
    554         << scalarType->getVtsScalarType()
    555         << "\"\n\n";
    556     std::vector<const EnumType*> chain = typeChain();
    557 
    558     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
    559         const auto &type = *it;
    560 
    561         for (const auto &entry : type->values()) {
    562             out << "enumerator: \"" << entry->name() << "\"\n";
    563             out << "scalar_value: {\n";
    564             out.indent();
    565             // use autofilled values for vts.
    566             std::string value = entry->value(scalarType->getKind());
    567             CHECK(!value.empty());
    568             out << mStorageType->resolveToScalarType()->getVtsScalarType()
    569                 << ": "
    570                 << value
    571                 << "\n";
    572             out.unindent();
    573             out << "}\n";
    574         }
    575     }
    576 
    577     out.unindent();
    578     out << "}\n";
    579 }
    580 
    581 void EnumType::emitVtsAttributeType(Formatter& out) const {
    582     out << "type: " << getVtsType() << "\n";
    583     out << "predefined_type: \"" << fullName() << "\"\n";
    584 }
    585 
    586 void EnumType::emitJavaDump(
    587         Formatter &out,
    588         const std::string &streamName,
    589         const std::string &name) const {
    590     out << streamName << ".append(" << fqName().javaName() << ".toString("
    591         << name << "));\n";
    592 }
    593 
    594 std::vector<const EnumType*> EnumType::typeChain() const {
    595     std::vector<const EnumType*> types;
    596     for (const EnumType* type = this; type != nullptr;) {
    597         types.push_back(type);
    598 
    599         const Type* superType = type->storageType();
    600         if (superType != nullptr && superType->isEnum()) {
    601             type = static_cast<const EnumType*>(superType);
    602         } else {
    603             type = nullptr;
    604         }
    605     }
    606 
    607     return types;
    608 }
    609 
    610 std::vector<const EnumType*> EnumType::superTypeChain() const {
    611     const Type* superType = storageType();
    612     if (superType == nullptr || !superType->isEnum()) {
    613         return {};
    614     }
    615     return static_cast<const EnumType*>(superType)->typeChain();
    616 }
    617 
    618 void EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
    619     mStorageType->getAlignmentAndSize(align, size);
    620 }
    621 
    622 const Annotation *EnumType::findExportAnnotation() const {
    623     for (const auto &annotation : annotations()) {
    624         if (annotation->name() == "export") {
    625             return annotation;
    626         }
    627     }
    628 
    629     return nullptr;
    630 }
    631 
    632 void EnumType::appendToExportedTypesVector(
    633         std::vector<const Type *> *exportedTypes) const {
    634     if (findExportAnnotation() != nullptr) {
    635         exportedTypes->push_back(this);
    636     }
    637 }
    638 
    639 void EnumType::emitExportedHeader(Formatter& out, bool forJava) const {
    640     const Annotation *annotation = findExportAnnotation();
    641     CHECK(annotation != nullptr);
    642 
    643     std::string name = localName();
    644 
    645     const AnnotationParam *nameParam = annotation->getParam("name");
    646     if (nameParam != nullptr) {
    647         name = nameParam->getSingleString();
    648     }
    649 
    650     bool exportParent = true;
    651     const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
    652     if (exportParentParam != nullptr) {
    653         exportParent = exportParentParam->getSingleBool();
    654     }
    655 
    656     std::string valuePrefix;
    657     const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
    658     if (prefixParam != nullptr) {
    659         valuePrefix = prefixParam->getSingleString();
    660     }
    661 
    662     std::string valueSuffix;
    663     const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
    664     if (suffixParam != nullptr) {
    665         valueSuffix = suffixParam->getSingleString();
    666     }
    667 
    668     const ScalarType *scalarType = mStorageType->resolveToScalarType();
    669     CHECK(scalarType != nullptr);
    670 
    671     std::vector<const EnumType *> chain;
    672     if (exportParent) {
    673         chain = typeChain();
    674     } else {
    675         chain = { this };
    676     }
    677 
    678     if (forJava) {
    679         if (!name.empty()) {
    680             out << "public final class "
    681                 << name
    682                 << " {\n";
    683 
    684             out.indent();
    685         } else {
    686             out << "// Values declared in " << localName() << " follow.\n";
    687         }
    688 
    689         const std::string typeName =
    690             scalarType->getJavaType(false /* forInitializer */);
    691 
    692         for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
    693             const auto &type = *it;
    694 
    695             for (const auto &entry : type->values()) {
    696                 out << "public static final "
    697                     << typeName
    698                     << " "
    699                     << valuePrefix
    700                     << entry->name()
    701                     << valueSuffix
    702                     << " = ";
    703 
    704                 // javaValue will make the number signed.
    705                 std::string value = entry->javaValue(scalarType->getKind());
    706                 CHECK(!value.empty()); // use autofilled values for java.
    707                 out << value;
    708 
    709                 out << ";";
    710 
    711                 std::string comment = entry->comment();
    712                 if (!comment.empty()) {
    713                     out << " // " << comment;
    714                 }
    715 
    716                 out << "\n";
    717             }
    718         }
    719 
    720         if (!name.empty()) {
    721             out.unindent();
    722             out << "};\n";
    723         }
    724         out << "\n";
    725 
    726         return;
    727     }
    728 
    729     if (!name.empty()) {
    730         out << "typedef ";
    731     }
    732 
    733     out << "enum {\n";
    734 
    735     out.indent();
    736 
    737     for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
    738         const auto &type = *it;
    739 
    740         for (const auto &entry : type->values()) {
    741             out << valuePrefix << entry->name() << valueSuffix;
    742 
    743             std::string value = entry->cppValue(scalarType->getKind());
    744             CHECK(!value.empty()); // use autofilled values for c++.
    745             out << " = " << value;
    746 
    747             out << ",";
    748 
    749             std::string comment = entry->comment();
    750             if (!comment.empty()) {
    751                 out << " // " << comment;
    752             }
    753 
    754             out << "\n";
    755         }
    756     }
    757 
    758     out.unindent();
    759     out << "}";
    760 
    761     if (!name.empty()) {
    762         out << " " << name;
    763     }
    764 
    765     out << ";\n\n";
    766 }
    767 
    768 ////////////////////////////////////////////////////////////////////////////////
    769 
    770 EnumValue::EnumValue(const char* name, ConstantExpression* value, const Location& location)
    771     : mName(name), mValue(value), mLocation(location), mIsAutoFill(false) {}
    772 
    773 std::string EnumValue::name() const {
    774     return mName;
    775 }
    776 
    777 std::string EnumValue::value(ScalarType::Kind castKind) const {
    778     CHECK(mValue != nullptr);
    779     return mValue->value(castKind);
    780 }
    781 
    782 std::string EnumValue::cppValue(ScalarType::Kind castKind) const {
    783     CHECK(mValue != nullptr);
    784     return mValue->cppValue(castKind);
    785 }
    786 std::string EnumValue::javaValue(ScalarType::Kind castKind) const {
    787     CHECK(mValue != nullptr);
    788     return mValue->javaValue(castKind);
    789 }
    790 
    791 std::string EnumValue::comment() const {
    792     CHECK(mValue != nullptr);
    793     if (mValue->descriptionIsTrivial()) return "";
    794     return mValue->description();
    795 }
    796 
    797 ConstantExpression *EnumValue::constExpr() const {
    798     CHECK(mValue != nullptr);
    799     return mValue;
    800 }
    801 
    802 void EnumValue::autofill(const EnumType* prevType, EnumValue* prevValue, const ScalarType* type) {
    803     // Value is defined explicitly
    804     if (mValue != nullptr) return;
    805 
    806     CHECK((prevType == nullptr) == (prevValue == nullptr));
    807 
    808     mIsAutoFill = true;
    809     if (prevValue == nullptr) {
    810         mValue = ConstantExpression::Zero(type->getKind()).release();
    811     } else {
    812         std::string description = prevType->fullName() + "." + prevValue->name() + " implicitly";
    813         auto* prevReference = new ReferenceConstantExpression(
    814             Reference<LocalIdentifier>(prevValue, mLocation), description);
    815         mValue = prevReference->addOne(type->getKind()).release();
    816     }
    817 }
    818 
    819 bool EnumValue::isAutoFill() const {
    820     return mIsAutoFill;
    821 }
    822 
    823 bool EnumValue::isEnumValue() const {
    824     return true;
    825 }
    826 
    827 const Location& EnumValue::location() const {
    828     return mLocation;
    829 }
    830 
    831 ////////////////////////////////////////////////////////////////////////////////
    832 
    833 BitFieldType::BitFieldType(Scope* parent) : TemplatedType(parent) {}
    834 
    835 bool BitFieldType::isBitField() const {
    836     return true;
    837 }
    838 
    839 const EnumType* BitFieldType::getElementEnumType() const {
    840     CHECK(mElementType.get() != nullptr && mElementType->isEnum());
    841     return static_cast<const EnumType*>(mElementType.get());
    842 }
    843 
    844 std::string BitFieldType::templatedTypeName() const {
    845     return "mask";
    846 }
    847 
    848 bool BitFieldType::isCompatibleElementType(const Type* elementType) const {
    849     return elementType->isEnum();
    850 }
    851 
    852 const ScalarType *BitFieldType::resolveToScalarType() const {
    853     return mElementType->resolveToScalarType();
    854 }
    855 
    856 std::string BitFieldType::getCppType(StorageMode mode,
    857                                  bool specifyNamespaces) const {
    858     return getElementEnumType()->getBitfieldCppType(mode, specifyNamespaces);
    859 }
    860 
    861 std::string BitFieldType::getJavaType(bool forInitializer) const {
    862     return getElementEnumType()->getBitfieldJavaType(forInitializer);
    863 }
    864 
    865 std::string BitFieldType::getJavaSuffix() const {
    866     return resolveToScalarType()->getJavaSuffix();
    867 }
    868 
    869 std::string BitFieldType::getJavaWrapperType() const {
    870     return getElementEnumType()->getBitfieldJavaWrapperType();
    871 }
    872 
    873 std::string BitFieldType::getVtsType() const {
    874     return "TYPE_MASK";
    875 }
    876 
    877 bool BitFieldType::isElidableType() const {
    878     return resolveToScalarType()->isElidableType();
    879 }
    880 
    881 bool BitFieldType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
    882     return resolveToScalarType()->canCheckEquality(visited);
    883 }
    884 
    885 void BitFieldType::emitVtsAttributeType(Formatter& out) const {
    886     out << "type: " << getVtsType() << "\n";
    887     out << "scalar_type: \""
    888         << mElementType->resolveToScalarType()->getVtsScalarType()
    889         << "\"\n";
    890     out << "predefined_type: \"" << static_cast<const NamedType*>(mElementType.get())->fullName()
    891         << "\"\n";
    892 }
    893 
    894 void BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
    895     resolveToScalarType()->getAlignmentAndSize(align, size);
    896 }
    897 
    898 void BitFieldType::emitReaderWriter(
    899         Formatter &out,
    900         const std::string &name,
    901         const std::string &parcelObj,
    902         bool parcelObjIsPointer,
    903         bool isReader,
    904         ErrorMode mode) const {
    905     resolveToScalarType()->emitReaderWriterWithCast(
    906             out,
    907             name,
    908             parcelObj,
    909             parcelObjIsPointer,
    910             isReader,
    911             mode,
    912             true /* needsCast */);
    913 }
    914 
    915 const EnumType* BitFieldType::getEnumType() const {
    916     CHECK(mElementType->isEnum());
    917     return static_cast<const EnumType*>(mElementType.get());
    918 }
    919 
    920 // a bitfield maps to the underlying scalar type in C++, so operator<< is
    921 // already defined. We can still emit useful information if the bitfield is
    922 // in a struct / union by overriding emitDump as below.
    923 void BitFieldType::emitDump(
    924         Formatter &out,
    925         const std::string &streamName,
    926         const std::string &name) const {
    927     out << streamName << " += "<< getEnumType()->fqName().cppNamespace()
    928         << "::toString<" << getEnumType()->getCppStackType()
    929         << ">(" << name << ");\n";
    930 }
    931 
    932 void BitFieldType::emitJavaDump(
    933         Formatter &out,
    934         const std::string &streamName,
    935         const std::string &name) const {
    936     out << streamName << ".append(" << getEnumType()->fqName().javaName() << ".dumpBitfield("
    937         << name << "));\n";
    938 }
    939 
    940 void BitFieldType::emitJavaFieldReaderWriter(
    941         Formatter &out,
    942         size_t depth,
    943         const std::string &parcelName,
    944         const std::string &blobName,
    945         const std::string &fieldName,
    946         const std::string &offset,
    947         bool isReader) const {
    948     return resolveToScalarType()->emitJavaFieldReaderWriter(
    949             out, depth, parcelName, blobName, fieldName, offset, isReader);
    950 }
    951 
    952 }  // namespace android
    953 
    954