generateVts.cpp revision c4e10605564ba5a8c656e5eabecd237abdc310e1
11aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber/*
21aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Copyright (C) 2016 The Android Open Source Project
31aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
41aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
51aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * you may not use this file except in compliance with the License.
61aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * You may obtain a copy of the License at
71aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
81aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
91aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber *
101aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * Unless required by applicable law or agreed to in writing, software
111aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
121aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * See the License for the specific language governing permissions and
141aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber * limitations under the License.
151aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber */
161aec397b1fdea7db4120dbe55b6995bb2a9d9138Andreas Huber
175158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include "AST.h"
185158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
195158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include "Annotation.h"
205158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include "Coordinator.h"
215158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include "Interface.h"
225158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include "Method.h"
235158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include "Scope.h"
245158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
25a72e0d2be173cebf62f728b9d215808bd862f219Iliyan Malchev#include <hidl-util/Formatter.h>
265158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include <android-base/logging.h>
275158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include <string>
285158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang#include <vector>
295158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
305158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangnamespace android {
315158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
32864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t AST::emitVtsTypeDeclarations(Formatter &out) const {
33864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    std::set<AST *> allImportedASTs;
34864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    return emitVtsTypeDeclarationsHelper(out, &allImportedASTs);
35864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang}
36864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
37864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhangstatus_t AST::emitVtsTypeDeclarationsHelper(
38c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        Formatter &out, std::set<AST *> *allImportSet) const {
39864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    // First, generate vts type declaration for all imported AST.
40c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    for (const auto &importedName : mImportedNames) {
41c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        AST *ast = mCoordinator->parse(importedName);
42864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Already processed, skip.
43864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (allImportSet->find(ast) != allImportSet->end()) {
44864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            continue;
45864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
46864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        allImportSet->insert(ast);
47c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        status_t status = ast->emitVtsTypeDeclarationsHelper(out,
48c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang                                                             allImportSet);
49c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        if (status != OK) {
50c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang            return status;
51864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
52864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
53864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    // Next, generate vts type declaration for the current AST.
54a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang    std::string ifaceName;
55c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    if (AST::isInterface(&ifaceName)) {
56c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        const Interface *iface = mRootScope->getInterface();
57c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        status_t status = iface->emitVtsAttributeDeclaration(out);
58c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        if (status != OK) {
59c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang            return status;
60c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        }
61c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    } else {
62a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        for (const auto &type : mRootScope->getSubTypes()) {
63a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            // Skip for TypeDef as it is just an alias of a defined type.
64a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            if (type->isTypeDef()) {
65a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang                continue;
66a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            }
67a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            out << "attribute: {\n";
68a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            out.indent();
69a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            status_t status = type->emitVtsTypeDeclarations(out);
70a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            if (status != OK) {
71a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang                return status;
72a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            }
73a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            out.unindent();
74a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            out << "}\n\n";
755158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
765158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
775158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
785158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
795158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
805158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t AST::generateVts(const std::string &outputPath) const {
815158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string path = outputPath;
825158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(mCoordinator->convertPackageRootToPath(mPackage));
835158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
845158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
855158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string ifaceName;
865158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string baseName;
875158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
885158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    bool isInterface = true;
895158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (!AST::isInterface(&ifaceName)) {
905158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        baseName = "types";
915158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        isInterface = false;
925158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    } else {
933f32c1f4cba298b0a9e750c4e073856392da726cJayant Chowdhary        const Interface *iface = mRootScope->getInterface();
943f32c1f4cba298b0a9e750c4e073856392da726cJayant Chowdhary        baseName = iface->getBaseName();
955158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
965158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
975158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(baseName);
985158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(".vts");
995158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1005158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    CHECK(Coordinator::MakeParentHierarchy(path));
1015158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    FILE *file = fopen(path.c_str(), "w");
1025158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1035158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (file == NULL) {
1045158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        return -errno;
1055158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1065158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1075158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    Formatter out(file);
1085158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1095158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_class: HAL_HIDL\n";
11090ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    out << "component_type_version: " << mPackage.version()
1118f49294db5ac2898bac7c58ca20ff37d4cacdf5eZhuoyao Zhang        << "\n";
1125158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_name: \""
1135158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        << (isInterface ? ifaceName : "types")
1145158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        << "\"\n\n";
1155158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1165158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "package: \"" << mPackage.package() << "\"\n\n";
1175158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
118c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    // Generate import statement for all imported interface/types.
119c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    std::set<FQName> allImportedNames;
120c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    getAllImportedNames(&allImportedNames);
121c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    for (const auto &name : allImportedNames) {
1225deccac0b31aef7d320ae5223a49d37a573f3079Zhuoyao Zhang        // ignore IBase.
123c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        if (name != gIBaseFqName) {
124c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang            out << "import: \"" << name.string() << "\"\n";
1255deccac0b31aef7d320ae5223a49d37a573f3079Zhuoyao Zhang        }
1265158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1275158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1285158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "\n";
1295158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1305158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (isInterface) {
1315158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        const Interface *iface = mRootScope->getInterface();
1325158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "interface: {\n";
1335158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.indent();
1345158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
13510fe0b55e774903fe37b658458053527da8b5a53Yifan Hong        std::vector<const Interface *> chain = iface->typeChain();
1365158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
137864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Generate all the attribute declarations first.
138a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        status_t status = emitVtsTypeDeclarations(out);
139a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        if (status != OK) {
140a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            return status;
141a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        }
142864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Generate all the method declarations.
143864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
144864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            const Interface *superInterface = *it;
145864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            status_t status = superInterface->emitVtsMethodDeclaration(out);
146864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            if (status != OK) {
147864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang                return status;
1485158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            }
1495158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1505158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1515158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.unindent();
1525158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "}\n";
1535158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    } else {
154864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        status_t status = emitVtsTypeDeclarations(out);
1555158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        if (status != OK) {
1565158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            return status;
1575158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1585158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1595158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
1605158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
1615158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1625158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}  // namespace android
163