blob: 89d87dec72698d2a7db2c789115aa30be504563e [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
2 * Copyright (C) 2015 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#ifndef AAPT_PROCESS_SYMBOLTABLE_H
18#define AAPT_PROCESS_SYMBOLTABLE_H
19
20#include "Resource.h"
21#include "ResourceTable.h"
22#include "ResourceValues.h"
23#include "util/Util.h"
24
25#include <utils/JenkinsHash.h>
26#include <utils/LruCache.h>
27
Adam Lesinski64587af2016-02-18 18:33:06 -080028#include <android-base/macros.h>
Adam Lesinski1ab598f2015-08-14 14:26:04 -070029#include <androidfw/AssetManager.h>
30#include <algorithm>
Adam Lesinski1ab598f2015-08-14 14:26:04 -070031#include <memory>
32#include <vector>
33
34namespace aapt {
35
Adam Lesinski1ab598f2015-08-14 14:26:04 -070036inline android::hash_t hash_type(const ResourceName& name) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070037 std::hash<std::string> strHash;
38 android::hash_t hash = 0;
39 hash = android::JenkinsHashMix(hash, (uint32_t)strHash(name.package));
40 hash = android::JenkinsHashMix(hash, (uint32_t)name.type);
41 hash = android::JenkinsHashMix(hash, (uint32_t)strHash(name.entry));
42 return hash;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070043}
44
45inline android::hash_t hash_type(const ResourceId& id) {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070046 return android::hash_type(id.id);
Adam Lesinski1ab598f2015-08-14 14:26:04 -070047}
48
Adam Lesinski64587af2016-02-18 18:33:06 -080049class ISymbolSource;
50
51class SymbolTable {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070052 public:
53 struct Symbol {
54 Symbol() : Symbol(Maybe<ResourceId>{}) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070055
Adam Lesinskicacb28f2016-10-19 12:18:14 -070056 explicit Symbol(const Maybe<ResourceId>& i) : Symbol(i, nullptr) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070057
Adam Lesinskicacb28f2016-10-19 12:18:14 -070058 Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr)
59 : Symbol(i, attr, false) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070060
Adam Lesinskicacb28f2016-10-19 12:18:14 -070061 Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr,
62 bool pub)
63 : id(i), attribute(attr), isPublic(pub) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070064
Adam Lesinskicacb28f2016-10-19 12:18:14 -070065 Symbol(const Symbol&) = default;
66 Symbol(Symbol&&) = default;
67 Symbol& operator=(const Symbol&) = default;
68 Symbol& operator=(Symbol&&) = default;
Adam Lesinski626b3db2016-04-07 13:24:59 -070069
Adam Lesinskicacb28f2016-10-19 12:18:14 -070070 Maybe<ResourceId> id;
71 std::shared_ptr<Attribute> attribute;
72 bool isPublic = false;
73 };
Adam Lesinski64587af2016-02-18 18:33:06 -080074
Adam Lesinskicacb28f2016-10-19 12:18:14 -070075 SymbolTable() : mCache(200), mIdCache(200) {}
Adam Lesinski64587af2016-02-18 18:33:06 -080076
Adam Lesinskicacb28f2016-10-19 12:18:14 -070077 void appendSource(std::unique_ptr<ISymbolSource> source);
78 void prependSource(std::unique_ptr<ISymbolSource> source);
Adam Lesinski64587af2016-02-18 18:33:06 -080079
Adam Lesinskicacb28f2016-10-19 12:18:14 -070080 /**
81 * Never hold on to the result between calls to findByName or findById. The
82 * results
83 * are typically stored in a cache which may evict entries.
84 */
85 const Symbol* findByName(const ResourceName& name);
86 const Symbol* findById(const ResourceId& id);
Adam Lesinski64587af2016-02-18 18:33:06 -080087
Adam Lesinskicacb28f2016-10-19 12:18:14 -070088 /**
89 * Let's the ISymbolSource decide whether looking up by name or ID is faster,
90 * if both
91 * are available.
92 */
93 const Symbol* findByReference(const Reference& ref);
Adam Lesinski7656554f2016-03-10 21:55:04 -080094
Adam Lesinskicacb28f2016-10-19 12:18:14 -070095 private:
96 std::vector<std::unique_ptr<ISymbolSource>> mSources;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070097
Adam Lesinskicacb28f2016-10-19 12:18:14 -070098 // We use shared_ptr because unique_ptr is not supported and
99 // we need automatic deletion.
100 android::LruCache<ResourceName, std::shared_ptr<Symbol>> mCache;
101 android::LruCache<ResourceId, std::shared_ptr<Symbol>> mIdCache;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700102
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700103 DISALLOW_COPY_AND_ASSIGN(SymbolTable);
Adam Lesinski64587af2016-02-18 18:33:06 -0800104};
105
106/**
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700107 * An interface that a symbol source implements in order to surface symbol
108 * information
Adam Lesinski64587af2016-02-18 18:33:06 -0800109 * to the symbol table.
110 */
111class ISymbolSource {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700112 public:
113 virtual ~ISymbolSource() = default;
Adam Lesinski64587af2016-02-18 18:33:06 -0800114
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700115 virtual std::unique_ptr<SymbolTable::Symbol> findByName(
116 const ResourceName& name) = 0;
117 virtual std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) = 0;
Adam Lesinski7656554f2016-03-10 21:55:04 -0800118
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700119 /**
120 * Default implementation tries the name if it exists, else the ID.
121 */
122 virtual std::unique_ptr<SymbolTable::Symbol> findByReference(
123 const Reference& ref) {
124 if (ref.name) {
125 return findByName(ref.name.value());
126 } else if (ref.id) {
127 return findById(ref.id.value());
Adam Lesinski7656554f2016-03-10 21:55:04 -0800128 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700129 return {};
130 }
Adam Lesinski64587af2016-02-18 18:33:06 -0800131};
132
133/**
134 * Exposes the resources in a ResourceTable as symbols for SymbolTable.
135 * Instances of this class must outlive the encompassed ResourceTable.
136 * Lookups by ID are ignored.
137 */
138class ResourceTableSymbolSource : public ISymbolSource {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700139 public:
140 explicit ResourceTableSymbolSource(ResourceTable* table) : mTable(table) {}
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700141
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700142 std::unique_ptr<SymbolTable::Symbol> findByName(
143 const ResourceName& name) override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700144
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override {
146 return {};
147 }
Adam Lesinski64587af2016-02-18 18:33:06 -0800148
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700149 private:
150 ResourceTable* mTable;
Adam Lesinski64587af2016-02-18 18:33:06 -0800151
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700152 DISALLOW_COPY_AND_ASSIGN(ResourceTableSymbolSource);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700153};
154
Adam Lesinski64587af2016-02-18 18:33:06 -0800155class AssetManagerSymbolSource : public ISymbolSource {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700156 public:
157 AssetManagerSymbolSource() = default;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700158
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700159 bool addAssetPath(const StringPiece& path);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700160
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700161 std::unique_ptr<SymbolTable::Symbol> findByName(
162 const ResourceName& name) override;
163 std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override;
164 std::unique_ptr<SymbolTable::Symbol> findByReference(
165 const Reference& ref) override;
Adam Lesinski64587af2016-02-18 18:33:06 -0800166
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700167 private:
168 android::AssetManager mAssets;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700169
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700170 DISALLOW_COPY_AND_ASSIGN(AssetManagerSymbolSource);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700171};
172
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700173} // namespace aapt
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700174
175#endif /* AAPT_PROCESS_SYMBOLTABLE_H */