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