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; ~ReferenceReference35 virtual ~Reference() {} 36 ReferenceReference37 Reference(const FQName& fqName, const Location& location) 38 : mResolved(nullptr), mFqName(fqName), mLocation(location) {} 39 ReferenceReference40 Reference(T* type, const Location& location) : mResolved(type), mLocation(location) { 41 CHECK(type != nullptr); 42 } 43 44 template <class OtherT> ReferenceReference45 Reference(const Reference<OtherT>& ref) 46 : mResolved(ref.mResolved), mFqName(ref.mFqName), mLocation(ref.mLocation) {} 47 48 template <class OtherT> ReferenceReference49 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 */ isResolvedReference54 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. */ getReference61 T* get() { 62 CHECK(mResolved != nullptr); 63 return mResolved->resolve(); 64 } getReference65 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. */ shallowGetReference72 T* shallowGet() { 73 CHECK(mResolved != nullptr); 74 return mResolved; 75 } shallowGetReference76 const T* shallowGet() const { 77 CHECK(mResolved != nullptr); 78 return mResolved; 79 } 80 setReference81 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 */ isEmptyReferenceReference89 bool isEmptyReference() const { return !isResolved() && !hasLookupFqName(); } 90 getLookupFqNameReference91 const FQName& getLookupFqName() const { 92 CHECK(hasLookupFqName()); 93 return mFqName; 94 } 95 hasLocationReference96 bool hasLocation() const { return mLocation.isValid(); } 97 locationReference98 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 hasLookupFqNameReference112 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 != FQName(); 117 } 118 119 template <class OtherT> 120 friend struct Reference; 121 }; 122 123 template <class T> 124 struct NamedReference : public Reference<T>, DocCommentable { NamedReferenceNamedReference125 NamedReference(const std::string& name, const Reference<T>& reference, const Location& location) 126 : Reference<T>(reference, location), mName(name) {} 127 nameNamedReference128 const std::string& name() const { return mName; } 129 130 // TODO(b/64715470) Legacy typeNamedReference131 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