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 "Scope.h"
     18 
     19 #include "Interface.h"
     20 
     21 #include <android-base/logging.h>
     22 #include <hidl-util/Formatter.h>
     23 #include <vector>
     24 
     25 namespace android {
     26 
     27 Scope::Scope(const char *localName,
     28         const Location &location)
     29     : NamedType(localName, location) {
     30 }
     31 Scope::~Scope(){}
     32 
     33 bool Scope::addType(NamedType *type, std::string *errorMsg) {
     34     const std::string &localName = type->localName();
     35 
     36     auto it = mTypeIndexByName.find(localName);
     37 
     38     if (it != mTypeIndexByName.end()) {
     39         *errorMsg = "A type named '";
     40         (*errorMsg) += localName;
     41         (*errorMsg) += "' is already declared in the  current scope.";
     42 
     43         return false;
     44     }
     45 
     46     size_t index = mTypes.size();
     47     mTypes.push_back(type);
     48     mTypeIndexByName[localName] = index;
     49 
     50     return true;
     51 }
     52 
     53 NamedType *Scope::lookupType(const FQName &fqName) const {
     54     CHECK(fqName.package().empty() && fqName.version().empty());
     55     if (!fqName.valueName().empty()) {
     56         LOG(WARNING) << fqName.string() << " does not refer to a type.";
     57         return nullptr;
     58     }
     59     std::vector<std::string> names = fqName.names();
     60     CHECK_GT(names.size(), 0u);
     61     auto it = mTypeIndexByName.find(names[0]);
     62 
     63     if (it == mTypeIndexByName.end()) {
     64         return nullptr;
     65     }
     66 
     67     NamedType *outerType = mTypes[it->second];
     68     if (names.size() == 1) {
     69         return outerType;
     70     }
     71     if (!outerType->isScope()) {
     72         // more than one names, but the first name is not a scope
     73         return nullptr;
     74     }
     75     Scope *outerScope = static_cast<Scope *>(outerType);
     76     // *slowly* pop first element
     77     names.erase(names.begin());
     78     FQName innerName(names);
     79     return outerScope->lookupType(innerName);
     80 }
     81 
     82 LocalIdentifier *Scope::lookupIdentifier(const std::string & /*name*/) const {
     83     return NULL;
     84 }
     85 
     86 bool Scope::isScope() const {
     87     return true;
     88 }
     89 
     90 Interface *Scope::getInterface() const {
     91     if (mTypes.size() == 1 && mTypes[0]->isInterface()) {
     92         return static_cast<Interface *>(mTypes[0]);
     93     }
     94 
     95     return NULL;
     96 }
     97 
     98 bool Scope::containsSingleInterface(std::string *ifaceName) const {
     99     Interface *iface = getInterface();
    100 
    101     if (iface != NULL) {
    102         *ifaceName = iface->localName();
    103         return true;
    104     }
    105 
    106     return false;
    107 }
    108 
    109 bool Scope::containsInterfaces() const {
    110     for (const NamedType *type : mTypes) {
    111         if (type->isInterface()) {
    112             return true;
    113         }
    114     }
    115 
    116     return false;
    117 }
    118 
    119 status_t Scope::forEachType(std::function<status_t(Type *)> func) const {
    120     for (size_t i = 0; i < mTypes.size(); ++i) {
    121         status_t err = func(mTypes[i]);
    122 
    123         if (err != OK) {
    124             return err;
    125         }
    126     }
    127 
    128     return OK;
    129 }
    130 
    131 status_t Scope::emitTypeDeclarations(Formatter &out) const {
    132     return forEachType([&](Type *type) {
    133         return type->emitTypeDeclarations(out);
    134     });
    135 }
    136 
    137 status_t Scope::emitGlobalTypeDeclarations(Formatter &out) const {
    138     return forEachType([&](Type *type) {
    139         return type->emitGlobalTypeDeclarations(out);
    140     });
    141 }
    142 
    143 status_t Scope::emitGlobalHwDeclarations(Formatter &out) const {
    144     return forEachType([&](Type *type) {
    145         return type->emitGlobalHwDeclarations(out);
    146     });
    147 }
    148 
    149 status_t Scope::emitJavaTypeDeclarations(
    150         Formatter &out, bool atTopLevel) const {
    151     return forEachType([&](Type *type) {
    152         return type->emitJavaTypeDeclarations(out, atTopLevel);
    153     });
    154 }
    155 
    156 status_t Scope::emitTypeDefinitions(
    157         Formatter &out, const std::string prefix) const {
    158     return forEachType([&](Type *type) {
    159         return type->emitTypeDefinitions(out, prefix);
    160     });
    161 }
    162 
    163 const std::vector<NamedType *> &Scope::getSubTypes() const {
    164     return mTypes;
    165 }
    166 
    167 status_t Scope::emitVtsTypeDeclarations(Formatter &out) const {
    168     return forEachType([&](Type *type) {
    169         return type->emitVtsTypeDeclarations(out);
    170     });
    171 }
    172 
    173 bool Scope::isJavaCompatible() const {
    174     for (const auto &type : mTypes) {
    175         if (!type->isJavaCompatible()) {
    176             return false;
    177         }
    178     }
    179 
    180     return true;
    181 }
    182 
    183 bool Scope::containsPointer() const {
    184     for (const auto &type : mTypes) {
    185         if (type->containsPointer()) {
    186             return true;
    187         }
    188     }
    189 
    190     return false;
    191 }
    192 
    193 void Scope::appendToExportedTypesVector(
    194         std::vector<const Type *> *exportedTypes) const {
    195     forEachType([&](Type *type) {
    196         type->appendToExportedTypesVector(exportedTypes);
    197         return OK;
    198     });
    199 }
    200 
    201 LocalIdentifier::LocalIdentifier(){}
    202 LocalIdentifier::~LocalIdentifier(){}
    203 
    204 bool LocalIdentifier::isEnumValue() const {
    205     return false;
    206 }
    207 
    208 }  // namespace android
    209 
    210