blob: efc0f0862c8a6f51bf6bfa034396d78516ca5a01 [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 Huber881227d2016-08-02 14:20:21 -070019#include "ScalarType.h"
Andreas Huberc9410c72016-07-28 12:18:40 -070020
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070021#include <inttypes.h>
22#include <hidl-util/Formatter.h>
Andreas Huber737080b2016-08-02 15:38:04 -070023#include <android-base/logging.h>
24
Andreas Huberc9410c72016-07-28 12:18:40 -070025namespace android {
26
Andreas Huberc9410c72016-07-28 12:18:40 -070027EnumType::EnumType(
Andreas Huber9ed827c2016-08-22 12:31:13 -070028 const char *localName,
Andreas Huber9ed827c2016-08-22 12:31:13 -070029 Type *storageType)
Yifan Hongf24fa852016-09-23 11:03:15 -070030 : Scope(localName),
31 mValues(),
Andreas Huber881227d2016-08-02 14:20:21 -070032 mStorageType(
33 storageType != NULL
34 ? storageType
35 : new ScalarType(ScalarType::KIND_INT32)) {
Andreas Huberc9410c72016-07-28 12:18:40 -070036}
37
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070038const Type *EnumType::storageType() const {
39 return mStorageType;
40}
41
42const std::vector<EnumValue *> &EnumType::values() const {
Yifan Hongf24fa852016-09-23 11:03:15 -070043 return mValues;
44}
45
46void EnumType::addValue(EnumValue *value) {
47 CHECK(value != nullptr);
48
49 EnumValue *prev = nullptr;
50 std::vector<const EnumType *> chain;
51 getTypeChain(&chain);
52 for (auto it = chain.begin(); it != chain.end(); ++it) {
53 const auto &type = *it;
54 if(!type->values().empty()) {
55 prev = type->values().back();
56 break;
57 }
58 }
59
60 value->autofill(prev, resolveToScalarType());
61 mValues.push_back(value);
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070062}
63
Andreas Huber737080b2016-08-02 15:38:04 -070064const ScalarType *EnumType::resolveToScalarType() const {
65 return mStorageType->resolveToScalarType();
66}
67
Andreas Huber8d3ac0c2016-08-04 14:49:23 -070068bool EnumType::isEnum() const {
69 return true;
70}
71
Steven Moreland979e0992016-09-07 09:18:08 -070072std::string EnumType::getCppType(StorageMode,
73 std::string *extra,
74 bool specifyNamespaces) const {
Andreas Huber881227d2016-08-02 14:20:21 -070075 extra->clear();
76
Steven Moreland979e0992016-09-07 09:18:08 -070077 return specifyNamespaces ? fullName() : partialCppName();
Andreas Huber881227d2016-08-02 14:20:21 -070078}
79
Andreas Huber4c865b72016-09-14 15:26:27 -070080std::string EnumType::getJavaType(
81 std::string *extra, bool forInitializer) const {
82 return mStorageType->resolveToScalarType()->getJavaType(
83 extra, forInitializer);
Andreas Huber2831d512016-08-15 09:33:47 -070084}
85
86std::string EnumType::getJavaSuffix() const {
87 return mStorageType->resolveToScalarType()->getJavaSuffix();
88}
89
Andreas Hubera3558b32016-09-14 09:12:42 -070090std::string EnumType::getJavaWrapperType() const {
91 return mStorageType->resolveToScalarType()->getJavaWrapperType();
92}
93
Yifan Hongf24fa852016-09-23 11:03:15 -070094LocalIdentifier *EnumType::lookupIdentifier(const std::string &name) const {
95 std::vector<const EnumType *> chain;
96 getTypeChain(&chain);
97 for (auto it = chain.begin(); it != chain.end(); ++it) {
98 const auto &type = *it;
99 for(EnumValue *v : type->values()) {
100 if(v->name() == name) {
101 return v;
102 }
103 }
104 }
105 return nullptr;
106}
107
Andreas Huber881227d2016-08-02 14:20:21 -0700108void EnumType::emitReaderWriter(
109 Formatter &out,
110 const std::string &name,
111 const std::string &parcelObj,
112 bool parcelObjIsPointer,
113 bool isReader,
114 ErrorMode mode) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700115 const ScalarType *scalarType = mStorageType->resolveToScalarType();
116 CHECK(scalarType != NULL);
117
118 scalarType->emitReaderWriterWithCast(
119 out,
120 name,
121 parcelObj,
122 parcelObjIsPointer,
123 isReader,
124 mode,
125 true /* needsCast */);
Andreas Huber881227d2016-08-02 14:20:21 -0700126}
127
Andreas Huber85eabdb2016-08-25 11:24:49 -0700128void EnumType::emitJavaFieldReaderWriter(
129 Formatter &out,
Andreas Huber4c865b72016-09-14 15:26:27 -0700130 size_t depth,
Andreas Huber709b62d2016-09-19 11:21:18 -0700131 const std::string &parcelName,
Andreas Huber85eabdb2016-08-25 11:24:49 -0700132 const std::string &blobName,
133 const std::string &fieldName,
134 const std::string &offset,
135 bool isReader) const {
136 return mStorageType->emitJavaFieldReaderWriter(
Andreas Huber709b62d2016-09-19 11:21:18 -0700137 out, depth, parcelName, blobName, fieldName, offset, isReader);
Andreas Huber85eabdb2016-08-25 11:24:49 -0700138}
139
Andreas Huber881227d2016-08-02 14:20:21 -0700140status_t EnumType::emitTypeDeclarations(Formatter &out) const {
Andreas Huber737080b2016-08-02 15:38:04 -0700141 const ScalarType *scalarType = mStorageType->resolveToScalarType();
142 CHECK(scalarType != NULL);
143
Andreas Huber881227d2016-08-02 14:20:21 -0700144 std::string extra;
145
146 out << "enum class "
Andreas Huber0e00de42016-08-03 09:56:02 -0700147 << localName()
Andreas Huber881227d2016-08-02 14:20:21 -0700148 << " : "
Andreas Huber737080b2016-08-02 15:38:04 -0700149 << ((Type *)scalarType)->getCppType(&extra)
Andreas Huber881227d2016-08-02 14:20:21 -0700150 << " {\n";
151
152 out.indent();
153
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700154 std::vector<const EnumType *> chain;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700155 getTypeChain(&chain);
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700156
157 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
158 const auto &type = *it;
159
160 for (const auto &entry : type->values()) {
161 out << entry->name();
162
Yifan Hongfc610cd2016-09-22 13:34:45 -0700163 std::string value = entry->cppValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700164 CHECK(!value.empty()); // use autofilled values for c++.
165 out << " = " << value;
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700166
Yifan Hong57886972016-08-17 10:42:15 -0700167 out << ",";
168
Yifan Hongfc610cd2016-09-22 13:34:45 -0700169 std::string comment = entry->comment();
170 if (!comment.empty() && comment != value) {
Yifan Hong57886972016-08-17 10:42:15 -0700171 out << " // " << comment;
172 }
173
174 out << "\n";
Andreas Huber8d3ac0c2016-08-04 14:49:23 -0700175 }
Andreas Huber881227d2016-08-02 14:20:21 -0700176 }
177
178 out.unindent();
179 out << "};\n\n";
180
181 return OK;
182}
183
Andreas Huber85eabdb2016-08-25 11:24:49 -0700184status_t EnumType::emitJavaTypeDeclarations(Formatter &out, bool) const {
Andreas Huber2831d512016-08-15 09:33:47 -0700185 const ScalarType *scalarType = mStorageType->resolveToScalarType();
186 CHECK(scalarType != NULL);
187
188 out << "public final class "
189 << localName()
190 << " {\n";
191
192 out.indent();
193
Andreas Huber4c865b72016-09-14 15:26:27 -0700194 std::string extra; // unused, because ScalarType leaves this empty.
195 const std::string typeName =
196 scalarType->getJavaType(&extra, false /* forInitializer */);
Andreas Huber2831d512016-08-15 09:33:47 -0700197
198 std::vector<const EnumType *> chain;
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700199 getTypeChain(&chain);
Andreas Huber2831d512016-08-15 09:33:47 -0700200
201 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
202 const auto &type = *it;
203
204 for (const auto &entry : type->values()) {
205 out << "public static final "
206 << typeName
207 << " "
Andreas Huberab647c02016-09-14 09:44:00 -0700208 << entry->name()
209 << " = ";
Andreas Huber2831d512016-08-15 09:33:47 -0700210
Yifan Hongf24fa852016-09-23 11:03:15 -0700211 // javaValue will make the number signed.
Yifan Hongfc610cd2016-09-22 13:34:45 -0700212 std::string value = entry->javaValue(scalarType->getKind());
Yifan Hongf24fa852016-09-23 11:03:15 -0700213 CHECK(!value.empty()); // use autofilled values for java.
214 out << value;
Andreas Huber2831d512016-08-15 09:33:47 -0700215
Yifan Hong19ca75a2016-08-31 10:20:03 -0700216 out << ";";
217
Yifan Hongfc610cd2016-09-22 13:34:45 -0700218 std::string comment = entry->comment();
219 if (!comment.empty() && comment != value) {
Yifan Hong19ca75a2016-08-31 10:20:03 -0700220 out << " // " << comment;
221 }
222
223 out << "\n";
Andreas Huber2831d512016-08-15 09:33:47 -0700224 }
225 }
226
227 out.unindent();
228 out << "};\n\n";
229
230 return OK;
231}
232
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700233status_t EnumType::emitVtsTypeDeclarations(Formatter &out) const {
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700234 out << "name: \"" << localName() << "\"\n"
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700235 << "type: TYPE_ENUM\n"
236 << "enum_value: {\n";
237 out.indent();
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700238
239 std::vector<const EnumType *> chain;
240 getTypeChain(&chain);
241
242 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
243 const auto &type = *it;
244
245 for (const auto &entry : type->values()) {
246 out << "enumerator: \"" << entry->name() << "\"\n";
247
Yifan Hongf24fa852016-09-23 11:03:15 -0700248 if (!entry->isAutoFill()) {
249 // don't autofill values for vts.
250 std::string value = entry->value();
251 CHECK(!value.empty());
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700252 out << "value: " << value << "\n";
253 }
254 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700255 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700256
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700257 out.unindent();
258 out << "}\n";
259 return OK;
260}
261
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700262status_t EnumType::emitVtsAttributeType(Formatter &out) const {
Zhuoyao Zhang19933522016-08-29 15:06:38 -0700263 out << "type: TYPE_ENUM\n"
264 << "predefined_type: \""
265 << localName()
266 << "\"\n";
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700267 return OK;
268}
269
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700270void EnumType::getTypeChain(std::vector<const EnumType *> *out) const {
271 out->clear();
272 const EnumType *type = this;
273 for (;;) {
274 out->push_back(type);
275
276 const Type *superType = type->storageType();
277 if (superType == NULL || !superType->isEnum()) {
278 break;
279 }
280
281 type = static_cast<const EnumType *>(superType);
282 }
283}
284
Andreas Huber85eabdb2016-08-25 11:24:49 -0700285void EnumType::getAlignmentAndSize(size_t *align, size_t *size) const {
286 mStorageType->getAlignmentAndSize(align, size);
287}
288
Andreas Huber31629bc2016-08-03 09:06:40 -0700289////////////////////////////////////////////////////////////////////////////////
290
Yifan Hongf24fa852016-09-23 11:03:15 -0700291EnumValue::EnumValue(const char *name, ConstantExpression *value)
Andreas Huber31629bc2016-08-03 09:06:40 -0700292 : mName(name),
Yifan Hongf24fa852016-09-23 11:03:15 -0700293 mValue(value),
294 mIsAutoFill(false) {
Andreas Huber31629bc2016-08-03 09:06:40 -0700295}
296
297std::string EnumValue::name() const {
298 return mName;
299}
300
Yifan Hongfc610cd2016-09-22 13:34:45 -0700301std::string EnumValue::value() const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700302 CHECK(mValue != nullptr);
303 return mValue->value();
Yifan Hong57886972016-08-17 10:42:15 -0700304}
305
Yifan Hongfc610cd2016-09-22 13:34:45 -0700306std::string EnumValue::cppValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700307 CHECK(mValue != nullptr);
308 return mValue->cppValue(castKind);
Yifan Hong57886972016-08-17 10:42:15 -0700309}
Yifan Hongfc610cd2016-09-22 13:34:45 -0700310std::string EnumValue::javaValue(ScalarType::Kind castKind) const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700311 CHECK(mValue != nullptr);
312 return mValue->javaValue(castKind);
Yifan Hong19ca75a2016-08-31 10:20:03 -0700313}
Yifan Hong57886972016-08-17 10:42:15 -0700314
Yifan Hongfc610cd2016-09-22 13:34:45 -0700315std::string EnumValue::comment() const {
Yifan Hongf24fa852016-09-23 11:03:15 -0700316 CHECK(mValue != nullptr);
317 return mValue->description();
318}
319
320ConstantExpression *EnumValue::constExpr() const {
321 CHECK(mValue != nullptr);
322 return mValue;
323}
324
325void EnumValue::autofill(const EnumValue *prev, const ScalarType *type) {
326 if(mValue != nullptr)
327 return;
328 mIsAutoFill = true;
329 ConstantExpression *value = new ConstantExpression();
330 if(prev == nullptr) {
331 *value = ConstantExpression::Zero(type->getKind());
332 } else {
333 CHECK(prev->mValue != nullptr);
334 *value = prev->mValue->addOne();
335 }
336 mValue = value;
337}
338
339bool EnumValue::isAutoFill() const {
340 return mIsAutoFill;
341}
342
343bool EnumValue::isEnumValue() const {
344 return true;
Andreas Huber31629bc2016-08-03 09:06:40 -0700345}
346
Andreas Huberc9410c72016-07-28 12:18:40 -0700347} // namespace android
348