blob: 1a56c1bf0ddd8993e82fcd68bb364bc3b8f91b55 [file] [log] [blame]
Zhuoyao Zhang5158db42016-08-10 10:25:20 -07001#include "AST.h"
2
3#include "Annotation.h"
4#include "Coordinator.h"
5#include "Formatter.h"
6#include "Interface.h"
7#include "Method.h"
8#include "Scope.h"
9
10#include <android-base/logging.h>
11#include <string>
12#include <vector>
13
14namespace android {
15
16// Remove the double quotas in a string.
17static std::string removeQuotes(const std::string in) {
18 std::string out{in};
19 return out.substr(1, out.size() - 2);
20}
21
Zhuoyao Zhang864c7712016-08-16 15:35:28 -070022status_t AST::emitVtsTypeDeclarations(Formatter &out) const {
23 std::set<AST *> allImportedASTs;
24 return emitVtsTypeDeclarationsHelper(out, &allImportedASTs);
25}
26
27status_t AST::emitVtsTypeDeclarationsHelper(
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070028 Formatter &out,
Zhuoyao Zhang864c7712016-08-16 15:35:28 -070029 std::set<AST *> *allImportSet) const {
30 // First, generate vts type declaration for all imported AST.
31 for (const auto &ast : mImportedASTs) {
32 // Already processed, skip.
33 if (allImportSet->find(ast) != allImportSet->end()) {
34 continue;
35 }
36 allImportSet->insert(ast);
37 std::string ifaceName;
38 // We only care about types.hal.
39 if (!ast->isInterface(&ifaceName)) {
40 status_t status = ast->emitVtsTypeDeclarationsHelper(
41 out, allImportSet);
42 if (status != OK) {
43 return status;
44 }
45 }
46 }
47 // Next, generate vts type declaration for the current AST.
48 for (const auto &type : mRootScope->getSubTypes()) {
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070049 out << "attribute: {\n";
50 out.indent();
51 status_t status = type->emitVtsTypeDeclarations(out);
52 if (status != OK) {
53 return status;
54 }
55 out.unindent();
56 out << "}\n\n";
57 }
58 return OK;
59}
60
61status_t AST::generateVts(const std::string &outputPath) const {
62 std::string path = outputPath;
63 path.append(mCoordinator->convertPackageRootToPath(mPackage));
64 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
65
66 std::string ifaceName;
67 std::string baseName;
68
69 bool isInterface = true;
70 if (!AST::isInterface(&ifaceName)) {
71 baseName = "types";
72 isInterface = false;
73 } else {
74 baseName = ifaceName.substr(1); // cut off the leading 'I'.
75 }
76
77 path.append(baseName);
78 path.append(".vts");
79
80 CHECK(Coordinator::MakeParentHierarchy(path));
81 FILE *file = fopen(path.c_str(), "w");
82
83 if (file == NULL) {
84 return -errno;
85 }
86
87 Formatter out(file);
88
89 out << "component_class: HAL_HIDL\n";
90
91 // Get the component_type for interface from annotation.
92 if (isInterface) {
93 const Interface *iface = mRootScope->getInterface();
94 Annotation *annotation = iface->annotations().valueFor("hal_type");
95 if (annotation != NULL) {
96 std::vector<std::string> * values = annotation->params().valueFor(
97 "type");
98 if (values != NULL) {
99 out << "component_type: "
100 << removeQuotes(values->at(0))
101 << "\n";
102 }
103 }
104 }
105
106 out << "component_type_version: " << mPackage.version().substr(1) << "\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
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700124 std::vector<const Interface *> chain;
125 while (iface != NULL) {
126 chain.push_back(iface);
127 iface = iface->superType();
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700128 }
129
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700130 // Generate all the attribute declarations first.
131 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
132 const Interface *superInterface = *it;
133 status_t status = superInterface->emitVtsAttributeDeclaration(out);
134 if (status != OK) {
135 return status;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700136 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700137 }
138
139 // Generate all the method declarations.
140 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
141 const Interface *superInterface = *it;
142 status_t status = superInterface->emitVtsMethodDeclaration(out);
143 if (status != OK) {
144 return status;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700145 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700146 }
147
148 out.unindent();
149 out << "}\n";
150 } else {
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700151 status_t status = emitVtsTypeDeclarations(out);
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700152 if (status != OK) {
153 return status;
154 }
155 }
156 return OK;
157}
158
159} // namespace android
160
161
162
163