EnumType.cpp revision 1c71fd5ab3381d1c59671adf2b8ca5c9a3f74401
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(),
341c71fd5ab3381d1c59671adf2b8ca5c9a3f74401Steven Moreland      mStorageType(storageType) {
35c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}
36c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
378d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst Type *EnumType::storageType() const {
388d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return mStorageType;
398d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
408d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
418d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberconst std::vector<EnumValue *> &EnumType::values() const {
42f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValues;
43f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
44f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
45f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumType::addValue(EnumValue *value) {
46f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(value != nullptr);
47f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
48f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    EnumValue *prev = nullptr;
49f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    std::vector<const EnumType *> chain;
50f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    getTypeChain(&chain);
51f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
52f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
53f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        if(!type->values().empty()) {
54f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            prev = type->values().back();
55f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            break;
56f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
57f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
58f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
59f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    value->autofill(prev, resolveToScalarType());
60f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValues.push_back(value);
618d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
628d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
63737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huberconst ScalarType *EnumType::resolveToScalarType() const {
64737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    return mStorageType->resolveToScalarType();
65737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber}
66737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
678d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huberbool EnumType::isEnum() const {
688d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    return true;
698d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber}
708d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
71979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string EnumType::getCppType(StorageMode,
72979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland                                 bool specifyNamespaces) const {
73979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland    return specifyNamespaces ? fullName() : partialCppName();
74881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
75881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
764ed1347cd29e6e07acad368891bb03078c798abaYifan Hongstd::string EnumType::getJavaType(bool forInitializer) const {
774ed1347cd29e6e07acad368891bb03078c798abaYifan Hong    return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
782831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
792831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
802831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string EnumType::getJavaSuffix() const {
812831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return mStorageType->resolveToScalarType()->getJavaSuffix();
822831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
832831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
84a3558b3b273695b31fbe1025339956966cde39c4Andreas Huberstd::string EnumType::getJavaWrapperType() const {
85a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber    return mStorageType->resolveToScalarType()->getJavaWrapperType();
86a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber}
87a3558b3b273695b31fbe1025339956966cde39c4Andreas Huber
88c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhangstd::string EnumType::getVtsType() const {
89c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    return "TYPE_ENUM";
90c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang}
91c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang
92f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongLocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
93f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    std::vector<const EnumType *> chain;
94f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    getTypeChain(&chain);
95f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    for (auto it = chain.begin(); it != chain.end(); ++it) {
96f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        const auto &type = *it;
97f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        for(EnumValue *v : type->values()) {
98f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            if(v->name() == name) {
99f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong                return v;
100f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            }
101f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        }
102f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
103f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return nullptr;
104f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
105f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
106881227d860c59471eee31d39946e96ce2daa35d6Andreas Hubervoid EnumType::emitReaderWriter(
107881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        Formatter &out,
108881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &name,
109881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        const std::string &parcelObj,
110881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool parcelObjIsPointer,
111881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        bool isReader,
112881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        ErrorMode mode) const {
113737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
114737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    CHECK(scalarType != NULL);
115737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
116737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    scalarType->emitReaderWriterWithCast(
117737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            out,
118737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            name,
119737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObj,
120737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            parcelObjIsPointer,
121737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            isReader,
122737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            mode,
123737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber            true /* needsCast */);
124881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
125881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
12685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::emitJavaFieldReaderWriter(
12785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        Formatter &out,
1284c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber        size_t depth,
129709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber        const std::string &parcelName,
13085eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &blobName,
13185eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &fieldName,
13285eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        const std::string &offset,
13385eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber        bool isReader) const {
13485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    return mStorageType->emitJavaFieldReaderWriter(
135709b62dbda6184770bb34470ff550e02c1643e67Andreas Huber            out, depth, parcelName, blobName, fieldName, offset, isReader);
13685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
13785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
138881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberstatus_t EnumType::emitTypeDeclarations(Formatter &out) const {
139737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
140e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
141737080baf85882c45bb322ee2191ae5fd9e1283aAndreas Huber
1423b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
143881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
144881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "enum class "
1450e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        << localName()
146881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " : "
147e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
148881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber        << " {\n";
149881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
150881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.indent();
151881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1528d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    std::vector<const EnumType *> chain;
153864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
1548d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1558d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
1568d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        const auto &type = *it;
1578d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1588d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        for (const auto &entry : type->values()) {
1598d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber            out << entry->name();
1608d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
161fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->cppValue(scalarType->getKind());
162f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for c++.
163f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << " = " << value;
1648d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber
1655788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << ",";
1665788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
167fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
168fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
1695788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong                out << " // " << comment;
1705788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            }
1715788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
1725788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong            out << "\n";
1738d3ac0c6112e02e3a705fd4f9d82e523f10b4287Andreas Huber        }
174881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
175881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
176881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out.unindent();
177881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    out << "};\n\n";
178881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
179881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    return OK;
180881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber}
181881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber
1822820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdharyvoid EnumType::emitEnumBitwiseOperator(
1832820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        Formatter &out,
1842820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        bool mutating,
1852820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        const std::string &op) const {
186e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
187e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    CHECK(scalarType != nullptr);
188e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
1893b320f8a60e4343bf06319bca3fc949c95eaf326Yifan Hong    const std::string storageType = scalarType->getCppStackType();
190e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
191e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "inline "
1922820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << (mutating ? fullName() : storageType)
193e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << (mutating ? " &" : "")
1942820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << " operator"
1952820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << op
196e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << (mutating ? "=" : "")
197e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << "(\n";
198e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
199e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
200e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
201e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
202e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << fullName()
203e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << (mutating ? " &" : " ")
204e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << "lhs, "
205e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << fullName()
206e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << " rhs) {\n";
207e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
208e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
209e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    if (mutating) {
210e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        out << "lhs = ";
211e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    } else {
212e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        out << "return ";
213e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    }
214e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "static_cast<"
2152820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << (mutating ? fullName() : storageType)
216e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << ">(\n";
217e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
218e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.indent();
219e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "static_cast<"
220e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
2212820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << ">(lhs) "
2222820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        << op
2232820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary        <<" static_cast<"
224e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << storageType
225e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        << ">(rhs));\n";
226e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
227e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
228e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
229e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    if (mutating) {
230e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber        out << "return lhs;\n";
231e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    }
232e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
233e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out.unindent();
234e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
235e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    out << "}\n\n";
236e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
237e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
238e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huberstatus_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
2392820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary    emitEnumBitwiseOperator(out, false /* mutating */, "|");
2402820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary    emitEnumBitwiseOperator(out, true /* mutating */, "|");
2412820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary    emitEnumBitwiseOperator(out, false /* mutating */, "&");
2422820f8a2b8f1d525e7ea5eaed50ba600c0186ccfJayant Chowdhary    emitEnumBitwiseOperator(out, true /* mutating */, "&");
243e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
244e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber    return OK;
245e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber}
246e3f769aa75dd6be6bb1ba83904def47d9e464769Andreas Huber
24785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huberstatus_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
2482831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
2492831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    CHECK(scalarType != NULL);
2502831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2512831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "public final class "
2522831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << localName()
2532831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        << " {\n";
2542831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2552831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.indent();
2562831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2574c865b72b320a46f326a335cfd326b66b0e10f67Andreas Huber    const std::string typeName =
2584ed1347cd29e6e07acad368891bb03078c798abaYifan Hong        scalarType->getJavaType(false /* forInitializer */);
2592831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2602831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    std::vector<const EnumType *> chain;
261864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
2622831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2632831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
2642831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        const auto &type = *it;
2652831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2662831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        for (const auto &entry : type->values()) {
2672831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber            out << "public static final "
2682831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << typeName
2692831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber                << " "
270ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << entry->name()
271ab647c09e65af4f6236f48b999244cccb11f6b57Andreas Huber                << " = ";
2722831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
273f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            // javaValue will make the number signed.
274fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string value = entry->javaValue(scalarType->getKind());
275f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            CHECK(!value.empty()); // use autofilled values for java.
276f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong            out << value;
2772831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
27819ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << ";";
27919ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
280fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            std::string comment = entry->comment();
281fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hong            if (!comment.empty() && comment != value) {
28219ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong                out << " // " << comment;
28319ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            }
28419ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong
28519ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong            out << "\n";
2862831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber        }
2872831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    }
2882831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2892831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out.unindent();
2902831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    out << "};\n\n";
2912831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2922831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    return OK;
2932831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
2942831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
2955158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
296c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    const ScalarType *scalarType = mStorageType->resolveToScalarType();
297c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong
298bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "name: \"" << fullName() << "\"\n";
299c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
300c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "enum_value: {\n";
3015158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.indent();
302864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
303c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "scalar_type: \""
304c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong        << scalarType->getVtsScalarType()
305c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang        << "\"\n\n";
306864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    std::vector<const EnumType *> chain;
307864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    getTypeChain(&chain);
308864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
309864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
310864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const auto &type = *it;
311864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
312864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (const auto &entry : type->values()) {
313864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            out << "enumerator: \"" << entry->name() << "\"\n";
314c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "scalar_value: {\n";
315c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.indent();
316c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            // use autofilled values for vts.
317c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            std::string value = entry->value(scalarType->getKind());
318c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            CHECK(!value.empty());
319c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong            out << mStorageType->resolveToScalarType()->getVtsScalarType()
320c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << ": "
321c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << value
322c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong                << "\n";
323c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out.unindent();
324c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang            out << "}\n";
325864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
3265158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
327864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
3285158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out.unindent();
3295158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "}\n";
3305158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
3315158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
3325158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
333864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t EnumType::emitVtsAttributeType(Formatter &out) const {
334c5ea9f589cc7cce0b5e97bd4ac6a8561eb313a02Zhuoyao Zhang    out << "type: " << getVtsType() << "\n";
335bf828c8f6e1a1345e352976d5b6b91b2f5c52a2bZhuoyao Zhang    out << "predefined_type: \"" << fullName() << "\"\n";
3365158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
3375158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
3385158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
339864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangvoid EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
340864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    out->clear();
341864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    const EnumType *type = this;
342864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (;;) {
343864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        out->push_back(type);
344864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
345864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        const Type *superType = type->storageType();
346864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (superType == NULL || !superType->isEnum()) {
347864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            break;
348864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
349864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
350864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        type = static_cast<const EnumType *>(superType);
351864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
352864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
353864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
35485eabdbe56720dcdcf130e5ca83129d47b143768Andreas Hubervoid EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
35585eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber    mStorageType->getAlignmentAndSize(align, size);
35685eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber}
35785eabdbe56720dcdcf130e5ca83129d47b143768Andreas Huber
358019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huberconst Annotation *EnumType::findExportAnnotation() const {
359019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (const auto &annotation : annotations()) {
360019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        if (annotation->name() == "export") {
361019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            return annotation;
362019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
363019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
364019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
365019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return nullptr;
366019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
367019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
368019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Hubervoid EnumType::appendToExportedTypesVector(
369019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::vector<const Type *> *exportedTypes) const {
370019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (findExportAnnotation() != nullptr) {
371019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        exportedTypes->push_back(this);
372019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
373019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
374019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
3751c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huberstatus_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
376019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const Annotation *annotation = findExportAnnotation();
377019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    CHECK(annotation != nullptr);
378019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
379019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::string name = localName();
380019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
381019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const AnnotationParam *nameParam = annotation->getParam("name");
382019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (nameParam != nullptr) {
383019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        CHECK_EQ(nameParam->getValues()->size(), 1u);
384019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
385019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        std::string quotedString = nameParam->getValues()->at(0);
386019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        name = quotedString.substr(1, quotedString.size() - 2);
387019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
388019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
389b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    std::string valuePrefix;
390b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
391b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    if (prefixParam != nullptr) {
392b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber        CHECK_EQ(prefixParam->getValues()->size(), 1u);
393b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
394b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber        std::string quotedString = prefixParam->getValues()->at(0);
395b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber        valuePrefix = quotedString.substr(1, quotedString.size() - 2);
396b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber    }
397b0627fb40221fcd6d838d3704d270eb2b825aed8Andreas Huber
39873cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    std::string valueSuffix;
39973cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
40073cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    if (suffixParam != nullptr) {
40173cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland        CHECK_EQ(suffixParam->getValues()->size(), 1u);
40273cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
40373cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland        std::string quotedString = suffixParam->getValues()->at(0);
40473cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland        valueSuffix = quotedString.substr(1, quotedString.size() - 2);
40573cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland    }
40673cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland
407019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    const ScalarType *scalarType = mStorageType->resolveToScalarType();
4081c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    CHECK(scalarType != nullptr);
409019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
4101c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    if (forJava) {
4111c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
4121c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "public final class "
4131c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << name
4141c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                << " {\n";
4151c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4161c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.indent();
4171c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        } else {
4181c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "// Values declared in " << localName() << " follow.\n";
4191c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4201c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4211c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        const std::string typeName =
4224ed1347cd29e6e07acad368891bb03078c798abaYifan Hong            scalarType->getJavaType(false /* forInitializer */);
4231c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4241c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        std::vector<const EnumType *> chain;
4251c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        getTypeChain(&chain);
4261c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4271c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
4281c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            const auto &type = *it;
4291c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4301c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            for (const auto &entry : type->values()) {
4311c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "public static final "
4321c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << typeName
4331c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " "
4341c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << valuePrefix
4351c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << entry->name()
43673cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland                    << valueSuffix
4371c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    << " = ";
4381c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4391c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                // javaValue will make the number signed.
4401c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string value = entry->javaValue(scalarType->getKind());
4411c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                CHECK(!value.empty()); // use autofilled values for java.
4421c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << value;
4431c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4441c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << ";";
4451c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4461c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                std::string comment = entry->comment();
4471c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                if (!comment.empty() && comment != value) {
4481c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                    out << " // " << comment;
4491c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                }
4501c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4511c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber                out << "\n";
4521c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            }
4531c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4541c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4551c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        if (!name.empty()) {
4561c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out.unindent();
4571c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber            out << "};\n";
4581c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        }
4591c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        out << "\n";
4601c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber
4611c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber        return OK;
4621c507273be6a1beefbe7ef6ec63992a7cf66c4f8Andreas Huber    }
463019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
464019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
465019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << "typedef ";
466019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
467019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
468019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "enum {\n";
469019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
470019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.indent();
471019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
472019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    std::vector<const EnumType *> chain;
473019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    getTypeChain(&chain);
474019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
475019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
476019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        const auto &type = *it;
477019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
478019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        for (const auto &entry : type->values()) {
47973cdc887c6d3c20b66890c1363db64f70b0f77c8Steven Moreland            out << valuePrefix << entry->name() << valueSuffix;
480019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
481019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string value = entry->cppValue(scalarType->getKind());
482019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            CHECK(!value.empty()); // use autofilled values for c++.
483019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << " = " << value;
484019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
485019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << ",";
486019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
487019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            std::string comment = entry->comment();
488019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            if (!comment.empty() && comment != value) {
489019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber                out << " // " << comment;
490019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            }
491019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
492019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber            out << "\n";
493019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        }
494019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
495019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
496019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out.unindent();
497019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << "}";
498019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
499019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    if (!name.empty()) {
500019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber        out << " " << name;
501019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    }
502019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
503019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    out << ";\n\n";
504019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
505019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber    return OK;
506019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber}
507019d21db821ee4ae6dd3858174a0a5cee4d33c25Andreas Huber
50831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber////////////////////////////////////////////////////////////////////////////////
50931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
510f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongEnumValue::EnumValue(const char *name, ConstantExpression *value)
51131629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    : mName(name),
512f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValue(value),
513f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mIsAutoFill(false) {
51431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
51531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
51631629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huberstd::string EnumValue::name() const {
51731629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber    return mName;
51831629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
51931629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
520c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hongstd::string EnumValue::value(ScalarType::Kind castKind) const {
521f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
522c07b202bc91024356c50ded5a65d69f03b92e557Yifan Hong    return mValue->value(castKind);
5235788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
5245788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
525fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::cppValue(ScalarType::Kind castKind) const {
526f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
527f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->cppValue(castKind);
5285788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong}
529fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::javaValue(ScalarType::Kind castKind) const {
530f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
531f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->javaValue(castKind);
53219ca75ae47df5cd9447b232c31c5df1d110e85d9Yifan Hong}
5335788697381666844eeb23e04e5c6f83ec6ec8b44Yifan Hong
534fc610cd36bb07244f46c9a9baed6634bbdc564e9Yifan Hongstd::string EnumValue::comment() const {
535f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
536f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue->description();
537f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
538f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
539f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongConstantExpression *EnumValue::constExpr() const {
540f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    CHECK(mValue != nullptr);
541f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mValue;
542f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
543f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
544f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongvoid EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
545f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(mValue != nullptr)
546f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        return;
547f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mIsAutoFill = true;
548f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    ConstantExpression *value = new ConstantExpression();
549f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    if(prev == nullptr) {
550f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = ConstantExpression::Zero(type->getKind());
551f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    } else {
552f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        CHECK(prev->mValue != nullptr);
553f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong        *value = prev->mValue->addOne();
554f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    }
555f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    mValue = value;
556f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
557f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
558f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isAutoFill() const {
559f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return mIsAutoFill;
560f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
561f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
562f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hongbool EnumValue::isEnumValue() const {
563f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    return true;
56431629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber}
56531629bcd51ab30bc0aadc69f3fc8ce4893eca900Andreas Huber
566c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber}  // namespace android
567c9410c7e62a33fd7599b2f3e025093a2d171577eAndreas Huber
568