11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/*
21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project
31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License.
61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at
71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software
111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and
141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License.
151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */
161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber
1784f89de8395a78577f80db0f860b61a9f2409294Andreas Huber#include "FQName.h"
1884f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
197ae3d54cb65f1309cb643b83a2040225ad5f3128Steven Moreland#include "StringHelper.h"
207ae3d54cb65f1309cb643b83a2040225ad5f3128Steven Moreland
2184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber#include <android-base/logging.h>
223b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong#include <android-base/parseint.h>
23800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev#include <iostream>
2484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber#include <regex>
25800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev#include <sstream>
2684f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
2784f89de8395a78577f80db0f860b61a9f2409294Andreas Huber#define RE_COMPONENT    "[a-zA-Z_][a-zA-Z_0-9]*"
2895a47bb42784bf74b8385b962cbe464dec037774Yifan Hong#define RE_PATH         RE_COMPONENT "(?:[.]" RE_COMPONENT ")*"
2990ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong#define RE_MAJOR        "[0-9]+"
3090ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong#define RE_MINOR        "[0-9]+"
3184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
32333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// android.hardware.foo@1.0::IFoo.Type
33333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hongstatic const std::regex kRE1("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
34333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// @1.0::IFoo.Type
3590ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hongstatic const std::regex kRE2("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH ")");
36333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// android.hardware.foo@1.0 (for package declaration and whole package import)
3790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hongstatic const std::regex kRE3("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")");
38333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// IFoo.Type
39b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hongstatic const std::regex kRE4("(" RE_COMPONENT ")([.]" RE_COMPONENT ")+");
40333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// Type (a plain identifier)
41b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hongstatic const std::regex kRE5("(" RE_COMPONENT ")");
42b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
43333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// android.hardware.foo@1.0::IFoo.Type:MY_ENUM_VALUE
44333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hongstatic const std::regex kRE6("(" RE_PATH ")@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
45333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// @1.0::IFoo.Type:MY_ENUM_VALUE
4690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hongstatic const std::regex kRE7("@(" RE_MAJOR ")[.](" RE_MINOR ")::(" RE_PATH "):(" RE_COMPONENT ")");
47333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// IFoo.Type:MY_ENUM_VALUE
48b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hongstatic const std::regex kRE8("(" RE_PATH "):(" RE_COMPONENT ")");
4984f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
50333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong// 1.0
5190ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hongstatic const std::regex kREVer("(" RE_MAJOR ")[.](" RE_MINOR ")");
5290ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong
5384f89de8395a78577f80db0f860b61a9f2409294Andreas Hubernamespace android {
5484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
55da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas HuberFQName::FQName()
56327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong    : mValid(false),
57327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong      mIsIdentifier(false) {
58da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber}
59da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber
6084f89de8395a78577f80db0f860b61a9f2409294Andreas HuberFQName::FQName(const std::string &s)
61327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong    : mValid(false),
62327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong      mIsIdentifier(false) {
6384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    setTo(s);
6484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
6584f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
6668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas HuberFQName::FQName(
6768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        const std::string &package,
6868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        const std::string &version,
69b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        const std::string &name,
70b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        const std::string &valueName)
7168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    : mValid(true),
72b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong      mIsIdentifier(false),
7368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber      mPackage(package),
74b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong      mName(name),
75b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong      mValueName(valueName) {
7690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    setVersion(version);
77fece6ecab34d69d38f57419d2500017a7136083eYifan Hong
78fece6ecab34d69d38f57419d2500017a7136083eYifan Hong    // Check if this is actually a valid fqName
79fece6ecab34d69d38f57419d2500017a7136083eYifan Hong    FQName other;
80fece6ecab34d69d38f57419d2500017a7136083eYifan Hong    other.setTo(this->string());
81fece6ecab34d69d38f57419d2500017a7136083eYifan Hong    CHECK(other.mValid && (*this) == other);
8268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber}
8368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
84f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan HongFQName::FQName(const FQName& other)
85f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong    : mValid(other.mValid),
86f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mIsIdentifier(other.mIsIdentifier),
87f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mPackage(other.mPackage),
8890ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong      mMajor(other.mMajor),
8990ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong      mMinor(other.mMinor),
90f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mName(other.mName),
91f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong      mValueName(other.mValueName) {
92f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong}
93f24fa85b362d7eb66c7b880f48e1e2e9916bc8a9Yifan Hong
94327cfe12d51908469e1544db14a9232e0ddc6855Yifan HongFQName::FQName(const std::vector<std::string> &names)
95327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong    : mValid(false),
96327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong      mIsIdentifier(false) {
97327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong    setTo(StringHelper::JoinStrings(names, "."));
98327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong}
99327cfe12d51908469e1544db14a9232e0ddc6855Yifan Hong
10084f89de8395a78577f80db0f860b61a9f2409294Andreas Huberbool FQName::isValid() const {
10184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    return mValid;
10284f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
10384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
104b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hongbool FQName::isIdentifier() const {
105b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    return mIsIdentifier;
106b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong}
107b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
10868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberbool FQName::isFullyQualified() const {
10990ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    return !mPackage.empty() && !version().empty() && !mName.empty();
11068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber}
11168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
112b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hongbool FQName::isValidValueName() const {
113b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    return mIsIdentifier
114b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        || (!mName.empty() && !mValueName.empty());
115b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong}
116b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
11784f89de8395a78577f80db0f860b61a9f2409294Andreas Huberbool FQName::setTo(const std::string &s) {
1183b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    clearVersion();
11984f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    mPackage.clear();
12084f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    mName.clear();
12184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
12284f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    mValid = true;
12384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
12484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    std::smatch match;
12584f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    if (std::regex_match(s, match, kRE1)) {
12690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        CHECK_EQ(match.size(), 5u);
12784f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
12884f89de8395a78577f80db0f860b61a9f2409294Andreas Huber        mPackage = match.str(1);
1293b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        parseVersion(match.str(2), match.str(3));
13090ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mName = match.str(4);
13184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    } else if (std::regex_match(s, match, kRE2)) {
13290ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        CHECK_EQ(match.size(), 4u);
13384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
1343b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        parseVersion(match.str(1), match.str(2));
13590ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mName = match.str(3);
13684f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    } else if (std::regex_match(s, match, kRE3)) {
13790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        CHECK_EQ(match.size(), 4u);
138da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber
139da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber        mPackage = match.str(1);
1403b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        parseVersion(match.str(2), match.str(3));
141da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber    } else if (std::regex_match(s, match, kRE4)) {
14284f89de8395a78577f80db0f860b61a9f2409294Andreas Huber        mName = match.str(0);
143b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    } else if (std::regex_match(s, match, kRE5)) {
144b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        mIsIdentifier = true;
145b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        mName = match.str(0);
146b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    } else if (std::regex_match(s, match, kRE6)) {
14790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        CHECK_EQ(match.size(), 6u);
148b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
149b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        mPackage = match.str(1);
1503b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        parseVersion(match.str(2), match.str(3));
15190ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mName = match.str(4);
15290ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mValueName = match.str(5);
153b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    } else if (std::regex_match(s, match, kRE7)) {
15490ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        CHECK_EQ(match.size(), 5u);
155b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
1563b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        parseVersion(match.str(1), match.str(2));
15790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mName = match.str(3);
15890ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mValueName = match.str(4);
159b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    } else if (std::regex_match(s, match, kRE8)) {
16095a47bb42784bf74b8385b962cbe464dec037774Yifan Hong        CHECK_EQ(match.size(), 3u);
161b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
162b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        mName = match.str(1);
16395a47bb42784bf74b8385b962cbe464dec037774Yifan Hong        mValueName = match.str(2);
16484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    } else {
16584f89de8395a78577f80db0f860b61a9f2409294Andreas Huber        mValid = false;
16684f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    }
16784f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
168b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    // mValueName must go with mName.
169333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong    CHECK(mValueName.empty() || !mName.empty());
170333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong
171333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong    // package without version is not allowed.
172333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong    CHECK(mPackage.empty() || !version().empty());
173b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
17484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    return isValid();
17584f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
17684f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
17784f89de8395a78577f80db0f860b61a9f2409294Andreas Huberstd::string FQName::package() const {
17884f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    return mPackage;
17984f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
18084f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
18184f89de8395a78577f80db0f860b61a9f2409294Andreas Huberstd::string FQName::version() const {
1823b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    if (!hasVersion()) {
18390ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        return "";
18490ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    }
1853b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    return std::to_string(mMajor) + "." + std::to_string(mMinor);
18690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong}
18790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong
18897288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hongstd::string FQName::sanitizedVersion() const {
1893b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    if (!hasVersion()) {
19097288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong        return "";
19197288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong    }
1923b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    return "V" + std::to_string(mMajor) + "_" + std::to_string(mMinor);
19397288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong}
19497288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong
19590ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hongstd::string FQName::atVersion() const {
19690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    std::string v = version();
19790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    return v.empty() ? "" : ("@" + v);
19890ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong}
19990ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong
20090ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hongvoid FQName::setVersion(const std::string &v) {
20190ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    if (v.empty()) {
2023b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        clearVersion();
20390ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        return;
20490ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    }
20590ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    std::smatch match;
20690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    if (std::regex_match(v, match, kREVer)) {
20790ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        CHECK_EQ(match.size(), 3u);
20890ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong
2093b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        parseVersion(match.str(1), match.str(2));
21090ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    } else {
21190ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        mValid = false;
21290ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    }
21384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
21484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
2153b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hongvoid FQName::clearVersion() {
2163b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    mMajor = mMinor = 0;
2173b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong}
2183b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong
2193b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hongvoid FQName::parseVersion(const std::string &majorStr, const std::string &minorStr) {
2203b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    bool versionParseSuccess =
2213b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        ::android::base::ParseUint(majorStr, &mMajor) &&
2223b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        ::android::base::ParseUint(minorStr, &mMinor);
2233b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    if (!versionParseSuccess) {
2243b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        LOG(ERROR) << "numbers in " << majorStr << "." << minorStr << " are out of range.";
2253b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        mValid = false;
2263b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    }
2273b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong}
2283b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong
22984f89de8395a78577f80db0f860b61a9f2409294Andreas Huberstd::string FQName::name() const {
23084f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    return mName;
23184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
23284f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
233800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchevstd::vector<std::string> FQName::names() const {
234800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev    std::vector<std::string> res {};
235800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev    std::istringstream ss(name());
236800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev    std::string s;
237800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev    while (std::getline(ss, s, '.')) {
238800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev        res.push_back(s);
239800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev    }
240800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev    return res;
241800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev}
242800273d49f418065f5efbe41f7c74c5510707be4Iliyan Malchev
243b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hongstd::string FQName::valueName() const {
244b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    return mValueName;
245b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong}
246b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
247b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan HongFQName FQName::typeName() const {
24890ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    return FQName(mPackage, version(), mName);
249b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong}
250b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
25184f89de8395a78577f80db0f860b61a9f2409294Andreas Hubervoid FQName::applyDefaults(
25284f89de8395a78577f80db0f860b61a9f2409294Andreas Huber        const std::string &defaultPackage,
25384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber        const std::string &defaultVersion) {
254333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong
255333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong    // package without version is not allowed.
256333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong    CHECK(mPackage.empty() || !version().empty());
257333a6d2f842fdf8938aeae5fea0295fe2d7c6bcdYifan Hong
25884f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    if (mPackage.empty()) {
25984f89de8395a78577f80db0f860b61a9f2409294Andreas Huber        mPackage = defaultPackage;
26084f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    }
26184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
26290ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    if (version().empty()) {
26390ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        setVersion(defaultVersion);
26484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    }
26584f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
26684f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
26768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberstd::string FQName::string() const {
26884f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    CHECK(mValid);
26984f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
2705345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    std::string out;
27184f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    out.append(mPackage);
27290ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    out.append(atVersion());
273da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber    if (!mName.empty()) {
27490ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong        if (!mPackage.empty() || !version().empty()) {
275da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber            out.append("::");
276da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber        }
277da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber        out.append(mName);
278b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong
279b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        if (!mValueName.empty()) {
280b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong            out.append(":");
281b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong            out.append(mValueName);
282b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        }
28384f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    }
28484f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
28584f89de8395a78577f80db0f860b61a9f2409294Andreas Huber    return out;
28684f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}
28784f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
288da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Hubervoid FQName::print() const {
289da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber    if (!mValid) {
290da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber        LOG(INFO) << "INVALID";
291da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber        return;
292da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber    }
293da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber
29468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    LOG(INFO) << string();
29568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber}
29668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
29768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberbool FQName::operator<(const FQName &other) const {
29868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    return string() < other.string();
299da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber}
300da51b8e0dd17a0edcb5c3e72beb65d45ef0ce8b0Andreas Huber
301d2943e11533697b97aa5330f05fc144493748c0bAndreas Huberbool FQName::operator==(const FQName &other) const {
302d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber    return string() == other.string();
303d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber}
304d2943e11533697b97aa5330f05fc144493748c0bAndreas Huber
305c89340422f53046bfe24ff3e529161f9194120f8Yifan Hongbool FQName::operator!=(const FQName &other) const {
306c89340422f53046bfe24ff3e529161f9194120f8Yifan Hong    return !(*this == other);
307c89340422f53046bfe24ff3e529161f9194120f8Yifan Hong}
308c89340422f53046bfe24ff3e529161f9194120f8Yifan Hong
309eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hongstd::string FQName::getInterfaceName() const {
310197d56cc937e3f3e3762eb7e9a188b795e0267bfSteven Moreland    CHECK(names().size() == 1) << "Must be a top level type";
311197d56cc937e3f3e3762eb7e9a188b795e0267bfSteven Moreland    CHECK(!mName.empty() && mName[0] == 'I') << mName;
312197d56cc937e3f3e3762eb7e9a188b795e0267bfSteven Moreland
313eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return mName;
314eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
315eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
316eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hongstd::string FQName::getInterfaceBaseName() const {
317197d56cc937e3f3e3762eb7e9a188b795e0267bfSteven Moreland    // cut off the leading 'I'.
318eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return getInterfaceName().substr(1);
319eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
320eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
321eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hongstd::string FQName::getInterfaceHwName() const {
322eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return "IHw" + getInterfaceBaseName();
323eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
324eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
325eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hongstd::string FQName::getInterfaceProxyName() const {
32601e7cdef5d4198104a4e772cb742fb88777dccebYifan Hong    return "BpHw" + getInterfaceBaseName();
327eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
328eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
329eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hongstd::string FQName::getInterfaceStubName() const {
33001e7cdef5d4198104a4e772cb742fb88777dccebYifan Hong    return "BnHw" + getInterfaceBaseName();
331eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
332eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
333eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hongstd::string FQName::getInterfacePassthroughName() const {
334eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return "Bs" + getInterfaceBaseName();
335eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
336eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
337eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan HongFQName FQName::getInterfaceProxyFqName() const {
338eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return FQName(package(), version(), getInterfaceProxyName());
339eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
340eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
341eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan HongFQName FQName::getInterfaceStubFqName() const {
342eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return FQName(package(), version(), getInterfaceStubName());
343eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong}
344eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong
345eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan HongFQName FQName::getInterfacePassthroughFqName() const {
346eefe4f2405c3cb0f1d164bdb748e5d0ded3624f9Yifan Hong    return FQName(package(), version(), getInterfacePassthroughName());
347197d56cc937e3f3e3762eb7e9a188b795e0267bfSteven Moreland}
348197d56cc937e3f3e3762eb7e9a188b795e0267bfSteven Moreland
3491977ea3e1f1e6b45c46cacff27020fd988029dc3Yifan HongFQName FQName::getTypesForPackage() const {
3501977ea3e1f1e6b45c46cacff27020fd988029dc3Yifan Hong    return FQName(package(), version(), "types");
3511977ea3e1f1e6b45c46cacff27020fd988029dc3Yifan Hong}
3521977ea3e1f1e6b45c46cacff27020fd988029dc3Yifan Hong
353fece6ecab34d69d38f57419d2500017a7136083eYifan HongFQName FQName::getPackageAndVersion() const {
354fece6ecab34d69d38f57419d2500017a7136083eYifan Hong    return FQName(package(), version(), "");
355fece6ecab34d69d38f57419d2500017a7136083eYifan Hong}
356fece6ecab34d69d38f57419d2500017a7136083eYifan Hong
357fece6ecab34d69d38f57419d2500017a7136083eYifan HongFQName FQName::getTopLevelType() const {
3589c38761b9650ff98b326c130807b0c1733de881dSteven Moreland    auto idx = mName.find('.');
3599c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
3609c38761b9650ff98b326c130807b0c1733de881dSteven Moreland    if (idx == std::string::npos) {
3619c38761b9650ff98b326c130807b0c1733de881dSteven Moreland        return *this;
3629c38761b9650ff98b326c130807b0c1733de881dSteven Moreland    }
3639c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
36490ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    return FQName(mPackage, version(), mName.substr(0, idx));
3659c38761b9650ff98b326c130807b0c1733de881dSteven Moreland}
3669c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
3679c38761b9650ff98b326c130807b0c1733de881dSteven Morelandstd::string FQName::tokenName() const {
3689c38761b9650ff98b326c130807b0c1733de881dSteven Moreland    std::vector<std::string> components;
3699c38761b9650ff98b326c130807b0c1733de881dSteven Moreland    getPackageAndVersionComponents(&components, true /* cpp_compatible */);
3709c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
3716f596c89968164351c9c8ef6e94bbcebc6796d64Steven Moreland    if (!mName.empty()) {
3726f596c89968164351c9c8ef6e94bbcebc6796d64Steven Moreland        std::vector<std::string> nameComponents;
3736f596c89968164351c9c8ef6e94bbcebc6796d64Steven Moreland        StringHelper::SplitString(mName, '.', &nameComponents);
3749c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
3756f596c89968164351c9c8ef6e94bbcebc6796d64Steven Moreland        components.insert(components.end(), nameComponents.begin(), nameComponents.end());
3766f596c89968164351c9c8ef6e94bbcebc6796d64Steven Moreland    }
3779c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
378af44014f7b42697be072a7bde111c432b313d684Steven Moreland    return StringHelper::JoinStrings(components, "_");
3799c38761b9650ff98b326c130807b0c1733de881dSteven Moreland}
3809c38761b9650ff98b326c130807b0c1733de881dSteven Moreland
3810e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huberstd::string FQName::cppNamespace() const {
3820e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    std::vector<std::string> components;
3830e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    getPackageAndVersionComponents(&components, true /* cpp_compatible */);
3840e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
3850e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    std::string out = "::";
386af44014f7b42697be072a7bde111c432b313d684Steven Moreland    out += StringHelper::JoinStrings(components, "::");
3870e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
3880e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    return out;
389979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland}
390979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland
391979e099f1163ff75beed5776cd01fb409b90a0cdSteven Morelandstd::string FQName::cppLocalName() const {
392979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland    std::vector<std::string> components;
393af44014f7b42697be072a7bde111c432b313d684Steven Moreland    StringHelper::SplitString(mName, '.', &components);
394979e099f1163ff75beed5776cd01fb409b90a0cdSteven Moreland
395b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    return StringHelper::JoinStrings(components, "::")
396b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong            + (mValueName.empty() ? "" : ("::" + mValueName));
3970e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber}
3980e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
3990e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huberstd::string FQName::cppName() const {
4000e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    std::string out = cppNamespace();
4010e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
4020e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    std::vector<std::string> components;
403af44014f7b42697be072a7bde111c432b313d684Steven Moreland    StringHelper::SplitString(name(), '.', &components);
4040e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    out += "::";
405af44014f7b42697be072a7bde111c432b313d684Steven Moreland    out += StringHelper::JoinStrings(components, "::");
406b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    if (!mValueName.empty()) {
407b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong        out  += "::" + mValueName;
408b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    }
4090e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
4100e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    return out;
4110e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber}
4120e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
4132831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string FQName::javaPackage() const {
4142831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    std::vector<std::string> components;
4152831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber    getPackageAndVersionComponents(&components, true /* cpp_compatible */);
4162831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
417af44014f7b42697be072a7bde111c432b313d684Steven Moreland    return StringHelper::JoinStrings(components, ".");
4182831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
4192831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4202831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huberstd::string FQName::javaName() const {
421b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong    return javaPackage() + "." + name()
422b44a6c8ed35bc63fa0e65111c31fa1339325eb41Yifan Hong            + (mValueName.empty() ? "" : ("." + mValueName));
4232831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber}
4242831d5145675ead9f2fb767bf5fe4ae56b88349fAndreas Huber
4250e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Hubervoid FQName::getPackageComponents(std::vector<std::string> *components) const {
426af44014f7b42697be072a7bde111c432b313d684Steven Moreland    StringHelper::SplitString(package(), '.', components);
4270e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber}
4280e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
4290e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Hubervoid FQName::getPackageAndVersionComponents(
4300e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        std::vector<std::string> *components,
4310e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        bool cpp_compatible) const {
4320e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    getPackageComponents(components);
4330e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
4343b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    if (!hasVersion()) {
4353b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        LOG(WARNING) << "FQName: getPackageAndVersionComponents expects version.";
4363b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        return;
4373b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    }
4383b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong
4390e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    if (!cpp_compatible) {
4403b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong        components->push_back(std::to_string(getPackageMajorVersion()) +
4413b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong                "." + std::to_string(getPackageMinorVersion()));
4420e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber        return;
4430e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber    }
4440e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
44597288acdcff66df30cc443c65ddb815e8d0cfeaaYifan Hong    components->push_back(sanitizedVersion());
4460e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber}
4470e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas Huber
4483b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hongbool FQName::hasVersion() const {
4493b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    return mMajor > 0;
4503b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong}
4513b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong
4523b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hongsize_t FQName::getPackageMajorVersion() const {
4533b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    CHECK(hasVersion()) << "FQName: No version exists at getPackageMajorVersion(). "
4543b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong                        << "Did you check hasVersion()?";
45590ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    return mMajor;
456a21f1494a1b75ebd799d3f1156047caecc643270Martijn Coenen}
457a21f1494a1b75ebd799d3f1156047caecc643270Martijn Coenen
4583b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hongsize_t FQName::getPackageMinorVersion() const {
4593b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong    CHECK(hasVersion()) << "FQName: No version exists at getPackageMinorVersion(). "
4603b8a65a5a8dbff4b2e554c386745f1e2bd934fe3Yifan Hong                        << "Did you check hasVersion()?";
46190ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    return mMinor;
4628f49294db5ac2898bac7c58ca20ff37d4cacdf5eZhuoyao Zhang}
4638f49294db5ac2898bac7c58ca20ff37d4cacdf5eZhuoyao Zhang
46439fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huberbool FQName::endsWith(const FQName &other) const {
46539fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber    std::string s1 = string();
46639fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber    std::string s2 = other.string();
46739fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber
46839fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber    size_t pos = s1.rfind(s2);
46939fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber    if (pos == std::string::npos || pos + s2.size() != s1.size()) {
47039fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber        return false;
47139fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber    }
47239fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber
473d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    // A match is only a match if it is preceded by a "boundary", i.e.
474d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    // we perform a component-wise match from the end.
475d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    // "az" is not a match for "android.hardware.foo@1.0::IFoo.bar.baz",
476d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    // "baz", "bar.baz", "IFoo.bar.baz", "@1.0::IFoo.bar.baz" are.
477d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    if (pos == 0) {
478d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        // matches "android.hardware.foo@1.0::IFoo.bar.baz"
479d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        return true;
480d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    }
481d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong
482d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    if (s1[pos - 1] == '.') {
483d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        // matches "baz" and "bar.baz"
484d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        return true;
485d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    }
486d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong
487d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    if (s1[pos - 1] == ':') {
488d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        // matches "IFoo.bar.baz"
489d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        return true;
490d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    }
491d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong
492d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    if (s1[pos] == '@') {
493d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        // matches "@1.0::IFoo.bar.baz"
494d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong        return true;
49539fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber    }
49639fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber
497d9f22f7fe1f124601a99ba9204a18838d034dbe5Yifan Hong    return false;
49839fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber}
49939fa71827738f6c1340e4523946fe9bf704eef3aAndreas Huber
50062709d73d7f260fae0a475f8d4d30eb3665e8168Steven Morelandbool FQName::inPackage(const std::string &package) const {
50162709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    std::vector<std::string> components;
50262709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    getPackageComponents(&components);
50362709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland
50462709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    std::vector<std::string> inComponents;
50562709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    StringHelper::SplitString(package, '.', &inComponents);
50662709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland
50762709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    if (inComponents.size() > components.size()) {
50862709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland        return false;
50962709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    }
51062709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland
51162709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    for (size_t i = 0; i < inComponents.size(); i++) {
51262709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland        if (inComponents[i] != components[i]) {
51362709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland            return false;
51462709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland        }
51562709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    }
51662709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland
51762709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland    return true;
51862709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland}
51962709d73d7f260fae0a475f8d4d30eb3665e8168Steven Moreland
52078b38d1e36934a60b3abcd82d576b54ca254b323Yifan HongFQName FQName::downRev() const {
52178b38d1e36934a60b3abcd82d576b54ca254b323Yifan Hong    FQName ret(*this);
52278b38d1e36934a60b3abcd82d576b54ca254b323Yifan Hong    CHECK(ret.mMinor > 0);
52378b38d1e36934a60b3abcd82d576b54ca254b323Yifan Hong    ret.mMinor--;
52478b38d1e36934a60b3abcd82d576b54ca254b323Yifan Hong    return ret;
52578b38d1e36934a60b3abcd82d576b54ca254b323Yifan Hong}
52678b38d1e36934a60b3abcd82d576b54ca254b323Yifan Hong
52784f89de8395a78577f80db0f860b61a9f2409294Andreas Huber}  // namespace android
52884f89de8395a78577f80db0f860b61a9f2409294Andreas Huber
529