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 27 Type::Type() 28 : mAnnotations(nullptr) { 29 } 30 31 Type::~Type() {} 32 33 void Type::setAnnotations(std::vector<Annotation *> *annotations) { 34 mAnnotations = annotations; 35 } 36 37 const std::vector<Annotation *> &Type::annotations() const { 38 return *mAnnotations; 39 } 40 41 bool Type::isScope() const { 42 return false; 43 } 44 45 bool Type::isInterface() const { 46 return false; 47 } 48 49 bool Type::isScalar() const { 50 return false; 51 } 52 53 bool Type::isString() const { 54 return false; 55 } 56 57 bool Type::isEnum() const { 58 return false; 59 } 60 61 bool Type::isBitField() const { 62 return false; 63 } 64 65 bool Type::isHandle() const { 66 return false; 67 } 68 69 bool Type::isTypeDef() const { 70 return false; 71 } 72 73 bool Type::isBinder() const { 74 return false; 75 } 76 77 bool Type::isNamedType() const { 78 return false; 79 } 80 81 bool Type::isMemory() const { 82 return false; 83 } 84 85 bool Type::isCompoundType() const { 86 return false; 87 } 88 89 bool Type::isArray() const { 90 return false; 91 } 92 93 bool Type::isVector() const { 94 return false; 95 } 96 97 bool Type::isTemplatedType() const { 98 return false; 99 } 100 101 bool Type::isPointer() const { 102 return false; 103 } 104 105 std::string Type::typeName() const { 106 return ""; 107 } 108 109 const ScalarType *Type::resolveToScalarType() const { 110 return NULL; 111 } 112 113 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 123 bool Type::isElidableType() const { 124 return false; 125 } 126 127 bool Type::canCheckEquality() const { 128 return false; 129 } 130 131 std::string Type::getCppType(StorageMode, bool) const { 132 CHECK(!"Should not be here"); 133 return std::string(); 134 } 135 136 std::string Type::decorateCppName( 137 const std::string &name, StorageMode mode, bool specifyNamespaces) const { 138 return getCppType(mode, specifyNamespaces) + " " + name; 139 } 140 141 std::string Type::getJavaType(bool /* forInitializer */) const { 142 CHECK(!"Should not be here"); 143 return std::string(); 144 } 145 146 std::string Type::getJavaWrapperType() const { 147 return getJavaType(); 148 } 149 150 std::string Type::getJavaSuffix() const { 151 CHECK(!"Should not be here"); 152 return std::string(); 153 } 154 155 std::string Type::getVtsType() const { 156 CHECK(!"Should not be here"); 157 return std::string(); 158 } 159 160 std::string Type::getVtsValueName() const { 161 CHECK(!"Should not be here"); 162 return std::string(); 163 } 164 165 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 175 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 186 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 201 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 208 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 221 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 228 bool Type::useParentInEmitResolveReferencesEmbedded() const { 229 return needsResolveReferences(); 230 } 231 232 bool Type::useNameInEmitReaderWriterEmbedded(bool) const { 233 return needsEmbeddedReadWrite(); 234 } 235 236 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 251 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 265 void Type::emitJavaFieldInitializer( 266 Formatter &out, 267 const std::string &fieldName) const { 268 out << getJavaType() 269 << " " 270 << fieldName 271 << ";\n"; 272 } 273 274 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 285 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 313 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 377 status_t Type::emitTypeDeclarations(Formatter &) const { 378 return OK; 379 } 380 381 status_t Type::emitGlobalTypeDeclarations(Formatter &) const { 382 return OK; 383 } 384 385 status_t Type::emitGlobalHwDeclarations(Formatter &) const { 386 return OK; 387 } 388 389 status_t Type::emitTypeDefinitions( 390 Formatter &, const std::string) const { 391 return OK; 392 } 393 394 status_t Type::emitJavaTypeDeclarations(Formatter &, bool) const { 395 return OK; 396 } 397 398 bool Type::needsEmbeddedReadWrite() const { 399 return false; 400 } 401 402 bool Type::needsResolveReferences() const { 403 return false; 404 } 405 406 bool Type::resultNeedsDeref() const { 407 return false; 408 } 409 410 std::string Type::getCppStackType(bool specifyNamespaces) const { 411 return getCppType(StorageMode_Stack, specifyNamespaces); 412 } 413 414 std::string Type::getCppResultType(bool specifyNamespaces) const { 415 return getCppType(StorageMode_Result, specifyNamespaces); 416 } 417 418 std::string Type::getCppArgumentType(bool specifyNamespaces) const { 419 return getCppType(StorageMode_Argument, specifyNamespaces); 420 } 421 422 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 445 status_t Type::emitVtsTypeDeclarations(Formatter &) const { 446 return OK; 447 } 448 449 status_t Type::emitVtsAttributeType(Formatter &out) const { 450 return emitVtsTypeDeclarations(out); 451 } 452 453 bool Type::isJavaCompatible() const { 454 return true; 455 } 456 457 void Type::getAlignmentAndSize( 458 size_t * /* align */, size_t * /* size */) const { 459 CHECK(!"Should not be here."); 460 } 461 462 bool Type::containsPointer() const { 463 return false; 464 } 465 466 void Type::appendToExportedTypesVector( 467 std::vector<const Type *> * /* exportedTypes */) const { 468 } 469 470 status_t Type::emitExportedHeader( 471 Formatter & /* out */, bool /* forJava */) const { 472 return OK; 473 } 474 475 //////////////////////////////////////// 476 477 TemplatedType::TemplatedType() : mElementType(nullptr) { 478 } 479 480 void TemplatedType::setElementType(Type *elementType) { 481 CHECK(mElementType == nullptr); // can only be set once. 482 CHECK(isCompatibleElementType(elementType)); 483 mElementType = elementType; 484 } 485 486 Type *TemplatedType::getElementType() const { 487 return mElementType; 488 } 489 490 bool TemplatedType::isTemplatedType() const { 491 return true; 492 } 493 494 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 507 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