EnumType.cpp revision 6961d3f487ba89ff73d89ec78f148cd130d27fa5
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
179c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongstd::string EnumType::getBitfieldCppType(StorageMode mode, bool specifyNamespaces) const {
180c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return resolveToScalarType()->getCppType(mode, specifyNamespaces);
181c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong}
18263f399021d053453704d41845d4ebcc06fe01738Timur Iskhakov
183c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongstd::string EnumType::getBitfieldJavaType(bool forInitializer) const {
184c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return resolveToScalarType()->getJavaType(forInitializer);
185c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong}
186c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong
187c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongstd::string EnumType::getBitfieldJavaWrapperType() const {
188c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return resolveToScalarType()->getJavaWrapperType();
189e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
190e45b5303e072043679483a70606f6c00dde17382Yifan Hong
191f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongLocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
192f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
193f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
194f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
195f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        for(EnumValue *v : type->values()) {
196f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if(v->name() == name) {
197f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                return v;
198f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            }
199f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
200f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
201f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return nullptr;
202f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
203f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
204881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid EnumType::emitReaderWriter(
205881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
206881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
207881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
208881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
209881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
210881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
211737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
212737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    CHECK(scalarType != NULL);
213737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
214737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    scalarType->emitReaderWriterWithCast(
215737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            out,
216737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            name,
217737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObj,
218737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObjIsPointer,
219737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            isReader,
220737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            mode,
221737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            true /* needsCast */);
222881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
223881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
22485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::emitJavaFieldReaderWriter(
22585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
2264c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
227709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
22885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
22985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
23085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
23185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
23285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    return mStorageType->emitJavaFieldReaderWriter(
233709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            out, depth, parcelName, blobName, fieldName, offset, isReader);
23485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
23585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
236881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberstatus_t EnumType::emitTypeDeclarations(Formatter &out) const {
237737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
238e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
239737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
2403b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
241881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
242881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "enum class "
2430e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        << localName()
244881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " : "
245e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
246881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " {\n";
247881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
248881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
249881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
250f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
2518d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2528d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
2538d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        const auto &type = *it;
2548d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2558d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        for (const auto &entry : type->values()) {
2568d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber            out << entry->name();
2578d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
258fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->cppValue(scalarType->getKind());
259f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for c++.
260f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << " = " << value;
2618d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
2625788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << ",";
2635788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
264fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
265505e56125eba2ce327892646eed799419240e59dTimur Iskhakov            if (!comment.empty()) {
2665788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong                out << " // " << comment;
2675788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            }
2685788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
2695788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << "\n";
2708d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        }
271881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
272881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
273881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
274881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "};\n\n";
275881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
276881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return OK;
277881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
278881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
279fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakovvoid EnumType::emitTypeForwardDeclaration(Formatter& out) const {
280fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov    const ScalarType* scalarType = mStorageType->resolveToScalarType();
281fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov    const std::string storageType = scalarType->getCppStackType();
282fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov
283fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov    out << "enum class " << localName() << " : " << storageType << ";\n";
284fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov}
285fd3f250dfb0f1a990c29a76de184830e6dd9e883Timur Iskhakov
2866961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Morelandvoid EnumType::emitIteratorDeclaration(Formatter& out) const {
2876961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    size_t elementCount = 0;
2886961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    for (const auto* type : typeChain()) {
2896961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        elementCount += type->mValues.size();
2906961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    }
2916961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
2926961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "template<> struct hidl_enum_iterator<" << getCppStackType() << ">\n";
2936961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out.block([&] {
2946961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "const " << getCppStackType() << "* begin() { return static_begin(); }\n";
2956961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "const " << getCppStackType() << "* end() { return begin() + " << elementCount
2966961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            << "; }\n";
2976961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "private:\n";
2986961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out << "static const " << getCppStackType() << "* static_begin() ";
2996961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        out.block([&] {
3006961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            out << "static const " << getCppStackType() << " kVals[" << elementCount << "] ";
3016961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            out.block([&] {
3026961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                auto enumerators = typeChain();
3036961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                std::reverse(enumerators.begin(), enumerators.end());
3046961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                for (const auto* type : enumerators) {
3056961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                    for (const auto* enumValue : type->mValues) {
3066961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                        out << fullName() << "::" << enumValue->name() << ",\n";
3076961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                    }
3086961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland                }
3096961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            }) << ";\n";
3106961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland            out << "return &kVals[0];\n";
3116961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland        });
3126961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    }) << ";\n\n";
3136961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland}
3146961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3152820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdharyvoid EnumType::emitEnumBitwiseOperator(
3162820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        Formatter &out,
317c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool lhsIsEnum,
318c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool rhsIsEnum,
3192820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        const std::string &op) const {
320e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
321e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
322e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
3233b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
324e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
325c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr "
326c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType
3272820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << " operator"
3282820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << op
329c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << "(const "
330c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (lhsIsEnum ? fullName() : storageType)
331c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " lhs, const "
332c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << (rhsIsEnum ? fullName() : storageType)
333c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << " rhs) {\n";
334e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
33533223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
336c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return static_cast<"
337c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << storageType
338c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            << ">(";
339e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
340c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (lhsIsEnum) {
341c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
342c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
343c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(lhs)";
344c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
345c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "lhs";
346c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
347c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << " " << op << " ";
348c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        if (rhsIsEnum) {
349c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "static_cast<"
350c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << storageType
351c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                << ">(rhs)";
352c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        } else {
353c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out << "rhs";
354c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        }
355c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << ");\n";
356c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
357e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
358c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "}\n\n";
359c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
360e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
361c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid EnumType::emitBitFieldBitwiseAssignmentOperator(
362c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
363c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &op) const {
364c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
365c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    CHECK(scalarType != nullptr);
366e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
367c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    const std::string storageType = scalarType->getCppStackType();
368c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
369c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "constexpr " << storageType << " &operator" << op << "=("
370c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        << storageType << "& v, const " << fullName() << " e) {\n";
371c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
37233223ca2a9b8126d357e0986905fa35c0970a30eYifan Hong    out.indent([&] {
373c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
374c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        out << "return v;\n";
375c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    });
376e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
377e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "}\n\n";
378e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
379e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
3806961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Morelandvoid EnumType::emitGlobalTypeDeclarations(Formatter& out) const {
3816961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "namespace android {\n";
3826961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "namespace hardware {\n";
3836961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3846961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    emitIteratorDeclaration(out);
3856961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3866961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "}  // namespace hardware\n";
3876961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland    out << "}  // namespace android\n";
3886961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland}
3896961d3f487ba89ff73d89ec78f148cd130d27fa5Steven Moreland
3904b8f7a11f794d9b4899af92a856b4a03b80b31e8Steven Morelandstatus_t EnumType::emitPackageTypeDeclarations(Formatter& out) const {
391c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
392c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "|");
393c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "|");
394c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
395c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true  /* rhsIsEnum */, "&");
396c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitEnumBitwiseOperator(out, true  /* lhsIsEnum */, false /* rhsIsEnum */, "&");
397c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
398c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "|");
399c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    emitBitFieldBitwiseAssignmentOperator(out, "&");
400e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
401bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    // TODO(b/65200821): remove these ifndefs
402bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out << "#ifdef REALLY_IS_HIDL_INTERNAL_LIB" << gCurrentCompileName << "\n";
403bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        // toString for bitfields, equivalent to dumpBitfield in Java
404bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "template<typename>\n"
405bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << "std::string toString("
406bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << resolveToScalarType()->getCppArgumentType()
407bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << " o);\n";
408bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "template<>\n"
409bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << "std::string toString<" << getCppStackType() << ">("
410bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << resolveToScalarType()->getCppArgumentType()
411bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << " o);\n\n";
412bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
413bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        // toString for enum itself
414bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "std::string toString("
415bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << getCppArgumentType()
416bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << " o);\n\n";
417bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out << "#else\n";
418bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    const ScalarType *scalarType = mStorageType->resolveToScalarType();
419bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    CHECK(scalarType != NULL);
420bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
421f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<typename>\n"
422bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        << "static inline std::string toString(" << resolveToScalarType()->getCppArgumentType()
423f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o);\n";
424f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
425bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        << "inline std::string toString<" << getCppStackType() << ">("
426bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        << scalarType->getCppArgumentType() << " o) ";
427bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out.block([&] {
428bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        // include toHexString for scalar types
429bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "using ::android::hardware::details::toHexString;\n"
430bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << "std::string os;\n"
431bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << getBitfieldCppType(StorageMode_Stack) << " flipped = 0;\n"
432bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            << "bool first = true;\n";
433bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        for (EnumValue *value : values()) {
434bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            std::string valueName = fullName() + "::" + value->name();
435bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            out.sIf("(o & " + valueName + ")" +
436bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    " == static_cast<" + scalarType->getCppStackType() +
437bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    ">(" + valueName + ")", [&] {
438bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                out << "os += (first ? \"\" : \" | \");\n"
439bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    << "os += \"" << value->name() << "\";\n"
440bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    << "first = false;\n"
441bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                    << "flipped |= " << valueName << ";\n";
442bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            }).endl();
443bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        }
444bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        // put remaining bits
445bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out.sIf("o != flipped", [&] {
446bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            out << "os += (first ? \"\" : \" | \");\n";
447bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            scalarType->emitHexDump(out, "os", "o & (~flipped)");
448bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        });
449bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "os += \" (\";\n";
450bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        scalarType->emitHexDump(out, "os", "o");
451bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "os += \")\";\n";
452bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
453bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "return os;\n";
454bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    }).endl().endl();
455f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
456bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out << "static inline std::string toString(" << getCppArgumentType() << " o) ";
457bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
458bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out.block([&] {
459bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "using ::android::hardware::details::toHexString;\n";
460bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        for (EnumValue *value : values()) {
461bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            out.sIf("o == " + fullName() + "::" + value->name(), [&] {
462bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland                out << "return \"" << value->name() << "\";\n";
463bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            }).endl();
464bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        }
465bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "std::string os;\n";
466bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        scalarType->emitHexDump(out, "os",
467bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland            "static_cast<" + scalarType->getCppStackType() + ">(o)");
468bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland        out << "return os;\n";
469bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    }).endl().endl();
470bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    out << "#endif  // REALLY_IS_HIDL_INTERNAL_LIB\n";
471f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
472f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    return OK;
473f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
474f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
4758c90cc59bf93bd0c08970b4488067a33015d4a1cChih-Hung Hsiehstatus_t EnumType::emitTypeDefinitions(Formatter& out, const std::string& /* prefix */) const {
476bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland    // TODO(b/65200821): remove toString from .cpp once all prebuilts are rebuilt
477bf71421a737c2b4f518bc3b21d0e21c6b2e00fdbSteven Moreland
478f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
479f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    CHECK(scalarType != NULL);
480f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
481f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out << "template<>\n"
482f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << "std::string toString<" << getCppStackType() << ">("
483870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << scalarType->getCppArgumentType()
484f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << " o) ";
485f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    out.block([&] {
486f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        // include toHexString for scalar types
487f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "using ::android::hardware::details::toHexString;\n"
488870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << "std::string os;\n"
489c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong            << getBitfieldCppType(StorageMode_Stack) << " flipped = 0;\n"
490870d1a7ccd70bd710128993de401278614d1975eYifan Hong            << "bool first = true;\n";
4910a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong
4920a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        forEachValueFromRoot([&](EnumValue* value) {
493870d1a7ccd70bd710128993de401278614d1975eYifan Hong            std::string valueName = fullName() + "::" + value->name();
494870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out.sIf("(o & " + valueName + ")" +
495870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    " == static_cast<" + scalarType->getCppStackType() +
496870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    ">(" + valueName + ")", [&] {
497870d1a7ccd70bd710128993de401278614d1975eYifan Hong                out << "os += (first ? \"\" : \" | \");\n"
498870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    << "os += \"" << value->name() << "\";\n"
499f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong                    << "first = false;\n"
500870d1a7ccd70bd710128993de401278614d1975eYifan Hong                    << "flipped |= " << valueName << ";\n";
501f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong            }).endl();
5020a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        });
503870d1a7ccd70bd710128993de401278614d1975eYifan Hong        // put remaining bits
504870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out.sIf("o != flipped", [&] {
505870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out << "os += (first ? \"\" : \" | \");\n";
506870d1a7ccd70bd710128993de401278614d1975eYifan Hong            scalarType->emitHexDump(out, "os", "o & (~flipped)");
507870d1a7ccd70bd710128993de401278614d1975eYifan Hong        });
508f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \" (\";\n";
509f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        scalarType->emitHexDump(out, "os", "o");
510f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "os += \")\";\n";
511f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
512f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        out << "return os;\n";
513f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong    }).endl().endl();
514f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
515870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out << "std::string toString("
516870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << getCppArgumentType()
517870d1a7ccd70bd710128993de401278614d1975eYifan Hong        << " o) ";
518870d1a7ccd70bd710128993de401278614d1975eYifan Hong
519870d1a7ccd70bd710128993de401278614d1975eYifan Hong    out.block([&] {
520870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "using ::android::hardware::details::toHexString;\n";
5210a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong
5220a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        forEachValueFromRoot([&](EnumValue* value) {
523870d1a7ccd70bd710128993de401278614d1975eYifan Hong            out.sIf("o == " + fullName() + "::" + value->name(), [&] {
524870d1a7ccd70bd710128993de401278614d1975eYifan Hong                out << "return \"" << value->name() << "\";\n";
525870d1a7ccd70bd710128993de401278614d1975eYifan Hong            }).endl();
5260a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        });
5270a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong
528870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "std::string os;\n";
529870d1a7ccd70bd710128993de401278614d1975eYifan Hong        scalarType->emitHexDump(out, "os",
530870d1a7ccd70bd710128993de401278614d1975eYifan Hong            "static_cast<" + scalarType->getCppStackType() + ">(o)");
531870d1a7ccd70bd710128993de401278614d1975eYifan Hong        out << "return os;\n";
532870d1a7ccd70bd710128993de401278614d1975eYifan Hong    }).endl().endl();
533870d1a7ccd70bd710128993de401278614d1975eYifan Hong
534e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    return OK;
535e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
536e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
537e45b5303e072043679483a70606f6c00dde17382Yifan Hongstatus_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool atTopLevel) const {
5382831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
5392831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
5402831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
541e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "public "
542e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << (atTopLevel ? "" : "static ")
543e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "final class "
5442831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
5452831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
5462831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
5472831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
5482831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
5494c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
5504ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        scalarType->getJavaType(false /* forInitializer */);
5512831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
552f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
5532831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
5542831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
5552831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
5562831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
5572831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
5582831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
5592831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
5602831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
561ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
562ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
5632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
564f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
565fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
566f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
567f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
5682831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
56919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
57019ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
571fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
572505e56125eba2ce327892646eed799419240e59dTimur Iskhakov            if (!comment.empty()) {
57319ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
57419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
57519ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
57619ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
5772831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
5782831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
5792831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
580e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "public static final String toString("
581e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << typeName << " o) ";
582e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out.block([&] {
5830a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        forEachValueFromRoot([&](EnumValue* value) {
584e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out.sIf("o == " + value->name(), [&] {
585e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "return \"" << value->name() << "\";\n";
586e45b5303e072043679483a70606f6c00dde17382Yifan Hong            }).endl();
5870a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        });
588e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "return \"0x\" + ";
589e45b5303e072043679483a70606f6c00dde17382Yifan Hong        scalarType->emitConvertToJavaHexString(out, "o");
590e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << ";\n";
591e45b5303e072043679483a70606f6c00dde17382Yifan Hong    }).endl();
592e45b5303e072043679483a70606f6c00dde17382Yifan Hong
593c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    auto bitfieldType = getBitfieldJavaType(false /* forInitializer */);
594c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    auto bitfieldWrapperType = getBitfieldJavaWrapperType();
595e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << "\n"
596e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "public static final String dumpBitfield("
597e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << bitfieldType << " o) ";
598e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out.block([&] {
599e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "java.util.ArrayList<String> list = new java.util.ArrayList<>();\n";
600e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << bitfieldType << " flipped = 0;\n";
6010a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        forEachValueFromRoot([&](EnumValue* value) {
602dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong            if (value->constExpr()->castSizeT() == 0) {
603dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong                out << "list.add(\"" << value->name() << "\"); // " << value->name() << " == 0\n";
6040a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong                return;  // continue to next value
605dd7c57474d49cd3860c0b076fc25d8bc68ae0ec3Yifan Hong            }
606e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out.sIf("(o & " + value->name() + ") == " + value->name(), [&] {
607e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "list.add(\"" << value->name() << "\");\n";
608e45b5303e072043679483a70606f6c00dde17382Yifan Hong                out << "flipped |= " << value->name() << ";\n";
609e45b5303e072043679483a70606f6c00dde17382Yifan Hong            }).endl();
6100a9cc8627f85104721f7b32c7ced2c8b1062004bYifan Hong        });
611e45b5303e072043679483a70606f6c00dde17382Yifan Hong        // put remaining bits
612e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out.sIf("o != flipped", [&] {
613e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out << "list.add(\"0x\" + ";
614e45b5303e072043679483a70606f6c00dde17382Yifan Hong            scalarType->emitConvertToJavaHexString(out, "o & (~flipped)");
615e45b5303e072043679483a70606f6c00dde17382Yifan Hong            out << ");\n";
616e45b5303e072043679483a70606f6c00dde17382Yifan Hong        }).endl();
617e45b5303e072043679483a70606f6c00dde17382Yifan Hong        out << "return String.join(\" | \", list);\n";
618e45b5303e072043679483a70606f6c00dde17382Yifan Hong    }).endl().endl();
619e45b5303e072043679483a70606f6c00dde17382Yifan Hong
6202831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
6212831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
6222831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
6232831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return OK;
6242831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
6252831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
6265158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
627c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
628c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong
629bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
630c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
631c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
6325158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
633864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
634c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
635c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong        << scalarType->getVtsScalarType()
636c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
637f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> chain = typeChain();
638864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
639864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
640864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
641864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
642864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
643864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
644c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
645c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
646c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            // use autofilled values for vts.
647c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            std::string value = entry->value(scalarType->getKind());
648c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            CHECK(!value.empty());
649c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            out << mStorageType->resolveToScalarType()->getVtsScalarType()
650c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << ": "
651c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << value
652c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << "\n";
653c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
654c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
655864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
6565158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
657864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
6585158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
6595158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
6605158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
6615158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
6625158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
663864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t EnumType::emitVtsAttributeType(Formatter &out) const {
664c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
665bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
6665158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
6675158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
6685158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
669e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid EnumType::emitJavaDump(
670e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
671e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
672e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
673e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(" << fqName().javaName() << ".toString("
674e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
675e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
676e45b5303e072043679483a70606f6c00dde17382Yifan Hong
677f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakovstd::vector<const EnumType*> EnumType::typeChain() const {
678f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    std::vector<const EnumType*> types;
679f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    for (const EnumType* type = this; type != nullptr;) {
680f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        types.push_back(type);
681864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
682f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        const Type* superType = type->storageType();
683f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        if (superType != nullptr && superType->isEnum()) {
684f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov            type = static_cast<const EnumType*>(superType);
685f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        } else {
686f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov            type = nullptr;
687864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
688f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    }
689f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov
690f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    return types;
691f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov}
692864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
693f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakovstd::vector<const EnumType*> EnumType::superTypeChain() const {
694f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    const Type* superType = storageType();
695f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    if (superType == nullptr || !superType->isEnum()) {
696f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        return {};
697864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
698f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov    return static_cast<const EnumType*>(superType)->typeChain();
699864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
700864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
70185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
70285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
70385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
70485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
705019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
706019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
707019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
708019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
709019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
710019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
711019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
712019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
713019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
714019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
715019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
716019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
717019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
718019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
719019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
720019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
721019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
7221c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huberstatus_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
723019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
724019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
725019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
726019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
727019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
728019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
729019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
730db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        name = nameParam->getSingleString();
731db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
732019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
733db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    bool exportParent = true;
734db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
735db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParentParam != nullptr) {
736db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        exportParent = exportParentParam->getSingleBool();
737019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
738019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
739b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
740b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
741b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
742db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valuePrefix = prefixParam->getSingleString();
743b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
744b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
74573cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    std::string valueSuffix;
74673cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
74773cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    if (suffixParam != nullptr) {
748db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        valueSuffix = suffixParam->getSingleString();
74973cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    }
75073cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
751019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
7521c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
753019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
754db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    std::vector<const EnumType *> chain;
755db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    if (exportParent) {
756f1b902d10bd2d71ad7f4769620678101821fd5d1Timur Iskhakov        chain = typeChain();
757db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    } else {
758db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland        chain = { this };
759db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland    }
760db1b1b638865a2043c9cddd8c865751e9742b181Steven Moreland
7611c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
7621c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
7631c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
7641c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
7651c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
7661c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7671c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
7681c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
7691c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
7701c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
7711c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7721c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
7734ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            scalarType->getJavaType(false /* forInitializer */);
7741c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7751c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
7761c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
7771c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7781c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
7791c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
7801c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
7811c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
7821c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
7831c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
78473cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland                    << valueSuffix
7851c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
7861c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7871c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
7881c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
7891c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
7901c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
7911c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7921c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
7931c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7941c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
795505e56125eba2ce327892646eed799419240e59dTimur Iskhakov                if (!comment.empty()) {
7961c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
7971c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
7981c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
7991c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
8001c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
8011c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
8021c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
8031c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
8041c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
8051c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
8061c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
8071c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
8081c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
8091c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        return OK;
8101c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
811019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
812019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
813019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
814019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
815019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
816019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
817019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
818019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
819019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
820019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
821019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
822019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
823019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
82473cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland            out << valuePrefix << entry->name() << valueSuffix;
825019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
826019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
827019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
828019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
829019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
830019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
831019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
832019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
833505e56125eba2ce327892646eed799419240e59dTimur Iskhakov            if (!comment.empty()) {
834019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
835019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
836019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
837019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
838019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
839019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
840019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
841019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
842019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
843019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
844019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
845019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
846019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
847019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
848019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
849019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
850019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return OK;
851019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
852019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
85331629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
85431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
855cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur IskhakovEnumValue::EnumValue(const char* name, ConstantExpression* value, const Location& location)
856cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    : mName(name), mValue(value), mLocation(location), mIsAutoFill(false) {}
85731629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
85831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
85931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
86031629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
86131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
862c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hongstd::string EnumValue::value(ScalarType::Kind castKind) const {
863f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
864c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    return mValue->value(castKind);
8655788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
8665788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
867fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
868f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
869f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
8705788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
871fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
872f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
873f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
87419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
8755788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
876fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
877f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
878505e56125eba2ce327892646eed799419240e59dTimur Iskhakov    if (mValue->descriptionIsTrivial()) return "";
879f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
880f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
881f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
882f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
883f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
884f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
885f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
886f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
887cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovvoid EnumValue::autofill(const EnumType* prevType, EnumValue* prevValue, const ScalarType* type) {
888cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    // Value is defined explicitly
8897296af19687b1c90dfd238398cd2c8ccb6bcd232Timur Iskhakov    if (mValue != nullptr) return;
890cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
891cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    CHECK((prevType == nullptr) == (prevValue == nullptr));
892cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
893f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
894cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    if (prevValue == nullptr) {
8957296af19687b1c90dfd238398cd2c8ccb6bcd232Timur Iskhakov        mValue = ConstantExpression::Zero(type->getKind()).release();
896f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
897cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        std::string description = prevType->fullName() + "." + prevValue->name() + " implicitly";
898cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        auto* prevReference = new ReferenceConstantExpression(
899cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov            Reference<LocalIdentifier>(prevValue, mLocation), description);
900cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov        mValue = prevReference->addOne(type->getKind()).release();
901f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
902f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
903f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
904f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
905f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
906f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
907f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
908f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
909f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
91031629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
91131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
912cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakovconst Location& EnumValue::location() const {
913cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov    return mLocation;
914cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov}
915cec46c48853a8c1246656d0095a9faa3fad5c4f9Timur Iskhakov
916abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong////////////////////////////////////////////////////////////////////////////////
917abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
918c14dd6e8452b43d2ced67c891070d09890374377Yifan HongBitFieldType::BitFieldType(Scope* parent) : TemplatedType(parent) {}
919c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong
920abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hongbool BitFieldType::isBitField() const {
921abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong    return true;
922abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong}
923abf73eef7f23f0b0ba0fe85694dcd511f4e69962Yifan Hong
924c14dd6e8452b43d2ced67c891070d09890374377Yifan Hongconst EnumType* BitFieldType::getElementEnumType() const {
925c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    CHECK(mElementType.get() != nullptr && mElementType->isEnum());
926c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return static_cast<const EnumType*>(mElementType.get());
927c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong}
928c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong
9293f1d26ed2a4843498c187126f95bed67838e08a4Timur Iskhakovstd::string BitFieldType::templatedTypeName() const {
9303f1d26ed2a4843498c187126f95bed67838e08a4Timur Iskhakov    return "mask";
931c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
932c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
93324e605b5194d969a1558d94896d69cc554881e46Timur Iskhakovbool BitFieldType::isCompatibleElementType(const Type* elementType) const {
934c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return elementType->isEnum();
935c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
936c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
937c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongconst ScalarType *BitFieldType::resolveToScalarType() const {
938c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return mElementType->resolveToScalarType();
939c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
940c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
941c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getCppType(StorageMode mode,
942c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong                                 bool specifyNamespaces) const {
943c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return getElementEnumType()->getBitfieldCppType(mode, specifyNamespaces);
944c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
945c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
946c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaType(bool forInitializer) const {
947c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return getElementEnumType()->getBitfieldJavaType(forInitializer);
948c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
949c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
950c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaSuffix() const {
951c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->getJavaSuffix();
952c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
953c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
954c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getJavaWrapperType() const {
955c14dd6e8452b43d2ced67c891070d09890374377Yifan Hong    return getElementEnumType()->getBitfieldJavaWrapperType();
956c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
957c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
958c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstd::string BitFieldType::getVtsType() const {
959c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return "TYPE_MASK";
960c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
961c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
9628c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hongbool BitFieldType::isElidableType() const {
9638c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong    return resolveToScalarType()->isElidableType();
9648c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong}
9658c56cbe4b107934da1bea14475b5cc41280a4f01Yifan Hong
9665dc72fe4f6f1d2c03c75307a9bd80f055f752ed3Timur Iskhakovbool BitFieldType::deepCanCheckEquality(std::unordered_set<const Type*>* visited) const {
9675dc72fe4f6f1d2c03c75307a9bd80f055f752ed3Timur Iskhakov    return resolveToScalarType()->canCheckEquality(visited);
9687d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong}
9697d1839fe75d3ddc13321ee176ba73b610d884beeYifan Hong
970c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongstatus_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
971c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    out << "type: " << getVtsType() << "\n";
972132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang    out << "scalar_type: \""
973132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << mElementType->resolveToScalarType()->getVtsScalarType()
974132362395dbc1ec52a70a5a4587ce1dd7616a8daZhuoyao Zhang        << "\"\n";
97524e605b5194d969a1558d94896d69cc554881e46Timur Iskhakov    out << "predefined_type: \"" << static_cast<const NamedType*>(mElementType.get())->fullName()
976505316c499a4dbb95f6567e8531fb6f1e74c3dedTimur Iskhakov        << "\"\n";
977c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return OK;
978c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
979c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
980c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
981c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->getAlignmentAndSize(align, size);
982c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
983c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
984c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitReaderWriter(
985c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
986c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &name,
987c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelObj,
988c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool parcelObjIsPointer,
989c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader,
990c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        ErrorMode mode) const {
991c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    resolveToScalarType()->emitReaderWriterWithCast(
992c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out,
993c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            name,
994c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObj,
995c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            parcelObjIsPointer,
996c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            isReader,
997c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            mode,
998c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            true /* needsCast */);
999c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
1000c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
100124e605b5194d969a1558d94896d69cc554881e46Timur Iskhakovconst EnumType* BitFieldType::getEnumType() const {
1002e45b5303e072043679483a70606f6c00dde17382Yifan Hong    CHECK(mElementType->isEnum());
100324e605b5194d969a1558d94896d69cc554881e46Timur Iskhakov    return static_cast<const EnumType*>(mElementType.get());
1004e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
1005e45b5303e072043679483a70606f6c00dde17382Yifan Hong
1006f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// a bitfield maps to the underlying scalar type in C++, so operator<< is
1007f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// already defined. We can still emit useful information if the bitfield is
1008f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong// in a struct / union by overriding emitDump as below.
1009f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hongvoid BitFieldType::emitDump(
1010f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        Formatter &out,
1011f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &streamName,
1012f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        const std::string &name) const {
1013e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << " += "<< getEnumType()->fqName().cppNamespace()
1014e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << "::toString<" << getEnumType()->getCppStackType()
1015f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong        << ">(" << name << ");\n";
1016f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong}
1017f5cc2f74e86504f7904a0a24e7fcc00fa19cd579Yifan Hong
1018e45b5303e072043679483a70606f6c00dde17382Yifan Hongvoid BitFieldType::emitJavaDump(
1019e45b5303e072043679483a70606f6c00dde17382Yifan Hong        Formatter &out,
1020e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &streamName,
1021e45b5303e072043679483a70606f6c00dde17382Yifan Hong        const std::string &name) const {
1022e45b5303e072043679483a70606f6c00dde17382Yifan Hong    out << streamName << ".append(" << getEnumType()->fqName().javaName() << ".dumpBitfield("
1023e45b5303e072043679483a70606f6c00dde17382Yifan Hong        << name << "));\n";
1024e45b5303e072043679483a70606f6c00dde17382Yifan Hong}
1025e45b5303e072043679483a70606f6c00dde17382Yifan Hong
1026c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hongvoid BitFieldType::emitJavaFieldReaderWriter(
1027c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        Formatter &out,
1028c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        size_t depth,
1029c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &parcelName,
1030c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &blobName,
1031c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &fieldName,
1032c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        const std::string &offset,
1033c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong        bool isReader) const {
1034c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong    return resolveToScalarType()->emitJavaFieldReaderWriter(
1035c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong            out, depth, parcelName, blobName, fieldName, offset, isReader);
1036c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong}
1037c57c8bb9f368faca636bdb6b39773e72255e8b08Yifan Hong
1038c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
1039c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
1040