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, const std::string& definedName);
42     virtual ~Type();
43 
44     virtual bool isArray() const;
45     virtual bool isBitField() const;
46     virtual bool isCompoundType() const;
47     virtual bool isEnum() const;
48     virtual bool isHandle() const;
49     virtual bool isInterface() const;
50     virtual bool isNamedType() const;
51     virtual bool isMemory() const;
52     virtual bool isPointer() const;
53     virtual bool isScope() const;
54     virtual bool isScalar() const;
55     virtual bool isString() const;
56     virtual bool isTemplatedType() const;
57     virtual bool isTypeDef() const;
58     virtual bool isVector() const;
59     virtual bool isFmq() 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     // Indicate stage of parsing.
83     enum class ParseStage {
84         // Indicate that the source file is being parsed and this object is being filled.
85         PARSE,
86         // Indicate that all source files are parsed, and program is working on type dependencies
87         // and validation.
88         POST_PARSE,
89         // Indicate that parsing is completed, and program is in code-generation stage.
90         COMPLETED,
91     };
92 
93     // Proceeds recursive pass
94     // Makes sure to visit each node only once.
95     // If mParseStage < stage, object is not ready for this recursivePass() call
96     // yet, and function will return error.
97     status_t recursivePass(ParseStage stage, const std::function<status_t(Type*)>& func,
98                            std::unordered_set<const Type*>* visited);
99     status_t recursivePass(ParseStage stage, const std::function<status_t(const Type*)>& func,
100                            std::unordered_set<const Type*>* visited) const;
101 
102     // Recursive tree pass that completes type declarations
103     // that depend on super types
104     virtual status_t resolveInheritance();
105 
106     // Recursive tree pass that validates all type-related
107     // syntax restrictions
108     virtual status_t validate() const;
109 
110     // Recursive tree pass checkAcyclic return type.
111     // Stores cycle end for nice error messages.
112     struct CheckAcyclicStatus {
113         CheckAcyclicStatus(status_t status, const Type* cycleEnd = nullptr);
114 
115         status_t status;
116 
117         // If a cycle is found, stores the end of cycle.
118         // While going back in recursion, this is used to stop printing the cycle.
119         const Type* cycleEnd;
120     };
121 
122     // Recursive tree pass that ensures that type definitions and references
123     // are acyclic and builds reversed topological order of the types.
124     // If some cases allow using of incomplete types, these cases are to be
125     // declared in Type::getStrongReferences.
126     CheckAcyclicStatus topologicalOrder(std::unordered_map<const Type*, size_t>* reversedOrder,
127                                         std::unordered_set<const Type*>* stack) const;
128 
129     // Checks following C++ restriction on forward declaration:
130     // inner struct could be forward declared only inside its parent.
131     status_t checkForwardReferenceRestrictions(const Reference<Type>& ref) const;
132 
133     virtual const ScalarType *resolveToScalarType() const;
134 
135     virtual std::string typeName() const = 0;
136 
137     bool isValidEnumStorageType() const;
138     virtual bool isElidableType() const;
139 
140     virtual bool canCheckEquality() const;
141     bool canCheckEquality(std::unordered_set<const Type*>* visited) const;
142     virtual bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const;
143 
144     // ParseStage can only be incremented.
145     ParseStage getParseStage() const;
146     void setParseStage(ParseStage stage);
147 
148     Scope* parent();
149     const Scope* parent() const;
150 
151     const std::string& definedName() const;
152 
153     enum StorageMode {
154         StorageMode_Stack,
155         StorageMode_Argument,
156         StorageMode_Result,
157     };
158 
159     // specifyNamespaces: whether to specify namespaces for built-in types
160     virtual std::string getCppType(
161             StorageMode mode,
162             bool specifyNamespaces) const;
163 
164     std::string decorateCppName(
165             const std::string &name,
166             StorageMode mode,
167             bool specifyNamespaces) const;
168 
169     std::string getCppStackType(bool specifyNamespaces = true) const;
170 
171     std::string getCppResultType(bool specifyNamespaces = true) const;
172 
173     std::string getCppArgumentType(bool specifyNamespaces = true) const;
174 
175     std::string getCppTypeCast(const std::string& objName,
176                                bool specifyNamespaces = true) const;
177 
178     // For an array type, dimensionality information will be accumulated at the
179     // end of the returned string.
180     // if forInitializer == true, actual dimensions are included, i.e. [3][5],
181     // otherwise (and by default), they are omitted, i.e. [][].
182     virtual std::string getJavaType(bool forInitializer = false) const;
183 
184     // Identical to getJavaType() for most types, except: primitives, in which
185     // case the wrapper type is returned, and generics (such as ArrayList<?>),
186     // where the type specialization is omitted to facilitate use of
187     // instanceof or class.isInstance().
188     virtual std::string getJavaTypeClass() const;
189 
190     virtual std::string getJavaTypeCast(const std::string& objName) const;
191     virtual std::string getJavaSuffix() const;
192 
193     virtual std::string getVtsType() const;
194     virtual std::string getVtsValueName() const;
195 
196     enum ErrorMode {
197         ErrorMode_Goto,
198         ErrorMode_Break,
199         ErrorMode_Return,
200         ErrorMode_ReturnNothing,
201     };
202     virtual void emitReaderWriter(
203             Formatter &out,
204             const std::string &name,
205             const std::string &parcelObj,
206             bool parcelObjIsPointer,
207             bool isReader,
208             ErrorMode mode) const;
209 
210     virtual void emitReaderWriterEmbedded(
211             Formatter &out,
212             size_t depth,
213             const std::string &name,
214             const std::string &sanitizedName,
215             bool nameIsPointer,
216             const std::string &parcelObj,
217             bool parcelObjIsPointer,
218             bool isReader,
219             ErrorMode mode,
220             const std::string &parentName,
221             const std::string &offsetText) const;
222 
223     virtual void emitDump(
224             Formatter &out,
225             const std::string &streamName,
226             const std::string &name) const;
227 
228     virtual void emitJavaDump(
229             Formatter &out,
230             const std::string &streamName,
231             const std::string &name) const;
232 
233     virtual void emitJavaReaderWriter(
234             Formatter &out,
235             const std::string &parcelObj,
236             const std::string &argName,
237             bool isReader) const;
238 
239     virtual void emitJavaFieldInitializer(
240             Formatter &out,
241             const std::string &fieldName) const;
242 
243     virtual void emitJavaFieldDefaultInitialValue(
244             Formatter &out,
245             const std::string &declaredFieldName) const;
246 
247     virtual void emitJavaFieldReaderWriter(
248             Formatter &out,
249             size_t depth,
250             const std::string &parcelName,
251             const std::string &blobName,
252             const std::string &fieldName,
253             const std::string &offset,
254             bool isReader) const;
255 
256     virtual void emitHidlDefinition(Formatter& out) const;
257 
258     virtual void emitTypeDeclarations(Formatter& out) const;
259 
260     virtual void emitGlobalTypeDeclarations(Formatter& out) const;
261 
262     // Emit scope C++ forward declaration.
263     // There is no need to forward declare interfaces, as
264     // they are always declared in global scope in dedicated file.
265     virtual void emitTypeForwardDeclaration(Formatter& out) const;
266 
267     // Emit any declarations pertaining to this type that have to be
268     // directly in a namespace, i.e. enum class operators.
269     // For android.hardware.foo@1.0::*, this will be in namespace
270     // android::hardware::foo::V1_0
271     virtual void emitPackageTypeDeclarations(Formatter& out) const;
272 
273     // Emit any definitions pertaining to this type that have to be
274     // directly in a namespace. Typically, these are things that are only
275     // used for a small subset of types, so by putting them in the header,
276     // the space cost is moved to the small number of clients that use the
277     // feature.
278     // For android.hardware.foo@1.0::*, this will be in namespace
279     // android::hardware::foo::V1_0
280     virtual void emitPackageTypeHeaderDefinitions(Formatter& out) const;
281 
282     // Emit any declarations pertaining to this type that have to be
283     // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel
284     // For android.hardware.foo@1.0::*, this will be in namespace
285     // android::hardware::foo::V1_0
286     virtual void emitPackageHwDeclarations(Formatter& out) const;
287 
288     virtual void emitTypeDefinitions(Formatter& out, const std::string& prefix) const;
289 
290     virtual void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const;
291 
292     virtual bool needsEmbeddedReadWrite() const;
293     virtual bool resultNeedsDeref() const;
294 
295     // Generates type declaration for vts proto file.
296     // TODO (b/30844146): make it a pure virtual method.
297     virtual void emitVtsTypeDeclarations(Formatter& out) const;
298     // Generates type declaration as attribute of method (return value or method
299     // argument) or attribute of compound type for vts proto file.
300     virtual void emitVtsAttributeType(Formatter& out) const;
301 
302     // Returns true iff this type is supported through the Java backend.
303     bool isJavaCompatible() const;
304     bool isJavaCompatible(std::unordered_set<const Type*>* visited) const;
305     virtual bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const;
306     // Returns true iff type contains pointer
307     // (excluding methods and inner types).
308     bool containsPointer() const;
309     bool containsPointer(std::unordered_set<const Type*>* visited) const;
310     virtual bool deepContainsPointer(std::unordered_set<const Type*>* visited) const;
311 
312     virtual void getAlignmentAndSize(size_t *align, size_t *size) const;
313 
314     virtual void appendToExportedTypesVector(
315             std::vector<const Type *> *exportedTypes) const;
316 
317     virtual void emitExportedHeader(Formatter& out, bool forJava) const;
318 
319     virtual bool isNeverStrongReference() const;
320 
321     static void handleError(Formatter &out, ErrorMode mode);
322    protected:
323     void emitReaderWriterEmbeddedForTypeName(
324             Formatter &out,
325             const std::string &name,
326             bool nameIsPointer,
327             const std::string &parcelObj,
328             bool parcelObjIsPointer,
329             bool isReader,
330             ErrorMode mode,
331             const std::string &parentName,
332             const std::string &offsetText,
333             const std::string &typeName,
334             const std::string &childName,
335             const std::string &funcNamespace) const;
336 
337     void emitJavaReaderWriterWithSuffix(
338             Formatter &out,
339             const std::string &parcelObj,
340             const std::string &argName,
341             bool isReader,
342             const std::string &suffix,
343             const std::string &extra) const;
344 
345     void emitDumpWithMethod(
346             Formatter &out,
347             const std::string &streamName,
348             const std::string &methodName,
349             const std::string &name) const;
350 
351     // This is the name given to the type in the hidl file
352     std::string mDefinedName;
353 
354   private:
355     ParseStage mParseStage = ParseStage::PARSE;
356     Scope* const mParent;
357 
358     DISALLOW_COPY_AND_ASSIGN(Type);
359 };
360 
361 struct TemplatedType : public Type {
362     void setElementType(const Reference<Type>& elementType);
363     const Type* getElementType() const;
364 
365     virtual std::string templatedTypeName() const = 0;
366     std::string typeName() const override;
367 
368     bool isTemplatedType() const override;
369 
370     virtual bool isCompatibleElementType(const Type* elementType) const = 0;
371 
372     std::vector<const Reference<Type>*> getReferences() const override;
373 
374     virtual status_t validate() const override;
375 
376     void emitVtsTypeDeclarations(Formatter& out) const override;
377     void emitVtsAttributeType(Formatter& out) const override;
378 
379    protected:
380      TemplatedType(Scope* parent, const std::string& definedName);
381      Reference<Type> mElementType;
382 
383    private:
384     DISALLOW_COPY_AND_ASSIGN(TemplatedType);
385 };
386 
387 }  // namespace android
388 
389 #endif  // TYPE_H_
390 
391