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 {
3319f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland    if (AST::isInterface()) {
3400d1614c5ccb148e0f12f09bf90e5eb034d0e300Timur Iskhakov        const Interface* iface = mRootScope.getInterface();
3500d1614c5ccb148e0f12f09bf90e5eb034d0e300Timur Iskhakov        return iface->emitVtsAttributeDeclaration(out);
36864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang    }
3719f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland
3800d1614c5ccb148e0f12f09bf90e5eb034d0e300Timur Iskhakov    for (const auto& type : mRootScope.getSubTypes()) {
3919f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        // Skip for TypeDef as it is just an alias of a defined type.
4019f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        if (type->isTypeDef()) {
4119f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland            continue;
4219f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        }
4319f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        out << "attribute: {\n";
4419f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        out.indent();
4519f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        status_t status = type->emitVtsTypeDeclarations(out);
4619f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        if (status != OK) {
4719f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland            return status;
4819f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        }
4919f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        out.unindent();
5019f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        out << "}\n\n";
515158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
5219f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland
5319f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland    return OK;
545158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
555158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
565158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhangstatus_t AST::generateVts(const std::string &outputPath) const {
5719f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland    std::string baseName = AST::getBaseName();
5819f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland    const Interface *iface = AST::getInterface();
5919f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland
605158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    std::string path = outputPath;
615158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(mCoordinator->convertPackageRootToPath(mPackage));
625158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
635158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(baseName);
645158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    path.append(".vts");
655158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
665158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    CHECK(Coordinator::MakeParentHierarchy(path));
675158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    FILE *file = fopen(path.c_str(), "w");
685158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
695158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    if (file == NULL) {
705158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        return -errno;
715158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
725158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
735158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    Formatter out(file);
745158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
755158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_class: HAL_HIDL\n";
7690ea87f36e60a8db0c12d8e7870d45c90c51922dYifan Hong    out << "component_type_version: " << mPackage.version()
778f49294db5ac2898bac7c58ca20ff37d4cacdf5eZhuoyao Zhang        << "\n";
785158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "component_name: \""
7919f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland        << (iface ? iface->localName() : "types")
805158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        << "\"\n\n";
815158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
825158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "package: \"" << mPackage.package() << "\"\n\n";
835158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
84c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    // Generate import statement for all imported interface/types.
85c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    std::set<FQName> allImportedNames;
86c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    getAllImportedNames(&allImportedNames);
87c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang    for (const auto &name : allImportedNames) {
885deccac0b31aef7d320ae5223a49d37a573f3079Zhuoyao Zhang        // ignore IBase.
89c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang        if (name != gIBaseFqName) {
90c4e10605564ba5a8c656e5eabecd237abdc310e1Zhuoyao Zhang            out << "import: \"" << name.string() << "\"\n";
915deccac0b31aef7d320ae5223a49d37a573f3079Zhuoyao Zhang        }
925158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
935158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
945158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    out << "\n";
955158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
9619f11b53241877c442d31d9dc6b372e294a500d0Steven Moreland    if (isInterface()) {
9700d1614c5ccb148e0f12f09bf90e5eb034d0e300Timur Iskhakov        const Interface* iface = mRootScope.getInterface();
985158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "interface: {\n";
995158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.indent();
1005158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
10110fe0b55e774903fe37b658458053527da8b5a53Yifan Hong        std::vector<const Interface *> chain = iface->typeChain();
1025158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
103864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Generate all the attribute declarations first.
104a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        status_t status = emitVtsTypeDeclarations(out);
105a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        if (status != OK) {
106a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang            return status;
107a6239b3694b195617468f88b4553499e60cda80aZhuoyao Zhang        }
108864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        // Generate all the method declarations.
109864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
110864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            const Interface *superInterface = *it;
111864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            status_t status = superInterface->emitVtsMethodDeclaration(out);
112864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang            if (status != OK) {
113864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang                return status;
1145158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            }
1155158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1165158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1175158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out.unindent();
1185158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        out << "}\n";
1195158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    } else {
120864c771ca4ec8a01e31c7c243625b7a5f6316768Zhuoyao Zhang        status_t status = emitVtsTypeDeclarations(out);
1215158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        if (status != OK) {
1225158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang            return status;
1235158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang        }
1245158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    }
1255158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang    return OK;
1265158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}
1275158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang
1285158db484e5ab302368f191d75d5b1334c270e52Zhuoyao Zhang}  // namespace android
129