Coordinator.cpp revision e61e3f7b138a992047a60c4b8c27f1c752ed57ba
15345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "Coordinator.h" 25345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 35345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "AST.h" 45345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "RefType.h" 55345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 65345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include <android-base/logging.h> 75345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberextern android::status_t parseFile(android::AST *ast, const char *path); 95345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Hubernamespace android { 115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 12dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas HuberCoordinator::Coordinator(const std::string &interfacesPath) 13dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber : mInterfacesPath(interfacesPath) { 14dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber} 15dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber 165345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas HuberCoordinator::~Coordinator() {} 175345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas HuberAST *Coordinator::parse(const FQName &fqName) { 1968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 2068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 216e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // LOG(INFO) << "parsing " << fqName.string(); 226e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 2368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(fqName); 245345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 255345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 265345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 285345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 295345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 3068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Add this to the cache immediately, so we can discover circular imports. 3168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, NULL); 3268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 33dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber const std::string packagePath = getPackagePath(fqName); 3468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 3568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (fqName.name() != "types") { 3668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Any interface file implicitly imports its package's types.hal. 3768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 3868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber (void)parse(typesName); 3968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 4068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // fall through. 4168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 4268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 4368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber std::string path = packagePath; 4468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(fqName.name()); 4568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber path.append(".hal"); 465345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 475345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = new AST(this); 4868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber status_t err = parseFile(ast, path.c_str()); 4968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 5068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber if (err != OK) { 516e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // LOG(ERROR) << "parsing '" << path << "' FAILED."; 526e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 5368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber delete ast; 5468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ast = NULL; 555345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 5668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber return NULL; 5768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber } 5868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber 59a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->package().package() != fqName.package() 60a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber || ast->package().version() != fqName.version()) { 61a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 62a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' does not match expected package " 63a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "and/or version."; 64a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 65a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 66a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else { 67a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber std::string ifaceName; 68a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (ast->isInterface(&ifaceName)) { 69a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (fqName.name() == "types") { 70a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 71a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' declares an interface '" 72a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << ifaceName 73a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "' instead of the expected types common to the package."; 74a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 75a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 76a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (ifaceName != fqName.name()) { 77a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 78a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' does not declare interface type '" 79a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << fqName.name() 80a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "'."; 81a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 82a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 83a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 84a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } else if (fqName.name() != "types") { 85a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber LOG(ERROR) 86a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "File at '" << path << "' declares types rather than the " 87a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber << "expected interface type '" << fqName.name() << "'."; 88a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 89a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber err = UNKNOWN_ERROR; 90a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 91a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 92a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 93a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber if (err != OK) { 94a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber delete ast; 95a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber ast = NULL; 96a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 97a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber return NULL; 98a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber } 99a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber 10068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber mCache.add(fqName, ast); 1015345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1025345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return ast; 1035345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1045345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 105881227d860c59471eee31d39946e96ce2daa35d6Andreas Huberstd::string Coordinator::getPackagePath( 106881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber const FQName &fqName, bool relative) const { 1075345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.package().empty()); 1085345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK(!fqName.version().empty()); 1095345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber const char *const kPrefix = "android.hardware."; 1105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_EQ(fqName.package().find(kPrefix), 0u); 1115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1125345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber const std::string packageSuffix = fqName.package().substr(strlen(kPrefix)); 1135345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 114881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber std::string packagePath; 115881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber if (!relative) { 116881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber packagePath = mInterfacesPath; 117881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber } 1185345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t startPos = 0; 1205345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos; 1215345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber while ((dotPos = packageSuffix.find('.', startPos)) != std::string::npos) { 1225345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos, dotPos - startPos)); 1235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1245345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1255345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber startPos = dotPos + 1; 1265345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_LT(startPos + 1, packageSuffix.length()); 1285345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(packageSuffix.substr(startPos)); 1295345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1305345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1315345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber CHECK_EQ(fqName.version().find('@'), 0u); 1325345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append(fqName.version().substr(1)); 1335345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber packagePath.append("/"); 1345345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1355345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return packagePath; 1365345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1375345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1380e00de41d11a83ce3becb0dbd20b799acceb19a7Andreas HuberRefType *Coordinator::lookupType(const FQName &fqName) const { 1395345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber // Fully qualified. 14068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber CHECK(fqName.isFullyQualified()); 1415345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1425345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber std::string topType; 1435345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber size_t dotPos = fqName.name().find('.'); 1445345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (dotPos == std::string::npos) { 1455345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name(); 1465345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } else { 1475345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber topType = fqName.name().substr(0, dotPos); 1485345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1495345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 15068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // Assuming {topType} is the name of an interface type, let's see if the 15168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber // associated {topType}.hal file was imported. 15268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName ifaceName(fqName.package(), fqName.version(), topType); 15368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber ssize_t index = mCache.indexOfKey(ifaceName); 1545345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 1555345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 1566e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber CHECK(ast != NULL); 1576e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber 1585345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 1595345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1605345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (type != NULL) { 161867fcb63af8c3ac96ed1b3f3950525aa70393bdfAndreas Huber return new RefType(type); 1625345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1635345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1645345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 16568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber FQName typesName(fqName.package(), fqName.version(), "types"); 16668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber index = mCache.indexOfKey(typesName); 1675345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber if (index >= 0) { 1685345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber AST *ast = mCache.valueAt(index); 1696e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber if (ast != NULL) { 1706e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber // ast could be NULL if types.hal didn't exist, which is valid. 1716e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber Type *type = ast->lookupTypeInternal(fqName.name()); 1725345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1736e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber if (type != NULL) { 174867fcb63af8c3ac96ed1b3f3950525aa70393bdfAndreas Huber return new RefType(type); 1756e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber } 1765345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1775345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber } 1785345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 1795345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber return NULL; 1805345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} 1815345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 182e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huberstatus_t Coordinator::forEachAST(for_each_cb cb) const { 183e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber for (size_t i = 0; i < mCache.size(); ++i) { 184e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber status_t err = cb(mCache.valueAt(i)); 185e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 186e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber if (err != OK) { 187e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber return err; 188e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 189e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber } 190e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 191e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber return OK; 192e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber} 193e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber 1945345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber} // namespace android 1955345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber 196