EnumType.cpp revision a4b53d0da8c1c6889c361fd30b913adc364163bc
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
19019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber#include "Annotation.h"
20881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber#include "ScalarType.h"
21c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
22a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <inttypes.h>
23a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <hidl-util/Formatter.h>
24737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber#include <android-base/logging.h>
25737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
26c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Hubernamespace android {
27c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
28c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas HuberEnumType::EnumType(
299ed827c8cd6e8eddb1ad9987ab9413c1de8a27dfAndreas Huber        const char *localName,
30a4b53d0da8c1c6889c361fd30b913adc364163bcYifan Hong        const Location &location,
319ed827c8cd6e8eddb1ad9987ab9413c1de8a27dfAndreas Huber        Type *storageType)
32a4b53d0da8c1c6889c361fd30b913adc364163bcYifan Hong    : Scope(localName, location),
33f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValues(),
34881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber      mStorageType(
35881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber              storageType != NULL
36881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber                ? storageType
37881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber                : new ScalarType(ScalarType::KIND_INT32)) {
38c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}
39c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
408d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst Type *EnumType::storageType() const {
418d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return mStorageType;
428d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
438d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
448d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst std::vector<EnumValue *> &EnumType::values() const {
45f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValues;
46f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
47f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
48f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumType::addValue(EnumValue *value) {
49f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(value != nullptr);
50f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
51f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    EnumValue *prev = nullptr;
52f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    std::vector<const EnumType *> chain;
53f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    getTypeChain(&chain);
54f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
55f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
56f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        if(!type->values().empty()) {
57f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            prev = type->values().back();
58f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            break;
59f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
60f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
61f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
62f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    value->autofill(prev, resolveToScalarType());
63f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValues.push_back(value);
648d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
658d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
66737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huberconst ScalarType *EnumType::resolveToScalarType() const {
67737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    return mStorageType->resolveToScalarType();
68737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber}
69737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
708d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberbool EnumType::isEnum() const {
718d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return true;
728d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
738d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
74979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string EnumType::getCppType(StorageMode,
75979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland                                 std::string *extra,
76979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland                                 bool specifyNamespaces) const {
77881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    extra->clear();
78881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
79979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland    return specifyNamespaces ? fullName() : partialCppName();
80881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
81881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
824c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huberstd::string EnumType::getJavaType(
834c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        std::string *extra, bool forInitializer) const {
844c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    return mStorageType->resolveToScalarType()->getJavaType(
854c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber            extra, forInitializer);
862831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
872831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
882831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string EnumType::getJavaSuffix() const {
892831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return mStorageType->resolveToScalarType()->getJavaSuffix();
902831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
912831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
92a3558b3b273695b31fbe1025339956966cde39c4Andreas Huberstd::string EnumType::getJavaWrapperType() const {
93a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber    return mStorageType->resolveToScalarType()->getJavaWrapperType();
94a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber}
95a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber
96c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhangstd::string EnumType::getVtsType() const {
97c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    return "TYPE_ENUM";
98c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang}
99c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang
100f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongLocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
101f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    std::vector<const EnumType *> chain;
102f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    getTypeChain(&chain);
103f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
104f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
105f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        for(EnumValue *v : type->values()) {
106f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if(v->name() == name) {
107f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                return v;
108f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            }
109f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
110f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
111f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return nullptr;
112f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
113f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
114881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid EnumType::emitReaderWriter(
115881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
116881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
117881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
118881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
119881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
120881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
121737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
122737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    CHECK(scalarType != NULL);
123737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
124737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    scalarType->emitReaderWriterWithCast(
125737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            out,
126737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            name,
127737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObj,
128737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObjIsPointer,
129737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            isReader,
130737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            mode,
131737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            true /* needsCast */);
132881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
133881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
13485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::emitJavaFieldReaderWriter(
13585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
1364c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
137709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
13885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
13985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
14085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
14185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
14285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    return mStorageType->emitJavaFieldReaderWriter(
143709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            out, depth, parcelName, blobName, fieldName, offset, isReader);
14485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
14585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
146881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberstatus_t EnumType::emitTypeDeclarations(Formatter &out) const {
147737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
148e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
149737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
150881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    std::string extra;
151e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const std::string storageType = ((Type *)scalarType)->getCppType(&extra);
152881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
153881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "enum class "
1540e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        << localName()
155881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " : "
156e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
157881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " {\n";
158881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
159881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
160881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1618d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    std::vector<const EnumType *> chain;
162864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
1638d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1648d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
1658d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        const auto &type = *it;
1668d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1678d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        for (const auto &entry : type->values()) {
1688d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber            out << entry->name();
1698d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
170fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->cppValue(scalarType->getKind());
171f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for c++.
172f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << " = " << value;
1738d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1745788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << ",";
1755788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
176fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
177fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
1785788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong                out << " // " << comment;
1795788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            }
1805788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
1815788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << "\n";
1828d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        }
183881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
184881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
185881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
186881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "};\n\n";
187881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
188881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return OK;
189881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
190881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
191e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Hubervoid EnumType::emitEnumBitwiseOrOperator(Formatter &out, bool mutating) const {
192e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
193e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
194e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
195e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    std::string extra;
196e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const std::string storageType = ((Type *)scalarType)->getCppType(&extra);
197e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
198e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "inline "
199e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << fullName()
200e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << (mutating ? " &" : "")
201e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << " operator|"
202e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << (mutating ? "=" : "")
203e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << "(\n";
204e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
205e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
206e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
207e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
208e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << fullName()
209e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << (mutating ? " &" : " ")
210e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << "lhs, "
211e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << fullName()
212e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << " rhs) {\n";
213e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
214e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
215e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    if (mutating) {
216e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        out << "lhs = ";
217e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    } else {
218e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        out << "return ";
219e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    }
220e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "static_cast<"
221e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << fullName()
222e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << ">(\n";
223e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
224e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
225e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "static_cast<"
226e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
227e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << ">(lhs) | static_cast<"
228e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
229e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << ">(rhs));\n";
230e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
231e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
232e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
233e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    if (mutating) {
234e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        out << "return lhs;\n";
235e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    }
236e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
237e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
238e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
239e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "}\n\n";
240e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
241e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
242e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huberstatus_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
243e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    emitEnumBitwiseOrOperator(out, false /* mutating */);
244e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    emitEnumBitwiseOrOperator(out, true /* mutating */);
245e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
246e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    return OK;
247e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
248e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
24985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huberstatus_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
2502831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
2512831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
2522831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2532831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "public final class "
2542831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
2552831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
2562831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2572831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
2582831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2594c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    std::string extra;  // unused, because ScalarType leaves this empty.
2604c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
2614c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        scalarType->getJavaType(&extra, false /* forInitializer */);
2622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    std::vector<const EnumType *> chain;
264864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
2652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
2672831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
2682831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2692831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
2702831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
2712831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
2722831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
273ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
274ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
2752831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
276f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
277fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
278f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
279f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
2802831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
28119ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
28219ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
283fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
284fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
28519ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
28619ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
28719ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
28819ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
2892831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
2902831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
2912831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2922831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
2932831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
2942831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2952831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return OK;
2962831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
2972831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2985158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
299bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
300c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
301c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
3025158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
303864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
304c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
305c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << mStorageType->resolveToScalarType()->getVtsScalarType()
306c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
307864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    std::vector<const EnumType *> chain;
308864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
309864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
310864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
311864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
312864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
313864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
314864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
315c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
316c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
317f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if (!entry->isAutoFill()) {
318f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                // don't autofill values for vts.
319f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                std::string value = entry->value();
320f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                CHECK(!value.empty());
321c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang                out << mStorageType->resolveToScalarType()->getVtsScalarType()
322c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang                    << ": "
323c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang                    << value
324c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang                    << "\n";
325864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            }
326c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
327c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
328864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
3295158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
330864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
3315158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
3325158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
3335158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
3345158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
3355158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
336864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t EnumType::emitVtsAttributeType(Formatter &out) const {
337c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
338bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
3395158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
3405158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
3415158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
342864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangvoid EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
343864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    out->clear();
344864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    const EnumType *type = this;
345864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (;;) {
346864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        out->push_back(type);
347864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
348864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const Type *superType = type->storageType();
349864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (superType == NULL || !superType->isEnum()) {
350864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            break;
351864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
352864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
353864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        type = static_cast<const EnumType *>(superType);
354864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
355864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
356864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
35785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
35885eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
35985eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
36085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
361019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
362019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
363019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
364019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
365019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
366019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
367019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
368019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
369019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
370019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
371019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
372019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
373019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
374019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
375019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
376019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
377019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
3781c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huberstatus_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
379019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
380019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
381019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
382019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
383019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
384019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
385019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
386019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        CHECK_EQ(nameParam->getValues()->size(), 1u);
387019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
388019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::string quotedString = nameParam->getValues()->at(0);
389019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        name = quotedString.substr(1, quotedString.size() - 2);
390019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
391019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
392b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
393b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
394b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
395b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
396b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber        CHECK_EQ(prefixParam->getValues()->size(), 1u);
397b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
398b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber        std::string quotedString = prefixParam->getValues()->at(0);
399b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber        valuePrefix = quotedString.substr(1, quotedString.size() - 2);
400b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
401b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
402019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
4031c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
404019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
4051c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
4061c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
4071c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
4081c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
4091c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
4101c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4111c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
4121c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
4131c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
4141c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4151c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4161c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        std::string extra;  // unused, because ScalarType leaves this empty.
4171c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
4181c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            scalarType->getJavaType(&extra, false /* forInitializer */);
4191c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4201c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        std::vector<const EnumType *> chain;
4211c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        getTypeChain(&chain);
4221c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4231c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
4241c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
4251c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4261c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
4271c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
4281c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
4291c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
4301c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
4311c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
4321c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
4331c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4341c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
4351c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
4361c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
4371c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
4381c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4391c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
4401c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4411c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
4421c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                if (!comment.empty() && comment != value) {
4431c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
4441c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
4451c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4461c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
4471c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
4481c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4491c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4501c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
4511c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
4521c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
4531c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4541c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
4551c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4561c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        return OK;
4571c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
458019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
459019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
460019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
461019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
462019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
463019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
464019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
465019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
466019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
467019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::vector<const EnumType *> chain;
468019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    getTypeChain(&chain);
469019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
470019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
471019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
472019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
473019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
474b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber            out << valuePrefix << entry->name();
475019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
476019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
477019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
478019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
479019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
480019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
481019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
482019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
483019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            if (!comment.empty() && comment != value) {
484019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
485019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
486019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
487019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
488019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
489019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
490019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
491019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
492019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
493019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
494019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
495019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
496019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
497019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
498019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
499019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
500019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return OK;
501019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
502019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
50331629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
50431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
505f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongEnumValue::EnumValue(const char *name, ConstantExpression *value)
50631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    : mName(name),
507f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValue(value),
508f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mIsAutoFill(false) {
50931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
51031629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
51131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
51231629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
51331629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
51431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
515fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::value() const {
516f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
517f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->value();
5185788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
5195788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
520fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
521f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
522f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
5235788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
524fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
525f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
526f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
52719ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
5285788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
529fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
530f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
531f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
532f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
533f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
534f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
535f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
536f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
537f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
538f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
539f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
540f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(mValue != nullptr)
541f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        return;
542f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
543f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    ConstantExpression *value = new ConstantExpression();
544f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(prev == nullptr) {
545f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = ConstantExpression::Zero(type->getKind());
546f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
547f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        CHECK(prev->mValue != nullptr);
548f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = prev->mValue->addOne();
549f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
550f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValue = value;
551f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
552f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
553f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
554f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
555f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
556f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
557f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
558f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
55931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
56031629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
561c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
562c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
563