1 /*
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
17 #include "Type.h"
18
19 #include "Annotation.h"
20 #include "ScalarType.h"
21
22 #include <hidl-util/Formatter.h>
23 #include <android-base/logging.h>
24
25 namespace android {
26
Type()27 Type::Type()
28 : mAnnotations(nullptr) {
29 }
30
~Type()31 Type::~Type() {}
32
setAnnotations(std::vector<Annotation * > * annotations)33 void Type::setAnnotations(std::vector<Annotation *> *annotations) {
34 mAnnotations = annotations;
35 }
36
annotations() const37 const std::vector<Annotation *> &Type::annotations() const {
38 return *mAnnotations;
39 }
40
isScope() const41 bool Type::isScope() const {
42 return false;
43 }
44
isInterface() const45 bool Type::isInterface() const {
46 return false;
47 }
48
isScalar() const49 bool Type::isScalar() const {
50 return false;
51 }
52
isString() const53 bool Type::isString() const {
54 return false;
55 }
56
isEnum() const57 bool Type::isEnum() const {
58 return false;
59 }
60
isBitField() const61 bool Type::isBitField() const {
62 return false;
63 }
64
isHandle() const65 bool Type::isHandle() const {
66 return false;
67 }
68
isTypeDef() const69 bool Type::isTypeDef() const {
70 return false;
71 }
72
isBinder() const73 bool Type::isBinder() const {
74 return false;
75 }
76
isNamedType() const77 bool Type::isNamedType() const {
78 return false;
79 }
80
isMemory() const81 bool Type::isMemory() const {
82 return false;
83 }
84
isCompoundType() const85 bool Type::isCompoundType() const {
86 return false;
87 }
88
isArray() const89 bool Type::isArray() const {
90 return false;
91 }
92
isVector() const93 bool Type::isVector() const {
94 return false;
95 }
96
isTemplatedType() const97 bool Type::isTemplatedType() const {
98 return false;
99 }
100
isPointer() const101 bool Type::isPointer() const {
102 return false;
103 }
104
resolveToScalarType() const105 const ScalarType *Type::resolveToScalarType() const {
106 return NULL;
107 }
108
isValidEnumStorageType() const109 bool Type::isValidEnumStorageType() const {
110 const ScalarType *scalarType = resolveToScalarType();
111
112 if (scalarType == NULL) {
113 return false;
114 }
115
116 return scalarType->isValidEnumStorageType();
117 }
118
isElidableType() const119 bool Type::isElidableType() const {
120 return false;
121 }
122
canCheckEquality() const123 bool Type::canCheckEquality() const {
124 return false;
125 }
126
getCppType(StorageMode,bool) const127 std::string Type::getCppType(StorageMode, bool) const {
128 CHECK(!"Should not be here");
129 return std::string();
130 }
131
decorateCppName(const std::string & name,StorageMode mode,bool specifyNamespaces) const132 std::string Type::decorateCppName(
133 const std::string &name, StorageMode mode, bool specifyNamespaces) const {
134 return getCppType(mode, specifyNamespaces) + " " + name;
135 }
136
getJavaType(bool) const137 std::string Type::getJavaType(bool /* forInitializer */) const {
138 CHECK(!"Should not be here");
139 return std::string();
140 }
141
getJavaWrapperType() const142 std::string Type::getJavaWrapperType() const {
143 return getJavaType();
144 }
145
getJavaSuffix() const146 std::string Type::getJavaSuffix() const {
147 CHECK(!"Should not be here");
148 return std::string();
149 }
150
getVtsType() const151 std::string Type::getVtsType() const {
152 CHECK(!"Should not be here");
153 return std::string();
154 }
155
getVtsValueName() const156 std::string Type::getVtsValueName() const {
157 CHECK(!"Should not be here");
158 return std::string();
159 }
160
emitReaderWriter(Formatter &,const std::string &,const std::string &,bool,bool,ErrorMode) const161 void Type::emitReaderWriter(
162 Formatter &,
163 const std::string &,
164 const std::string &,
165 bool,
166 bool,
167 ErrorMode) const {
168 CHECK(!"Should not be here");
169 }
170
emitResolveReferences(Formatter &,const std::string &,bool,const std::string &,bool,bool,ErrorMode) const171 void Type::emitResolveReferences(
172 Formatter &,
173 const std::string &,
174 bool,
175 const std::string &,
176 bool,
177 bool,
178 ErrorMode) const {
179 CHECK(!"Should not be here");
180 }
181
emitResolveReferencesEmbedded(Formatter &,size_t,const std::string &,const std::string &,bool,const std::string &,bool,bool,ErrorMode,const std::string &,const std::string &) const182 void Type::emitResolveReferencesEmbedded(
183 Formatter &,
184 size_t,
185 const std::string &,
186 const std::string &,
187 bool,
188 const std::string &,
189 bool,
190 bool,
191 ErrorMode,
192 const std::string &,
193 const std::string &) const {
194 CHECK(!"Should not be here");
195 }
196
emitDump(Formatter & out,const std::string & streamName,const std::string & name) const197 void Type::emitDump(
198 Formatter &out,
199 const std::string &streamName,
200 const std::string &name) const {
201 emitDumpWithMethod(out, streamName, "::android::hardware::toString", name);
202 }
203
emitDumpWithMethod(Formatter & out,const std::string & streamName,const std::string & methodName,const std::string & name) const204 void Type::emitDumpWithMethod(
205 Formatter &out,
206 const std::string &streamName,
207 const std::string &methodName,
208 const std::string &name) const {
209 out << streamName
210 << " += "
211 << methodName
212 << "("
213 << name
214 << ");\n";
215 }
216
emitJavaDump(Formatter & out,const std::string & streamName,const std::string & name) const217 void Type::emitJavaDump(
218 Formatter &out,
219 const std::string &streamName,
220 const std::string &name) const {
221 out << streamName << ".append(" << name << ");\n";
222 }
223
useParentInEmitResolveReferencesEmbedded() const224 bool Type::useParentInEmitResolveReferencesEmbedded() const {
225 return needsResolveReferences();
226 }
227
useNameInEmitReaderWriterEmbedded(bool) const228 bool Type::useNameInEmitReaderWriterEmbedded(bool) const {
229 return needsEmbeddedReadWrite();
230 }
231
emitReaderWriterEmbedded(Formatter &,size_t,const std::string &,const std::string &,bool,const std::string &,bool,bool,ErrorMode,const std::string &,const std::string &) const232 void Type::emitReaderWriterEmbedded(
233 Formatter &,
234 size_t,
235 const std::string &,
236 const std::string &,
237 bool,
238 const std::string &,
239 bool,
240 bool,
241 ErrorMode,
242 const std::string &,
243 const std::string &) const {
244 CHECK(!"Should not be here");
245 }
246
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const247 void Type::emitJavaReaderWriter(
248 Formatter &out,
249 const std::string &parcelObj,
250 const std::string &argName,
251 bool isReader) const {
252 emitJavaReaderWriterWithSuffix(
253 out,
254 parcelObj,
255 argName,
256 isReader,
257 getJavaSuffix(),
258 "" /* extra */);
259 }
260
emitJavaFieldInitializer(Formatter & out,const std::string & fieldName) const261 void Type::emitJavaFieldInitializer(
262 Formatter &out,
263 const std::string &fieldName) const {
264 out << getJavaType()
265 << " "
266 << fieldName
267 << ";\n";
268 }
269
emitJavaFieldReaderWriter(Formatter &,size_t,const std::string &,const std::string &,const std::string &,const std::string &,bool) const270 void Type::emitJavaFieldReaderWriter(
271 Formatter &,
272 size_t,
273 const std::string &,
274 const std::string &,
275 const std::string &,
276 const std::string &,
277 bool) const {
278 CHECK(!"Should not be here");
279 }
280
handleError(Formatter & out,ErrorMode mode) const281 void Type::handleError(Formatter &out, ErrorMode mode) const {
282 switch (mode) {
283 case ErrorMode_Ignore:
284 {
285 out << "/* _hidl_err ignored! */\n\n";
286 break;
287 }
288
289 case ErrorMode_Goto:
290 {
291 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
292 break;
293 }
294
295 case ErrorMode_Break:
296 {
297 out << "if (_hidl_err != ::android::OK) { break; }\n\n";
298 break;
299 }
300
301 case ErrorMode_Return:
302 {
303 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n\n";
304 break;
305 }
306 }
307 }
308
emitReaderWriterEmbeddedForTypeName(Formatter & out,const std::string & name,bool nameIsPointer,const std::string & parcelObj,bool parcelObjIsPointer,bool isReader,ErrorMode mode,const std::string & parentName,const std::string & offsetText,const std::string & typeName,const std::string & childName,const std::string & funcNamespace) const309 void Type::emitReaderWriterEmbeddedForTypeName(
310 Formatter &out,
311 const std::string &name,
312 bool nameIsPointer,
313 const std::string &parcelObj,
314 bool parcelObjIsPointer,
315 bool isReader,
316 ErrorMode mode,
317 const std::string &parentName,
318 const std::string &offsetText,
319 const std::string &typeName,
320 const std::string &childName,
321 const std::string &funcNamespace) const {
322
323 const std::string parcelObjDeref =
324 parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;
325
326 const std::string parcelObjPointer =
327 parcelObjIsPointer ? parcelObj : ("&" + parcelObj);
328
329 const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
330 const std::string namePointer = nameIsPointer ? name : ("&" + name);
331
332 out << "_hidl_err = ";
333
334 if (!funcNamespace.empty()) {
335 out << funcNamespace << "::";
336 }
337
338 out << (isReader ? "readEmbeddedFromParcel(\n" : "writeEmbeddedToParcel(\n");
339
340 out.indent();
341 out.indent();
342
343 if (isReader) {
344 out << "const_cast<"
345 << typeName
346 << " &>("
347 << nameDerefed
348 << "),\n";
349 } else {
350 out << nameDerefed
351 << ",\n";
352 }
353
354 out << (isReader ? parcelObjDeref : parcelObjPointer)
355 << ",\n"
356 << parentName
357 << ",\n"
358 << offsetText;
359
360 if (!childName.empty()) {
361 out << ", &"
362 << childName;
363 }
364
365 out << ");\n\n";
366
367 out.unindent();
368 out.unindent();
369
370 handleError(out, mode);
371 }
372
emitTypeDeclarations(Formatter &) const373 status_t Type::emitTypeDeclarations(Formatter &) const {
374 return OK;
375 }
376
emitGlobalTypeDeclarations(Formatter &) const377 status_t Type::emitGlobalTypeDeclarations(Formatter &) const {
378 return OK;
379 }
380
emitGlobalHwDeclarations(Formatter &) const381 status_t Type::emitGlobalHwDeclarations(Formatter &) const {
382 return OK;
383 }
384
emitTypeDefinitions(Formatter &,const std::string) const385 status_t Type::emitTypeDefinitions(
386 Formatter &, const std::string) const {
387 return OK;
388 }
389
emitJavaTypeDeclarations(Formatter &,bool) const390 status_t Type::emitJavaTypeDeclarations(Formatter &, bool) const {
391 return OK;
392 }
393
needsEmbeddedReadWrite() const394 bool Type::needsEmbeddedReadWrite() const {
395 return false;
396 }
397
needsResolveReferences() const398 bool Type::needsResolveReferences() const {
399 return false;
400 }
401
resultNeedsDeref() const402 bool Type::resultNeedsDeref() const {
403 return false;
404 }
405
getCppStackType(bool specifyNamespaces) const406 std::string Type::getCppStackType(bool specifyNamespaces) const {
407 return getCppType(StorageMode_Stack, specifyNamespaces);
408 }
409
getCppResultType(bool specifyNamespaces) const410 std::string Type::getCppResultType(bool specifyNamespaces) const {
411 return getCppType(StorageMode_Result, specifyNamespaces);
412 }
413
getCppArgumentType(bool specifyNamespaces) const414 std::string Type::getCppArgumentType(bool specifyNamespaces) const {
415 return getCppType(StorageMode_Argument, specifyNamespaces);
416 }
417
emitJavaReaderWriterWithSuffix(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader,const std::string & suffix,const std::string & extra) const418 void Type::emitJavaReaderWriterWithSuffix(
419 Formatter &out,
420 const std::string &parcelObj,
421 const std::string &argName,
422 bool isReader,
423 const std::string &suffix,
424 const std::string &extra) const {
425 out << parcelObj
426 << "."
427 << (isReader ? "read" : "write")
428 << suffix
429 << "(";
430
431 if (isReader) {
432 out << extra;
433 } else {
434 out << (extra.empty() ? "" : (extra + ", "));
435 out << argName;
436 }
437
438 out << ");\n";
439 }
440
emitVtsTypeDeclarations(Formatter &) const441 status_t Type::emitVtsTypeDeclarations(Formatter &) const {
442 return OK;
443 }
444
emitVtsAttributeType(Formatter & out) const445 status_t Type::emitVtsAttributeType(Formatter &out) const {
446 return emitVtsTypeDeclarations(out);
447 }
448
isJavaCompatible() const449 bool Type::isJavaCompatible() const {
450 return true;
451 }
452
getAlignmentAndSize(size_t *,size_t *) const453 void Type::getAlignmentAndSize(
454 size_t * /* align */, size_t * /* size */) const {
455 CHECK(!"Should not be here.");
456 }
457
containsPointer() const458 bool Type::containsPointer() const {
459 return false;
460 }
461
appendToExportedTypesVector(std::vector<const Type * > *) const462 void Type::appendToExportedTypesVector(
463 std::vector<const Type *> * /* exportedTypes */) const {
464 }
465
emitExportedHeader(Formatter &,bool) const466 status_t Type::emitExportedHeader(
467 Formatter & /* out */, bool /* forJava */) const {
468 return OK;
469 }
470
471 ////////////////////////////////////////
472
TemplatedType()473 TemplatedType::TemplatedType() : mElementType(nullptr) {
474 }
475
setElementType(Type * elementType)476 void TemplatedType::setElementType(Type *elementType) {
477 CHECK(mElementType == nullptr); // can only be set once.
478 CHECK(isCompatibleElementType(elementType));
479 mElementType = elementType;
480 }
481
getElementType() const482 Type *TemplatedType::getElementType() const {
483 return mElementType;
484 }
485
isTemplatedType() const486 bool TemplatedType::isTemplatedType() const {
487 return true;
488 }
489
emitVtsTypeDeclarations(Formatter & out) const490 status_t TemplatedType::emitVtsTypeDeclarations(Formatter &out) const {
491 out << "type: " << getVtsType() << "\n";
492 out << getVtsValueName() << ": {\n";
493 out.indent();
494 status_t err = mElementType->emitVtsTypeDeclarations(out);
495 if (err != OK) {
496 return err;
497 }
498 out.unindent();
499 out << "}\n";
500 return OK;
501 }
502
emitVtsAttributeType(Formatter & out) const503 status_t TemplatedType::emitVtsAttributeType(Formatter &out) const {
504 out << "type: " << getVtsType() << "\n";
505 out << getVtsValueName() << ": {\n";
506 out.indent();
507 status_t status = mElementType->emitVtsAttributeType(out);
508 if (status != OK) {
509 return status;
510 }
511 out.unindent();
512 out << "}\n";
513 return OK;
514 }
515 } // namespace android
516
517