Coordinator.cpp revision dca261ff8a8fed807c6e8206360eb84b1ff9e0a9
15345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "Coordinator.h"
25345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
35345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include "AST.h"
45345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
55345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber#include <android-base/logging.h>
6dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber#include <iterator>
75345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huberextern android::status_t parseFile(android::AST *ast, const char *path);
95345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Hubernamespace android {
115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
12dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::Coordinator(
13dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        const std::vector<std::string> &packageRootPaths,
14dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        const std::vector<std::string> &packageRoots)
15dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    : mPackageRootPaths(packageRootPaths),
16dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber      mPackageRoots(packageRoots) {
17dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // empty
18dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber}
19dc981333b38f47f416b9b810dc80e5cf2d7ac68aAndreas Huber
20dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::~Coordinator() {
21dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // empty
22dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber}
235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
2468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas HuberAST *Coordinator::parse(const FQName &fqName) {
2568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    CHECK(fqName.isFullyQualified());
2668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
276e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber    // LOG(INFO) << "parsing " << fqName.string();
286e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber
2968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    ssize_t index = mCache.indexOfKey(fqName);
305345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    if (index >= 0) {
315345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        AST *ast = mCache.valueAt(index);
325345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
335345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        return ast;
345345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    }
355345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
3668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    // Add this to the cache immediately, so we can discover circular imports.
3768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    mCache.add(fqName, NULL);
3868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
3968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    if (fqName.name() != "types") {
4068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        // Any interface file implicitly imports its package's types.hal.
4168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        FQName typesName(fqName.package(), fqName.version(), "types");
4268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        (void)parse(typesName);
4368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
4468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        // fall through.
4568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    }
4668f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
47dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    std::string path = getPackagePath(fqName);
48dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
4968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    path.append(fqName.name());
5068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    path.append(".hal");
515345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
525345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    AST *ast = new AST(this);
5368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    status_t err = parseFile(ast, path.c_str());
5468f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
5568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    if (err != OK) {
566e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber        // LOG(ERROR) << "parsing '" << path << "' FAILED.";
576e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber
5868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        delete ast;
5968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        ast = NULL;
605345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
6168f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber        return NULL;
6268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    }
6368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber
64a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber    if (ast->package().package() != fqName.package()
65a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            || ast->package().version() != fqName.version()) {
66a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        LOG(ERROR)
67a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            << "File at '" << path << "' does not match expected package "
68a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            << "and/or version.";
69a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
70a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        err = UNKNOWN_ERROR;
71a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber    } else {
72a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        std::string ifaceName;
73a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        if (ast->isInterface(&ifaceName)) {
74a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            if (fqName.name() == "types") {
75a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                LOG(ERROR)
76a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                    << "File at '" << path << "' declares an interface '"
77a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                    << ifaceName
78a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                    << "' instead of the expected types common to the package.";
79a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
80a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                err = UNKNOWN_ERROR;
81a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            } else if (ifaceName != fqName.name()) {
82a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                LOG(ERROR)
83a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                    << "File at '" << path << "' does not declare interface type '"
84a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                    << fqName.name()
85a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                    << "'.";
86a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
87a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                err = UNKNOWN_ERROR;
88a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            }
89a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        } else if (fqName.name() != "types") {
90a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            LOG(ERROR)
91a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                << "File at '" << path << "' declares types rather than the "
92a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber                << "expected interface type '" << fqName.name() << "'.";
93a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
94a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber            err = UNKNOWN_ERROR;
95a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        }
96a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber    }
97a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
98a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber    if (err != OK) {
99a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        delete ast;
100a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        ast = NULL;
101a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
102a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber        return NULL;
103a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber    }
104a2723d26427f7db19777dfed330047253e7a4e1bAndreas Huber
10568f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    mCache.add(fqName, ast);
1065345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
1075345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    return ast;
1085345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber}
1095345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
110dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::vector<std::string>::const_iterator
111dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas HuberCoordinator::findPackageRoot(const FQName &fqName) const {
1125345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    CHECK(!fqName.package().empty());
1135345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    CHECK(!fqName.version().empty());
1145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
115dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // Find the right package prefix and path for this FQName.  For
116dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // example, if FQName is "android.hardware.nfc@1.0::INfc", and the
117dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // prefix:root is set to [ "android.hardware:hardware/interfaces",
118dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // "vendor.qcom.hardware:vendor/qcom"], then we will identify the
119dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // prefix "android.hardware" and the package root
120dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // "hardware/interfaces".
121dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
122dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // TODO: This now returns on the first match.  Throw an error if
123dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // there are multiple hits.
124dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    auto it = mPackageRoots.begin();
125dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    for (; it != mPackageRoots.end(); it++) {
126dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        if (fqName.package().find(*it) != std::string::npos) {
127dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber            break;
128dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        }
129dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    }
130dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    CHECK(it != mPackageRoots.end());
131dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
132dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    return it;
133dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber}
134dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
135dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackageRoot(const FQName &fqName) const {
136dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    auto it = findPackageRoot(fqName);
137dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    auto prefix = *it;
138dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    return prefix;
139dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber}
140dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
141dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huberstd::string Coordinator::getPackagePath(
142dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        const FQName &fqName, bool relative) const {
143dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
144dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    auto it = findPackageRoot(fqName);
145dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    auto prefix = *it;
146dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    auto root = mPackageRootPaths[std::distance(mPackageRoots.begin(), it)];
147dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
148dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // Make sure the prefix ends on a '.' and the root path on a '/'
149dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    if ((*--prefix.end()) != '.') {
150dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        prefix += '.';
151dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    }
152dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
153dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    if ((*--root.end()) != '/') {
154dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        root += '/';
155dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    }
156dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber
157dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // Given FQName of "android.hardware.nfc@1.0::IFoo" and a prefix
158dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    // "android.hardware.", the suffix is "nfc@1.0::IFoo".
159dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber    const std::string packageSuffix = fqName.package().substr(prefix.length());
1605345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
161881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    std::string packagePath;
162881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    if (!relative) {
163dca261ff8a8fed807c6e8206360eb84b1ff9e0a9Andreas Huber        packagePath = root;
164881227d860c59471eee31d39946e96ce2daa35d6Andreas Huber    }
1655345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
1665345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    size_t startPos = 0;
1675345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    size_t dotPos;
1685345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    while ((dotPos = packageSuffix.find('.', startPos)) != std::string::npos) {
1695345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        packagePath.append(packageSuffix.substr(startPos, dotPos - startPos));
1705345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        packagePath.append("/");
1715345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
1725345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        startPos = dotPos + 1;
1735345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    }
1745345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    CHECK_LT(startPos + 1, packageSuffix.length());
1755345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    packagePath.append(packageSuffix.substr(startPos));
1765345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    packagePath.append("/");
1775345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
1785345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    CHECK_EQ(fqName.version().find('@'), 0u);
1795345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    packagePath.append(fqName.version().substr(1));
1805345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    packagePath.append("/");
1815345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
1825345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    return packagePath;
1835345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber}
1845345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
185fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas HuberType *Coordinator::lookupType(const FQName &fqName) const {
1865345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    // Fully qualified.
18768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    CHECK(fqName.isFullyQualified());
1885345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
1895345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    std::string topType;
1905345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    size_t dotPos = fqName.name().find('.');
1915345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    if (dotPos == std::string::npos) {
1925345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        topType = fqName.name();
1935345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    } else {
1945345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        topType = fqName.name().substr(0, dotPos);
1955345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    }
1965345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
19768f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    // Assuming {topType} is the name of an interface type, let's see if the
19868f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    // associated {topType}.hal file was imported.
19968f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    FQName ifaceName(fqName.package(), fqName.version(), topType);
20068f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    ssize_t index = mCache.indexOfKey(ifaceName);
2015345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    if (index >= 0) {
2025345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        AST *ast = mCache.valueAt(index);
2036e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber        CHECK(ast != NULL);
2046e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber
2055345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        Type *type = ast->lookupTypeInternal(fqName.name());
2065345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
2075345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        if (type != NULL) {
208fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas Huber            return type->ref();
2095345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        }
2105345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    }
2115345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
21268f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    FQName typesName(fqName.package(), fqName.version(), "types");
21368f24590cda230fb92eac44ed0247f54f9b31ad0Andreas Huber    index = mCache.indexOfKey(typesName);
2145345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    if (index >= 0) {
2155345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        AST *ast = mCache.valueAt(index);
2166e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber        if (ast != NULL) {
2176e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber            // ast could be NULL if types.hal didn't exist, which is valid.
2186e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber            Type *type = ast->lookupTypeInternal(fqName.name());
2195345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
2206e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber            if (type != NULL) {
221fd4afabde8fb9bbdd0021addeb9fbb62428f2c17Andreas Huber                return type->ref();
2226e584b70065ce37615980aba5ed60d27a54da1c3Andreas Huber            }
2235345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber        }
2245345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    }
2255345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
2265345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber    return NULL;
2275345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber}
2285345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
229e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huberstatus_t Coordinator::forEachAST(for_each_cb cb) const {
230e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber    for (size_t i = 0; i < mCache.size(); ++i) {
2316cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber        const AST *ast = mCache.valueAt(i);
2326cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber
2336cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber        if (!ast) {
2346cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber            // This could happen for an interface's "types.hal" AST.
2356cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber            continue;
2366cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber        }
2376cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber
2386cb08cf9f021a01d9d2b1eaec6729aac6ae70708Andreas Huber        status_t err = cb(ast);
239e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber
240e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber        if (err != OK) {
241e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber            return err;
242e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber        }
243e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber    }
244e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber
245e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber    return OK;
246e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber}
247e61e3f7b138a992047a60c4b8c27f1c752ed57baAndreas Huber
2485345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber}  // namespace android
2495345ec2b1b7e4126b77aa2131b231a9eb5ee811dAndreas Huber
250