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 COMPOUND_TYPE_H_
18 
19 #define COMPOUND_TYPE_H_
20 
21 #include "Reference.h"
22 #include "Scope.h"
23 
24 #include <string>
25 #include <vector>
26 
27 namespace android {
28 
29 struct CompoundType : public Scope {
30     enum Style {
31         STYLE_STRUCT,
32         STYLE_UNION,
33         STYLE_SAFE_UNION,
34     };
35 
36     CompoundType(Style style, const std::string& localName, const FQName& fullName,
37                  const Location& location, Scope* parent);
38 
39     Style style() const;
40 
41     std::vector<const NamedReference<Type>*> getFields() const;
42     void addField(NamedReference<Type>* field);
43 
44     bool isCompoundType() const override;
45 
46     bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const override;
47 
48     std::string typeName() const override;
49 
50     std::vector<const Reference<Type>*> getReferences() const override;
51 
52     status_t validate() const override;
53     status_t validateUniqueNames() const;
54     status_t validateSubTypeNames() const;
55 
56     std::string getCppType(StorageMode mode,
57                            bool specifyNamespaces) const override;
58 
59     std::string getJavaType(bool forInitializer) const override;
60 
61     std::string getVtsType() const override;
62 
63     void emitReaderWriter(
64             Formatter &out,
65             const std::string &name,
66             const std::string &parcelObj,
67             bool parcelObjIsPointer,
68             bool isReader,
69             ErrorMode mode) const override;
70 
71     void emitReaderWriterEmbedded(
72             Formatter &out,
73             size_t depth,
74             const std::string &name,
75             const std::string &sanitizedName,
76             bool nameIsPointer,
77             const std::string &parcelObj,
78             bool parcelObjIsPointer,
79             bool isReader,
80             ErrorMode mode,
81             const std::string &parentName,
82             const std::string &offsetText) const override;
83 
84     void emitJavaReaderWriter(
85             Formatter &out,
86             const std::string &parcelObj,
87             const std::string &argName,
88             bool isReader) const override;
89 
90     void emitJavaFieldInitializer(
91             Formatter &out, const std::string &fieldName) const override;
92 
93     void emitJavaFieldDefaultInitialValue(
94             Formatter &out, const std::string &declaredFieldName) const override;
95 
96     void emitJavaFieldReaderWriter(
97             Formatter &out,
98             size_t depth,
99             const std::string &parcelName,
100             const std::string &blobName,
101             const std::string &fieldName,
102             const std::string &offset,
103             bool isReader) const override;
104 
105     void emitHidlDefinition(Formatter& out) const override;
106     void emitTypeDeclarations(Formatter& out) const override;
107     void emitTypeForwardDeclaration(Formatter& out) const override;
108     void emitPackageTypeDeclarations(Formatter& out) const override;
109     void emitPackageTypeHeaderDefinitions(Formatter& out) const override;
110     void emitPackageHwDeclarations(Formatter& out) const override;
111 
112     void emitTypeDefinitions(Formatter& out, const std::string& prefix) const override;
113 
114     void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const override;
115 
116     bool needsEmbeddedReadWrite() const override;
117     bool resultNeedsDeref() const override;
118 
119     void emitVtsTypeDeclarations(Formatter& out) const override;
120     void emitVtsAttributeType(Formatter& out) const override;
121 
122     bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const override;
123     bool deepContainsPointer(std::unordered_set<const Type*>* visited) const override;
124 
125     void getAlignmentAndSize(size_t *align, size_t *size) const override;
126 
127     bool containsInterface() const;
128 private:
129 
130     struct Layout {
131         size_t offset;
132         size_t align;
133         size_t size;
134 
LayoutCompoundType::Layout135         Layout() : offset(0), align(1), size(0) {}
136         static size_t getPad(size_t offset, size_t align);
137     };
138 
139     struct CompoundLayout {
140         // Layout of this entire object including metadata.
141         // For struct/union, this is the same as innerStruct.
142         Layout overall;
143         // Layout of user-specified data
144         Layout innerStruct;
145         // Layout of discriminator for safe union (otherwise zero)
146         Layout discriminator;
147     };
148 
149     Style mStyle;
150     std::vector<NamedReference<Type>*> mFields;
151 
152     // only emits the struct body. doesn't emit the last ";\n" from the definition
153     void emitInlineHidlDefinition(Formatter& out) const;
154     // emits the hidl definition line for a field inside the struct. used by emitHidlDefinition
155     void emitFieldHidlDefinition(Formatter& out, const NamedReference<Type>& ref) const;
156 
157     void emitLayoutAsserts(Formatter& out, const Layout& localLayout,
158                            const std::string& localLayoutName) const;
159 
160     void emitInvalidSubTypeNamesError(const std::string& subTypeName,
161                                       const Location& location) const;
162 
163     void emitSafeUnionTypeDefinitions(Formatter& out) const;
164     void emitSafeUnionTypeConstructors(Formatter& out) const;
165     void emitSafeUnionTypeDeclarations(Formatter& out) const;
166     std::unique_ptr<ScalarType> getUnionDiscriminatorType() const;
167 
168     void emitSafeUnionUnknownDiscriminatorError(Formatter& out, const std::string& value,
169                                                 bool fatal) const;
170 
171     void emitSafeUnionCopyAndAssignDefinition(Formatter& out,
172                                               const std::string& parameterName,
173                                               bool isCopyConstructor,
174                                               bool usesMoveSemantics) const;
175 
176     CompoundLayout getCompoundAlignmentAndSize() const;
177     void emitPaddingZero(Formatter& out, size_t offset, size_t size) const;
178 
179     void emitSafeUnionReaderWriterForInterfaces(
180             Formatter &out,
181             const std::string &name,
182             const std::string &parcelObj,
183             bool parcelObjIsPointer,
184             bool isReader,
185             ErrorMode mode) const;
186 
187     void emitStructReaderWriter(
188             Formatter &out, const std::string &prefix, bool isReader) const;
189 
190     DISALLOW_COPY_AND_ASSIGN(CompoundType);
191 };
192 
193 }  // namespace android
194 
195 #endif  // COMPOUND_TYPE_H_
196 
197