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>
21e8ee6a005bee05611c9ac6b4d29850a191152021Timur Iskhakov#include <iostream>
22cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov#include <unordered_map>
23cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
24019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber#include "Annotation.h"
25505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov#include "Location.h"
26881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber#include "ScalarType.h"
27c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
28c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android {
29c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
30565b0137b2ad0e8e239d38e92c025f096de62f2dTimur IskhakovEnumType::EnumType(const char* localName, const FQName& fullName, const Location& location,
31505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov                   const Reference<Type>& storageType, Scope* parent)
32c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    : Scope(localName, fullName, location, parent), mValues(), mStorageType(storageType) {}
33c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
348d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst Type *EnumType::storageType() const {
35b3f8bcb56965177f8064679150497b6e586df2eeTimur Iskhakov    return mStorageType.get();
368d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
378d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
388d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst std::vector<EnumValue *> &EnumType::values() const {
39f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValues;
40f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
41f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
420a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hongvoid EnumType::forEachValueFromRoot(const std::function<void(EnumValue*)> f) const {
430a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong    std::vector<const EnumType*> chain = typeChain();
440a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
450a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        const auto& type = *it;
460a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        for (EnumValue* v : type->values()) {
470a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong            f(v);
480a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        }
490a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong    }
500a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong}
510a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong
52cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovvoid EnumType::addValue(EnumValue* value) {
53f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(value != nullptr);
54cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    mValues.push_back(value);
55cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
56f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
57cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumType::resolveInheritance() {
58cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    const EnumType* prevType = nullptr;
59cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    EnumValue* prevValue = nullptr;
60cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
61cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (const auto* type : superTypeChain()) {
62cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        if (!type->values().empty()) {
63cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            prevType = type;
64cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            prevValue = type->values().back();
65f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            break;
66f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
67f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
68f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
69cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    for (auto* value : mValues) {
70cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        value->autofill(prevType, prevValue, mStorageType->resolveToScalarType());
71cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        prevType = this;
72cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        prevValue = value;
73cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
74cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
75cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return Scope::resolveInheritance();
76cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
77cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
78b58f4185934a93fc511c03a8a970b31c5ea0dfcaTimur Iskhakovstd::vector<const Reference<Type>*> EnumType::getReferences() const {
79b58f4185934a93fc511c03a8a970b31c5ea0dfcaTimur Iskhakov    return {&mStorageType};
8033431e6cd425c6cd179080442a8616e2baa20aaeTimur Iskhakov}
81cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
82b58f4185934a93fc511c03a8a970b31c5ea0dfcaTimur Iskhakovstd::vector<const ConstantExpression*> EnumType::getConstantExpressions() const {
83b58f4185934a93fc511c03a8a970b31c5ea0dfcaTimur Iskhakov    std::vector<const ConstantExpression*> ret;
84891a866402345777c7e746cf8d0e4ffd0bd28ca2Timur Iskhakov    for (const auto* value : mValues) {
85891a866402345777c7e746cf8d0e4ffd0bd28ca2Timur Iskhakov        ret.push_back(value->constExpr());
86cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    }
87891a866402345777c7e746cf8d0e4ffd0bd28ca2Timur Iskhakov    return ret;
88cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
89cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
90cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovstatus_t EnumType::validate() const {
91a15f8091d2d4312a16edfcebccb13b3ea4782c29Timur Iskhakov    CHECK(getSubTypes().empty());
92a15f8091d2d4312a16edfcebccb13b3ea4782c29Timur 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
9933431e6cd425c6cd179080442a8616e2baa20aaeTimur Iskhakov    status_t 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
125ec123f3609c91fb5b1361466aedd8e2591c6bf83Timur Iskhakov                std::cerr << "ERROR: Redefinition of value '" << value->name()
126ec123f3609c91fb5b1361466aedd8e2591c6bf83Timur Iskhakov                          << "' defined in enum '" << 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
1545dc72fe4f6f1d2c03c75307a9bd80f055f752ed3Timur Iskhakovbool EnumType::deepCanCheckEquality(std::unordered_set<const Type*>* /* visited */) 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
17938a4fa19e2b941bbaab59b4e4e8fe69555bb57e7Steven Morelandstd::string EnumType::getBitfieldCppType(StorageMode /* mode */, bool specifyNamespaces) const {
18038a4fa19e2b941bbaab59b4e4e8fe69555bb57e7Steven Moreland    const std::string space = specifyNamespaces ? "::android::hardware::" : "";
18138a4fa19e2b941bbaab59b4e4e8fe69555bb57e7Steven Moreland    return space + "hidl_bitfield<" + (specifyNamespaces ? fullName() : localName()) + ">";
182c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong}
18363f399021d053453704d41845d4ebcc06fe01738Timur Iskhakov
184c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongstd::string EnumType::getBitfieldJavaType(bool forInitializer) const {
185c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return resolveToScalarType()->getJavaType(forInitializer);
186c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong}
187c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong
188c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongstd::string EnumType::getBitfieldJavaWrapperType() const {
189c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return resolveToScalarType()->getJavaWrapperType();
190e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
191e45b5303e072043679483a70606f6c00dde17382Yifan Hong
192f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongLocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
193f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
194f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
195f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
196f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        for(EnumValue *v : type->values()) {
197f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if(v->name() == name) {
198f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                return v;
199f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            }
200f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
201f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
202f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return nullptr;
203f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
204f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
205881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid EnumType::emitReaderWriter(
206881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
207881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
208881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
209881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
210881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
211881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
212737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
213737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    CHECK(scalarType != NULL);
214737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
215737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    scalarType->emitReaderWriterWithCast(
216737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            out,
217737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            name,
218737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObj,
219737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObjIsPointer,
220737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            isReader,
221737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            mode,
222737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            true /* needsCast */);
223881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
224881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
22585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::emitJavaFieldReaderWriter(
22685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
2274c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
228709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
22985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
23085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
23185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
23285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
23385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    return mStorageType->emitJavaFieldReaderWriter(
234709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            out, depth, parcelName, blobName, fieldName, offset, isReader);
23585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
23685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
237368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid EnumType::emitTypeDeclarations(Formatter& out) const {
238737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
239e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
240737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
2413b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
242881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
243881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "enum class "
2440e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        << localName()
245881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " : "
246e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
247881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " {\n";
248881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
249881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
250881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
251f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
2528d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2538d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
2548d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        const auto &type = *it;
2558d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2568d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        for (const auto &entry : type->values()) {
25749bad8df77e1fe1ca3c06fe49790a6e3304e7249Steven Moreland            entry->emitDocComment(out);
25849bad8df77e1fe1ca3c06fe49790a6e3304e7249Steven Moreland
2598d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber            out << entry->name();
2608d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
261fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->cppValue(scalarType->getKind());
262f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for c++.
263f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << " = " << value;
2648d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2655788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << ",";
2665788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
267fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
268505e56125eba2ce327892646eed799419240e59dTimur Iskhakov            if (!comment.empty()) {
2695788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong                out << " // " << comment;
2705788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            }
2715788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
2725788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << "\n";
2738d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        }
274881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
275881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
276881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
277881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "};\n\n";
278881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
279881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
280fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakovvoid EnumType::emitTypeForwardDeclaration(Formatter& out) const {
281fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov    const ScalarType* scalarType = mStorageType->resolveToScalarType();
282fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov    const std::string storageType = scalarType->getCppStackType();
283fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov
284fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov    out << "enum class " << localName() << " : " << storageType << ";\n";
285fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov}
286fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov
2876961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Morelandvoid EnumType::emitIteratorDeclaration(Formatter& out) const {
2886961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    size_t elementCount = 0;
2896961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    for (const auto* type : typeChain()) {
2906961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        elementCount += type->mValues.size();
2916961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    }
2926961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
2936961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "template<> struct hidl_enum_iterator<" << getCppStackType() << ">\n";
2946961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out.block([&] {
2956961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "const " << getCppStackType() << "* begin() { return static_begin(); }\n";
2966961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "const " << getCppStackType() << "* end() { return begin() + " << elementCount
2976961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            << "; }\n";
2986961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "private:\n";
2996961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "static const " << getCppStackType() << "* static_begin() ";
3006961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out.block([&] {
3016961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            out << "static const " << getCppStackType() << " kVals[" << elementCount << "] ";
3026961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            out.block([&] {
3036961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                auto enumerators = typeChain();
3046961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                std::reverse(enumerators.begin(), enumerators.end());
3056961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                for (const auto* type : enumerators) {
3066961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                    for (const auto* enumValue : type->mValues) {
3076961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                        out << fullName() << "::" << enumValue->name() << ",\n";
3086961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                    }
3096961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                }
3106961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            }) << ";\n";
3116961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            out << "return &kVals[0];\n";
3126961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        });
3136961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    }) << ";\n\n";
3146961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland}
3156961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3162820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdharyvoid EnumType::emitEnumBitwiseOperator(
3172820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        Formatter &out,
318c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool lhsIsEnum,
319c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool rhsIsEnum,
3202820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        const std::string &op) const {
321e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
322e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
323e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
3243b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
325e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
326c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr "
327c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType
3282820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << " operator"
3292820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << op
330c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << "(const "
331c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (lhsIsEnum ? fullName() : storageType)
332c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " lhs, const "
333c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (rhsIsEnum ? fullName() : storageType)
334c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " rhs) {\n";
335e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
33633223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
337c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return static_cast<"
338c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << storageType
339c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << ">(";
340e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
341c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (lhsIsEnum) {
342c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
343c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
344c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(lhs)";
345c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
346c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "lhs";
347c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
348c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << " " << op << " ";
349c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (rhsIsEnum) {
350c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
351c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
352c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(rhs)";
353c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
354c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "rhs";
355c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
356c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << ");\n";
357c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
358e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
359c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "}\n\n";
360c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
361e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
362c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid EnumType::emitBitFieldBitwiseAssignmentOperator(
363c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
364c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &op) const {
365c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
366c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    CHECK(scalarType != nullptr);
367e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
368c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const std::string storageType = scalarType->getCppStackType();
369c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
370c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr " << storageType << " &operator" << op << "=("
371c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType << "& v, const " << fullName() << " e) {\n";
372c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
37333223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
374c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
375c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return v;\n";
376c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
377e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
378e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "}\n\n";
379e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
380e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
3816961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Morelandvoid EnumType::emitGlobalTypeDeclarations(Formatter& out) const {
3826961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "namespace android {\n";
3836961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "namespace hardware {\n";
3846961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3856961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    emitIteratorDeclaration(out);
3866961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3876961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "}  // namespace hardware\n";
3886961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "}  // namespace android\n";
3896961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland}
3906961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
391368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid EnumType::emitPackageTypeDeclarations(Formatter& out) const {
392c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
393c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
394c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "|");
395c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
396c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
397c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "&");
398c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
399c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "|");
400c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "&");
401e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
402bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    const ScalarType *scalarType = mStorageType->resolveToScalarType();
403bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    CHECK(scalarType != NULL);
404bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
405f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<typename>\n"
406bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        << "static inline std::string toString(" << resolveToScalarType()->getCppArgumentType()
407f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n";
408f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
409bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        << "inline std::string toString<" << getCppStackType() << ">("
410bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        << scalarType->getCppArgumentType() << " o) ";
411bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out.block([&] {
412bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        // include toHexString for scalar types
413bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "using ::android::hardware::details::toHexString;\n"
414bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << "std::string os;\n"
415bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << getBitfieldCppType(StorageMode_Stack) << " flipped = 0;\n"
416bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << "bool first = true;\n";
4175f93004be6d4c527f261817f0262e2970065913aSteven Moreland        forEachValueFromRoot([&](EnumValue* value) {
418bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            std::string valueName = fullName() + "::" + value->name();
419bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            out.sIf("(o & " + valueName + ")" +
420bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    " == static_cast<" + scalarType->getCppStackType() +
421bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    ">(" + valueName + ")", [&] {
422bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                out << "os += (first ? \"\" : \" | \");\n"
423bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    << "os += \"" << value->name() << "\";\n"
424bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    << "first = false;\n"
425bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    << "flipped |= " << valueName << ";\n";
426bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            }).endl();
4275f93004be6d4c527f261817f0262e2970065913aSteven Moreland        });
428bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        // put remaining bits
429bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out.sIf("o != flipped", [&] {
430bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            out << "os += (first ? \"\" : \" | \");\n";
431bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            scalarType->emitHexDump(out, "os", "o & (~flipped)");
432bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        });
433bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "os += \" (\";\n";
434bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        scalarType->emitHexDump(out, "os", "o");
435bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "os += \")\";\n";
436bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
437bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "return os;\n";
438bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    }).endl().endl();
439f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
440bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
441bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
442bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out.block([&] {
443bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "using ::android::hardware::details::toHexString;\n";
4445f93004be6d4c527f261817f0262e2970065913aSteven Moreland        forEachValueFromRoot([&](EnumValue* value) {
445bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            out.sIf("o == " + fullName() + "::" + value->name(), [&] {
446bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                out << "return \"" << value->name() << "\";\n";
447bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            }).endl();
4485f93004be6d4c527f261817f0262e2970065913aSteven Moreland        });
449bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "std::string os;\n";
450bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        scalarType->emitHexDump(out, "os",
451bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            "static_cast<" + scalarType->getCppStackType() + ">(o)");
452bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "return os;\n";
453bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    }).endl().endl();
454e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
455e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
456368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid EnumType::emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const {
4572831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
4582831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
4592831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
460e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "public "
461e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << (atTopLevel ? "" : "static ")
462e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "final class "
4632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
4642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
4652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
4672831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4684c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
4694ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        scalarType->getJavaType(false /* forInitializer */);
4702831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
471f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
4722831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4732831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
4742831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
4752831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4762831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
47749bad8df77e1fe1ca3c06fe49790a6e3304e7249Steven Moreland            entry->emitDocComment(out);
47849bad8df77e1fe1ca3c06fe49790a6e3304e7249Steven Moreland
4792831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
4802831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
4812831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
482ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
483ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
4842831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
485f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
486fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
487f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
488f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
4892831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
49019ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
49119ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
492fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
493505e56125eba2ce327892646eed799419240e59dTimur Iskhakov            if (!comment.empty()) {
49419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
49519ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
49619ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
49719ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
4982831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
4992831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
5002831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
501e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "public static final String toString("
502e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << typeName << " o) ";
503e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out.block([&] {
5040a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        forEachValueFromRoot([&](EnumValue* value) {
505e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out.sIf("o == " + value->name(), [&] {
506e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "return \"" << value->name() << "\";\n";
507e45b5303e072043679483a70606f6c00dde17382Yifan Hong            }).endl();
5080a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        });
509e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "return \"0x\" + ";
510e45b5303e072043679483a70606f6c00dde17382Yifan Hong        scalarType->emitConvertToJavaHexString(out, "o");
511e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << ";\n";
512e45b5303e072043679483a70606f6c00dde17382Yifan Hong    }).endl();
513e45b5303e072043679483a70606f6c00dde17382Yifan Hong
514c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    auto bitfieldType = getBitfieldJavaType(false /* forInitializer */);
515c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    auto bitfieldWrapperType = getBitfieldJavaWrapperType();
516e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "\n"
517e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "public static final String dumpBitfield("
518e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << bitfieldType << " o) ";
519e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out.block([&] {
520e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "java.util.ArrayList<String> list = new java.util.ArrayList<>();\n";
521e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << bitfieldType << " flipped = 0;\n";
5220a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        forEachValueFromRoot([&](EnumValue* value) {
523dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong            if (value->constExpr()->castSizeT() == 0) {
524dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong                out << "list.add(\"" << value->name() << "\"); // " << value->name() << " == 0\n";
5250a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong                return;  // continue to next value
526dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong            }
527e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out.sIf("(o & " + value->name() + ") == " + value->name(), [&] {
528e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "list.add(\"" << value->name() << "\");\n";
529e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "flipped |= " << value->name() << ";\n";
530e45b5303e072043679483a70606f6c00dde17382Yifan Hong            }).endl();
5310a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        });
532e45b5303e072043679483a70606f6c00dde17382Yifan Hong        // put remaining bits
533e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out.sIf("o != flipped", [&] {
534e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out << "list.add(\"0x\" + ";
535e45b5303e072043679483a70606f6c00dde17382Yifan Hong            scalarType->emitConvertToJavaHexString(out, "o & (~flipped)");
536e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out << ");\n";
537e45b5303e072043679483a70606f6c00dde17382Yifan Hong        }).endl();
538e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "return String.join(\" | \", list);\n";
539e45b5303e072043679483a70606f6c00dde17382Yifan Hong    }).endl().endl();
540e45b5303e072043679483a70606f6c00dde17382Yifan Hong
5412831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
5422831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
5432831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
5442831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
545368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid EnumType::emitVtsTypeDeclarations(Formatter& out) const {
546c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
547c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong
548bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
549c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
550c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
5515158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
552864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
553c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
554c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong        << scalarType->getVtsScalarType()
555c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
556f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
557864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
558864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
559864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
560864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
561864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
562864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
563c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
564c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
565c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            // use autofilled values for vts.
566c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            std::string value = entry->value(scalarType->getKind());
567c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            CHECK(!value.empty());
568c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            out << mStorageType->resolveToScalarType()->getVtsScalarType()
569c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << ": "
570c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << value
571c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << "\n";
572c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
573c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
574864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
5755158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
576864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
5775158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
5785158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
5795158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
5805158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
581368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid EnumType::emitVtsAttributeType(Formatter& out) const {
582c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
583bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
5845158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
5855158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
586e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid EnumType::emitJavaDump(
587e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
588e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
589e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
590e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(" << fqName().javaName() << ".toString("
591e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
592e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
593e45b5303e072043679483a70606f6c00dde17382Yifan Hong
594f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakovstd::vector<const EnumType*> EnumType::typeChain() const {
595f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> types;
596f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    for (const EnumType* type = this; type != nullptr;) {
597f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        types.push_back(type);
598864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
599f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        const Type* superType = type->storageType();
600f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        if (superType != nullptr && superType->isEnum()) {
601f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov            type = static_cast<const EnumType*>(superType);
602f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        } else {
603f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov            type = nullptr;
604864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
605f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    }
606f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov
607f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    return types;
608f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov}
609864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
610f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakovstd::vector<const EnumType*> EnumType::superTypeChain() const {
611f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    const Type* superType = storageType();
612f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    if (superType == nullptr || !superType->isEnum()) {
613f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        return {};
614864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
615f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    return static_cast<const EnumType*>(superType)->typeChain();
616864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
617864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
61885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
61985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
62085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
62185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
622019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
623019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
624019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
625019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
626019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
627019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
628019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
629019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
630019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
631019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
632019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
633019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
634019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
635019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
636019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
637019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
638019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
639368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid EnumType::emitExportedHeader(Formatter& out, bool forJava) const {
640019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
641019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
642019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
643019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
644019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
645019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
646019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
647db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        name = nameParam->getSingleString();
648db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
649019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
650db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    bool exportParent = true;
651db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
652db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParentParam != nullptr) {
653db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        exportParent = exportParentParam->getSingleBool();
654019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
655019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
656b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
657b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
658b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
659db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valuePrefix = prefixParam->getSingleString();
660b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
661b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
66273cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    std::string valueSuffix;
66373cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
66473cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    if (suffixParam != nullptr) {
665db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valueSuffix = suffixParam->getSingleString();
66673cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    }
66773cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
668019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
6691c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
670019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
671db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    std::vector<const EnumType *> chain;
672db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParent) {
673f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        chain = typeChain();
674db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    } else {
675db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        chain = { this };
676db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
677db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland
6781c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
6791c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
6801c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
6811c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
6821c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
6831c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6841c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
6851c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
6861c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
6871c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
6881c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6891c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
6904ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            scalarType->getJavaType(false /* forInitializer */);
6911c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6921c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
6931c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
6941c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
6951c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
6961c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
6971c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
6981c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
6991c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
7001c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
70173cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland                    << valueSuffix
7021c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
7031c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7041c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
7051c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
7061c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
7071c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
7081c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7091c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
7101c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7111c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
712505e56125eba2ce327892646eed799419240e59dTimur Iskhakov                if (!comment.empty()) {
7131c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
7141c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
7151c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7161c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
7171c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
7181c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
7191c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7201c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
7211c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
7221c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
7231c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
7241c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
7251c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
726368e46077eb9fbe52242e037a5b9de91693fe70fSteven Moreland        return;
7271c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
728019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
729019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
730019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
731019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
732019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
733019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
734019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
735019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
736019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
737019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
738019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
739019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
740019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
74173cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland            out << valuePrefix << entry->name() << valueSuffix;
742019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
743019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
744019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
745019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
746019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
747019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
748019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
749019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
750505e56125eba2ce327892646eed799419240e59dTimur Iskhakov            if (!comment.empty()) {
751019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
752019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
753019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
754019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
755019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
756019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
757019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
758019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
759019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
760019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
761019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
762019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
763019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
764019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
765019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
766019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
767019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
76831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
76931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
770cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur IskhakovEnumValue::EnumValue(const char* name, ConstantExpression* value, const Location& location)
771cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    : mName(name), mValue(value), mLocation(location), mIsAutoFill(false) {}
77231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
77331629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
77431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
77531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
77631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
777c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hongstd::string EnumValue::value(ScalarType::Kind castKind) const {
778f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
779c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    return mValue->value(castKind);
7805788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
7815788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
782fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
783f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
784f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
7855788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
786fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
787f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
788f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
78919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
7905788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
791fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
792f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
793505e56125eba2ce327892646eed799419240e59dTimur Iskhakov    if (mValue->descriptionIsTrivial()) return "";
794f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
795f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
796f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
797f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
798f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
799f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
800f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
801f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
802cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovvoid EnumValue::autofill(const EnumType* prevType, EnumValue* prevValue, const ScalarType* type) {
803cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    // Value is defined explicitly
8047296af19687b1c90dfd238398cd2c8ccb6bcd232Timur Iskhakov    if (mValue != nullptr) return;
805cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
806cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    CHECK((prevType == nullptr) == (prevValue == nullptr));
807cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
808f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
809cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (prevValue == nullptr) {
8107296af19687b1c90dfd238398cd2c8ccb6bcd232Timur Iskhakov        mValue = ConstantExpression::Zero(type->getKind()).release();
811f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
812cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        std::string description = prevType->fullName() + "." + prevValue->name() + " implicitly";
813cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        auto* prevReference = new ReferenceConstantExpression(
814cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            Reference<LocalIdentifier>(prevValue, mLocation), description);
815cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        mValue = prevReference->addOne(type->getKind()).release();
816f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
817f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
818f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
819f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
820f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
821f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
822f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
823f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
824f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
82531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
82631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
827cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovconst Location& EnumValue::location() const {
828cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return mLocation;
829cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
830cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
831abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong////////////////////////////////////////////////////////////////////////////////
832abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
833c14dd6e8452b43d2ced67c891070d09890374377Yifan HongBitFieldType::BitFieldType(Scope* parent) : TemplatedType(parent) {}
834c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong
835abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hongbool BitFieldType::isBitField() const {
836abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong    return true;
837abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong}
838abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
839c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongconst EnumType* BitFieldType::getElementEnumType() const {
840c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    CHECK(mElementType.get() != nullptr && mElementType->isEnum());
841c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return static_cast<const EnumType*>(mElementType.get());
842c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong}
843c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong
8443f1d26ed2a4843498c187126f95bed67838e08a4Timur Iskhakovstd::string BitFieldType::templatedTypeName() const {
8453f1d26ed2a4843498c187126f95bed67838e08a4Timur Iskhakov    return "mask";
846c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
847c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
84824e605b5194d969a1558d94896d69cc554881e46Timur Iskhakovbool BitFieldType::isCompatibleElementType(const Type* elementType) const {
849c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return elementType->isEnum();
850c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
851c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
852c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongconst ScalarType *BitFieldType::resolveToScalarType() const {
853c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return mElementType->resolveToScalarType();
854c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
855c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
856c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getCppType(StorageMode mode,
857c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                                 bool specifyNamespaces) const {
858c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return getElementEnumType()->getBitfieldCppType(mode, specifyNamespaces);
859c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
860c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
861c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaType(bool forInitializer) const {
862c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return getElementEnumType()->getBitfieldJavaType(forInitializer);
863c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
864c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
865c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaSuffix() const {
866c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaSuffix();
867c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
868c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
869c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaWrapperType() const {
870c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return getElementEnumType()->getBitfieldJavaWrapperType();
871c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
872c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
873c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getVtsType() const {
874c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "TYPE_MASK";
875c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
876c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
8778c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hongbool BitFieldType::isElidableType() const {
8788c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong    return resolveToScalarType()->isElidableType();
8798c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong}
8808c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong
8815dc72fe4f6f1d2c03c75307a9bd80f055f752ed3Timur Iskhakovbool BitFieldType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
8825dc72fe4f6f1d2c03c75307a9bd80f055f752ed3Timur Iskhakov    return resolveToScalarType()->canCheckEquality(visited);
8837d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong}
8847d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong
885368e46077eb9fbe52242e037a5b9de91693fe70fSteven Morelandvoid BitFieldType::emitVtsAttributeType(Formatter& out) const {
886c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "type: " << getVtsType() << "\n";
887132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang    out << "scalar_type: \""
888132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << mElementType->resolveToScalarType()->getVtsScalarType()
889132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << "\"\n";
89024e605b5194d969a1558d94896d69cc554881e46Timur Iskhakov    out << "predefined_type: \"" << static_cast<const NamedType*>(mElementType.get())->fullName()
891505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov        << "\"\n";
892c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
893c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
894c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
895c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->getAlignmentAndSize(align, size);
896c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
897c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
898c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitReaderWriter(
899c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
900c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &name,
901c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelObj,
902c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool parcelObjIsPointer,
903c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader,
904c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        ErrorMode mode) const {
905c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->emitReaderWriterWithCast(
906c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out,
907c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            name,
908c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObj,
909c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObjIsPointer,
910c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            isReader,
911c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            mode,
912c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            true /* needsCast */);
913c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
914c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
91524e605b5194d969a1558d94896d69cc554881e46Timur Iskhakovconst EnumType* BitFieldType::getEnumType() const {
916e45b5303e072043679483a70606f6c00dde17382Yifan Hong    CHECK(mElementType->isEnum());
91724e605b5194d969a1558d94896d69cc554881e46Timur Iskhakov    return static_cast<const EnumType*>(mElementType.get());
918e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
919e45b5303e072043679483a70606f6c00dde17382Yifan Hong
920f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// a bitfield maps to the underlying scalar type in C++, so operator<< is
921f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// already defined. We can still emit useful information if the bitfield is
922f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// in a struct / union by overriding emitDump as below.
923f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongvoid BitFieldType::emitDump(
924f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        Formatter &out,
925f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &streamName,
926f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &name) const {
927e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << " += "<< getEnumType()->fqName().cppNamespace()
928e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "::toString<" << getEnumType()->getCppStackType()
929f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << ">(" << name << ");\n";
930f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
931f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
932e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid BitFieldType::emitJavaDump(
933e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
934e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
935e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
936e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(" << getEnumType()->fqName().javaName() << ".dumpBitfield("
937e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
938e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
939e45b5303e072043679483a70606f6c00dde17382Yifan Hong
940c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitJavaFieldReaderWriter(
941c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
942c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        size_t depth,
943c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelName,
944c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &blobName,
945c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &fieldName,
946c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &offset,
947c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader) const {
948c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->emitJavaFieldReaderWriter(
949c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out, depth, parcelName, blobName, fieldName, offset, isReader);
950c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
951c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
952c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
953c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
954