1 /*
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 
17 #ifndef FQNAME_H_
18 
19 #define FQNAME_H_
20 
21 #include <string>
22 #include <vector>
23 
24 namespace android {
25 
26 struct FQName {
27     __attribute__((warn_unused_result)) static bool parse(const std::string& s, FQName* into);
28 
29     explicit FQName();
30 
31     FQName(const std::string& package, const std::string& version, const std::string& name = "",
32            const std::string& valueName = "");
33 
34     bool isIdentifier() const;
35 
36     // Returns false if string isn't a valid FQName object.
37     __attribute__((warn_unused_result)) bool setTo(const std::string& s);
38     __attribute__((warn_unused_result)) bool setTo(const std::string& package, size_t majorVer,
39                                                    size_t minorVer, const std::string& name = "",
40                                                    const std::string& valueName = "");
41 
42     void applyDefaults(
43             const std::string &defaultPackage,
44             const std::string &defaultVersion);
45 
46     const std::string& package() const;
47     // Return version in the form "@1.0" if it is present, otherwise empty string.
48     std::string atVersion() const;
49     // Return version in the form "1.0" if it is present, otherwise empty string.
50     std::string version() const;
51     // Return version in the form "V1_0" if it is present, otherwise empty string.
52     std::string sanitizedVersion() const;
53     // Return true only if version is present.
54     bool hasVersion() const;
55     // Return pair of (major, minor) version. Defaults to 0, 0.
56     std::pair<size_t, size_t> getVersion() const;
57 
58     FQName withVersion(size_t major, size_t minor) const;
59 
60     // The next two methods return the name part of the FQName, that is, the
61     // part after the version field.  For example:
62     //
63     // package android.hardware.tests.foo@1.0;
64     // interface IFoo {
65     //    struct bar {
66     //        struct baz {
67     //            ...
68     //        };
69     //    };
70     // };
71     //
72     // package android.hardware.tests.bar@1.0;
73     // import android.hardware.tests.foo@1.0;
74     // interface {
75     //    struct boo {
76     //        IFoo.bar.baz base;
77     //    };
78     // }
79     //
80     // The FQName for base is android.hardware.tests.foo@1.0::IFoo.bar.baz; so
81     // FQName::name() will return "IFoo.bar.baz". FQName::names() will return
82     // std::vector<std::string>{"IFoo","bar","baz"}
83 
84     const std::string& name() const;
85     std::vector<std::string> names() const;
86 
87     // The next two methods returns two parts of the FQName, that is,
88     // the first part package + version + name, the second part valueName.
89     FQName typeName() const;
90     const std::string& valueName() const;
91 
92     // has package version and name
93     bool isFullyQualified() const;
94 
95     // true if:
96     // 1. (package)?(version)?(name):(valueName)
97     // 2. (valueName), aka a single identifier
98     bool isValidValueName() const;
99 
100     // Interface names start with 'I'
101     bool isInterfaceName() const;
102 
103     std::string string() const;
104 
105     bool operator<(const FQName &other) const;
106     bool operator==(const FQName &other) const;
107     bool operator!=(const FQName &other) const;
108 
109     // Provides the FQName relative to "relativeTo"
110     // If this is android.hardware.foo@1.0::IFoo it returns
111     // relativeTo: android.hardware.foo@1.0::IBar - IFoo
112     // relativeTo: android.hardware.foo@1.2::IFoo - @1.0::IFoo
113     // relativeTo: android.hardware.bar@1.0::IFoo - android.hardware.foo@1.0::IFoo
114     std::string getRelativeFQName(const FQName& relativeTo) const;
115 
116     // Must be called on an interface
117     // android.hardware.foo@1.0::IBar
118     // -> Bar
119     std::string getInterfaceBaseName() const;
120 
121     // Must be called on an interface
122     // android.hardware.foo@1.0::IBar
123     // -> ABar
124     std::string getInterfaceAdapterName() const;
125 
126     // Must be called on an interface
127     // android.hardware.foo@1.0::IBar
128     // -> IBar
129     const std::string& getInterfaceName() const;
130 
131     // Must be called on an interface
132     // android.hardware.foo@1.0::IBar
133     // -> IHwBar
134     std::string getInterfaceHwName() const;
135 
136     // Must be called on an interface
137     // android.hardware.foo@1.0::IBar
138     // -> BpHwBar
139     std::string getInterfaceProxyName() const;
140 
141     // Must be called on an interface
142     // android.hardware.foo@1.0::IBar
143     // -> BnHwBar
144     std::string getInterfaceStubName() const;
145 
146     // Must be called on an interface
147     // android.hardware.foo@1.0::IBar
148     // -> BsBar
149     std::string getInterfacePassthroughName() const;
150 
151     // Must be called on an interface
152     // android.hardware.foo@1.0::IBar
153     // -> android.hardware.foo@1.0::BpBar
154     FQName getInterfaceProxyFqName() const;
155 
156     // Must be called on an interface
157     // android.hardware.foo@1.0::IBar
158     // -> android.hardware.foo@1.0::ABar
159     FQName getInterfaceAdapterFqName() const;
160 
161     // Must be called on an interface
162     // android.hardware.foo@1.0::IBar
163     // -> android.hardware.foo@1.0::BnBar
164     FQName getInterfaceStubFqName() const;
165 
166     // Must be called on an interface
167     // android.hardware.foo@1.0::IBar
168     // -> android.hardware.foo@1.0::BsBar
169     FQName getInterfacePassthroughFqName() const;
170 
171     // Replace whatever after :: with "types"
172     // android.hardware.foo@1.0::Abc.Type:VALUE
173     // -> android.hardware.foo@1.0::types
174     FQName getTypesForPackage() const;
175 
176     // android.hardware.foo@1.0::Abc.Type:VALUE
177     // -> android.hardware.foo@1.0
178     FQName getPackageAndVersion() const;
179 
180     // the following comments all assume that the FQName
181     // is android.hardware.foo@1.0::IBar.Baz.Bam
182 
183     // returns highest type in the hidl namespace, i.e.
184     // android.hardware.foo@1.0::IBar
185     FQName getTopLevelType() const;
186 
187     // returns an unambiguous fully qualified name which can be
188     // baked into a token, i.e.
189     // android_hardware_Foo_V1_0_IBar_Baz
190     std::string tokenName() const;
191 
192     // Returns an absolute C++ namespace prefix, i.e.
193     // ::android::hardware::Foo::V1_0.
194     std::string cppNamespace() const;
195 
196     // Returns a name qualified assuming we are in cppNamespace, i.e.
197     // IBar::Baz.
198     std::string cppLocalName() const;
199 
200     // Returns a fully qualified absolute C++ type name, i.e.
201     // ::android::hardware::Foo::V1_0::IBar::Baz.
202     std::string cppName() const;
203 
204     // Returns the java package name, i.e. "android.hardware.Foo.V1_0".
205     std::string javaPackage() const;
206 
207     // Returns the fully qualified java type name,
208     // i.e. "android.hardware.Foo.V1_0.IBar.Baz"
209     std::string javaName() const;
210 
211     bool endsWith(const FQName &other) const;
212 
213     // If this is android.hardware@1.0::IFoo
214     // package = "and" -> false
215     // package = "android" -> true
216     // package = "android.hardware@1.0" -> false
217     bool inPackage(const std::string &package) const;
218 
219     std::vector<std::string> getPackageComponents() const;
220 
221     std::vector<std::string> getPackageAndVersionComponents(bool sanitized) const;
222 
223     // return major and minor version if they exist, else abort program.
224     // Existence of version can be checked via hasVersion().
225     size_t getPackageMajorVersion() const;
226     size_t getPackageMinorVersion() const;
227 
228     // minor-- if result doesn't underflow, else abort.
229     FQName downRev() const;
230     // minor++
231     FQName upRev() const;
232 
233   private:
234     bool mIsIdentifier;
235     std::string mPackage;
236     // mMajor == 0 means empty.
237     size_t mMajor = 0;
238     size_t mMinor = 0;
239     std::string mName;
240     std::string mValueName;
241 
242     void clear();
243 
244     __attribute__((warn_unused_result)) bool setVersion(const std::string& v);
245     __attribute__((warn_unused_result)) bool parseVersion(const std::string& majorStr,
246                                                           const std::string& minorStr);
247     __attribute__((warn_unused_result)) static bool parseVersion(const std::string& majorStr,
248                                                                  const std::string& minorStr,
249                                                                  size_t* majorVer,
250                                                                  size_t* minorVer);
251     __attribute__((warn_unused_result)) static bool parseVersion(const std::string& v,
252                                                                  size_t* majorVer,
253                                                                  size_t* minorVer);
254     static void clearVersion(size_t* majorVer, size_t* minorVer);
255 
256     void clearVersion();
257 };
258 
259 }  // namespace android
260 
261 #endif  // FQNAME_H_
262