Type.cpp revision abf73eef7f23f0b0ba0fe85694dcd511f4e69962
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
119std::string Type::getCppType(StorageMode, bool) const {
120    CHECK(!"Should not be here");
121    return std::string();
122}
123
124std::string Type::decorateCppName(
125        const std::string &name, StorageMode mode, bool specifyNamespaces) const {
126    return getCppType(mode, specifyNamespaces) + " " + name;
127}
128
129std::string Type::getJavaType(bool /* forInitializer */) const {
130    CHECK(!"Should not be here");
131    return std::string();
132}
133
134std::string Type::getJavaWrapperType() const {
135    return getJavaType();
136}
137
138std::string Type::getJavaSuffix() const {
139    CHECK(!"Should not be here");
140    return std::string();
141}
142
143std::string Type::getVtsType() const {
144    CHECK(!"Should not be here");
145    return std::string();
146}
147
148void Type::emitReaderWriter(
149        Formatter &,
150        const std::string &,
151        const std::string &,
152        bool,
153        bool,
154        ErrorMode) const {
155    CHECK(!"Should not be here");
156}
157
158void Type::emitResolveReferences(
159        Formatter &,
160        const std::string &,
161        bool,
162        const std::string &,
163        bool,
164        bool,
165        ErrorMode) const {
166    CHECK(!"Should not be here");
167}
168
169void Type::emitResolveReferencesEmbedded(
170        Formatter &,
171        size_t,
172        const std::string &,
173        const std::string &,
174        bool,
175        const std::string &,
176        bool,
177        bool,
178        ErrorMode,
179        const std::string &,
180        const std::string &) const {
181    CHECK(!"Should not be here");
182}
183
184bool Type::useParentInEmitResolveReferencesEmbedded() const {
185    return needsResolveReferences();
186}
187
188bool Type::useNameInEmitReaderWriterEmbedded(bool) const {
189    return needsEmbeddedReadWrite();
190}
191
192void Type::emitReaderWriterEmbedded(
193        Formatter &,
194        size_t,
195        const std::string &,
196        const std::string &,
197        bool,
198        const std::string &,
199        bool,
200        bool,
201        ErrorMode,
202        const std::string &,
203        const std::string &) const {
204    CHECK(!"Should not be here");
205}
206
207void Type::emitJavaReaderWriter(
208        Formatter &out,
209        const std::string &parcelObj,
210        const std::string &argName,
211        bool isReader) const {
212    emitJavaReaderWriterWithSuffix(
213            out,
214            parcelObj,
215            argName,
216            isReader,
217            getJavaSuffix(),
218            "" /* extra */);
219}
220
221void Type::emitJavaFieldInitializer(
222        Formatter &out,
223        const std::string &fieldName) const {
224    out << getJavaType()
225        << " "
226        << fieldName
227        << ";\n";
228}
229
230void Type::emitJavaFieldReaderWriter(
231        Formatter &,
232        size_t,
233        const std::string &,
234        const std::string &,
235        const std::string &,
236        const std::string &,
237        bool) const {
238    CHECK(!"Should not be here");
239}
240
241void Type::handleError(Formatter &out, ErrorMode mode) const {
242    switch (mode) {
243        case ErrorMode_Ignore:
244        {
245            out << "/* _hidl_err ignored! */\n\n";
246            break;
247        }
248
249        case ErrorMode_Goto:
250        {
251            out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
252            break;
253        }
254
255        case ErrorMode_Break:
256        {
257            out << "if (_hidl_err != ::android::OK) { break; }\n\n";
258            break;
259        }
260
261        case ErrorMode_Return:
262        {
263            out << "if (_hidl_err != ::android::OK) { return _hidl_err; }\n\n";
264            break;
265        }
266    }
267}
268
269void Type::handleError2(Formatter &out, ErrorMode mode) const {
270    switch (mode) {
271        case ErrorMode_Goto:
272        {
273            out << "goto _hidl_error;\n";
274            break;
275        }
276
277        case ErrorMode_Break:
278        {
279            out << "break;\n";
280            break;
281        }
282
283        case ErrorMode_Ignore:
284        {
285            out << "/* ignoring _hidl_error! */";
286            break;
287        }
288
289        case ErrorMode_Return:
290        {
291            out << "return _hidl_err;\n";
292            break;
293        }
294    }
295}
296
297void Type::emitReaderWriterEmbeddedForTypeName(
298        Formatter &out,
299        const std::string &name,
300        bool nameIsPointer,
301        const std::string &parcelObj,
302        bool parcelObjIsPointer,
303        bool isReader,
304        ErrorMode mode,
305        const std::string &parentName,
306        const std::string &offsetText,
307        const std::string &typeName,
308        const std::string &childName,
309        const std::string &funcNamespace) const {
310
311        const std::string parcelObjDeref =
312        parcelObjIsPointer ? ("*" + parcelObj) : parcelObj;
313
314    const std::string parcelObjPointer =
315        parcelObjIsPointer ? parcelObj : ("&" + parcelObj);
316
317    const std::string nameDerefed = nameIsPointer ? ("*" + name) : name;
318    const std::string namePointer = nameIsPointer ? name : ("&" + name);
319
320    out << "_hidl_err = ";
321
322    if (!funcNamespace.empty()) {
323        out << funcNamespace << "::";
324    }
325
326    out << (isReader ? "readEmbeddedFromParcel(\n" : "writeEmbeddedToParcel(\n");
327
328    out.indent();
329    out.indent();
330
331    if (isReader) {
332        out << "const_cast<"
333            << typeName
334            << " *>("
335            << namePointer
336            << "),\n";
337    } else {
338        out << nameDerefed
339            << ",\n";
340    }
341
342    out << (isReader ? parcelObjDeref : parcelObjPointer)
343        << ",\n"
344        << parentName
345        << ",\n"
346        << offsetText;
347
348    if (!childName.empty()) {
349        out << ", &"
350            << childName;
351    }
352
353    out << ");\n\n";
354
355    out.unindent();
356    out.unindent();
357
358    handleError(out, mode);
359}
360
361status_t Type::emitTypeDeclarations(Formatter &) const {
362    return OK;
363}
364
365status_t Type::emitGlobalTypeDeclarations(Formatter &) const {
366    return OK;
367}
368
369status_t Type::emitGlobalHwDeclarations(Formatter &) const {
370    return OK;
371}
372
373status_t Type::emitTypeDefinitions(
374        Formatter &, const std::string) const {
375    return OK;
376}
377
378status_t Type::emitJavaTypeDeclarations(Formatter &, bool) const {
379    return OK;
380}
381
382bool Type::needsEmbeddedReadWrite() const {
383    return false;
384}
385
386bool Type::needsResolveReferences() const {
387    return false;
388}
389
390bool Type::resultNeedsDeref() const {
391    return false;
392}
393
394std::string Type::getCppStackType(bool specifyNamespaces) const {
395    return getCppType(StorageMode_Stack, specifyNamespaces);
396}
397
398std::string Type::getCppResultType(bool specifyNamespaces) const {
399    return getCppType(StorageMode_Result, specifyNamespaces);
400}
401
402std::string Type::getCppArgumentType(bool specifyNamespaces) const {
403    return getCppType(StorageMode_Argument, specifyNamespaces);
404}
405
406void Type::emitJavaReaderWriterWithSuffix(
407        Formatter &out,
408        const std::string &parcelObj,
409        const std::string &argName,
410        bool isReader,
411        const std::string &suffix,
412        const std::string &extra) const {
413    out << parcelObj
414        << "."
415        << (isReader ? "read" : "write")
416        << suffix
417        << "(";
418
419    if (isReader) {
420        out << extra;
421    } else {
422        out << (extra.empty() ? "" : (extra + ", "));
423        out << argName;
424    }
425
426    out << ");\n";
427}
428
429status_t Type::emitVtsTypeDeclarations(Formatter &) const {
430    return OK;
431}
432
433status_t Type::emitVtsAttributeType(Formatter &out) const {
434    return emitVtsTypeDeclarations(out);
435}
436
437bool Type::isJavaCompatible() const {
438    return true;
439}
440
441void Type::getAlignmentAndSize(size_t *, size_t *) const {
442    CHECK(!"Should not be here");
443}
444
445void Type::appendToExportedTypesVector(
446        std::vector<const Type *> * /* exportedTypes */) const {
447}
448
449status_t Type::emitExportedHeader(
450        Formatter & /* out */, bool /* forJava */) const {
451    return OK;
452}
453
454////////////////////////////////////////
455
456TemplatedType::TemplatedType() : mElementType(nullptr) {
457}
458
459void TemplatedType::setElementType(Type *elementType) {
460    CHECK(mElementType == nullptr); // can only be set once.
461    CHECK(isCompatibleElementType(elementType));
462    mElementType = elementType;
463}
464
465Type *TemplatedType::getElementType() const {
466    return mElementType;
467}
468
469bool TemplatedType::isTemplatedType() const {
470    return true;
471}
472
473}  // namespace android
474
475