blob: 87cc19b364b3d895a66e076e962a71b8634dfcfa [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Huberc9410c72016-07-28 12:18:40 -070017#include "EnumType.h"
18
Andreas Huber019d21d2016-10-03 12:59:47 -070019#include "Annotation.h"
Andreas Huber881227d2016-08-02 14:20:21 -070020#include "ScalarType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070021
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070022#include <inttypes.h>
23#include <hidl-util/Formatter.h>
Andreas Huber737080b2016-08-02 15:38:04 -070024#include <android-base/logging.h>
25
Andreas Huberc9410c72016-07-28 12:18:40 -070026namespace android {
27
Andreas Huberc9410c72016-07-28 12:18:40 -070028EnumType::EnumType(
Andreas Huber9ed827c2016-08-22 12:31:13 -070029 const char *localName,
Yifan Honga4b53d02016-10-31 17:29:10 -070030 const Location &location,
Andreas Huber9ed827c2016-08-22 12:31:13 -070031 Type *storageType)
Yifan Honga4b53d02016-10-31 17:29:10 -070032 : Scope(localName, location),
Yifan Hongf24fa852016-09-23 11:03:15 -070033 mValues(),
Steven Moreland1c71fd52016-11-29 14:03:33 -080034 mStorageType(storageType) {
Andreas Huberc9410c72016-07-28 12:18:40 -070035}
36
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070037const Type *EnumType::storageType() const {
38 return mStorageType;
39}
40
41const std::vector<EnumValue *> &EnumType::values() const {
Yifan Hongf24fa852016-09-23 11:03:15 -070042 return mValues;
43}
44
45void EnumType::addValue(EnumValue *value) {
46 CHECK(value != nullptr);
47
48 EnumValue *prev = nullptr;
49 std::vector<const EnumType *> chain;
50 getTypeChain(&chain);
51 for (auto it = chain.begin(); it != chain.end(); ++it) {
52 const auto &type = *it;
53 if(!type->values().empty()) {
54 prev = type->values().back();
55 break;
56 }
57 }
58
59 value->autofill(prev, resolveToScalarType());
60 mValues.push_back(value);
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070061}
62
Steven Moreland9df52442016-12-12 08:51:14 -080063bool EnumType::isElidableType() const {
64 return mStorageType->isElidableType();
65}
66
Andreas Huber737080b2016-08-02 15:38:04 -070067const ScalarType *EnumType::resolveToScalarType() const {
68 return mStorageType->resolveToScalarType();
69}
70
Steven Moreland30bb6a82016-11-30 09:18:34 -080071std::string EnumType::typeName() const {
72 return "enum " + localName();
73}
74
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070075bool EnumType::isEnum() const {
76 return true;
77}
78
Yifan Hongc6752dc2016-12-20 14:00:14 -080079bool EnumType::canCheckEquality() const {
80 return true;
81}
82
Steven Moreland979e0992016-09-07 09:18:08 -070083std::string EnumType::getCppType(StorageMode,
Steven Moreland979e0992016-09-07 09:18:08 -070084 bool specifyNamespaces) const {
Steven Moreland979e0992016-09-07 09:18:08 -070085 return specifyNamespaces ? fullName() : partialCppName();
Andreas Huber881227d2016-08-02 14:20:21 -070086}
87
Yifan Hong4ed13472016-11-02 10:44:11 -070088std::string EnumType::getJavaType(bool forInitializer) const {
89 return mStorageType->resolveToScalarType()->getJavaType(forInitializer);
Andreas Huber2831d512016-08-15 09:33:47 -070090}
91
92std::string EnumType::getJavaSuffix() const {
93 return mStorageType->resolveToScalarType()->getJavaSuffix();
94}
95
Andreas Hubera3558b32016-09-14 09:12:42 -070096std::string EnumType::getJavaWrapperType() const {
97 return mStorageType->resolveToScalarType()->getJavaWrapperType();
98}
99
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700100std::string EnumType::getVtsType() const {
101 return "TYPE_ENUM";
102}
103
Yifan Hongf24fa852016-09-23 11:03:15 -0700104LocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
105 std::vector<const EnumType *> chain;
106 getTypeChain(&chain);
107 for (auto it = chain.begin(); it != chain.end(); ++it) {
108 const auto &type = *it;
109 for(EnumValue *v : type->values()) {
110 if(v->name() == name) {
111 return v;
112 }
113 }
114 }
115 return nullptr;
116}
117
Andreas Huber881227d2016-08-02 14:20:21 -0700118void EnumType::emitReaderWriter(
119 Formatter &out,
120 const std::string &name,
121 const std::string &parcelObj,
122 bool parcelObjIsPointer,
123 bool isReader,
124 ErrorMode mode) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700125 const ScalarType *scalarType = mStorageType->resolveToScalarType();
126 CHECK(scalarType != NULL);
127
128 scalarType->emitReaderWriterWithCast(
129 out,
130 name,
131 parcelObj,
132 parcelObjIsPointer,
133 isReader,
134 mode,
135 true /* needsCast */);
Andreas Huber881227d2016-08-02 14:20:21 -0700136}
137
Andreas Huber85eabdb2016-08-25 11:24:49 -0700138void EnumType::emitJavaFieldReaderWriter(
139 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700140 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700141 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700142 const std::string &blobName,
143 const std::string &fieldName,
144 const std::string &offset,
145 bool isReader) const {
146 return mStorageType->emitJavaFieldReaderWriter(
Andreas Huber709b62d2016-09-19 11:21:18 -0700147 out, depth, parcelName, blobName, fieldName, offset, isReader);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700148}
149
Andreas Huber881227d2016-08-02 14:20:21 -0700150status_t EnumType::emitTypeDeclarations(Formatter &out) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700151 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700152 CHECK(scalarType != nullptr);
Andreas Huber737080b2016-08-02 15:38:04 -0700153
Yifan Hong3b320f82016-11-01 15:15:54 -0700154 const std::string storageType = scalarType->getCppStackType();
Andreas Huber881227d2016-08-02 14:20:21 -0700155
156 out << "enum class "
Andreas Huber0e00de42016-08-03 09:56:02 -0700157 << localName()
Andreas Huber881227d2016-08-02 14:20:21 -0700158 << " : "
Andreas Hubere3f769a2016-10-10 10:54:44 -0700159 << storageType
Andreas Huber881227d2016-08-02 14:20:21 -0700160 << " {\n";
161
162 out.indent();
163
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700164 std::vector<const EnumType *> chain;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700165 getTypeChain(&chain);
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700166
167 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
168 const auto &type = *it;
169
170 for (const auto &entry : type->values()) {
171 out << entry->name();
172
Yifan Hongfc610cd2016-09-22 13:34:45 -0700173 std::string value = entry->cppValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700174 CHECK(!value.empty()); // use autofilled values for c++.
175 out << " = " << value;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700176
Yifan Hong57886972016-08-17 10:42:15 -0700177 out << ",";
178
Yifan Hongfc610cd2016-09-22 13:34:45 -0700179 std::string comment = entry->comment();
180 if (!comment.empty() && comment != value) {
Yifan Hong57886972016-08-17 10:42:15 -0700181 out << " // " << comment;
182 }
183
184 out << "\n";
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700185 }
Andreas Huber881227d2016-08-02 14:20:21 -0700186 }
187
188 out.unindent();
189 out << "};\n\n";
190
191 return OK;
192}
193
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800194void EnumType::emitEnumBitwiseOperator(
195 Formatter &out,
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800196 bool lhsIsEnum,
197 bool rhsIsEnum,
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800198 const std::string &op) const {
Andreas Hubere3f769a2016-10-10 10:54:44 -0700199 const ScalarType *scalarType = mStorageType->resolveToScalarType();
200 CHECK(scalarType != nullptr);
201
Yifan Hong3b320f82016-11-01 15:15:54 -0700202 const std::string storageType = scalarType->getCppStackType();
Andreas Hubere3f769a2016-10-10 10:54:44 -0700203
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800204 out << "constexpr "
205 << storageType
Jayant Chowdhary2820f8a2016-11-10 12:29:09 -0800206 << " operator"
207 << op
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800208 << "(const "
209 << (lhsIsEnum ? fullName() : storageType)
210 << " lhs, const "
211 << (rhsIsEnum ? fullName() : storageType)
Andreas Hubere3f769a2016-10-10 10:54:44 -0700212 << " rhs) {\n";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700213
Yifan Hong33223ca2016-12-13 15:07:35 -0800214 out.indent([&] {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800215 out << "return static_cast<"
216 << storageType
217 << ">(";
Andreas Hubere3f769a2016-10-10 10:54:44 -0700218
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800219 if (lhsIsEnum) {
220 out << "static_cast<"
221 << storageType
222 << ">(lhs)";
223 } else {
224 out << "lhs";
225 }
226 out << " " << op << " ";
227 if (rhsIsEnum) {
228 out << "static_cast<"
229 << storageType
230 << ">(rhs)";
231 } else {
232 out << "rhs";
233 }
234 out << ");\n";
235 });
Andreas Hubere3f769a2016-10-10 10:54:44 -0700236
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800237 out << "}\n\n";
238}
239
240void EnumType::emitBitFieldBitwiseAssignmentOperator(
241 Formatter &out,
242 const std::string &op) const {
243 const ScalarType *scalarType = mStorageType->resolveToScalarType();
244 CHECK(scalarType != nullptr);
245
246 const std::string storageType = scalarType->getCppStackType();
247
248 out << "constexpr " << storageType << " &operator" << op << "=("
249 << storageType << "& v, const " << fullName() << " e) {\n";
250
Yifan Hong33223ca2016-12-13 15:07:35 -0800251 out.indent([&] {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800252 out << "v " << op << "= static_cast<" << storageType << ">(e);\n";
253 out << "return v;\n";
254 });
Andreas Hubere3f769a2016-10-10 10:54:44 -0700255
256 out << "}\n\n";
257}
258
259status_t EnumType::emitGlobalTypeDeclarations(Formatter &out) const {
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800260 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, true /* rhsIsEnum */, "|");
261 emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true /* rhsIsEnum */, "|");
262 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, false /* rhsIsEnum */, "|");
263 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, true /* rhsIsEnum */, "&");
264 emitEnumBitwiseOperator(out, false /* lhsIsEnum */, true /* rhsIsEnum */, "&");
265 emitEnumBitwiseOperator(out, true /* lhsIsEnum */, false /* rhsIsEnum */, "&");
266
267 emitBitFieldBitwiseAssignmentOperator(out, "|");
268 emitBitFieldBitwiseAssignmentOperator(out, "&");
Andreas Hubere3f769a2016-10-10 10:54:44 -0700269
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800270 out << "template<typename>\n"
271 << "std::string toString("
272 << resolveToScalarType()->getCppArgumentType()
273 << " o);\n";
274 out << "template<>\n"
275 << "std::string toString<" << getCppStackType() << ">("
276 << resolveToScalarType()->getCppArgumentType()
277 << " o);\n\n";
278
279 out << "inline std::string toString("
280 << getCppArgumentType()
281 << " o) ";
282
283 out.block([&] {
284 out << "return toString<" << getCppStackType() << ">("
285 << "static_cast<" << resolveToScalarType()->getCppStackType() << ">(o));\n";
286 }).endl().endl();
287
288 return OK;
289}
290
291status_t EnumType::emitTypeDefinitions(Formatter &out, const std::string /* prefix */) const {
292
293 const ScalarType *scalarType = mStorageType->resolveToScalarType();
294 CHECK(scalarType != NULL);
295
296 out << "template<>\n"
297 << "std::string toString<" << getCppStackType() << ">("
298 << resolveToScalarType()->getCppArgumentType()
299 << " o) ";
300 out.block([&] {
301 // include toHexString for scalar types
302 out << "using ::android::hardware::details::toHexString;\n"
303 << "std::string os;\n";
304 out << "bool first = true;\n";
305 for (EnumValue *value : values()) {
306 out.sIf("o & " + fullName() + "::" + value->name(), [&] {
307 out << "os += (first ? \"\" : \" | \"); "
308 << "first = false;\n"
309 << "os += \"" << value->name() << "\";\n";
310 }).endl();
311 }
312 out << "os += \" (\";\n";
313 scalarType->emitHexDump(out, "os", "o");
314 out << "os += \")\";\n";
315
316 out << "return os;\n";
317 }).endl().endl();
318
Andreas Hubere3f769a2016-10-10 10:54:44 -0700319 return OK;
320}
321
Andreas Huber85eabdb2016-08-25 11:24:49 -0700322status_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
Andreas Huber2831d512016-08-15 09:33:47 -0700323 const ScalarType *scalarType = mStorageType->resolveToScalarType();
324 CHECK(scalarType != NULL);
325
326 out << "public final class "
327 << localName()
328 << " {\n";
329
330 out.indent();
331
Andreas Huber4c865b72016-09-14 15:26:27 -0700332 const std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700333 scalarType->getJavaType(false /* forInitializer */);
Andreas Huber2831d512016-08-15 09:33:47 -0700334
335 std::vector<const EnumType *> chain;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700336 getTypeChain(&chain);
Andreas Huber2831d512016-08-15 09:33:47 -0700337
338 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
339 const auto &type = *it;
340
341 for (const auto &entry : type->values()) {
342 out << "public static final "
343 << typeName
344 << " "
Andreas Huberab647c02016-09-14 09:44:00 -0700345 << entry->name()
346 << " = ";
Andreas Huber2831d512016-08-15 09:33:47 -0700347
Yifan Hongf24fa852016-09-23 11:03:15 -0700348 // javaValue will make the number signed.
Yifan Hongfc610cd2016-09-22 13:34:45 -0700349 std::string value = entry->javaValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700350 CHECK(!value.empty()); // use autofilled values for java.
351 out << value;
Andreas Huber2831d512016-08-15 09:33:47 -0700352
Yifan Hong19ca75a2016-08-31 10:20:03 -0700353 out << ";";
354
Yifan Hongfc610cd2016-09-22 13:34:45 -0700355 std::string comment = entry->comment();
356 if (!comment.empty() && comment != value) {
Yifan Hong19ca75a2016-08-31 10:20:03 -0700357 out << " // " << comment;
358 }
359
360 out << "\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700361 }
362 }
363
364 out.unindent();
365 out << "};\n\n";
366
367 return OK;
368}
369
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700370status_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
Yifan Hongc07b2022016-11-08 12:44:24 -0800371 const ScalarType *scalarType = mStorageType->resolveToScalarType();
372
Zhuoyao Zhangbf828c82016-10-26 14:15:10 -0700373 out << "name: \"" << fullName() << "\"\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700374 out << "type: " << getVtsType() << "\n";
375 out << "enum_value: {\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700376 out.indent();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700377
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700378 out << "scalar_type: \""
Yifan Hongc07b2022016-11-08 12:44:24 -0800379 << scalarType->getVtsScalarType()
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700380 << "\"\n\n";
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700381 std::vector<const EnumType *> chain;
382 getTypeChain(&chain);
383
384 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
385 const auto &type = *it;
386
387 for (const auto &entry : type->values()) {
388 out << "enumerator: \"" << entry->name() << "\"\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700389 out << "scalar_value: {\n";
390 out.indent();
Yifan Hongc07b2022016-11-08 12:44:24 -0800391 // use autofilled values for vts.
392 std::string value = entry->value(scalarType->getKind());
393 CHECK(!value.empty());
394 out << mStorageType->resolveToScalarType()->getVtsScalarType()
395 << ": "
396 << value
397 << "\n";
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700398 out.unindent();
399 out << "}\n";
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700400 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700401 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700402
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700403 out.unindent();
404 out << "}\n";
405 return OK;
406}
407
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700408status_t EnumType::emitVtsAttributeType(Formatter &out) const {
Zhuoyao Zhangc5ea9f52016-10-06 15:05:39 -0700409 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhangbf828c82016-10-26 14:15:10 -0700410 out << "predefined_type: \"" << fullName() << "\"\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700411 return OK;
412}
413
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700414void EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
415 out->clear();
416 const EnumType *type = this;
417 for (;;) {
418 out->push_back(type);
419
420 const Type *superType = type->storageType();
421 if (superType == NULL || !superType->isEnum()) {
422 break;
423 }
424
425 type = static_cast<const EnumType *>(superType);
426 }
427}
428
Andreas Huber85eabdb2016-08-25 11:24:49 -0700429void EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
430 mStorageType->getAlignmentAndSize(align, size);
431}
432
Andreas Huber019d21d2016-10-03 12:59:47 -0700433const Annotation *EnumType::findExportAnnotation() const {
434 for (const auto &annotation : annotations()) {
435 if (annotation->name() == "export") {
436 return annotation;
437 }
438 }
439
440 return nullptr;
441}
442
443void EnumType::appendToExportedTypesVector(
444 std::vector<const Type *> *exportedTypes) const {
445 if (findExportAnnotation() != nullptr) {
446 exportedTypes->push_back(this);
447 }
448}
449
Andreas Huber1c507272016-10-05 14:33:21 -0700450status_t EnumType::emitExportedHeader(Formatter &out, bool forJava) const {
Andreas Huber019d21d2016-10-03 12:59:47 -0700451 const Annotation *annotation = findExportAnnotation();
452 CHECK(annotation != nullptr);
453
454 std::string name = localName();
455
456 const AnnotationParam *nameParam = annotation->getParam("name");
457 if (nameParam != nullptr) {
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800458 name = nameParam->getSingleString();
459 }
Andreas Huber019d21d2016-10-03 12:59:47 -0700460
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800461 bool exportParent = true;
462 const AnnotationParam *exportParentParam = annotation->getParam("export_parent");
463 if (exportParentParam != nullptr) {
464 exportParent = exportParentParam->getSingleBool();
Andreas Huber019d21d2016-10-03 12:59:47 -0700465 }
466
Andreas Huberb0627fb2016-10-10 09:39:28 -0700467 std::string valuePrefix;
Andreas Huberb0627fb2016-10-10 09:39:28 -0700468 const AnnotationParam *prefixParam = annotation->getParam("value_prefix");
469 if (prefixParam != nullptr) {
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800470 valuePrefix = prefixParam->getSingleString();
Andreas Huberb0627fb2016-10-10 09:39:28 -0700471 }
472
Steven Moreland73cdc882016-11-21 16:43:50 -0800473 std::string valueSuffix;
474 const AnnotationParam *suffixParam = annotation->getParam("value_suffix");
475 if (suffixParam != nullptr) {
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800476 valueSuffix = suffixParam->getSingleString();
Steven Moreland73cdc882016-11-21 16:43:50 -0800477 }
478
Andreas Huber019d21d2016-10-03 12:59:47 -0700479 const ScalarType *scalarType = mStorageType->resolveToScalarType();
Andreas Huber1c507272016-10-05 14:33:21 -0700480 CHECK(scalarType != nullptr);
Andreas Huber019d21d2016-10-03 12:59:47 -0700481
Steven Morelanddb1b1b62017-01-10 09:50:55 -0800482 std::vector<const EnumType *> chain;
483 if (exportParent) {
484 getTypeChain(&chain);
485 } else {
486 chain = { this };
487 }
488
Andreas Huber1c507272016-10-05 14:33:21 -0700489 if (forJava) {
490 if (!name.empty()) {
491 out << "public final class "
492 << name
493 << " {\n";
494
495 out.indent();
496 } else {
497 out << "// Values declared in " << localName() << " follow.\n";
498 }
499
Andreas Huber1c507272016-10-05 14:33:21 -0700500 const std::string typeName =
Yifan Hong4ed13472016-11-02 10:44:11 -0700501 scalarType->getJavaType(false /* forInitializer */);
Andreas Huber1c507272016-10-05 14:33:21 -0700502
Andreas Huber1c507272016-10-05 14:33:21 -0700503 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
504 const auto &type = *it;
505
506 for (const auto &entry : type->values()) {
507 out << "public static final "
508 << typeName
509 << " "
510 << valuePrefix
511 << entry->name()
Steven Moreland73cdc882016-11-21 16:43:50 -0800512 << valueSuffix
Andreas Huber1c507272016-10-05 14:33:21 -0700513 << " = ";
514
515 // javaValue will make the number signed.
516 std::string value = entry->javaValue(scalarType->getKind());
517 CHECK(!value.empty()); // use autofilled values for java.
518 out << value;
519
520 out << ";";
521
522 std::string comment = entry->comment();
523 if (!comment.empty() && comment != value) {
524 out << " // " << comment;
525 }
526
527 out << "\n";
528 }
529 }
530
531 if (!name.empty()) {
532 out.unindent();
533 out << "};\n";
534 }
535 out << "\n";
536
537 return OK;
538 }
Andreas Huber019d21d2016-10-03 12:59:47 -0700539
540 if (!name.empty()) {
541 out << "typedef ";
542 }
543
544 out << "enum {\n";
545
546 out.indent();
547
Andreas Huber019d21d2016-10-03 12:59:47 -0700548 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
549 const auto &type = *it;
550
551 for (const auto &entry : type->values()) {
Steven Moreland73cdc882016-11-21 16:43:50 -0800552 out << valuePrefix << entry->name() << valueSuffix;
Andreas Huber019d21d2016-10-03 12:59:47 -0700553
554 std::string value = entry->cppValue(scalarType->getKind());
555 CHECK(!value.empty()); // use autofilled values for c++.
556 out << " = " << value;
557
558 out << ",";
559
560 std::string comment = entry->comment();
561 if (!comment.empty() && comment != value) {
562 out << " // " << comment;
563 }
564
565 out << "\n";
566 }
567 }
568
569 out.unindent();
570 out << "}";
571
572 if (!name.empty()) {
573 out << " " << name;
574 }
575
576 out << ";\n\n";
577
578 return OK;
579}
580
Andreas Huber31629bc2016-08-03 09:06:40 -0700581////////////////////////////////////////////////////////////////////////////////
582
Yifan Hongf24fa852016-09-23 11:03:15 -0700583EnumValue::EnumValue(const char *name, ConstantExpression *value)
Andreas Huber31629bc2016-08-03 09:06:40 -0700584 : mName(name),
Yifan Hongf24fa852016-09-23 11:03:15 -0700585 mValue(value),
586 mIsAutoFill(false) {
Andreas Huber31629bc2016-08-03 09:06:40 -0700587}
588
589std::string EnumValue::name() const {
590 return mName;
591}
592
Yifan Hongc07b2022016-11-08 12:44:24 -0800593std::string EnumValue::value(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700594 CHECK(mValue != nullptr);
Yifan Hongc07b2022016-11-08 12:44:24 -0800595 return mValue->value(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700596}
597
Yifan Hongfc610cd2016-09-22 13:34:45 -0700598std::string EnumValue::cppValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700599 CHECK(mValue != nullptr);
600 return mValue->cppValue(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700601}
Yifan Hongfc610cd2016-09-22 13:34:45 -0700602std::string EnumValue::javaValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700603 CHECK(mValue != nullptr);
604 return mValue->javaValue(castKind);
Yifan Hong19ca75a2016-08-31 10:20:03 -0700605}
Yifan Hong57886972016-08-17 10:42:15 -0700606
Yifan Hongfc610cd2016-09-22 13:34:45 -0700607std::string EnumValue::comment() const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700608 CHECK(mValue != nullptr);
609 return mValue->description();
610}
611
612ConstantExpression *EnumValue::constExpr() const {
613 CHECK(mValue != nullptr);
614 return mValue;
615}
616
617void EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
618 if(mValue != nullptr)
619 return;
620 mIsAutoFill = true;
621 ConstantExpression *value = new ConstantExpression();
622 if(prev == nullptr) {
623 *value = ConstantExpression::Zero(type->getKind());
624 } else {
625 CHECK(prev->mValue != nullptr);
626 *value = prev->mValue->addOne();
627 }
628 mValue = value;
629}
630
631bool EnumValue::isAutoFill() const {
632 return mIsAutoFill;
633}
634
635bool EnumValue::isEnumValue() const {
636 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700637}
638
Yifan Hongabf73ee2016-12-05 18:47:00 -0800639////////////////////////////////////////////////////////////////////////////////
640
641bool BitFieldType::isBitField() const {
642 return true;
643}
644
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800645std::string BitFieldType::typeName() const {
646 return "mask" + (mElementType == nullptr ? "" : (" of " + mElementType->typeName()));
647}
648
649void BitFieldType::addNamedTypesToSet(std::set<const FQName> &) const {
650}
651
652bool BitFieldType::isCompatibleElementType(Type *elementType) const {
653 return elementType->isEnum();
654}
655
656const ScalarType *BitFieldType::resolveToScalarType() const {
657 return mElementType->resolveToScalarType();
658}
659
660std::string BitFieldType::getCppType(StorageMode mode,
661 bool specifyNamespaces) const {
662 return resolveToScalarType()->getCppType(mode, specifyNamespaces);
663}
664
665std::string BitFieldType::getJavaType(bool forInitializer) const {
666 return resolveToScalarType()->getJavaType(forInitializer);
667}
668
669std::string BitFieldType::getJavaSuffix() const {
670 return resolveToScalarType()->getJavaSuffix();
671}
672
673std::string BitFieldType::getJavaWrapperType() const {
674 return resolveToScalarType()->getJavaWrapperType();
675}
676
677std::string BitFieldType::getVtsType() const {
678 return "TYPE_MASK";
679}
680
Yifan Hong8c56cbe2016-12-12 15:30:12 -0800681bool BitFieldType::isElidableType() const {
682 return resolveToScalarType()->isElidableType();
683}
684
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800685status_t BitFieldType::emitVtsAttributeType(Formatter &out) const {
686 out << "type: " << getVtsType() << "\n";
Zhuoyao Zhang13236232017-01-24 14:27:55 -0800687 out << "scalar_type: \""
688 << mElementType->resolveToScalarType()->getVtsScalarType()
689 << "\"\n";
Keun Soo Yim36ccc722017-01-13 13:27:33 -0800690 out << "predefined_type: \""
691 << static_cast<NamedType *>(mElementType)->fullName() << "\"\n";
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800692 return OK;
693}
694
695void BitFieldType::getAlignmentAndSize(size_t *align, size_t *size) const {
696 resolveToScalarType()->getAlignmentAndSize(align, size);
697}
698
699void BitFieldType::emitReaderWriter(
700 Formatter &out,
701 const std::string &name,
702 const std::string &parcelObj,
703 bool parcelObjIsPointer,
704 bool isReader,
705 ErrorMode mode) const {
706 resolveToScalarType()->emitReaderWriterWithCast(
707 out,
708 name,
709 parcelObj,
710 parcelObjIsPointer,
711 isReader,
712 mode,
713 true /* needsCast */);
714}
715
Yifan Hongf5cc2f72017-01-04 18:02:34 -0800716// a bitfield maps to the underlying scalar type in C++, so operator<< is
717// already defined. We can still emit useful information if the bitfield is
718// in a struct / union by overriding emitDump as below.
719void BitFieldType::emitDump(
720 Formatter &out,
721 const std::string &streamName,
722 const std::string &name) const {
723 CHECK(mElementType->isEnum());
724 const EnumType *enumType = static_cast<EnumType *>(mElementType);
725 out << streamName << " += "<< enumType->fqName().cppNamespace()
726 << "::toString<" << enumType->getCppStackType()
727 << ">(" << name << ");\n";
728}
729
Yifan Hongc57c8bb2016-12-01 11:37:18 -0800730void BitFieldType::emitJavaFieldReaderWriter(
731 Formatter &out,
732 size_t depth,
733 const std::string &parcelName,
734 const std::string &blobName,
735 const std::string &fieldName,
736 const std::string &offset,
737 bool isReader) const {
738 return resolveToScalarType()->emitJavaFieldReaderWriter(
739 out, depth, parcelName, blobName, fieldName, offset, isReader);
740}
741
Andreas Huberc9410c72016-07-28 12:18:40 -0700742} // namespace android
743