blob: 298da4d42c773a719cce242dd2bb21841b05d4bd [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
Adam Lesinskice5e56e2016-10-21 17:56:45 -070020#include <algorithm>
21#include <memory>
22#include <vector>
23
24#include "android-base/macros.h"
25#include "androidfw/AssetManager.h"
26#include "utils/JenkinsHash.h"
27#include "utils/LruCache.h"
28
Adam Lesinski1ab598f2015-08-14 14:26:04 -070029#include "Resource.h"
30#include "ResourceTable.h"
31#include "ResourceValues.h"
32#include "util/Util.h"
33
Adam Lesinski1ab598f2015-08-14 14:26:04 -070034namespace aapt {
35
Adam Lesinski1ab598f2015-08-14 14:26:04 -070036inline android::hash_t hash_type(const ResourceName& name) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -070037 std::hash<std::string> str_hash;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070038 android::hash_t hash = 0;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070039 hash = android::JenkinsHashMix(hash, (uint32_t)str_hash(name.package));
Adam Lesinskicacb28f2016-10-19 12:18:14 -070040 hash = android::JenkinsHashMix(hash, (uint32_t)name.type);
Adam Lesinskice5e56e2016-10-21 17:56:45 -070041 hash = android::JenkinsHashMix(hash, (uint32_t)str_hash(name.entry));
Adam Lesinskicacb28f2016-10-19 12:18:14 -070042 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;
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080050class NameMangler;
Adam Lesinski64587af2016-02-18 18:33:06 -080051
52class SymbolTable {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070053 public:
54 struct Symbol {
55 Symbol() : Symbol(Maybe<ResourceId>{}) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070056
Adam Lesinskicacb28f2016-10-19 12:18:14 -070057 explicit Symbol(const Maybe<ResourceId>& i) : Symbol(i, nullptr) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070058
Adam Lesinskicacb28f2016-10-19 12:18:14 -070059 Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr)
60 : Symbol(i, attr, false) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070061
Adam Lesinskicacb28f2016-10-19 12:18:14 -070062 Symbol(const Maybe<ResourceId>& i, const std::shared_ptr<Attribute>& attr,
63 bool pub)
Adam Lesinskice5e56e2016-10-21 17:56:45 -070064 : id(i), attribute(attr), is_public(pub) {}
Adam Lesinski626b3db2016-04-07 13:24:59 -070065
Adam Lesinskicacb28f2016-10-19 12:18:14 -070066 Symbol(const Symbol&) = default;
67 Symbol(Symbol&&) = default;
68 Symbol& operator=(const Symbol&) = default;
69 Symbol& operator=(Symbol&&) = default;
Adam Lesinski626b3db2016-04-07 13:24:59 -070070
Adam Lesinskicacb28f2016-10-19 12:18:14 -070071 Maybe<ResourceId> id;
72 std::shared_ptr<Attribute> attribute;
Adam Lesinskice5e56e2016-10-21 17:56:45 -070073 bool is_public = false;
Adam Lesinskicacb28f2016-10-19 12:18:14 -070074 };
Adam Lesinski64587af2016-02-18 18:33:06 -080075
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080076 SymbolTable(NameMangler* mangler) : mangler_(mangler), cache_(200), id_cache_(200) {}
Adam Lesinski64587af2016-02-18 18:33:06 -080077
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080078 // Appends a symbol source. The cache is not cleared since entries that
79 // have already been found would take precedence due to ordering.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070080 void AppendSource(std::unique_ptr<ISymbolSource> source);
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080081
82 // Prepends a symbol source so that its symbols take precedence. This will
83 // cause the existing cache to be cleared.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070084 void PrependSource(std::unique_ptr<ISymbolSource> source);
Adam Lesinski64587af2016-02-18 18:33:06 -080085
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080086 // NOTE: Never hold on to the result between calls to FindByXXX. The
87 // results are stored in a cache which may evict entries on subsequent calls.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070088 const Symbol* FindByName(const ResourceName& name);
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080089
90 // NOTE: Never hold on to the result between calls to FindByXXX. The
91 // results are stored in a cache which may evict entries on subsequent calls.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070092 const Symbol* FindById(const ResourceId& id);
Adam Lesinski64587af2016-02-18 18:33:06 -080093
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -080094 // Let's the ISymbolSource decide whether looking up by name or ID is faster,
95 // if both are available.
96 // NOTE: Never hold on to the result between calls to FindByXXX. The
97 // results are stored in a cache which may evict entries on subsequent calls.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070098 const Symbol* FindByReference(const Reference& ref);
Adam Lesinski76565542016-03-10 21:55:04 -080099
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700100 private:
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800101 NameMangler* mangler_;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700102 std::vector<std::unique_ptr<ISymbolSource>> sources_;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700103
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700104 // We use shared_ptr because unique_ptr is not supported and
105 // we need automatic deletion.
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700106 android::LruCache<ResourceName, std::shared_ptr<Symbol>> cache_;
107 android::LruCache<ResourceId, std::shared_ptr<Symbol>> id_cache_;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700108
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700109 DISALLOW_COPY_AND_ASSIGN(SymbolTable);
Adam Lesinski64587af2016-02-18 18:33:06 -0800110};
111
112/**
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700113 * An interface that a symbol source implements in order to surface symbol
114 * information
Adam Lesinski64587af2016-02-18 18:33:06 -0800115 * to the symbol table.
116 */
117class ISymbolSource {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700118 public:
119 virtual ~ISymbolSource() = default;
Adam Lesinski64587af2016-02-18 18:33:06 -0800120
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700121 virtual std::unique_ptr<SymbolTable::Symbol> FindByName(
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700122 const ResourceName& name) = 0;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700123 virtual std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) = 0;
Adam Lesinski76565542016-03-10 21:55:04 -0800124
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700125 /**
126 * Default implementation tries the name if it exists, else the ID.
127 */
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700128 virtual std::unique_ptr<SymbolTable::Symbol> FindByReference(
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700129 const Reference& ref) {
130 if (ref.name) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700131 return FindByName(ref.name.value());
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700132 } else if (ref.id) {
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700133 return FindById(ref.id.value());
Adam Lesinski76565542016-03-10 21:55:04 -0800134 }
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700135 return {};
136 }
Adam Lesinski64587af2016-02-18 18:33:06 -0800137};
138
139/**
140 * Exposes the resources in a ResourceTable as symbols for SymbolTable.
141 * Instances of this class must outlive the encompassed ResourceTable.
142 * Lookups by ID are ignored.
143 */
144class ResourceTableSymbolSource : public ISymbolSource {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700145 public:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700146 explicit ResourceTableSymbolSource(ResourceTable* table) : table_(table) {}
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700147
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700148 std::unique_ptr<SymbolTable::Symbol> FindByName(
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700149 const ResourceName& name) override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700150
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700151 std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700152 return {};
153 }
Adam Lesinski64587af2016-02-18 18:33:06 -0800154
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700155 private:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700156 ResourceTable* table_;
Adam Lesinski64587af2016-02-18 18:33:06 -0800157
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700158 DISALLOW_COPY_AND_ASSIGN(ResourceTableSymbolSource);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700159};
160
Adam Lesinski64587af2016-02-18 18:33:06 -0800161class AssetManagerSymbolSource : public ISymbolSource {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700162 public:
163 AssetManagerSymbolSource() = default;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700164
Adam Lesinskid5083f62017-01-16 15:07:21 -0800165 bool AddAssetPath(const android::StringPiece& path);
Adam Lesinskiceb9b2f2017-02-16 12:05:42 -0800166 std::map<size_t, std::string> GetAssignedPackageIds() const;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700167
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700168 std::unique_ptr<SymbolTable::Symbol> FindByName(
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700169 const ResourceName& name) override;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700170 std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override;
171 std::unique_ptr<SymbolTable::Symbol> FindByReference(
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700172 const Reference& ref) override;
Adam Lesinski64587af2016-02-18 18:33:06 -0800173
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700174 private:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700175 android::AssetManager assets_;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700176
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700177 DISALLOW_COPY_AND_ASSIGN(AssetManagerSymbolSource);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700178};
179
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700180} // namespace aapt
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700181
182#endif /* AAPT_PROCESS_SYMBOLTABLE_H */