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 TYPE_H_
18 
19 #define TYPE_H_
20 
21 #include <android-base/macros.h>
22 #include <utils/Errors.h>
23 #include <set>
24 #include <string>
25 #include <unordered_map>
26 #include <unordered_set>
27 #include <vector>
28 
29 #include "DocComment.h"
30 #include "Reference.h"
31 
32 namespace android {
33 
34 struct ConstantExpression;
35 struct Formatter;
36 struct FQName;
37 struct ScalarType;
38 struct Scope;
39 
40 struct Type : DocCommentable {
41     Type(Scope* parent);
42     virtual ~Type();
43 
44     virtual bool isArray() const;
45     virtual bool isBinder() const;
46     virtual bool isBitField() const;
47     virtual bool isCompoundType() const;
48     virtual bool isEnum() const;
49     virtual bool isHandle() const;
50     virtual bool isInterface() const;
51     virtual bool isNamedType() const;
52     virtual bool isMemory() const;
53     virtual bool isPointer() const;
54     virtual bool isScope() const;
55     virtual bool isScalar() const;
56     virtual bool isString() const;
57     virtual bool isTemplatedType() const;
58     virtual bool isTypeDef() const;
59     virtual bool isVector() const;
60 
61     // Resolves the type by unwrapping typedefs
62     Type* resolve();
63     virtual const Type* resolve() const;
64 
65     // All types defined in this type.
66     std::vector<Type*> getDefinedTypes();
67     virtual std::vector<const Type*> getDefinedTypes() const;
68 
69     // All types referenced in this type.
70     std::vector<Reference<Type>*> getReferences();
71     virtual std::vector<const Reference<Type>*> getReferences() const;
72 
73     // All constant expressions referenced in this type.
74     std::vector<ConstantExpression*> getConstantExpressions();
75     virtual std::vector<const ConstantExpression*> getConstantExpressions() const;
76 
77     // All types referenced in this type that must have completed
78     // definiton before being referenced.
79     std::vector<Reference<Type>*> getStrongReferences();
80     virtual std::vector<const Reference<Type>*> getStrongReferences() const;
81 
82     // Proceeds recursive pass
83     // Makes sure to visit each node only once.
84     status_t recursivePass(const std::function<status_t(Type*)>& func,
85                            std::unordered_set<const Type*>* visited);
86     status_t recursivePass(const std::function<status_t(const Type*)>& func,
87                            std::unordered_set<const Type*>* visited) const;
88 
89     // Recursive tree pass that completes type declarations
90     // that depend on super types
91     virtual status_t resolveInheritance();
92 
93     // Recursive tree pass that validates all type-related
94     // syntax restrictions
95     virtual status_t validate() const;
96 
97     // Recursive tree pass checkAcyclic return type.
98     // Stores cycle end for nice error messages.
99     struct CheckAcyclicStatus {
100         CheckAcyclicStatus(status_t status, const Type* cycleEnd = nullptr);
101 
102         status_t status;
103 
104         // If a cycle is found, stores the end of cycle.
105         // While going back in recursion, this is used to stop printing the cycle.
106         const Type* cycleEnd;
107     };
108 
109     // Recursive tree pass that ensures that type definitions and references
110     // are acyclic and builds reversed topological order of the types.
111     // If some cases allow using of incomplete types, these cases are to be
112     // declared in Type::getStrongReferences.
113     CheckAcyclicStatus topologicalOrder(std::unordered_map<const Type*, size_t>* reversedOrder,
114                                         std::unordered_set<const Type*>* stack) const;
115 
116     // Checks following C++ restriction on forward declaration:
117     // inner struct could be forward declared only inside its parent.
118     status_t checkForwardReferenceRestrictions(const Reference<Type>& ref) const;
119 
120     virtual const ScalarType *resolveToScalarType() const;
121 
122     virtual std::string typeName() const = 0;
123 
124     bool isValidEnumStorageType() const;
125     virtual bool isElidableType() const;
126 
127     virtual bool canCheckEquality() const;
128     bool canCheckEquality(std::unordered_set<const Type*>* visited) const;
129     virtual bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const;
130 
131     // Marks that package proceeding is completed
132     // Post parse passes must be proceeded during owner package parsing
133     void setPostParseCompleted();
134 
135     Scope* parent();
136     const Scope* parent() const;
137 
138     enum StorageMode {
139         StorageMode_Stack,
140         StorageMode_Argument,
141         StorageMode_Result,
142     };
143 
144     // specifyNamespaces: whether to specify namespaces for built-in types
145     virtual std::string getCppType(
146             StorageMode mode,
147             bool specifyNamespaces) const;
148 
149     std::string decorateCppName(
150             const std::string &name,
151             StorageMode mode,
152             bool specifyNamespaces) const;
153 
154     std::string getCppStackType(bool specifyNamespaces = true) const;
155 
156     std::string getCppResultType(bool specifyNamespaces = true) const;
157 
158     std::string getCppArgumentType(bool specifyNamespaces = true) const;
159 
160     // For an array type, dimensionality information will be accumulated at the
161     // end of the returned string.
162     // if forInitializer == true, actual dimensions are included, i.e. [3][5],
163     // otherwise (and by default), they are omitted, i.e. [][].
164     virtual std::string getJavaType(bool forInitializer = false) const;
165 
166     virtual std::string getJavaWrapperType() const;
167     virtual std::string getJavaSuffix() const;
168 
169     virtual std::string getVtsType() const;
170     virtual std::string getVtsValueName() const;
171 
172     enum ErrorMode {
173         ErrorMode_Ignore,
174         ErrorMode_Goto,
175         ErrorMode_Break,
176         ErrorMode_Return,
177     };
178     virtual void emitReaderWriter(
179             Formatter &out,
180             const std::string &name,
181             const std::string &parcelObj,
182             bool parcelObjIsPointer,
183             bool isReader,
184             ErrorMode mode) const;
185 
186     virtual void emitReaderWriterEmbedded(
187             Formatter &out,
188             size_t depth,
189             const std::string &name,
190             const std::string &sanitizedName,
191             bool nameIsPointer,
192             const std::string &parcelObj,
193             bool parcelObjIsPointer,
194             bool isReader,
195             ErrorMode mode,
196             const std::string &parentName,
197             const std::string &offsetText) const;
198 
199     virtual void emitResolveReferences(
200             Formatter &out,
201             const std::string &name,
202             bool nameIsPointer,
203             const std::string &parcelObj,
204             bool parcelObjIsPointer,
205             bool isReader,
206             ErrorMode mode) const;
207 
208     virtual void emitResolveReferencesEmbedded(
209             Formatter &out,
210             size_t depth,
211             const std::string &name,
212             const std::string &sanitizedName,
213             bool nameIsPointer,
214             const std::string &parcelObj,
215             bool parcelObjIsPointer,
216             bool isReader,
217             ErrorMode mode,
218             const std::string &parentName,
219             const std::string &offsetText) const;
220 
221     virtual void emitDump(
222             Formatter &out,
223             const std::string &streamName,
224             const std::string &name) const;
225 
226     virtual void emitJavaDump(
227             Formatter &out,
228             const std::string &streamName,
229             const std::string &name) const;
230 
231     virtual bool useParentInEmitResolveReferencesEmbedded() const;
232 
233     virtual bool useNameInEmitReaderWriterEmbedded(bool isReader) const;
234 
235     virtual void emitJavaReaderWriter(
236             Formatter &out,
237             const std::string &parcelObj,
238             const std::string &argName,
239             bool isReader) const;
240 
241     virtual void emitJavaFieldInitializer(
242             Formatter &out,
243             const std::string &fieldName) const;
244 
245     virtual void emitJavaFieldReaderWriter(
246             Formatter &out,
247             size_t depth,
248             const std::string &parcelName,
249             const std::string &blobName,
250             const std::string &fieldName,
251             const std::string &offset,
252             bool isReader) const;
253 
254     virtual void emitTypeDeclarations(Formatter& out) const;
255 
256     virtual void emitGlobalTypeDeclarations(Formatter& out) const;
257 
258     // Emit scope C++ forward declaration.
259     // There is no need to forward declare interfaces, as
260     // they are always declared in global scope in dedicated file.
261     virtual void emitTypeForwardDeclaration(Formatter& out) const;
262 
263     // Emit any declarations pertaining to this type that have to be
264     // at global scope, i.e. enum class operators.
265     // For android.hardware.foo@1.0::*, this will be in namespace
266     // android::hardware::foo::V1_0
267     virtual void emitPackageTypeDeclarations(Formatter& out) const;
268 
269     // Emit any declarations pertaining to this type that have to be
270     // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel
271     // For android.hardware.foo@1.0::*, this will be in namespace
272     // android::hardware::foo::V1_0
273     virtual void emitPackageHwDeclarations(Formatter& out) const;
274 
275     virtual void emitTypeDefinitions(Formatter& out, const std::string& prefix) const;
276 
277     virtual void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const;
278 
279     virtual bool needsEmbeddedReadWrite() const;
280     virtual bool resultNeedsDeref() const;
281 
282     bool needsResolveReferences() const;
283     bool needsResolveReferences(std::unordered_set<const Type*>* visited) const;
284     virtual bool deepNeedsResolveReferences(std::unordered_set<const Type*>* visited) const;
285 
286     // Generates type declaration for vts proto file.
287     // TODO (b/30844146): make it a pure virtual method.
288     virtual void emitVtsTypeDeclarations(Formatter& out) const;
289     // Generates type declaration as attribute of method (return value or method
290     // argument) or attribute of compound type for vts proto file.
291     virtual void emitVtsAttributeType(Formatter& out) const;
292 
293     // Returns true iff this type is supported through the Java backend.
294     bool isJavaCompatible() const;
295     bool isJavaCompatible(std::unordered_set<const Type*>* visited) const;
296     virtual bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const;
297     // Returns true iff type contains pointer
298     // (excluding methods and inner types).
299     bool containsPointer() const;
300     bool containsPointer(std::unordered_set<const Type*>* visited) const;
301     virtual bool deepContainsPointer(std::unordered_set<const Type*>* visited) const;
302 
303     virtual void getAlignmentAndSize(size_t *align, size_t *size) const;
304 
305     virtual void appendToExportedTypesVector(
306             std::vector<const Type *> *exportedTypes) const;
307 
308     virtual void emitExportedHeader(Formatter& out, bool forJava) const;
309 
310     virtual bool isNeverStrongReference() const;
311 
312    protected:
313     void handleError(Formatter &out, ErrorMode mode) const;
314 
315     void emitReaderWriterEmbeddedForTypeName(
316             Formatter &out,
317             const std::string &name,
318             bool nameIsPointer,
319             const std::string &parcelObj,
320             bool parcelObjIsPointer,
321             bool isReader,
322             ErrorMode mode,
323             const std::string &parentName,
324             const std::string &offsetText,
325             const std::string &typeName,
326             const std::string &childName,
327             const std::string &funcNamespace) const;
328 
329     void emitJavaReaderWriterWithSuffix(
330             Formatter &out,
331             const std::string &parcelObj,
332             const std::string &argName,
333             bool isReader,
334             const std::string &suffix,
335             const std::string &extra) const;
336 
337     void emitDumpWithMethod(
338             Formatter &out,
339             const std::string &streamName,
340             const std::string &methodName,
341             const std::string &name) const;
342 
343    private:
344     bool mIsPostParseCompleted = false;
345     Scope* const mParent;
346 
347     DISALLOW_COPY_AND_ASSIGN(Type);
348 };
349 
350 /* Base type for VectorType and RefType. */
351 struct TemplatedType : public Type {
352     void setElementType(const Reference<Type>& elementType);
353     const Type* getElementType() const;
354 
355     virtual std::string templatedTypeName() const = 0;
356     std::string typeName() const override;
357 
358     bool isTemplatedType() const override;
359 
360     virtual bool isCompatibleElementType(const Type* elementType) const = 0;
361 
362     std::vector<const Reference<Type>*> getReferences() const override;
363 
364     virtual status_t validate() const override;
365 
366     void emitVtsTypeDeclarations(Formatter& out) const override;
367     void emitVtsAttributeType(Formatter& out) const override;
368 
369    protected:
370     TemplatedType(Scope* parent);
371     Reference<Type> mElementType;
372 
373    private:
374     DISALLOW_COPY_AND_ASSIGN(TemplatedType);
375 };
376 
377 }  // namespace android
378 
379 #endif  // TYPE_H_
380 
381