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 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 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 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 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 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