Home | History | Annotate | Download | only in hidl
      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