• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 AST_H_
18 
19 #define AST_H_
20 
21 #include <android-base/macros.h>
22 #include <hidl-util/FQName.h>
23 #include <map>
24 #include <set>
25 #include <string>
26 #include <vector>
27 
28 #include "Scope.h"
29 #include "Type.h"
30 
31 namespace android {
32 
33 struct Coordinator;
34 struct Formatter;
35 struct Interface;
36 struct Location;
37 struct Method;
38 struct NamedType;
39 struct TypedVar;
40 struct EnumValue;
41 
42 struct AST {
43     AST(const Coordinator *coordinator, const std::string &path);
44 
45     bool setPackage(const char *package);
46     bool addImport(const char *import);
47 
48     // package and version really.
49     FQName package() const;
50     bool isInterface() const;
51     bool containsInterfaces() const;
52 
53     // Returns true iff successful.
54     bool addTypeDef(const char* localName, Type* type, const Location& location,
55                     std::string* errorMsg, Scope* scope);
56 
57     // Returns true iff successful.
58     bool addScopedType(NamedType* type, std::string* errorMsg, Scope* scope);
59 
60     const std::string &getFilename() const;
61 
62     // Look up an enum value by "FQName:valueName".
63     EnumValue* lookupEnumValue(const FQName& fqName, std::string* errorMsg, Scope* scope);
64 
65     // Look up a type by FQName, "pure" names, i.e. those without package
66     // or version are first looked up in the current scope chain.
67     // After that lookup proceeds to imports.
68     Type* lookupType(const FQName& fqName, Scope* scope);
69 
70     void addImportedAST(AST *ast);
71 
72     status_t generateCpp(const std::string &outputPath) const;
73     status_t generateCppHeaders(const std::string &outputPath) const;
74     status_t generateCppSources(const std::string &outputPath) const;
75     status_t generateCppImpl(const std::string &outputPath) const;
76     status_t generateStubImplHeader(const std::string& outputPath) const;
77     status_t generateStubImplSource(const std::string& outputPath) const;
78 
79     status_t generateJava(
80             const std::string &outputPath,
81             const std::string &limitToType) const;
82 
83     status_t generateJavaTypes(
84             const std::string &outputPath,
85             const std::string &limitToType) const;
86 
87     void getImportedPackages(std::set<FQName> *importSet) const;
88 
89     // Run getImportedPackages on this, then run getImportedPackages on
90     // each AST in each package referenced in importSet.
91     void getImportedPackagesHierarchy(std::set<FQName> *importSet) const;
92 
93     status_t generateVts(const std::string &outputPath) const;
94 
95     bool isJavaCompatible() const;
96 
97     // Return the set of FQNames for those interfaces and types that are
98     // actually referenced in the AST, not merely imported.
getImportedNamesAST99     const std::set<FQName>& getImportedNames() const {
100         return mImportedNames;
101     }
102 
103     // Get transitive closure of imported interface/types.
104     void getAllImportedNames(std::set<FQName> *allImportSet) const;
105 
106     void appendToExportedTypesVector(
107             std::vector<const Type *> *exportedTypes) const;
108 
109     // used by the parser.
110     void addSyntaxError();
111     size_t syntaxErrors() const;
112 
113     bool isIBase() const;
114 
115     // or nullptr if not isInterface
116     const Interface *getInterface() const;
117 
118     // types or Interface base name (e.x. Foo)
119     std::string getBaseName() const;
120 
121     Scope* getRootScope();
122 
123    private:
124     const Coordinator *mCoordinator;
125     std::string mPath;
126 
127     RootScope mRootScope;
128 
129     FQName mPackage;
130 
131     // A set of all external interfaces/types that are _actually_ referenced
132     // in this AST, this is a subset of those specified in import statements.
133     std::set<FQName> mImportedNames;
134 
135     // A set of all ASTs we explicitly or implicitly (types.hal) import.
136     std::set<AST *> mImportedASTs;
137 
138     // If a single type (instead of the whole AST) is imported, the AST will be
139     // present as a key to this map, with the value being a list of types
140     // imported from this AST. If an AST appears in mImportedASTs but not in
141     // mImportedTypes, then the whole AST is imported.
142     std::map<AST *, std::set<Type *>> mImportedTypes;
143 
144     // Types keyed by full names defined in this AST.
145     std::map<FQName, Type *> mDefinedTypesByFullName;
146 
147     // used by the parser.
148     size_t mSyntaxErrors = 0;
149 
150     bool addScopedTypeInternal(NamedType* type, std::string* errorMsg, Scope* scope);
151 
152     // Helper functions for lookupType.
153     Type* lookupTypeLocally(const FQName& fqName, Scope* scope);
154     status_t lookupAutofilledType(const FQName &fqName, Type **returnedType);
155     Type *lookupTypeFromImports(const FQName &fqName);
156 
157     // Find a type matching fqName (which may be partial) and if found
158     // return the associated type and fill in the full "matchingName".
159     // Only types defined in this very AST are considered.
160     Type *findDefinedType(const FQName &fqName, FQName *matchingName) const;
161 
162     void getPackageComponents(std::vector<std::string> *components) const;
163 
164     void getPackageAndVersionComponents(
165             std::vector<std::string> *components, bool cpp_compatible) const;
166 
167     static void generateCppPackageInclude(
168             Formatter &out,
169             const FQName &package,
170             const std::string &klass);
171 
172     std::string makeHeaderGuard(const std::string &baseName,
173                                 bool indicateGenerated = true) const;
174     void enterLeaveNamespace(Formatter &out, bool enter) const;
175 
176     static void generateCheckNonNull(Formatter &out, const std::string &nonNull);
177 
178     status_t generateInterfaceHeader(const std::string &outputPath) const;
179     status_t generateHwBinderHeader(const std::string &outputPath) const;
180     status_t generateStubHeader(const std::string &outputPath) const;
181     status_t generateProxyHeader(const std::string &outputPath) const;
182     status_t generatePassthroughHeader(const std::string &outputPath) const;
183 
184     status_t generateTypeSource(
185             Formatter &out, const std::string &ifaceName) const;
186 
187     // a method, and in which interface is it originally defined.
188     // be careful of the case where method.isHidlReserved(), where interface
189     // is effectively useless.
190     using MethodGenerator = std::function<status_t(const Method *, const Interface *)>;
191 
192     void generateTemplatizationLink(Formatter& out) const;
193 
194     status_t generateMethods(Formatter &out, MethodGenerator gen, bool includeParents = true) const;
195     status_t generateStubImplMethod(Formatter &out,
196                                     const std::string &className,
197                                     const Method *method) const;
198     status_t generatePassthroughMethod(Formatter &out,
199                                        const Method *method) const;
200     status_t generateStaticProxyMethodSource(Formatter &out,
201                                              const std::string &className,
202                                              const Method *method) const;
203     status_t generateProxyMethodSource(Formatter &out,
204                                        const std::string &className,
205                                        const Method *method,
206                                        const Interface *superInterface) const;
207 
208     void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const;
209 
210     status_t generateProxySource(
211             Formatter &out, const FQName &fqName) const;
212 
213     status_t generateStubSource(
214             Formatter &out, const Interface *iface) const;
215 
216     status_t generateStubSourceForMethod(Formatter &out,
217                                          const Method *method,
218                                          const Interface *superInterface) const;
219     status_t generateStaticStubMethodSource(Formatter &out,
220                                             const std::string &className,
221                                             const Method *method) const;
222 
223     status_t generatePassthroughSource(Formatter &out) const;
224 
225     status_t generateInterfaceSource(Formatter &out) const;
226 
227     enum InstrumentationEvent {
228         SERVER_API_ENTRY = 0,
229         SERVER_API_EXIT,
230         CLIENT_API_ENTRY,
231         CLIENT_API_EXIT,
232         SYNC_CALLBACK_ENTRY,
233         SYNC_CALLBACK_EXIT,
234         ASYNC_CALLBACK_ENTRY,
235         ASYNC_CALLBACK_EXIT,
236         PASSTHROUGH_ENTRY,
237         PASSTHROUGH_EXIT,
238     };
239 
240     void generateCppAtraceCall(
241             Formatter &out,
242             InstrumentationEvent event,
243             const Method *method) const;
244 
245     void generateCppInstrumentationCall(
246             Formatter &out,
247             InstrumentationEvent event,
248             const Method *method) const;
249 
250     void declareCppReaderLocals(
251             Formatter &out,
252             const std::vector<TypedVar *> &arg,
253             bool forResults) const;
254 
255     void emitCppReaderWriter(
256             Formatter &out,
257             const std::string &parcelObj,
258             bool parcelObjIsPointer,
259             const TypedVar *arg,
260             bool isReader,
261             Type::ErrorMode mode,
262             bool addPrefixToName) const;
263 
264     void emitCppResolveReferences(
265             Formatter &out,
266             const std::string &parcelObj,
267             bool parcelObjIsPointer,
268             const TypedVar *arg,
269             bool isReader,
270             Type::ErrorMode mode,
271             bool addPrefixToName) const;
272 
273     void emitJavaReaderWriter(
274             Formatter &out,
275             const std::string &parcelObj,
276             const TypedVar *arg,
277             bool isReader,
278             bool addPrefixToName) const;
279 
280     status_t emitTypeDeclarations(Formatter &out) const;
281     status_t emitJavaTypeDeclarations(Formatter &out) const;
282     status_t emitVtsTypeDeclarations(Formatter &out) const;
283 
284     DISALLOW_COPY_AND_ASSIGN(AST);
285 };
286 
287 }  // namespace android
288 
289 #endif  // AST_H_
290