EnumType.cpp revision a15f8091d2d4312a16edfcebccb13b3ea4782c29
11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/*
21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project
31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License.
61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at
71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software
111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and
141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License.
151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */
161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber
17c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber#include "EnumType.h"
18c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
19cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov#include <hidl-util/Formatter.h>
20cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov#include <inttypes.h>
21cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov#include <unordered_map>
22cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
23019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber#include "Annotation.h"
24505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov#include "Location.h"
25881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber#include "ScalarType.h"
26c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
27c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android {
28c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
29505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur IskhakovEnumType::EnumType(const char* localName, const Location& location,
30505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov                   const Reference<Type>& storageType, Scope* parent)
31cb0ba5213057de39aa164f2f9a3691370bcbfe6bTimur Iskhakov    : Scope(localName, location, parent), mValues(), mStorageType(storageType) {
32505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov    BitFieldType* bitfieldType = new BitFieldType();
33505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov    bitfieldType->setElementType(Reference<Type>(this, Location()));
34505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov    mBitfieldType.set(bitfieldType);
35c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}
36c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
378d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst Type *EnumType::storageType() const {
388d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return mStorageType;
398d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
408d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
418d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst std::vector<EnumValue *> &EnumType::values() const {
42f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValues;
43f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
44f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
45cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovvoid EnumType::addValue(EnumValue* value) {
46f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(value != nullptr);
47cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    mValues.push_back(value);
48cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
49f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
50cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumType::resolveInheritance() {
51cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    const EnumType* prevType = nullptr;
52cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    EnumValue* prevValue = nullptr;
53cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
54cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (const auto* type : superTypeChain()) {
55cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        if (!type->values().empty()) {
56cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            prevType = type;
57cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            prevValue = type->values().back();
58f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            break;
59f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
60f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
61f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
62cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (auto* value : mValues) {
63cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        value->autofill(prevType, prevValue, mStorageType->resolveToScalarType());
64cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        prevType = this;
65cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        prevValue = value;
66cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
67cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
68cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return Scope::resolveInheritance();
69cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
70cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
71cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumType::evaluate() {
72cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    status_t err = mStorageType->callForReference(&Type::evaluate);
73cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (err != OK) return err;
74cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
75cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (auto* value : mValues) {
76cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        err = value->evaluate();
77cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        if (err != OK) return err;
78cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
79cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return Scope::evaluate();
80cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
81cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
82cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumType::validate() const {
83a15f8091d2d4312a16edfcebccb13b3ea4782c29Timur Iskhakov    CHECK(getSubTypes().empty());
84a15f8091d2d4312a16edfcebccb13b3ea4782c29Timur Iskhakov
85cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    status_t err = mStorageType->callForReference(&Type::validate);
86cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (err != OK) return err;
87cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
88cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (auto* value : mValues) {
89cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        err = value->validate();
90cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        if (err != OK) return err;
91cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
92cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
93cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (!isElidableType() || !mStorageType->isValidEnumStorageType()) {
94cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        std::cerr << "ERROR: Invalid enum storage type (" << (mStorageType)->typeName()
95cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov                  << ") specified at " << mStorageType.location() << "\n";
96cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        return UNKNOWN_ERROR;
97cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
98cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
99cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    err = validateUniqueNames();
100cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (err != OK) return err;
101cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
102cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return Scope::validate();
103cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
104cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
105cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumType::validateUniqueNames() const {
106cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    std::unordered_map<std::string, const EnumType*> registeredValueNames;
107cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (const auto* type : superTypeChain()) {
108cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        for (const auto* enumValue : type->mValues) {
109cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            // No need to check super value uniqueness
110cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            registeredValueNames[enumValue->name()] = type;
111cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        }
112cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
113cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
114cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (const auto* value : mValues) {
115cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        auto registered = registeredValueNames.find(value->name());
116cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
117cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        if (registered != registeredValueNames.end()) {
118cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            const EnumType* definedInType = registered->second;
119cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
120cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            if (definedInType == this) {
121cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov                // Defined in this enum
122cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov                std::cerr << "ERROR: Redefinition of value '" << value->name() << "'";
123cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            } else {
124cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov                // Defined in super enum
125cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov                std::cerr << "ERROR: Redefinition of value '" << value->name() << "define in enum '"
126cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov                          << definedInType->fullName() << "'";
127cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            }
128cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            std::cerr << " at " << value->location() << "\n";
129cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            return UNKNOWN_ERROR;
130cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        }
131cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
132cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        registeredValueNames[value->name()] = this;
133cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
134cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
135cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return OK;
1368d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
1378d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1389df5244c1dd4508cc2e25f8a04d363903912d19cSteven Morelandbool EnumType::isElidableType() const {
1399df5244c1dd4508cc2e25f8a04d363903912d19cSteven Moreland    return mStorageType->isElidableType();
1409df5244c1dd4508cc2e25f8a04d363903912d19cSteven Moreland}
1419df5244c1dd4508cc2e25f8a04d363903912d19cSteven Moreland
142737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huberconst ScalarType *EnumType::resolveToScalarType() const {
143737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    return mStorageType->resolveToScalarType();
144737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber}
145737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
14630bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Morelandstd::string EnumType::typeName() const {
14730bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Moreland    return "enum " + localName();
14830bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Moreland}
14930bb6a869be0f3f82497b7b11c71ec9d47652ed0Steven Moreland
1508d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberbool EnumType::isEnum() const {
1518d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return true;
1528d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
1538d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
154c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hongbool EnumType::canCheckEquality() const {
155c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong    return true;
156c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong}
157c6752dcea3b5dae1e99960b5beb6af394280b393Yifan Hong
158979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string EnumType::getCppType(StorageMode,
159e30ee9b06ac578006161e84633db91289f889068Steven Moreland                                 bool /* specifyNamespaces */) const {
160e30ee9b06ac578006161e84633db91289f889068Steven Moreland    return fullName();
161881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
162881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1634ed1347cd29e6e07acad368891bb03078c798abaYifan Hongstd::string EnumType::getJavaType(bool forInitializer) const {
1644ed1347cd29e6e07acad368891bb03078c798abaYifan Hong    return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
1652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
1662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
1672831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string EnumType::getJavaSuffix() const {
1682831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return mStorageType->resolveToScalarType()->getJavaSuffix();
1692831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
1702831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
171a3558b3b273695b31fbe1025339956966cde39c4Andreas Huberstd::string EnumType::getJavaWrapperType() const {
172a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber    return mStorageType->resolveToScalarType()->getJavaWrapperType();
173a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber}
174a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber
175c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhangstd::string EnumType::getVtsType() const {
176c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    return "TYPE_ENUM";
177c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang}
178c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang
179505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur IskhakovBitFieldType* EnumType::getBitfieldType() const {
180e45b5303e072043679483a70606f6c00dde17382Yifan Hong    return mBitfieldType;
181e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
182e45b5303e072043679483a70606f6c00dde17382Yifan Hong
183f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongLocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
184f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
185f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
186f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
187f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        for(EnumValue *v : type->values()) {
188f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if(v->name() == name) {
189f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                return v;
190f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            }
191f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
192f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
193f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return nullptr;
194f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
195f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
196881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid EnumType::emitReaderWriter(
197881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
198881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
199881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
200881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
201881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
202881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
203737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
204737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    CHECK(scalarType != NULL);
205737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
206737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    scalarType->emitReaderWriterWithCast(
207737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            out,
208737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            name,
209737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObj,
210737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObjIsPointer,
211737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            isReader,
212737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            mode,
213737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            true /* needsCast */);
214881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
215881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
21685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::emitJavaFieldReaderWriter(
21785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
2184c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
219709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
22085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
22185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
22285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
22385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
22485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    return mStorageType->emitJavaFieldReaderWriter(
225709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            out, depth, parcelName, blobName, fieldName, offset, isReader);
22685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
22785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
228881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberstatus_t EnumType::emitTypeDeclarations(Formatter &out) const {
229737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
230e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
231737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
2323b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
233881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
234881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "enum class "
2350e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        << localName()
236881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " : "
237e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
238881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " {\n";
239881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
240881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
241881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
242f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
2438d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2448d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
2458d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        const auto &type = *it;
2468d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2478d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        for (const auto &entry : type->values()) {
2488d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber            out << entry->name();
2498d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
250fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->cppValue(scalarType->getKind());
251f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for c++.
252f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << " = " << value;
2538d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2545788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << ",";
2555788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
256fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
257fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
2585788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong                out << " // " << comment;
2595788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            }
2605788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
2615788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << "\n";
2628d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        }
263881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
264881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
265881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
266881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "};\n\n";
267881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
268881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return OK;
269881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
270881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
2712820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdharyvoid EnumType::emitEnumBitwiseOperator(
2722820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        Formatter &out,
273c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool lhsIsEnum,
274c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool rhsIsEnum,
2752820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        const std::string &op) const {
276e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
277e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
278e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
2793b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
280e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
281c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr "
282c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType
2832820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << " operator"
2842820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << op
285c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << "(const "
286c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (lhsIsEnum ? fullName() : storageType)
287c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " lhs, const "
288c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (rhsIsEnum ? fullName() : storageType)
289c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " rhs) {\n";
290e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
29133223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
292c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return static_cast<"
293c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << storageType
294c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << ">(";
295e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
296c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (lhsIsEnum) {
297c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
298c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
299c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(lhs)";
300c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
301c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "lhs";
302c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
303c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << " " << op << " ";
304c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (rhsIsEnum) {
305c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
306c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
307c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(rhs)";
308c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
309c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "rhs";
310c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
311c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << ");\n";
312c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
313e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
314c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "}\n\n";
315c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
316e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
317c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid EnumType::emitBitFieldBitwiseAssignmentOperator(
318c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
319c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &op) const {
320c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
321c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    CHECK(scalarType != nullptr);
322e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
323c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const std::string storageType = scalarType->getCppStackType();
324c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
325c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr " << storageType << " &operator" << op << "=("
326c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType << "& v, const " << fullName() << " e) {\n";
327c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
32833223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
329c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
330c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return v;\n";
331c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
332e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
333e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "}\n\n";
334e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
335e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
336e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huberstatus_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
337c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
338c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
339c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "|");
340c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
341c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
342c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "&");
343c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
344c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "|");
345c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "&");
346e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
347870d1a7ccd70bd710128993de401278614d1975eYifan Hong    // toString for bitfields, equivalent to dumpBitfield in Java
348f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<typename>\n"
349f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString("
350f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
351f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n";
352f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
353f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
354f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << resolveToScalarType()->getCppArgumentType()
355f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n\n";
356f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
357870d1a7ccd70bd710128993de401278614d1975eYifan Hong    // toString for enum itself
358870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out << "std::string toString("
359f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << getCppArgumentType()
360870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << " o);\n\n";
361f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
362f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    return OK;
363f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
364f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
3658c90cc59bf93bd0c08970b4488067a33015d4a1cChih-Hung Hsiehstatus_t EnumType::emitTypeDefinitions(Formatter& out, const std::string& /* prefix */) const {
366f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
367f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    CHECK(scalarType != NULL);
368f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
369f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
370f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
371870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << scalarType->getCppArgumentType()
372f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o) ";
373f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out.block([&] {
374f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        // include toHexString for scalar types
375f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "using ::android::hardware::details::toHexString;\n"
376870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << "std::string os;\n"
377870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << getBitfieldType()->getCppStackType() << " flipped = 0;\n"
378870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << "bool first = true;\n";
379f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        for (EnumValue *value : values()) {
380870d1a7ccd70bd710128993de401278614d1975eYifan Hong            std::string valueName = fullName() + "::" + value->name();
381870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out.sIf("(o & " + valueName + ")" +
382870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    " == static_cast<" + scalarType->getCppStackType() +
383870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    ">(" + valueName + ")", [&] {
384870d1a7ccd70bd710128993de401278614d1975eYifan Hong                out << "os += (first ? \"\" : \" | \");\n"
385870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    << "os += \"" << value->name() << "\";\n"
386f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong                    << "first = false;\n"
387870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    << "flipped |= " << valueName << ";\n";
388f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            }).endl();
389f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        }
390870d1a7ccd70bd710128993de401278614d1975eYifan Hong        // put remaining bits
391870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out.sIf("o != flipped", [&] {
392870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out << "os += (first ? \"\" : \" | \");\n";
393870d1a7ccd70bd710128993de401278614d1975eYifan Hong            scalarType->emitHexDump(out, "os", "o & (~flipped)");
394870d1a7ccd70bd710128993de401278614d1975eYifan Hong        });
395f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \" (\";\n";
396f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        scalarType->emitHexDump(out, "os", "o");
397f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \")\";\n";
398f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
399f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "return os;\n";
400f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    }).endl().endl();
401f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
402870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out << "std::string toString("
403870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << getCppArgumentType()
404870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << " o) ";
405870d1a7ccd70bd710128993de401278614d1975eYifan Hong
406870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out.block([&] {
407870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "using ::android::hardware::details::toHexString;\n";
408870d1a7ccd70bd710128993de401278614d1975eYifan Hong        for (EnumValue *value : values()) {
409870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out.sIf("o == " + fullName() + "::" + value->name(), [&] {
410870d1a7ccd70bd710128993de401278614d1975eYifan Hong                out << "return \"" << value->name() << "\";\n";
411870d1a7ccd70bd710128993de401278614d1975eYifan Hong            }).endl();
412870d1a7ccd70bd710128993de401278614d1975eYifan Hong        }
413870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "std::string os;\n";
414870d1a7ccd70bd710128993de401278614d1975eYifan Hong        scalarType->emitHexDump(out, "os",
415870d1a7ccd70bd710128993de401278614d1975eYifan Hong            "static_cast<" + scalarType->getCppStackType() + ">(o)");
416870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "return os;\n";
417870d1a7ccd70bd710128993de401278614d1975eYifan Hong    }).endl().endl();
418870d1a7ccd70bd710128993de401278614d1975eYifan Hong
419e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    return OK;
420e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
421e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
422e45b5303e072043679483a70606f6c00dde17382Yifan Hongstatus_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool atTopLevel) const {
4232831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
4242831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
4252831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
426e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "public "
427e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << (atTopLevel ? "" : "static ")
428e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "final class "
4292831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
4302831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
4312831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4322831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
4332831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4344c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
4354ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        scalarType->getJavaType(false /* forInitializer */);
4362831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
437f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
4382831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4392831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
4402831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
4412831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4422831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
4432831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
4442831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
4452831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
446ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
447ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
4482831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
449f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
450fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
451f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
452f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
4532831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
45419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
45519ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
456fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
457fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
45819ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
45919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
46019ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
46119ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
4622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
4632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
4642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
465e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "public static final String toString("
466e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << typeName << " o) ";
467e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out.block([&] {
468e45b5303e072043679483a70606f6c00dde17382Yifan Hong        for (EnumValue *value : values()) {
469e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out.sIf("o == " + value->name(), [&] {
470e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "return \"" << value->name() << "\";\n";
471e45b5303e072043679483a70606f6c00dde17382Yifan Hong            }).endl();
472e45b5303e072043679483a70606f6c00dde17382Yifan Hong        }
473e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "return \"0x\" + ";
474e45b5303e072043679483a70606f6c00dde17382Yifan Hong        scalarType->emitConvertToJavaHexString(out, "o");
475e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << ";\n";
476e45b5303e072043679483a70606f6c00dde17382Yifan Hong    }).endl();
477e45b5303e072043679483a70606f6c00dde17382Yifan Hong
478e45b5303e072043679483a70606f6c00dde17382Yifan Hong    auto bitfieldType = getBitfieldType()->getJavaType(false /* forInitializer */);
479e45b5303e072043679483a70606f6c00dde17382Yifan Hong    auto bitfieldWrapperType = getBitfieldType()->getJavaWrapperType();
480e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "\n"
481e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "public static final String dumpBitfield("
482e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << bitfieldType << " o) ";
483e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out.block([&] {
484e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "java.util.ArrayList<String> list = new java.util.ArrayList<>();\n";
485e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << bitfieldType << " flipped = 0;\n";
486e45b5303e072043679483a70606f6c00dde17382Yifan Hong        for (EnumValue *value : values()) {
487dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong            if (value->constExpr()->castSizeT() == 0) {
488dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong                out << "list.add(\"" << value->name() << "\"); // " << value->name() << " == 0\n";
489dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong                continue;
490dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong            }
491e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out.sIf("(o & " + value->name() + ") == " + value->name(), [&] {
492e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "list.add(\"" << value->name() << "\");\n";
493e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "flipped |= " << value->name() << ";\n";
494e45b5303e072043679483a70606f6c00dde17382Yifan Hong            }).endl();
495e45b5303e072043679483a70606f6c00dde17382Yifan Hong        }
496e45b5303e072043679483a70606f6c00dde17382Yifan Hong        // put remaining bits
497e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out.sIf("o != flipped", [&] {
498e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out << "list.add(\"0x\" + ";
499e45b5303e072043679483a70606f6c00dde17382Yifan Hong            scalarType->emitConvertToJavaHexString(out, "o & (~flipped)");
500e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out << ");\n";
501e45b5303e072043679483a70606f6c00dde17382Yifan Hong        }).endl();
502e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "return String.join(\" | \", list);\n";
503e45b5303e072043679483a70606f6c00dde17382Yifan Hong    }).endl().endl();
504e45b5303e072043679483a70606f6c00dde17382Yifan Hong
5052831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
5062831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
5072831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
5082831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return OK;
5092831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
5102831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
5115158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
512c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
513c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong
514bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
515c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
516c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
5175158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
518864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
519c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
520c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong        << scalarType->getVtsScalarType()
521c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
522f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
523864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
524864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
525864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
526864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
527864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
528864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
529c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
530c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
531c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            // use autofilled values for vts.
532c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            std::string value = entry->value(scalarType->getKind());
533c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            CHECK(!value.empty());
534c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            out << mStorageType->resolveToScalarType()->getVtsScalarType()
535c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << ": "
536c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << value
537c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << "\n";
538c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
539c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
540864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
5415158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
542864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
5435158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
5445158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
5455158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
5465158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
5475158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
548864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t EnumType::emitVtsAttributeType(Formatter &out) const {
549c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
550bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
5515158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
5525158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
5535158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
554e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid EnumType::emitJavaDump(
555e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
556e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
557e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
558e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(" << fqName().javaName() << ".toString("
559e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
560e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
561e45b5303e072043679483a70606f6c00dde17382Yifan Hong
562f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakovstd::vector<const EnumType*> EnumType::typeChain() const {
563f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> types;
564f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    for (const EnumType* type = this; type != nullptr;) {
565f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        types.push_back(type);
566864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
567f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        const Type* superType = type->storageType();
568f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        if (superType != nullptr && superType->isEnum()) {
569f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov            type = static_cast<const EnumType*>(superType);
570f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        } else {
571f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov            type = nullptr;
572864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
573f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    }
574f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov
575f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    return types;
576f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov}
577864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
578f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakovstd::vector<const EnumType*> EnumType::superTypeChain() const {
579f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    const Type* superType = storageType();
580f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    if (superType == nullptr || !superType->isEnum()) {
581f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        return {};
582864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
583f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    return static_cast<const EnumType*>(superType)->typeChain();
584864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
585864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
58685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
58785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
58885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
58985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
590019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
591019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
592019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
593019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
594019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
595019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
596019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
597019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
598019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
599019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
600019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
601019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
602019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
603019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
604019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
605019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
606019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
6071c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huberstatus_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
608019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
609019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
610019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
611019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
612019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
613019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
614019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
615db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        name = nameParam->getSingleString();
616db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
617019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
618db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    bool exportParent = true;
619db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
620db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParentParam != nullptr) {
621db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        exportParent = exportParentParam->getSingleBool();
622019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
623019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
624b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
625b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
626b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
627db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valuePrefix = prefixParam->getSingleString();
628b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
629b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
63073cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    std::string valueSuffix;
63173cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
63273cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    if (suffixParam != nullptr) {
633db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valueSuffix = suffixParam->getSingleString();
63473cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    }
63573cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
636019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
6371c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
638019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
639db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    std::vector<const EnumType *> chain;
640db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParent) {
641f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        chain = typeChain();
642db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    } else {
643db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        chain = { this };
644db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
645db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland
6461c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
6471c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
6481c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
6491c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
6501c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
6511c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6521c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
6531c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
6541c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
6551c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
6561c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6571c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
6584ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            scalarType->getJavaType(false /* forInitializer */);
6591c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6601c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
6611c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
6621c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6631c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
6641c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
6651c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
6661c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
6671c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
6681c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
66973cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland                    << valueSuffix
6701c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
6711c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6721c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
6731c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
6741c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
6751c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
6761c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6771c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
6781c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6791c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
6801c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                if (!comment.empty() && comment != value) {
6811c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
6821c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
6831c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6841c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
6851c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
6861c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
6871c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6881c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
6891c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
6901c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
6911c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
6921c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
6931c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6941c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        return OK;
6951c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
696019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
697019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
698019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
699019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
700019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
701019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
702019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
703019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
704019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
705019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
706019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
707019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
708019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
70973cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland            out << valuePrefix << entry->name() << valueSuffix;
710019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
711019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
712019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
713019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
714019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
715019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
716019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
717019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
718019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            if (!comment.empty() && comment != value) {
719019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
720019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
721019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
722019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
723019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
724019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
725019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
726019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
727019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
728019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
729019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
730019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
731019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
732019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
733019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
734019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
735019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return OK;
736019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
737019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
73831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
73931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
740cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur IskhakovEnumValue::EnumValue(const char* name, ConstantExpression* value, const Location& location)
741cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    : mName(name), mValue(value), mLocation(location), mIsAutoFill(false) {}
74231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
74331629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
74431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
74531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
74631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
747c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hongstd::string EnumValue::value(ScalarType::Kind castKind) const {
748f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
749c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    return mValue->value(castKind);
7505788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
7515788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
752fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
753f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
754f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
7555788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
756fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
757f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
758f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
75919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
7605788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
761fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
762f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
763f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
764f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
765f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
766f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
767f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
768f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
769f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
770f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
771cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovvoid EnumValue::autofill(const EnumType* prevType, EnumValue* prevValue, const ScalarType* type) {
772cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    // Value is defined explicitly
7737296af19687b1c90dfd238398cd2c8ccb6bcd232Timur Iskhakov    if (mValue != nullptr) return;
774cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
775cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    CHECK((prevType == nullptr) == (prevValue == nullptr));
776cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
777f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
778cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (prevValue == nullptr) {
7797296af19687b1c90dfd238398cd2c8ccb6bcd232Timur Iskhakov        mValue = ConstantExpression::Zero(type->getKind()).release();
780f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
781cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        std::string description = prevType->fullName() + "." + prevValue->name() + " implicitly";
782cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        auto* prevReference = new ReferenceConstantExpression(
783cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            Reference<LocalIdentifier>(prevValue, mLocation), description);
784cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        mValue = prevReference->addOne(type->getKind()).release();
785f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
786f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
787f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
788f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
789f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
790f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
791f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
792f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
793f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
79431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
79531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
796cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumValue::evaluate() {
797cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    mValue->evaluate();
798cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return OK;
799cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
800cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
801cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumValue::validate() const {
802cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    // TODO(b/64358435) move isSupported from ConstantExpression
803cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return OK;
804cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
805cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
806cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovconst Location& EnumValue::location() const {
807cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return mLocation;
808cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
809cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
810abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong////////////////////////////////////////////////////////////////////////////////
811abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
812abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hongbool BitFieldType::isBitField() const {
813abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong    return true;
814abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong}
815abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
816c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::typeName() const {
817c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "mask" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
818c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
819c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
820505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakovbool BitFieldType::isCompatibleElementType(Type* elementType) const {
821c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return elementType->isEnum();
822c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
823c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
824c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongconst ScalarType *BitFieldType::resolveToScalarType() const {
825c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return mElementType->resolveToScalarType();
826c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
827c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
828c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getCppType(StorageMode mode,
829c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                                 bool specifyNamespaces) const {
830c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getCppType(mode, specifyNamespaces);
831c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
832c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
833c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaType(bool forInitializer) const {
834c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaType(forInitializer);
835c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
836c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
837c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaSuffix() const {
838c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaSuffix();
839c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
840c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
841c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaWrapperType() const {
842c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaWrapperType();
843c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
844c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
845c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getVtsType() const {
846c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "TYPE_MASK";
847c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
848c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
8498c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hongbool BitFieldType::isElidableType() const {
8508c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong    return resolveToScalarType()->isElidableType();
8518c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong}
8528c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong
8537d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hongbool BitFieldType::canCheckEquality() const {
8547d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong    return resolveToScalarType()->canCheckEquality();
8557d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong}
8567d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong
857c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstatus_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
858c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "type: " << getVtsType() << "\n";
859132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang    out << "scalar_type: \""
860132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << mElementType->resolveToScalarType()->getVtsScalarType()
861132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << "\"\n";
862505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov    out << "predefined_type: \"" << static_cast<NamedType*>(mElementType.get())->fullName()
863505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov        << "\"\n";
864c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return OK;
865c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
866c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
867c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
868c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->getAlignmentAndSize(align, size);
869c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
870c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
871c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitReaderWriter(
872c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
873c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &name,
874c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelObj,
875c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool parcelObjIsPointer,
876c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader,
877c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        ErrorMode mode) const {
878c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->emitReaderWriterWithCast(
879c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out,
880c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            name,
881c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObj,
882c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObjIsPointer,
883c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            isReader,
884c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            mode,
885c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            true /* needsCast */);
886c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
887c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
888505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur IskhakovEnumType* BitFieldType::getEnumType() const {
889e45b5303e072043679483a70606f6c00dde17382Yifan Hong    CHECK(mElementType->isEnum());
890505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov    return static_cast<EnumType*>(mElementType.get());
891e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
892e45b5303e072043679483a70606f6c00dde17382Yifan Hong
893f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// a bitfield maps to the underlying scalar type in C++, so operator<< is
894f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// already defined. We can still emit useful information if the bitfield is
895f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// in a struct / union by overriding emitDump as below.
896f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongvoid BitFieldType::emitDump(
897f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        Formatter &out,
898f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &streamName,
899f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &name) const {
900e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << " += "<< getEnumType()->fqName().cppNamespace()
901e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "::toString<" << getEnumType()->getCppStackType()
902f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << ">(" << name << ");\n";
903f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
904f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
905e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid BitFieldType::emitJavaDump(
906e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
907e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
908e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
909e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(" << getEnumType()->fqName().javaName() << ".dumpBitfield("
910e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
911e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
912e45b5303e072043679483a70606f6c00dde17382Yifan Hong
913c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitJavaFieldReaderWriter(
914c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
915c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        size_t depth,
916c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelName,
917c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &blobName,
918c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &fieldName,
919c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &offset,
920c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader) const {
921c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->emitJavaFieldReaderWriter(
922c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out, depth, parcelName, blobName, fieldName, offset, isReader);
923c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
924c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
925c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
926c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
927