blob: 8ab5427fffbb6a873c607576ae902d6a0e6bb460 [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 Zhang36849132016-08-25 17:18:44 -070049 // Skip for TypeDef as it is just an alias of a defined type.
50 if (type->isTypeDef()) {
51 continue;
52 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -070053 out << "attribute: {\n";
54 out.indent();
55 status_t status = type->emitVtsTypeDeclarations(out);
56 if (status != OK) {
57 return status;
58 }
59 out.unindent();
60 out << "}\n\n";
61 }
62 return OK;
63}
64
65status_t AST::generateVts(const std::string &outputPath) const {
66 std::string path = outputPath;
67 path.append(mCoordinator->convertPackageRootToPath(mPackage));
68 path.append(mCoordinator->getPackagePath(mPackage, true /* relative */));
69
70 std::string ifaceName;
71 std::string baseName;
72
73 bool isInterface = true;
74 if (!AST::isInterface(&ifaceName)) {
75 baseName = "types";
76 isInterface = false;
77 } else {
78 baseName = ifaceName.substr(1); // cut off the leading 'I'.
79 }
80
81 path.append(baseName);
82 path.append(".vts");
83
84 CHECK(Coordinator::MakeParentHierarchy(path));
85 FILE *file = fopen(path.c_str(), "w");
86
87 if (file == NULL) {
88 return -errno;
89 }
90
91 Formatter out(file);
92
93 out << "component_class: HAL_HIDL\n";
94
95 // Get the component_type for interface from annotation.
96 if (isInterface) {
97 const Interface *iface = mRootScope->getInterface();
98 Annotation *annotation = iface->annotations().valueFor("hal_type");
99 if (annotation != NULL) {
100 std::vector<std::string> * values = annotation->params().valueFor(
101 "type");
102 if (values != NULL) {
103 out << "component_type: "
104 << removeQuotes(values->at(0))
105 << "\n";
106 }
107 }
108 }
109
110 out << "component_type_version: " << mPackage.version().substr(1) << "\n";
111 out << "component_name: \""
112 << (isInterface ? ifaceName : "types")
113 << "\"\n\n";
114
115 out << "package: \"" << mPackage.package() << "\"\n\n";
116
117 for (const auto &item : mImportedNames) {
118 out << "import: \"" << item.string() << "\"\n";
119 }
120
121 out << "\n";
122
123 if (isInterface) {
124 const Interface *iface = mRootScope->getInterface();
125 out << "interface: {\n";
126 out.indent();
127
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700128 std::vector<const Interface *> chain;
129 while (iface != NULL) {
130 chain.push_back(iface);
131 iface = iface->superType();
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700132 }
133
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700134 // Generate all the attribute declarations first.
135 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
136 const Interface *superInterface = *it;
137 status_t status = superInterface->emitVtsAttributeDeclaration(out);
138 if (status != OK) {
139 return status;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700140 }
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700141 }
142
143 // Generate all the method declarations.
144 for (auto it = chain.rbegin(); it != chain.rend(); ++it) {
145 const Interface *superInterface = *it;
146 status_t status = superInterface->emitVtsMethodDeclaration(out);
147 if (status != OK) {
148 return status;
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700149 }
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700150 }
151
152 out.unindent();
153 out << "}\n";
154 } else {
Zhuoyao Zhang864c7712016-08-16 15:35:28 -0700155 status_t status = emitVtsTypeDeclarations(out);
Zhuoyao Zhang5158db42016-08-10 10:25:20 -0700156 if (status != OK) {
157 return status;
158 }
159 }
160 return OK;
161}
162
163} // namespace android
164
165
166
167