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 <string> 25 26 #include "DocComment.h" 27 #include "Location.h" 28 29 namespace android { 30 31 /** 32 * Reference placeholder 33 */ 34 template <class T> 35 struct Reference { 36 Reference() = default; ~ReferenceReference37 virtual ~Reference() {} 38 39 Reference(const std::string& localName, const FQName& fqName, const Location& location, 40 bool definedInline = false) mResolvedReference41 : mResolved(nullptr), 42 mFqName(fqName), 43 mLocation(location), 44 mDefinedInline(definedInline), 45 mLocalName(localName) {} 46 47 Reference(const std::string& localName, T* type, const Location& location, 48 bool definedInline = false) mResolvedReference49 : mResolved(type), 50 mLocation(location), 51 mDefinedInline(definedInline), 52 mLocalName(localName) { 53 CHECK(type != nullptr); 54 } 55 56 template <class OtherT> ReferenceReference57 Reference(const Reference<OtherT>& ref) 58 : mResolved(ref.mResolved), 59 mFqName(ref.mFqName), 60 mLocation(ref.mLocation), 61 mDefinedInline(ref.mDefinedInline), 62 mLocalName(ref.mLocalName) {} 63 64 template <class OtherT> ReferenceReference65 Reference(const Reference<OtherT>& ref, const Location& location) 66 : mResolved(ref.mResolved), 67 mFqName(ref.mFqName), 68 mLocation(location), 69 mDefinedInline(ref.mDefinedInline), 70 mLocalName(ref.mLocalName) {} 71 72 /* Returns true iff referred type is resolved 73 Referred type's field might be not resolved */ isResolvedReference74 bool isResolved() const { return mResolved != nullptr; } 75 76 T* operator->() { return get(); } 77 const T* operator->() const { return get(); } 78 79 /* Returns referenced object. 80 If a type is referenced, all typedefs are unwrapped. */ getReference81 T* get() { 82 CHECK(mResolved != nullptr); 83 return mResolved->resolve(); 84 } getReference85 const T* get() const { 86 CHECK(mResolved != nullptr); 87 return mResolved->resolve(); 88 } 89 90 /* Returns exact referenced object. 91 If a type is referenced, typedefs are not unwraped. */ shallowGetReference92 T* shallowGet() { 93 CHECK(mResolved != nullptr); 94 return mResolved; 95 } shallowGetReference96 const T* shallowGet() const { 97 CHECK(mResolved != nullptr); 98 return mResolved; 99 } 100 setReference101 void set(T* resolved) { 102 CHECK(!isResolved()); 103 CHECK(resolved != nullptr); 104 mResolved = resolved; 105 } 106 107 /* Returns true iff this is reference to null: 108 not resolved and has not name for lookup */ isEmptyReferenceReference109 bool isEmptyReference() const { return !isResolved() && !hasLookupFqName(); } 110 getLookupFqNameReference111 const FQName& getLookupFqName() const { 112 CHECK(hasLookupFqName()); 113 return mFqName; 114 } 115 hasLocationReference116 bool hasLocation() const { return mLocation.isValid(); } 117 locationReference118 const Location& location() const { 119 CHECK(hasLocation()); 120 return mLocation; 121 } 122 definedInlineReference123 bool definedInline() const { return mDefinedInline; } 124 localNameReference125 const std::string& localName() const { return mLocalName; } 126 127 private: 128 /* Referred type */ 129 T* mResolved = nullptr; 130 /* Reference name for lookup */ 131 FQName mFqName; 132 /* Reference location is mainly used for printing errors 133 and handling forward reference restrictions */ 134 Location mLocation; 135 /* definedInline is true if T is defined where it is referenced */ 136 bool mDefinedInline; 137 138 /* Name used in the .hal file */ 139 std::string mLocalName; 140 hasLookupFqNameReference141 bool hasLookupFqName() const { 142 // Valid only while not resolved to prevent confusion when 143 // ref.hasLookupFqName() is false while ref,get()->fqName is valid. 144 CHECK(!isResolved()); 145 return mFqName != FQName(); 146 } 147 148 template <class OtherT> 149 friend struct Reference; 150 }; 151 152 template <class T> 153 struct NamedReference : public Reference<T>, DocCommentable { NamedReferenceNamedReference154 NamedReference(const std::string& name, const Reference<T>& reference, const Location& location) 155 : Reference<T>(reference, location), mName(name) {} 156 nameNamedReference157 const std::string& name() const { return mName; } 158 159 // TODO(b/64715470) Legacy typeNamedReference160 const T& type() const { return *Reference<T>::get(); } 161 162 private: 163 const std::string mName; 164 }; 165 166 } // namespace android 167 168 #endif // REFERENCE_H_ 169