Type.cpp revision 9df5244c1dd4508cc2e25f8a04d363903912d19c
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#include "Type.h"
18
19#include "Annotation.h"
20#include "ScalarType.h"
21
22#include <hidl-util/Formatter.h>
23#include <android-base/logging.h>
24
25namespace android {
26
27Type::Type()
28    : mAnnotations(nullptr) {
29}
30
31Type::~Type() {}
32
33void Type::setAnnotations(std::vector<Annotation *> *annotations) {
34    mAnnotations = annotations;
35}
36
37const std::vector<Annotation *> &Type::annotations() const {
38    return *mAnnotations;
39}
40
41bool Type::isScope() const {
42    return false;
43}
44
45bool Type::isInterface() const {
46    return false;
47}
48
49bool Type::isScalar() const {
50    return false;
51}
52
53bool Type::isString() const {
54    return false;
55}
56
57bool Type::isEnum() const {
58    return false;
59}
60
61bool Type::isBitField() const {
62    return false;
63}
64
65bool Type::isHandle() const {
66    return false;
67}
68
69bool Type::isTypeDef() const {
70    return false;
71}
72
73bool Type::isBinder() const {
74    return false;
75}
76
77bool Type::isNamedType() const {
78    return false;
79}
80
81bool Type::isCompoundType() const {
82    return false;
83}
84
85bool Type::isArray() const {
86    return false;
87}
88
89bool Type::isVector() const {
90    return false;
91}
92
93bool Type::isTemplatedType() const {
94    return false;
95}
96
97bool Type::isPointer() const {
98    return false;
99}
100
101std::string Type::typeName() const {
102    return "";
103}
104
105const ScalarType *Type::resolveToScalarType() const {
106    return NULL;
107}
108
109bool Type::isValidEnumStorageType() const {
110    const ScalarType *scalarType = resolveToScalarType();
111
112    if (scalarType == NULL) {
113        return false;
114    }
115
116    return scalarType->isValidEnumStorageType();
117}
118
119bool Type::isElidableType() const {
120    return false;
121}
122
123std::string Type::getCppType(StorageMode, bool) const {
124    CHECK(!"Should not be here");
125    return std::string();
126}
127
128std::string Type::decorateCppName(
129        const std::string &name, StorageMode mode, bool specifyNamespaces) const {
130    return getCppType(mode, specifyNamespaces) + " " + name;
131}
132
133std::string Type::getJavaType(bool /* forInitializer */) const {
134    CHECK(!"Should not be here");
135    return std::string();
136}
137
138std::string Type::getJavaWrapperType() const {
139    return getJavaType();
140}
141
142std::string Type::getJavaSuffix() const {
143    CHECK(!"Should not be here");
144    return std::string();
145}
146
147std::string Type::getVtsType() const {
148    CHECK(!"Should not be here");
149    return std::string();
150}
151
152void Type::emitReaderWriter(
153        Formatter &,
154        const std::string &,
155        const std::string &,
156        bool,
157        bool,
158        ErrorMode) const {
159    CHECK(!"Should not be here");
160}
161
162void Type::emitResolveReferences(
163        Formatter &,
164        const std::string &,
165        bool,
166        const std::string &,
167        bool,
168        bool,
169        ErrorMode) const {
170    CHECK(!"Should not be here");
171}
172
173void Type::emitResolveReferencesEmbedded(
174        Formatter &,
175        size_t,
176        const std::string &,
177        const std::string &,
178        bool,
179        const std::string &,
180        bool,
181        bool,
182        ErrorMode,
183        const std::string &,
184        const std::string &) const {
185    CHECK(!"Should not be here");
186}
187
188bool Type::useParentInEmitResolveReferencesEmbedded() const {
189    return needsResolveReferences();
190}
191
192bool Type::useNameInEmitReaderWriterEmbedded(bool) const {
193    return needsEmbeddedReadWrite();
194}
195
196void Type::emitReaderWriterEmbedded(
197        Formatter &,
198        size_t,
199        const std::string &,
200        const std::string &,
201        bool,
202        const std::string &,
203        bool,
204        bool,
205        ErrorMode,
206        const std::string &,
207        const std::string &) const {
208    CHECK(!"Should not be here");
209}
210
211void Type::emitJavaReaderWriter(
212        Formatter &out,
213        const std::string &parcelObj,
214        const std::string &argName,
215        bool isReader) const {
216    emitJavaReaderWriterWithSuffix(
217            out,
218            parcelObj,
219            argName,
220            isReader,
221            getJavaSuffix(),
222            "" /* extra */);
223}
224
225void Type::emitJavaFieldInitializer(
226        Formatter &out,
227        const std::string &fieldName) const {
228    out << getJavaType()
229        << " "
230        << fieldName
231        << ";\n";
232}
233
234void Type::emitJavaFieldReaderWriter(
235        Formatter &,
236        size_t,
237        const std::string &,
238        const std::string &,
239        const std::string &,
240        const std::string &,
241        bool) const {
242    CHECK(!"Should not be here");
243}
244
245void Type::handleError(Formatter &out, ErrorMode mode) const {
246    switch (mode) {
247        case ErrorMode_Ignore:
248        {
249            out << "/* _hidl_err ignored! */\n\n";
250            break;
251        }
252
253        case ErrorMode_Goto:
254        {
255            out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
256            break;
257        }
258
259        case ErrorMode_Break:
260        {
261            out << "if (_hidl_err != ::android::OK) { break; }\n\n";
262            break;
263        }
264
265        case ErrorMode_Return:
266        {
267            out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n\n";
268            break;
269        }
270    }
271}
272
273void Type::handleError2(Formatter &out, ErrorMode mode) const {
274    switch (mode) {
275        case ErrorMode_Goto:
276        {
277            out << "goto _hidl_error;\n";
278            break;
279        }
280
281        case ErrorMode_Break:
282        {
283            out << "break;\n";
284            break;
285        }
286
287        case ErrorMode_Ignore:
288        {
289            out << "/* ignoring _hidl_error! */";
290            break;
291        }
292
293        case ErrorMode_Return:
294        {
295            out << "return _hidl_err;\n";
296            break;
297        }
298    }
299}
300
301void Type::emitReaderWriterEmbeddedForTypeName(
302        Formatter &out,
303        const std::string &name,
304        bool nameIsPointer,
305        const std::string &parcelObj,
306        bool parcelObjIsPointer,
307        bool isReader,
308        ErrorMode mode,
309        const std::string &parentName,
310        const std::string &offsetText,
311        const std::string &typeName,
312        const std::string &childName,
313        const std::string &funcNamespace) const {
314
315        const std::string parcelObjDeref =
316        parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;
317
318    const std::string parcelObjPointer =
319        parcelObjIsPointer ? parcelObj : ("&" + parcelObj);
320
321    const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
322    const std::string namePointer = nameIsPointer ? name : ("&" + name);
323
324    out << "_hidl_err = ";
325
326    if (!funcNamespace.empty()) {
327        out << funcNamespace << "::";
328    }
329
330    out << (isReader ? "readEmbeddedFromParcel(\n" : "writeEmbeddedToParcel(\n");
331
332    out.indent();
333    out.indent();
334
335    if (isReader) {
336        out << "const_cast<"
337            << typeName
338            << " *>("
339            << namePointer
340            << "),\n";
341    } else {
342        out << nameDerefed
343            << ",\n";
344    }
345
346    out << (isReader ? parcelObjDeref : parcelObjPointer)
347        << ",\n"
348        << parentName
349        << ",\n"
350        << offsetText;
351
352    if (!childName.empty()) {
353        out << ", &"
354            << childName;
355    }
356
357    out << ");\n\n";
358
359    out.unindent();
360    out.unindent();
361
362    handleError(out, mode);
363}
364
365status_t Type::emitTypeDeclarations(Formatter &) const {
366    return OK;
367}
368
369status_t Type::emitGlobalTypeDeclarations(Formatter &) const {
370    return OK;
371}
372
373status_t Type::emitGlobalHwDeclarations(Formatter &) const {
374    return OK;
375}
376
377status_t Type::emitTypeDefinitions(
378        Formatter &, const std::string) const {
379    return OK;
380}
381
382status_t Type::emitJavaTypeDeclarations(Formatter &, bool) const {
383    return OK;
384}
385
386bool Type::needsEmbeddedReadWrite() const {
387    return false;
388}
389
390bool Type::needsResolveReferences() const {
391    return false;
392}
393
394bool Type::resultNeedsDeref() const {
395    return false;
396}
397
398std::string Type::getCppStackType(bool specifyNamespaces) const {
399    return getCppType(StorageMode_Stack, specifyNamespaces);
400}
401
402std::string Type::getCppResultType(bool specifyNamespaces) const {
403    return getCppType(StorageMode_Result, specifyNamespaces);
404}
405
406std::string Type::getCppArgumentType(bool specifyNamespaces) const {
407    return getCppType(StorageMode_Argument, specifyNamespaces);
408}
409
410void Type::emitJavaReaderWriterWithSuffix(
411        Formatter &out,
412        const std::string &parcelObj,
413        const std::string &argName,
414        bool isReader,
415        const std::string &suffix,
416        const std::string &extra) const {
417    out << parcelObj
418        << "."
419        << (isReader ? "read" : "write")
420        << suffix
421        << "(";
422
423    if (isReader) {
424        out << extra;
425    } else {
426        out << (extra.empty() ? "" : (extra + ", "));
427        out << argName;
428    }
429
430    out << ");\n";
431}
432
433status_t Type::emitVtsTypeDeclarations(Formatter &) const {
434    return OK;
435}
436
437status_t Type::emitVtsAttributeType(Formatter &out) const {
438    return emitVtsTypeDeclarations(out);
439}
440
441bool Type::isJavaCompatible() const {
442    return true;
443}
444
445void Type::getAlignmentAndSize(size_t *, size_t *) const {
446    CHECK(!"Should not be here");
447}
448
449void Type::appendToExportedTypesVector(
450        std::vector<const Type *> * /* exportedTypes */) const {
451}
452
453status_t Type::emitExportedHeader(
454        Formatter & /* out */, bool /* forJava */) const {
455    return OK;
456}
457
458////////////////////////////////////////
459
460TemplatedType::TemplatedType() : mElementType(nullptr) {
461}
462
463void TemplatedType::setElementType(Type *elementType) {
464    CHECK(mElementType == nullptr); // can only be set once.
465    CHECK(isCompatibleElementType(elementType));
466    mElementType = elementType;
467}
468
469Type *TemplatedType::getElementType() const {
470    return mElementType;
471}
472
473bool TemplatedType::isTemplatedType() const {
474    return true;
475}
476
477}  // namespace android
478
479