generateVts.cpp revision a72e0d2be173cebf62f728b9d215808bd862f219
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(
385158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        Formatter &out,
39864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        std::set<AST *> *allImportSet) const {
40864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    // First, generate vts type declaration for all imported AST.
41864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (const auto &ast : mImportedASTs) {
42864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Already processed, skip.
43864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (allImportSet->find(ast) != allImportSet->end()) {
44864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            continue;
45864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
46864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        allImportSet->insert(ast);
47864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        std::string ifaceName;
48864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // We only care about types.hal.
49864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        if (!ast->isInterface(&ifaceName)) {
50864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            status_t status = ast->emitVtsTypeDeclarationsHelper(
51864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang                    out, allImportSet);
52864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            if (status != OK) {
53864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang                return status;
54864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            }
55864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
56864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
57864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    // Next, generate vts type declaration for the current AST.
58864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    for (const auto &type : mRootScope->getSubTypes()) {
59368491306c932ef23939c3214cd014278e1aa6caZhuoyao Zhang        // Skip for TypeDef as it is just an alias of a defined type.
60368491306c932ef23939c3214cd014278e1aa6caZhuoyao Zhang        if (type->isTypeDef()) {
61368491306c932ef23939c3214cd014278e1aa6caZhuoyao Zhang            continue;
62368491306c932ef23939c3214cd014278e1aa6caZhuoyao Zhang        }
635158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "attribute: {\n";
645158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.indent();
655158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        status_t status = type->emitVtsTypeDeclarations(out);
665158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        if (status != OK) {
675158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            return status;
685158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
695158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.unindent();
705158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "}\n\n";
715158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
725158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
735158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
745158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
755158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t AST::generateVts(const std::string &outputPath) const {
765158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string path = outputPath;
775158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(mCoordinator->convertPackageRootToPath(mPackage));
785158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
795158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
805158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string ifaceName;
815158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string baseName;
825158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
835158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    bool isInterface = true;
845158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (!AST::isInterface(&ifaceName)) {
855158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        baseName = "types";
865158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        isInterface = false;
875158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    } else {
885158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        baseName = ifaceName.substr(1);  // cut off the leading 'I'.
895158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
905158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
915158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(baseName);
925158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(".vts");
935158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
945158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    CHECK(Coordinator::MakeParentHierarchy(path));
955158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    FILE *file = fopen(path.c_str(), "w");
965158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
975158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (file == NULL) {
985158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        return -errno;
995158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1005158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1015158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    Formatter out(file);
1025158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1035158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_class: HAL_HIDL\n";
1045158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_type_version: " << mPackage.version().substr(1) << "\n";
1055158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_name: \""
1065158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        << (isInterface ? ifaceName : "types")
1075158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        << "\"\n\n";
1085158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1095158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "package: \"" << mPackage.package() << "\"\n\n";
1105158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1115158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    for (const auto &item : mImportedNames) {
1125158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "import: \"" << item.string() << "\"\n";
1135158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1145158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1155158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "\n";
1165158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1175158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (isInterface) {
1185158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        const Interface *iface = mRootScope->getInterface();
1195158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "interface: {\n";
1205158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.indent();
1215158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
122864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        std::vector<const Interface *> chain;
123864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        while (iface != NULL) {
124864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            chain.push_back(iface);
125864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            iface = iface->superType();
1265158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1275158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
128864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Generate all the attribute declarations first.
129864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
130864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            const Interface *superInterface = *it;
131864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            status_t status = superInterface->emitVtsAttributeDeclaration(out);
132864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            if (status != OK) {
133864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang                return status;
1345158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            }
135864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        }
136864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang
137864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Generate all the method declarations.
138864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
139864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            const Interface *superInterface = *it;
140864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            status_t status = superInterface->emitVtsMethodDeclaration(out);
141864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            if (status != OK) {
142864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang                return status;
1435158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            }
1445158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1455158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1465158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.unindent();
1475158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "}\n";
1485158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    } else {
149864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        status_t status = emitVtsTypeDeclarations(out);
1505158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        if (status != OK) {
1515158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            return status;
1525158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1535158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1545158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
1555158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
1565158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1575158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}  // namespace android
1585158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1595158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1605158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1615158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
162