Home | History | Annotate | Download | only in hidl
      1 /*
      2  * Copyright (C) 2017 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 #ifndef REFERENCE_H_
     18 
     19 #define REFERENCE_H_
     20 
     21 #include <android-base/logging.h>
     22 #include <hidl-util/FQName.h>
     23 
     24 #include "DocComment.h"
     25 #include "Location.h"
     26 
     27 namespace android {
     28 
     29 /**
     30  * Reference placeholder
     31  */
     32 template <class T>
     33 struct Reference {
     34     Reference() = default;
     35     virtual ~Reference() {}
     36 
     37     Reference(const FQName& fqName, const Location& location)
     38         : mResolved(nullptr), mFqName(fqName), mLocation(location) {}
     39 
     40     Reference(T* type, const Location& location) : mResolved(type), mLocation(location) {
     41         CHECK(type != nullptr);
     42     }
     43 
     44     template <class OtherT>
     45     Reference(const Reference<OtherT>& ref)
     46         : mResolved(ref.mResolved), mFqName(ref.mFqName), mLocation(ref.mLocation) {}
     47 
     48     template <class OtherT>
     49     Reference(const Reference<OtherT>& ref, const Location& location)
     50         : mResolved(ref.mResolved), mFqName(ref.mFqName), mLocation(location) {}
     51 
     52     /* Returns true iff referred type is resolved
     53        Referred type's field might be not resolved */
     54     bool isResolved() const { return mResolved != nullptr; }
     55 
     56     T* operator->() { return get(); }
     57     const T* operator->() const { return get(); }
     58 
     59     /* Returns referenced object.
     60        If a type is referenced, all typedefs are unwrapped. */
     61     T* get() {
     62         CHECK(mResolved != nullptr);
     63         return mResolved->resolve();
     64     }
     65     const T* get() const {
     66         CHECK(mResolved != nullptr);
     67         return mResolved->resolve();
     68     }
     69 
     70     /* Returns exact referenced object.
     71        If a type is referenced, typedefs are not unwraped. */
     72     T* shallowGet() {
     73         CHECK(mResolved != nullptr);
     74         return mResolved;
     75     }
     76     const T* shallowGet() const {
     77         CHECK(mResolved != nullptr);
     78         return mResolved;
     79     }
     80 
     81     void set(T* resolved) {
     82         CHECK(!isResolved());
     83         CHECK(resolved != nullptr);
     84         mResolved = resolved;
     85     }
     86 
     87     /* Returns true iff this is reference to null:
     88        not resolved and has not name for lookup */
     89     bool isEmptyReference() const { return !isResolved() && !hasLookupFqName(); }
     90 
     91     const FQName& getLookupFqName() const {
     92         CHECK(hasLookupFqName());
     93         return mFqName;
     94     }
     95 
     96     bool hasLocation() const { return mLocation.isValid(); }
     97 
     98     const Location& location() const {
     99         CHECK(hasLocation());
    100         return mLocation;
    101     }
    102 
    103    private:
    104     /* Referred type */
    105     T* mResolved = nullptr;
    106     /* Reference name for lookup */
    107     FQName mFqName;
    108     /* Reference location is mainly used for printing errors
    109        and handling forward reference restrictions */
    110     Location mLocation;
    111 
    112     bool hasLookupFqName() const {
    113         // Valid only while not resolved to prevent confusion when
    114         // ref.hasLookupFqName() is false while ref,get()->fqName is valid.
    115         CHECK(!isResolved());
    116         return mFqName.isValid();
    117     }
    118 
    119     template <class OtherT>
    120     friend struct Reference;
    121 };
    122 
    123 template <class T>
    124 struct NamedReference : public Reference<T>, DocCommentable {
    125     NamedReference(const std::string& name, const Reference<T>& reference, const Location& location)
    126         : Reference<T>(reference, location), mName(name) {}
    127 
    128     const std::string& name() const { return mName; }
    129 
    130     // TODO(b/64715470) Legacy
    131     const T& type() const { return *Reference<T>::get(); }
    132 
    133    private:
    134     const std::string mName;
    135 };
    136 
    137 }  // namespace android
    138 
    139 #endif  // REFERENCE_H_
    140