generateVts.cpp revision 90ea87f36e60a8db0c12d8e7870d45c90c51922d
1/*
2 * Copyright (C) 2016 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 "AST.h"
18
19#include "Annotation.h"
20#include "Coordinator.h"
21#include "Interface.h"
22#include "Method.h"
23#include "Scope.h"
24
25#include <hidl-util/Formatter.h>
26#include <android-base/logging.h>
27#include <string>
28#include <vector>
29
30namespace android {
31
32status_t AST::emitVtsTypeDeclarations(Formatter &out) const {
33    std::set<AST *> allImportedASTs;
34    return emitVtsTypeDeclarationsHelper(out, &allImportedASTs);
35}
36
37status_t AST::emitVtsTypeDeclarationsHelper(
38        Formatter &out,
39        std::set<AST *> *allImportSet) const {
40    // First, generate vts type declaration for all imported AST.
41    for (const auto &ast : mImportedASTs) {
42        // Already processed, skip.
43        if (allImportSet->find(ast) != allImportSet->end()) {
44            continue;
45        }
46        allImportSet->insert(ast);
47        std::string ifaceName;
48        // We only care about types.hal.
49        if (!ast->isInterface(&ifaceName)) {
50            status_t status = ast->emitVtsTypeDeclarationsHelper(
51                    out, allImportSet);
52            if (status != OK) {
53                return status;
54            }
55        }
56    }
57    // Next, generate vts type declaration for the current AST.
58    for (const auto &type : mRootScope->getSubTypes()) {
59        // Skip for TypeDef as it is just an alias of a defined type.
60        if (type->isTypeDef()) {
61            continue;
62        }
63        out << "attribute: {\n";
64        out.indent();
65        status_t status = type->emitVtsTypeDeclarations(out);
66        if (status != OK) {
67            return status;
68        }
69        out.unindent();
70        out << "}\n\n";
71    }
72    return OK;
73}
74
75status_t AST::generateVts(const std::string &outputPath) const {
76    std::string path = outputPath;
77    path.append(mCoordinator->convertPackageRootToPath(mPackage));
78    path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
79
80    std::string ifaceName;
81    std::string baseName;
82
83    bool isInterface = true;
84    if (!AST::isInterface(&ifaceName)) {
85        baseName = "types";
86        isInterface = false;
87    } else {
88        const Interface *iface = mRootScope->getInterface();
89        baseName = iface->getBaseName();
90    }
91
92    path.append(baseName);
93    path.append(".vts");
94
95    CHECK(Coordinator::MakeParentHierarchy(path));
96    FILE *file = fopen(path.c_str(), "w");
97
98    if (file == NULL) {
99        return -errno;
100    }
101
102    Formatter out(file);
103
104    out << "component_class: HAL_HIDL\n";
105    out << "component_type_version: " << mPackage.version()
106        << "\n";
107    out << "component_name: \""
108        << (isInterface ? ifaceName : "types")
109        << "\"\n\n";
110
111    out << "package: \"" << mPackage.package() << "\"\n\n";
112
113    for (const auto &item : mImportedNames) {
114        out << "import: \"" << item.string() << "\"\n";
115    }
116
117    out << "\n";
118
119    if (isInterface) {
120        const Interface *iface = mRootScope->getInterface();
121        out << "interface: {\n";
122        out.indent();
123
124        std::vector<const Interface *> chain = iface->typeChain();
125
126        // Generate all the attribute declarations first.
127        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
128            const Interface *superInterface = *it;
129            status_t status = superInterface->emitVtsAttributeDeclaration(out);
130            if (status != OK) {
131                return status;
132            }
133        }
134
135        // Generate all the method declarations.
136        for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
137            const Interface *superInterface = *it;
138            status_t status = superInterface->emitVtsMethodDeclaration(out);
139            if (status != OK) {
140                return status;
141            }
142        }
143
144        out.unindent();
145        out << "}\n";
146    } else {
147        status_t status = emitVtsTypeDeclarations(out);
148        if (status != OK) {
149            return status;
150        }
151    }
152    return OK;
153}
154
155}  // namespace android
156
157
158
159
160