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
typeName() const105 std::string Type::typeName() const {
106 return "";
107 }
108
resolveToScalarType() const109 const ScalarType *Type::resolveToScalarType() const {
110 return NULL;
111 }
112
isValidEnumStorageType() const113 bool Type::isValidEnumStorageType() const {
114 const ScalarType *scalarType = resolveToScalarType();
115
116 if (scalarType == NULL) {
117 return false;
118 }
119
120 return scalarType->isValidEnumStorageType();
121 }
122
isElidableType() const123 bool Type::isElidableType() const {
124 return false;
125 }
126
canCheckEquality() const127 bool Type::canCheckEquality() const {
128 return false;
129 }
130
getCppType(StorageMode,bool) const131 std::string Type::getCppType(StorageMode, bool) const {
132 CHECK(!"Should not be here");
133 return std::string();
134 }
135
decorateCppName(const std::string & name,StorageMode mode,bool specifyNamespaces) const136 std::string Type::decorateCppName(
137 const std::string &name, StorageMode mode, bool specifyNamespaces) const {
138 return getCppType(mode, specifyNamespaces) + " " + name;
139 }
140
getJavaType(bool) const141 std::string Type::getJavaType(bool /* forInitializer */) const {
142 CHECK(!"Should not be here");
143 return std::string();
144 }
145
getJavaWrapperType() const146 std::string Type::getJavaWrapperType() const {
147 return getJavaType();
148 }
149
getJavaSuffix() const150 std::string Type::getJavaSuffix() const {
151 CHECK(!"Should not be here");
152 return std::string();
153 }
154
getVtsType() const155 std::string Type::getVtsType() const {
156 CHECK(!"Should not be here");
157 return std::string();
158 }
159
getVtsValueName() const160 std::string Type::getVtsValueName() const {
161 CHECK(!"Should not be here");
162 return std::string();
163 }
164
emitReaderWriter(Formatter &,const std::string &,const std::string &,bool,bool,ErrorMode) const165 void Type::emitReaderWriter(
166 Formatter &,
167 const std::string &,
168 const std::string &,
169 bool,
170 bool,
171 ErrorMode) const {
172 CHECK(!"Should not be here");
173 }
174
emitResolveReferences(Formatter &,const std::string &,bool,const std::string &,bool,bool,ErrorMode) const175 void Type::emitResolveReferences(
176 Formatter &,
177 const std::string &,
178 bool,
179 const std::string &,
180 bool,
181 bool,
182 ErrorMode) const {
183 CHECK(!"Should not be here");
184 }
185
emitResolveReferencesEmbedded(Formatter &,size_t,const std::string &,const std::string &,bool,const std::string &,bool,bool,ErrorMode,const std::string &,const std::string &) const186 void Type::emitResolveReferencesEmbedded(
187 Formatter &,
188 size_t,
189 const std::string &,
190 const std::string &,
191 bool,
192 const std::string &,
193 bool,
194 bool,
195 ErrorMode,
196 const std::string &,
197 const std::string &) const {
198 CHECK(!"Should not be here");
199 }
200
emitDump(Formatter & out,const std::string & streamName,const std::string & name) const201 void Type::emitDump(
202 Formatter &out,
203 const std::string &streamName,
204 const std::string &name) const {
205 emitDumpWithMethod(out, streamName, "::android::hardware::toString", name);
206 }
207
emitDumpWithMethod(Formatter & out,const std::string & streamName,const std::string & methodName,const std::string & name) const208 void Type::emitDumpWithMethod(
209 Formatter &out,
210 const std::string &streamName,
211 const std::string &methodName,
212 const std::string &name) const {
213 out << streamName
214 << " += "
215 << methodName
216 << "("
217 << name
218 << ");\n";
219 }
220
emitJavaDump(Formatter & out,const std::string & streamName,const std::string & name) const221 void Type::emitJavaDump(
222 Formatter &out,
223 const std::string &streamName,
224 const std::string &name) const {
225 out << streamName << ".append(" << name << ");\n";
226 }
227
useParentInEmitResolveReferencesEmbedded() const228 bool Type::useParentInEmitResolveReferencesEmbedded() const {
229 return needsResolveReferences();
230 }
231
useNameInEmitReaderWriterEmbedded(bool) const232 bool Type::useNameInEmitReaderWriterEmbedded(bool) const {
233 return needsEmbeddedReadWrite();
234 }
235
emitReaderWriterEmbedded(Formatter &,size_t,const std::string &,const std::string &,bool,const std::string &,bool,bool,ErrorMode,const std::string &,const std::string &) const236 void Type::emitReaderWriterEmbedded(
237 Formatter &,
238 size_t,
239 const std::string &,
240 const std::string &,
241 bool,
242 const std::string &,
243 bool,
244 bool,
245 ErrorMode,
246 const std::string &,
247 const std::string &) const {
248 CHECK(!"Should not be here");
249 }
250
emitJavaReaderWriter(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader) const251 void Type::emitJavaReaderWriter(
252 Formatter &out,
253 const std::string &parcelObj,
254 const std::string &argName,
255 bool isReader) const {
256 emitJavaReaderWriterWithSuffix(
257 out,
258 parcelObj,
259 argName,
260 isReader,
261 getJavaSuffix(),
262 "" /* extra */);
263 }
264
emitJavaFieldInitializer(Formatter & out,const std::string & fieldName) const265 void Type::emitJavaFieldInitializer(
266 Formatter &out,
267 const std::string &fieldName) const {
268 out << getJavaType()
269 << " "
270 << fieldName
271 << ";\n";
272 }
273
emitJavaFieldReaderWriter(Formatter &,size_t,const std::string &,const std::string &,const std::string &,const std::string &,bool) const274 void Type::emitJavaFieldReaderWriter(
275 Formatter &,
276 size_t,
277 const std::string &,
278 const std::string &,
279 const std::string &,
280 const std::string &,
281 bool) const {
282 CHECK(!"Should not be here");
283 }
284
handleError(Formatter & out,ErrorMode mode) const285 void Type::handleError(Formatter &out, ErrorMode mode) const {
286 switch (mode) {
287 case ErrorMode_Ignore:
288 {
289 out << "/* _hidl_err ignored! */\n\n";
290 break;
291 }
292
293 case ErrorMode_Goto:
294 {
295 out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
296 break;
297 }
298
299 case ErrorMode_Break:
300 {
301 out << "if (_hidl_err != ::android::OK) { break; }\n\n";
302 break;
303 }
304
305 case ErrorMode_Return:
306 {
307 out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n\n";
308 break;
309 }
310 }
311 }
312
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) const313 void Type::emitReaderWriterEmbeddedForTypeName(
314 Formatter &out,
315 const std::string &name,
316 bool nameIsPointer,
317 const std::string &parcelObj,
318 bool parcelObjIsPointer,
319 bool isReader,
320 ErrorMode mode,
321 const std::string &parentName,
322 const std::string &offsetText,
323 const std::string &typeName,
324 const std::string &childName,
325 const std::string &funcNamespace) const {
326
327 const std::string parcelObjDeref =
328 parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;
329
330 const std::string parcelObjPointer =
331 parcelObjIsPointer ? parcelObj : ("&" + parcelObj);
332
333 const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
334 const std::string namePointer = nameIsPointer ? name : ("&" + name);
335
336 out << "_hidl_err = ";
337
338 if (!funcNamespace.empty()) {
339 out << funcNamespace << "::";
340 }
341
342 out << (isReader ? "readEmbeddedFromParcel(\n" : "writeEmbeddedToParcel(\n");
343
344 out.indent();
345 out.indent();
346
347 if (isReader) {
348 out << "const_cast<"
349 << typeName
350 << " &>("
351 << nameDerefed
352 << "),\n";
353 } else {
354 out << nameDerefed
355 << ",\n";
356 }
357
358 out << (isReader ? parcelObjDeref : parcelObjPointer)
359 << ",\n"
360 << parentName
361 << ",\n"
362 << offsetText;
363
364 if (!childName.empty()) {
365 out << ", &"
366 << childName;
367 }
368
369 out << ");\n\n";
370
371 out.unindent();
372 out.unindent();
373
374 handleError(out, mode);
375 }
376
emitTypeDeclarations(Formatter &) const377 status_t Type::emitTypeDeclarations(Formatter &) const {
378 return OK;
379 }
380
emitGlobalTypeDeclarations(Formatter &) const381 status_t Type::emitGlobalTypeDeclarations(Formatter &) const {
382 return OK;
383 }
384
emitGlobalHwDeclarations(Formatter &) const385 status_t Type::emitGlobalHwDeclarations(Formatter &) const {
386 return OK;
387 }
388
emitTypeDefinitions(Formatter &,const std::string) const389 status_t Type::emitTypeDefinitions(
390 Formatter &, const std::string) const {
391 return OK;
392 }
393
emitJavaTypeDeclarations(Formatter &,bool) const394 status_t Type::emitJavaTypeDeclarations(Formatter &, bool) const {
395 return OK;
396 }
397
needsEmbeddedReadWrite() const398 bool Type::needsEmbeddedReadWrite() const {
399 return false;
400 }
401
needsResolveReferences() const402 bool Type::needsResolveReferences() const {
403 return false;
404 }
405
resultNeedsDeref() const406 bool Type::resultNeedsDeref() const {
407 return false;
408 }
409
getCppStackType(bool specifyNamespaces) const410 std::string Type::getCppStackType(bool specifyNamespaces) const {
411 return getCppType(StorageMode_Stack, specifyNamespaces);
412 }
413
getCppResultType(bool specifyNamespaces) const414 std::string Type::getCppResultType(bool specifyNamespaces) const {
415 return getCppType(StorageMode_Result, specifyNamespaces);
416 }
417
getCppArgumentType(bool specifyNamespaces) const418 std::string Type::getCppArgumentType(bool specifyNamespaces) const {
419 return getCppType(StorageMode_Argument, specifyNamespaces);
420 }
421
emitJavaReaderWriterWithSuffix(Formatter & out,const std::string & parcelObj,const std::string & argName,bool isReader,const std::string & suffix,const std::string & extra) const422 void Type::emitJavaReaderWriterWithSuffix(
423 Formatter &out,
424 const std::string &parcelObj,
425 const std::string &argName,
426 bool isReader,
427 const std::string &suffix,
428 const std::string &extra) const {
429 out << parcelObj
430 << "."
431 << (isReader ? "read" : "write")
432 << suffix
433 << "(";
434
435 if (isReader) {
436 out << extra;
437 } else {
438 out << (extra.empty() ? "" : (extra + ", "));
439 out << argName;
440 }
441
442 out << ");\n";
443 }
444
emitVtsTypeDeclarations(Formatter &) const445 status_t Type::emitVtsTypeDeclarations(Formatter &) const {
446 return OK;
447 }
448
emitVtsAttributeType(Formatter & out) const449 status_t Type::emitVtsAttributeType(Formatter &out) const {
450 return emitVtsTypeDeclarations(out);
451 }
452
isJavaCompatible() const453 bool Type::isJavaCompatible() const {
454 return true;
455 }
456
getAlignmentAndSize(size_t *,size_t *) const457 void Type::getAlignmentAndSize(
458 size_t * /* align */, size_t * /* size */) const {
459 CHECK(!"Should not be here.");
460 }
461
containsPointer() const462 bool Type::containsPointer() const {
463 return false;
464 }
465
appendToExportedTypesVector(std::vector<const Type * > *) const466 void Type::appendToExportedTypesVector(
467 std::vector<const Type *> * /* exportedTypes */) const {
468 }
469
emitExportedHeader(Formatter &,bool) const470 status_t Type::emitExportedHeader(
471 Formatter & /* out */, bool /* forJava */) const {
472 return OK;
473 }
474
475 ////////////////////////////////////////
476
TemplatedType()477 TemplatedType::TemplatedType() : mElementType(nullptr) {
478 }
479
setElementType(Type * elementType)480 void TemplatedType::setElementType(Type *elementType) {
481 CHECK(mElementType == nullptr); // can only be set once.
482 CHECK(isCompatibleElementType(elementType));
483 mElementType = elementType;
484 }
485
getElementType() const486 Type *TemplatedType::getElementType() const {
487 return mElementType;
488 }
489
isTemplatedType() const490 bool TemplatedType::isTemplatedType() const {
491 return true;
492 }
493
emitVtsTypeDeclarations(Formatter & out) const494 status_t TemplatedType::emitVtsTypeDeclarations(Formatter &out) const {
495 out << "type: " << getVtsType() << "\n";
496 out << getVtsValueName() << ": {\n";
497 out.indent();
498 status_t err = mElementType->emitVtsTypeDeclarations(out);
499 if (err != OK) {
500 return err;
501 }
502 out.unindent();
503 out << "}\n";
504 return OK;
505 }
506
emitVtsAttributeType(Formatter & out) const507 status_t TemplatedType::emitVtsAttributeType(Formatter &out) const {
508 out << "type: " << getVtsType() << "\n";
509 out << getVtsValueName() << ": {\n";
510 out.indent();
511 status_t status = mElementType->emitVtsAttributeType(out);
512 if (status != OK) {
513 return status;
514 }
515 out.unindent();
516 out << "}\n";
517 return OK;
518 }
519 } // namespace android
520
521