1 /*
2 * Copyright (C) 2019 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 "AidlHelper.h"
18 #include "CompoundType.h"
19 #include "Coordinator.h"
20 #include "EnumType.h"
21 #include "NamedType.h"
22 #include "TypeDef.h"
23
24 namespace android {
25
emitConversionNotes(Formatter & out,const NamedType & namedType)26 static void emitConversionNotes(Formatter& out, const NamedType& namedType) {
27 out << "// This is the HIDL definition of " << namedType.fqName().string() << "\n";
28 out.pushLinePrefix("// ");
29 namedType.emitHidlDefinition(out);
30 out.popLinePrefix();
31 out << "\n";
32 }
33
emitTypeDefAidlDefinition(Formatter & out,const TypeDef & typeDef)34 static void emitTypeDefAidlDefinition(Formatter& out, const TypeDef& typeDef) {
35 out << "// Cannot convert typedef " << typeDef.referencedType()->definedName() << " "
36 << typeDef.fqName().string() << " since AIDL does not support typedefs.\n";
37 emitConversionNotes(out, typeDef);
38 }
39
emitEnumAidlDefinition(Formatter & out,const EnumType & enumType)40 static void emitEnumAidlDefinition(Formatter& out, const EnumType& enumType) {
41 const ScalarType* scalar = enumType.storageType()->resolveToScalarType();
42 CHECK(scalar != nullptr) << enumType.typeName();
43
44 enumType.emitDocComment(out);
45 out << "@Backing(type=\"" << AidlHelper::getAidlType(*scalar, enumType.fqName()) << "\")\n";
46 out << "enum " << enumType.fqName().name() << " ";
47 out.block([&] {
48 enumType.forEachValueFromRoot([&](const EnumValue* value) {
49 value->emitDocComment(out);
50 out << value->name();
51 if (!value->isAutoFill()) {
52 out << " = " << value->constExpr()->expression();
53 }
54 out << ",\n";
55 });
56 });
57 }
58
emitCompoundTypeAidlDefinition(Formatter & out,const CompoundType & compoundType,const Coordinator & coordinator)59 static void emitCompoundTypeAidlDefinition(Formatter& out, const CompoundType& compoundType,
60 const Coordinator& coordinator) {
61 for (const NamedType* namedType : compoundType.getSubTypes()) {
62 AidlHelper::emitAidl(*namedType, coordinator);
63 }
64
65 compoundType.emitDocComment(out);
66 out << "parcelable " << AidlHelper::getAidlName(compoundType.fqName()) << " ";
67 if (compoundType.style() == CompoundType::STYLE_STRUCT) {
68 out.block([&] {
69 for (const NamedReference<Type>* field : compoundType.getFields()) {
70 field->emitDocComment(out);
71 out << AidlHelper::getAidlType(*field->get(), compoundType.fqName()) << " "
72 << field->name() << ";\n";
73 }
74 });
75 } else {
76 out << "{}\n";
77 out << "// Cannot convert unions/safe_unions since AIDL does not support them.\n";
78 emitConversionNotes(out, compoundType);
79 }
80 out << "\n\n";
81 }
82
83 // TODO: Enum/Typedef should just emit to hidl-error.log or similar
emitAidl(const NamedType & namedType,const Coordinator & coordinator)84 void AidlHelper::emitAidl(const NamedType& namedType, const Coordinator& coordinator) {
85 Formatter out = getFileWithHeader(namedType, coordinator);
86 if (namedType.isTypeDef()) {
87 const TypeDef& typeDef = static_cast<const TypeDef&>(namedType);
88 emitTypeDefAidlDefinition(out, typeDef);
89 } else if (namedType.isCompoundType()) {
90 const CompoundType& compoundType = static_cast<const CompoundType&>(namedType);
91 emitCompoundTypeAidlDefinition(out, compoundType, coordinator);
92 } else if (namedType.isEnum()) {
93 const EnumType& enumType = static_cast<const EnumType&>(namedType);
94 emitEnumAidlDefinition(out, enumType);
95 } else {
96 out << "// TODO: Fix this " << namedType.definedName() << "\n";
97 }
98 }
99
100 } // namespace android
101