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