blob: 83edb6129d9dfabae8f3f4b20894baeeecf09c43 [file] [log] [blame]
Timur Iskhakov505316c2017-08-05 03:38:59 +00001/*
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
Neel Mehta3b414a82019-07-02 15:47:48 -070024#include <string>
25
Steven Moreland49bad8d2018-05-17 15:45:26 -070026#include "DocComment.h"
Timur Iskhakov505316c2017-08-05 03:38:59 +000027#include "Location.h"
28
29namespace android {
30
31/**
32 * Reference placeholder
33 */
34template <class T>
35struct Reference {
36 Reference() = default;
Timur Iskhakov774ae7f2017-08-13 22:57:55 -070037 virtual ~Reference() {}
Timur Iskhakov505316c2017-08-05 03:38:59 +000038
Neel Mehta6de3cf82019-08-06 16:49:33 -070039 Reference(const std::string& localName, const FQName& fqName, const Location& location,
40 bool definedInline = false)
41 : mResolved(nullptr),
42 mFqName(fqName),
43 mLocation(location),
44 mDefinedInline(definedInline),
45 mLocalName(localName) {}
Timur Iskhakov505316c2017-08-05 03:38:59 +000046
Neel Mehta6de3cf82019-08-06 16:49:33 -070047 Reference(const std::string& localName, T* type, const Location& location,
48 bool definedInline = false)
49 : mResolved(type),
50 mLocation(location),
51 mDefinedInline(definedInline),
52 mLocalName(localName) {
Timur Iskhakov505316c2017-08-05 03:38:59 +000053 CHECK(type != nullptr);
54 }
55
Timur Iskhakov33431e62017-08-21 17:31:23 -070056 template <class OtherT>
57 Reference(const Reference<OtherT>& ref)
Neel Mehta3b414a82019-07-02 15:47:48 -070058 : mResolved(ref.mResolved),
59 mFqName(ref.mFqName),
60 mLocation(ref.mLocation),
Neel Mehta6de3cf82019-08-06 16:49:33 -070061 mDefinedInline(ref.mDefinedInline),
Neel Mehta3b414a82019-07-02 15:47:48 -070062 mLocalName(ref.mLocalName) {}
Timur Iskhakov505316c2017-08-05 03:38:59 +000063
Timur Iskhakova48a4d92017-09-09 20:34:53 -070064 template <class OtherT>
65 Reference(const Reference<OtherT>& ref, const Location& location)
Neel Mehta3b414a82019-07-02 15:47:48 -070066 : mResolved(ref.mResolved),
67 mFqName(ref.mFqName),
68 mLocation(location),
Neel Mehta6de3cf82019-08-06 16:49:33 -070069 mDefinedInline(ref.mDefinedInline),
Neel Mehta3b414a82019-07-02 15:47:48 -070070 mLocalName(ref.mLocalName) {}
Timur Iskhakova48a4d92017-09-09 20:34:53 -070071
Timur Iskhakov505316c2017-08-05 03:38:59 +000072 /* Returns true iff referred type is resolved
73 Referred type's field might be not resolved */
74 bool isResolved() const { return mResolved != nullptr; }
75
Timur Iskhakov24e605b2017-08-30 14:02:55 -070076 T* operator->() { return get(); }
77 const T* operator->() const { return get(); }
Timur Iskhakov505316c2017-08-05 03:38:59 +000078
Timur Iskhakovdbaed332017-08-31 16:33:41 -070079 /* Returns referenced object.
Andreas Huber4ba5c972017-11-29 11:06:25 -080080 If a type is referenced, all typedefs are unwrapped. */
Timur Iskhakov24e605b2017-08-30 14:02:55 -070081 T* get() {
82 CHECK(mResolved != nullptr);
Timur Iskhakovdbaed332017-08-31 16:33:41 -070083 return mResolved->resolve();
84 }
85 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. */
92 T* shallowGet() {
93 CHECK(mResolved != nullptr);
Timur Iskhakov24e605b2017-08-30 14:02:55 -070094 return mResolved;
95 }
Timur Iskhakovdbaed332017-08-31 16:33:41 -070096 const T* shallowGet() const {
Timur Iskhakov505316c2017-08-05 03:38:59 +000097 CHECK(mResolved != nullptr);
98 return mResolved;
99 }
100
Timur Iskhakov505316c2017-08-05 03:38:59 +0000101 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 */
109 bool isEmptyReference() const { return !isResolved() && !hasLookupFqName(); }
110
111 const FQName& getLookupFqName() const {
112 CHECK(hasLookupFqName());
113 return mFqName;
114 }
115
116 bool hasLocation() const { return mLocation.isValid(); }
117
Timur Iskhakovcec46c42017-08-09 00:22:02 -0700118 const Location& location() const {
Timur Iskhakov505316c2017-08-05 03:38:59 +0000119 CHECK(hasLocation());
120 return mLocation;
121 }
122
Neel Mehta6de3cf82019-08-06 16:49:33 -0700123 bool definedInline() const { return mDefinedInline; }
124
Neel Mehta3b414a82019-07-02 15:47:48 -0700125 const std::string& localName() const { return mLocalName; }
126
127 private:
Timur Iskhakov505316c2017-08-05 03:38:59 +0000128 /* Referred type */
129 T* mResolved = nullptr;
130 /* Reference name for lookup */
131 FQName mFqName;
Timur Iskhakova48a4d92017-09-09 20:34:53 -0700132 /* Reference location is mainly used for printing errors
133 and handling forward reference restrictions */
Timur Iskhakov505316c2017-08-05 03:38:59 +0000134 Location mLocation;
Neel Mehta6de3cf82019-08-06 16:49:33 -0700135 /* definedInline is true if T is defined where it is referenced */
136 bool mDefinedInline;
Timur Iskhakov505316c2017-08-05 03:38:59 +0000137
Neel Mehta3b414a82019-07-02 15:47:48 -0700138 /* Name used in the .hal file */
139 std::string mLocalName;
140
Timur Iskhakov505316c2017-08-05 03:38:59 +0000141 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());
Steven Moreland77730892018-03-06 14:39:41 -0800145 return mFqName != FQName();
Timur Iskhakov505316c2017-08-05 03:38:59 +0000146 }
147
148 template <class OtherT>
149 friend struct Reference;
150};
151
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700152template <class T>
Steven Moreland49bad8d2018-05-17 15:45:26 -0700153struct NamedReference : public Reference<T>, DocCommentable {
Timur Iskhakova48a4d92017-09-09 20:34:53 -0700154 NamedReference(const std::string& name, const Reference<T>& reference, const Location& location)
155 : Reference<T>(reference, location), mName(name) {}
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700156
157 const std::string& name() const { return mName; }
Timur Iskhakov774ae7f2017-08-13 22:57:55 -0700158
159 // TODO(b/64715470) Legacy
160 const T& type() const { return *Reference<T>::get(); }
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700161
Neel Mehta6de3cf82019-08-06 16:49:33 -0700162 private:
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700163 const std::string mName;
Timur Iskhakov7fa79f62017-08-09 11:04:54 -0700164};
165
Timur Iskhakov505316c2017-08-05 03:38:59 +0000166} // namespace android
167
168#endif // REFERENCE_H_