blob: 254a5a41c2e30a178fc9af4ab9f9400a40df7b36 [file] [log] [blame]
Andreas Huber1aec3972016-08-26 09:26:32 -07001/*
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
Andreas Huber84f89de2016-07-28 15:39:51 -070017#include "FQName.h"
18
Iliyan Malcheva72e0d22016-09-09 11:03:08 -070019#include <hidl-util/StringHelper.h>
Andreas Huber84f89de2016-07-28 15:39:51 -070020#include <android-base/logging.h>
Iliyan Malchev800273d2016-09-02 15:25:07 -070021#include <iostream>
Andreas Huber84f89de2016-07-28 15:39:51 -070022#include <regex>
Iliyan Malchev800273d2016-09-02 15:25:07 -070023#include <sstream>
Andreas Huber84f89de2016-07-28 15:39:51 -070024
25#define RE_COMPONENT "[a-zA-Z_][a-zA-Z_0-9]*"
Yifan Hong95a47bb2016-09-29 10:08:10 -070026#define RE_PATH RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
Yifan Hong90ea87f2016-11-01 14:25:47 -070027#define RE_MAJOR "[0-9]+"
28#define RE_MINOR "[0-9]+"
Andreas Huber84f89de2016-07-28 15:39:51 -070029
Yifan Hong333a6d22017-01-12 12:28:02 -080030// android.hardware.foo@1.0::IFoo.Type
31static const std::regex kRE1("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
32// @1.0::IFoo.Type
Yifan Hong90ea87f2016-11-01 14:25:47 -070033static const std::regex kRE2("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080034// android.hardware.foo@1.0 (for package declaration and whole package import)
Yifan Hong90ea87f2016-11-01 14:25:47 -070035static const std::regex kRE3("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080036// IFoo.Type
Yifan Hongb44a6c82016-09-22 15:50:18 -070037static const std::regex kRE4("(" RE_COMPONENT ")([.]" RE_COMPONENT ")+");
Yifan Hong333a6d22017-01-12 12:28:02 -080038// Type (a plain identifier)
Yifan Hongb44a6c82016-09-22 15:50:18 -070039static const std::regex kRE5("(" RE_COMPONENT ")");
40
Yifan Hong333a6d22017-01-12 12:28:02 -080041// android.hardware.foo@1.0::IFoo.Type:MY_ENUM_VALUE
42static const std::regex kRE6("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
43// @1.0::IFoo.Type:MY_ENUM_VALUE
Yifan Hong90ea87f2016-11-01 14:25:47 -070044static const std::regex kRE7("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
Yifan Hong333a6d22017-01-12 12:28:02 -080045// IFoo.Type:MY_ENUM_VALUE
Yifan Hongb44a6c82016-09-22 15:50:18 -070046static const std::regex kRE8("(" RE_PATH "):(" RE_COMPONENT ")");
Andreas Huber84f89de2016-07-28 15:39:51 -070047
Yifan Hong333a6d22017-01-12 12:28:02 -080048// 1.0
Yifan Hong90ea87f2016-11-01 14:25:47 -070049static const std::regex kREVer("(" RE_MAJOR ")[.](" RE_MINOR ")");
50
Andreas Huber84f89de2016-07-28 15:39:51 -070051namespace android {
52
Andreas Huberda51b8e2016-07-28 16:00:57 -070053FQName::FQName()
Yifan Hong327cfe12016-10-03 10:29:42 -070054 : mValid(false),
55 mIsIdentifier(false) {
Andreas Huberda51b8e2016-07-28 16:00:57 -070056}
57
Andreas Huber84f89de2016-07-28 15:39:51 -070058FQName::FQName(const std::string &s)
Yifan Hong327cfe12016-10-03 10:29:42 -070059 : mValid(false),
60 mIsIdentifier(false) {
Andreas Huber84f89de2016-07-28 15:39:51 -070061 setTo(s);
62}
63
Andreas Huber68f24592016-07-29 14:53:48 -070064FQName::FQName(
65 const std::string &package,
66 const std::string &version,
Yifan Hongb44a6c82016-09-22 15:50:18 -070067 const std::string &name,
68 const std::string &valueName)
Andreas Huber68f24592016-07-29 14:53:48 -070069 : mValid(true),
Yifan Hongb44a6c82016-09-22 15:50:18 -070070 mIsIdentifier(false),
Andreas Huber68f24592016-07-29 14:53:48 -070071 mPackage(package),
Yifan Hongb44a6c82016-09-22 15:50:18 -070072 mName(name),
73 mValueName(valueName) {
Yifan Hong90ea87f2016-11-01 14:25:47 -070074 setVersion(version);
Yifan Hongfece6ec2017-01-12 17:04:04 -080075
76 // Check if this is actually a valid fqName
77 FQName other;
78 other.setTo(this->string());
79 CHECK(other.mValid && (*this) == other);
Andreas Huber68f24592016-07-29 14:53:48 -070080}
81
Yifan Hongf24fa852016-09-23 11:03:15 -070082FQName::FQName(const FQName& other)
83 : mValid(other.mValid),
84 mIsIdentifier(other.mIsIdentifier),
85 mPackage(other.mPackage),
Yifan Hong90ea87f2016-11-01 14:25:47 -070086 mMajor(other.mMajor),
87 mMinor(other.mMinor),
Yifan Hongf24fa852016-09-23 11:03:15 -070088 mName(other.mName),
89 mValueName(other.mValueName) {
90}
91
Yifan Hong327cfe12016-10-03 10:29:42 -070092FQName::FQName(const std::vector<std::string> &names)
93 : mValid(false),
94 mIsIdentifier(false) {
95 setTo(StringHelper::JoinStrings(names, "."));
96}
97
Andreas Huber84f89de2016-07-28 15:39:51 -070098bool FQName::isValid() const {
99 return mValid;
100}
101
Yifan Hongb44a6c82016-09-22 15:50:18 -0700102bool FQName::isIdentifier() const {
103 return mIsIdentifier;
104}
105
Andreas Huber68f24592016-07-29 14:53:48 -0700106bool FQName::isFullyQualified() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700107 return !mPackage.empty() && !version().empty() && !mName.empty();
Andreas Huber68f24592016-07-29 14:53:48 -0700108}
109
Yifan Hongb44a6c82016-09-22 15:50:18 -0700110bool FQName::isValidValueName() const {
111 return mIsIdentifier
112 || (!mName.empty() && !mValueName.empty());
113}
114
Andreas Huber84f89de2016-07-28 15:39:51 -0700115bool FQName::setTo(const std::string &s) {
116 mPackage.clear();
Yifan Hong90ea87f2016-11-01 14:25:47 -0700117 mMajor.clear();
118 mMinor.clear();
Andreas Huber84f89de2016-07-28 15:39:51 -0700119 mName.clear();
120
121 mValid = true;
122
123 std::smatch match;
124 if (std::regex_match(s, match, kRE1)) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700125 CHECK_EQ(match.size(), 5u);
126
127 mPackage = match.str(1);
128 mMajor = match.str(2);
129 mMinor = match.str(3);
130 mName = match.str(4);
131 } else if (std::regex_match(s, match, kRE2)) {
132 CHECK_EQ(match.size(), 4u);
133
134 mMajor = match.str(1);
135 mMinor = match.str(2);
136 mName = match.str(3);
137 } else if (std::regex_match(s, match, kRE3)) {
Yifan Hong95a47bb2016-09-29 10:08:10 -0700138 CHECK_EQ(match.size(), 4u);
Andreas Huber84f89de2016-07-28 15:39:51 -0700139
140 mPackage = match.str(1);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700141 mMajor = match.str(2);
142 mMinor = match.str(3);
Andreas Huberda51b8e2016-07-28 16:00:57 -0700143 } else if (std::regex_match(s, match, kRE4)) {
Andreas Huber84f89de2016-07-28 15:39:51 -0700144 mName = match.str(0);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700145 } else if (std::regex_match(s, match, kRE5)) {
146 mIsIdentifier = true;
147 mName = match.str(0);
148 } else if (std::regex_match(s, match, kRE6)) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700149 CHECK_EQ(match.size(), 6u);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700150
151 mPackage = match.str(1);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700152 mMajor = match.str(2);
153 mMinor = match.str(3);
154 mName = match.str(4);
155 mValueName = match.str(5);
156 } else if (std::regex_match(s, match, kRE7)) {
157 CHECK_EQ(match.size(), 5u);
158
159 mMajor = match.str(1);
160 mMinor = match.str(2);
Yifan Hong95a47bb2016-09-29 10:08:10 -0700161 mName = match.str(3);
162 mValueName = match.str(4);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700163 } else if (std::regex_match(s, match, kRE8)) {
Yifan Hong95a47bb2016-09-29 10:08:10 -0700164 CHECK_EQ(match.size(), 3u);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700165
166 mName = match.str(1);
Yifan Hong95a47bb2016-09-29 10:08:10 -0700167 mValueName = match.str(2);
Andreas Huber84f89de2016-07-28 15:39:51 -0700168 } else {
169 mValid = false;
170 }
171
Yifan Hongb44a6c82016-09-22 15:50:18 -0700172 // mValueName must go with mName.
Yifan Hong333a6d22017-01-12 12:28:02 -0800173 CHECK(mValueName.empty() || !mName.empty());
174
175 // package without version is not allowed.
176 CHECK(mPackage.empty() || !version().empty());
Yifan Hongb44a6c82016-09-22 15:50:18 -0700177
Andreas Huber84f89de2016-07-28 15:39:51 -0700178 return isValid();
179}
180
181std::string FQName::package() const {
182 return mPackage;
183}
184
185std::string FQName::version() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700186 CHECK(mMajor.empty() == mMinor.empty());
187 if (mMajor.empty() && mMinor.empty()) {
188 return "";
189 }
190 return mMajor + "." + mMinor;
191}
192
Yifan Hong97288ac2016-12-12 16:03:51 -0800193std::string FQName::sanitizedVersion() const {
194 CHECK(mMajor.empty() == mMinor.empty());
195 if (mMajor.empty() && mMinor.empty()) {
196 return "";
197 }
198 return "V" + mMajor + "_" + mMinor;
199}
200
Yifan Hong90ea87f2016-11-01 14:25:47 -0700201std::string FQName::atVersion() const {
202 std::string v = version();
203 return v.empty() ? "" : ("@" + v);
204}
205
206void FQName::setVersion(const std::string &v) {
207 if (v.empty()) {
208 mMajor.clear();
209 mMinor.clear();
210 return;
211 }
212 std::smatch match;
213 if (std::regex_match(v, match, kREVer)) {
214 CHECK_EQ(match.size(), 3u);
215
216 mMajor = match.str(1);
217 mMinor = match.str(2);
218 } else {
219 mValid = false;
220 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700221}
222
223std::string FQName::name() const {
224 return mName;
225}
226
Iliyan Malchev800273d2016-09-02 15:25:07 -0700227std::vector<std::string> FQName::names() const {
228 std::vector<std::string> res {};
229 std::istringstream ss(name());
230 std::string s;
231 while (std::getline(ss, s, '.')) {
232 res.push_back(s);
233 }
234 return res;
235}
236
Yifan Hongb44a6c82016-09-22 15:50:18 -0700237std::string FQName::valueName() const {
238 return mValueName;
239}
240
241FQName FQName::typeName() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700242 return FQName(mPackage, version(), mName);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700243}
244
Andreas Huber84f89de2016-07-28 15:39:51 -0700245void FQName::applyDefaults(
246 const std::string &defaultPackage,
247 const std::string &defaultVersion) {
Yifan Hong333a6d22017-01-12 12:28:02 -0800248
249 // package without version is not allowed.
250 CHECK(mPackage.empty() || !version().empty());
251
Andreas Huber84f89de2016-07-28 15:39:51 -0700252 if (mPackage.empty()) {
253 mPackage = defaultPackage;
254 }
255
Yifan Hong90ea87f2016-11-01 14:25:47 -0700256 if (version().empty()) {
257 setVersion(defaultVersion);
Andreas Huber84f89de2016-07-28 15:39:51 -0700258 }
259}
260
Andreas Huber68f24592016-07-29 14:53:48 -0700261std::string FQName::string() const {
Andreas Huber84f89de2016-07-28 15:39:51 -0700262 CHECK(mValid);
263
Andreas Huber5345ec22016-07-29 13:33:27 -0700264 std::string out;
Andreas Huber84f89de2016-07-28 15:39:51 -0700265 out.append(mPackage);
Yifan Hong90ea87f2016-11-01 14:25:47 -0700266 out.append(atVersion());
Andreas Huberda51b8e2016-07-28 16:00:57 -0700267 if (!mName.empty()) {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700268 if (!mPackage.empty() || !version().empty()) {
Andreas Huberda51b8e2016-07-28 16:00:57 -0700269 out.append("::");
270 }
271 out.append(mName);
Yifan Hongb44a6c82016-09-22 15:50:18 -0700272
273 if (!mValueName.empty()) {
274 out.append(":");
275 out.append(mValueName);
276 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700277 }
Andreas Huber84f89de2016-07-28 15:39:51 -0700278
279 return out;
280}
281
Andreas Huberda51b8e2016-07-28 16:00:57 -0700282void FQName::print() const {
283 if (!mValid) {
284 LOG(INFO) << "INVALID";
285 return;
286 }
287
Andreas Huber68f24592016-07-29 14:53:48 -0700288 LOG(INFO) << string();
289}
290
291bool FQName::operator<(const FQName &other) const {
292 return string() < other.string();
Andreas Huberda51b8e2016-07-28 16:00:57 -0700293}
294
Andreas Huberd2943e12016-08-05 11:59:31 -0700295bool FQName::operator==(const FQName &other) const {
296 return string() == other.string();
297}
298
Yifan Hongc8934042016-11-17 17:10:52 -0800299bool FQName::operator!=(const FQName &other) const {
300 return !(*this == other);
301}
302
Yifan Hongeefe4f22017-01-04 15:32:42 -0800303std::string FQName::getInterfaceName() const {
Steven Moreland197d56c2016-09-09 10:03:58 -0700304 CHECK(names().size() == 1) << "Must be a top level type";
305 CHECK(!mName.empty() && mName[0] == 'I') << mName;
306
Yifan Hongeefe4f22017-01-04 15:32:42 -0800307 return mName;
308}
309
310std::string FQName::getInterfaceBaseName() const {
Steven Moreland197d56c2016-09-09 10:03:58 -0700311 // cut off the leading 'I'.
Yifan Hongeefe4f22017-01-04 15:32:42 -0800312 return getInterfaceName().substr(1);
313}
314
315std::string FQName::getInterfaceHwName() const {
316 return "IHw" + getInterfaceBaseName();
317}
318
319std::string FQName::getInterfaceProxyName() const {
Yifan Hong01e7cde2017-01-09 17:45:45 -0800320 return "BpHw" + getInterfaceBaseName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800321}
322
323std::string FQName::getInterfaceStubName() const {
Yifan Hong01e7cde2017-01-09 17:45:45 -0800324 return "BnHw" + getInterfaceBaseName();
Yifan Hongeefe4f22017-01-04 15:32:42 -0800325}
326
327std::string FQName::getInterfacePassthroughName() const {
328 return "Bs" + getInterfaceBaseName();
329}
330
331FQName FQName::getInterfaceProxyFqName() const {
332 return FQName(package(), version(), getInterfaceProxyName());
333}
334
335FQName FQName::getInterfaceStubFqName() const {
336 return FQName(package(), version(), getInterfaceStubName());
337}
338
339FQName FQName::getInterfacePassthroughFqName() const {
340 return FQName(package(), version(), getInterfacePassthroughName());
Steven Moreland197d56c2016-09-09 10:03:58 -0700341}
342
Yifan Hong1977ea32016-10-05 12:49:08 -0700343FQName FQName::getTypesForPackage() const {
344 return FQName(package(), version(), "types");
345}
346
Yifan Hongfece6ec2017-01-12 17:04:04 -0800347FQName FQName::getPackageAndVersion() const {
348 return FQName(package(), version(), "");
349}
350
351FQName FQName::getTopLevelType() const {
Steven Moreland9c387612016-09-07 09:54:26 -0700352 auto idx = mName.find('.');
353
354 if (idx == std::string::npos) {
355 return *this;
356 }
357
Yifan Hong90ea87f2016-11-01 14:25:47 -0700358 return FQName(mPackage, version(), mName.substr(0, idx));
Steven Moreland9c387612016-09-07 09:54:26 -0700359}
360
361std::string FQName::tokenName() const {
362 std::vector<std::string> components;
363 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
364
Steven Moreland6f596c82016-11-29 18:45:24 -0800365 if (!mName.empty()) {
366 std::vector<std::string> nameComponents;
367 StringHelper::SplitString(mName, '.', &nameComponents);
Steven Moreland9c387612016-09-07 09:54:26 -0700368
Steven Moreland6f596c82016-11-29 18:45:24 -0800369 components.insert(components.end(), nameComponents.begin(), nameComponents.end());
370 }
Steven Moreland9c387612016-09-07 09:54:26 -0700371
Steven Morelandaf440142016-09-07 10:09:11 -0700372 return StringHelper::JoinStrings(components, "_");
Steven Moreland9c387612016-09-07 09:54:26 -0700373}
374
Andreas Huber0e00de42016-08-03 09:56:02 -0700375std::string FQName::cppNamespace() const {
376 std::vector<std::string> components;
377 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
378
379 std::string out = "::";
Steven Morelandaf440142016-09-07 10:09:11 -0700380 out += StringHelper::JoinStrings(components, "::");
Andreas Huber0e00de42016-08-03 09:56:02 -0700381
382 return out;
383}
384
Steven Moreland979e0992016-09-07 09:18:08 -0700385std::string FQName::cppLocalName() const {
386 std::vector<std::string> components;
Steven Morelandaf440142016-09-07 10:09:11 -0700387 StringHelper::SplitString(mName, '.', &components);
Steven Moreland979e0992016-09-07 09:18:08 -0700388
Yifan Hongb44a6c82016-09-22 15:50:18 -0700389 return StringHelper::JoinStrings(components, "::")
390 + (mValueName.empty() ? "" : ("::" + mValueName));
Steven Moreland979e0992016-09-07 09:18:08 -0700391}
392
Andreas Huber0e00de42016-08-03 09:56:02 -0700393std::string FQName::cppName() const {
394 std::string out = cppNamespace();
395
396 std::vector<std::string> components;
Steven Morelandaf440142016-09-07 10:09:11 -0700397 StringHelper::SplitString(name(), '.', &components);
Andreas Huber0e00de42016-08-03 09:56:02 -0700398 out += "::";
Steven Morelandaf440142016-09-07 10:09:11 -0700399 out += StringHelper::JoinStrings(components, "::");
Yifan Hongb44a6c82016-09-22 15:50:18 -0700400 if (!mValueName.empty()) {
401 out += "::" + mValueName;
402 }
Andreas Huber0e00de42016-08-03 09:56:02 -0700403
404 return out;
405}
406
Andreas Huber2831d512016-08-15 09:33:47 -0700407std::string FQName::javaPackage() const {
408 std::vector<std::string> components;
409 getPackageAndVersionComponents(&components, true /* cpp_compatible */);
410
Steven Morelandaf440142016-09-07 10:09:11 -0700411 return StringHelper::JoinStrings(components, ".");
Andreas Huber2831d512016-08-15 09:33:47 -0700412}
413
414std::string FQName::javaName() const {
Yifan Hongb44a6c82016-09-22 15:50:18 -0700415 return javaPackage() + "." + name()
416 + (mValueName.empty() ? "" : ("." + mValueName));
Andreas Huber2831d512016-08-15 09:33:47 -0700417}
418
Andreas Huber0e00de42016-08-03 09:56:02 -0700419void FQName::getPackageComponents(std::vector<std::string> *components) const {
Steven Morelandaf440142016-09-07 10:09:11 -0700420 StringHelper::SplitString(package(), '.', components);
Andreas Huber0e00de42016-08-03 09:56:02 -0700421}
422
423void FQName::getPackageAndVersionComponents(
424 std::vector<std::string> *components,
425 bool cpp_compatible) const {
426 getPackageComponents(components);
427
Andreas Huber0e00de42016-08-03 09:56:02 -0700428 if (!cpp_compatible) {
Martijn Coenena21f1492016-09-08 15:55:14 +0200429 components->push_back(getPackageMajorVersion() +
430 "." + getPackageMinorVersion());
Andreas Huber0e00de42016-08-03 09:56:02 -0700431 return;
432 }
433
Yifan Hong97288ac2016-12-12 16:03:51 -0800434 components->push_back(sanitizedVersion());
Andreas Huber0e00de42016-08-03 09:56:02 -0700435}
436
Martijn Coenena21f1492016-09-08 15:55:14 +0200437std::string FQName::getPackageMajorVersion() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700438 return mMajor;
Martijn Coenena21f1492016-09-08 15:55:14 +0200439}
440
441std::string FQName::getPackageMinorVersion() const {
Yifan Hong90ea87f2016-11-01 14:25:47 -0700442 return mMinor;
Zhuoyao Zhang8f492942016-09-28 14:27:56 -0700443}
444
Andreas Huber39fa7182016-08-19 14:27:33 -0700445bool FQName::endsWith(const FQName &other) const {
446 std::string s1 = string();
447 std::string s2 = other.string();
448
449 size_t pos = s1.rfind(s2);
450 if (pos == std::string::npos || pos + s2.size() != s1.size()) {
451 return false;
452 }
453
Yifan Hongd9f22f72016-10-05 15:17:33 -0700454 // A match is only a match if it is preceded by a "boundary", i.e.
455 // we perform a component-wise match from the end.
456 // "az" is not a match for "android.hardware.foo@1.0::IFoo.bar.baz",
457 // "baz", "bar.baz", "IFoo.bar.baz", "@1.0::IFoo.bar.baz" are.
458 if (pos == 0) {
459 // matches "android.hardware.foo@1.0::IFoo.bar.baz"
460 return true;
Andreas Huber39fa7182016-08-19 14:27:33 -0700461 }
462
Yifan Hongd9f22f72016-10-05 15:17:33 -0700463 if (s1[pos - 1] == '.') {
464 // matches "baz" and "bar.baz"
465 return true;
466 }
467
468 if (s1[pos - 1] == ':') {
469 // matches "IFoo.bar.baz"
470 return true;
471 }
472
473 if (s1[pos] == '@') {
474 // matches "@1.0::IFoo.bar.baz"
475 return true;
476 }
477
478 return false;
Andreas Huber39fa7182016-08-19 14:27:33 -0700479}
480
Andreas Huber84f89de2016-07-28 15:39:51 -0700481} // namespace android
482