11ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski/*
21ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Copyright (C) 2015 The Android Open Source Project
31ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
41ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
51ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * you may not use this file except in compliance with the License.
61ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * You may obtain a copy of the License at
71ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
81ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
91ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski *
101ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * Unless required by applicable law or agreed to in writing, software
111ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
121ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * See the License for the specific language governing permissions and
141ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski * limitations under the License.
151ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski */
161ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
171ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#ifndef AAPT_TEST_CONTEXT_H
181ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#define AAPT_TEST_CONTEXT_H
191ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
20ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include <list>
21ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
22ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/logging.h"
23ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski#include "android-base/macros.h"
24ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "NameMangler.h"
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "process/IResourceTableConsumer.h"
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "process/SymbolTable.h"
281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "test/Common.h"
29cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski#include "util/Util.h"
301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace test {
331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass Context : public IAaptContext {
35cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
36ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski  Context() : name_mangler_({}), symbols_(&name_mangler_), min_sdk_version_(0) {}
37ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
38b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  PackageType GetPackageType() override {
39b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return package_type_;
40b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
41b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski
42b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  SymbolTable* GetExternalSymbols() override {
43b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return &symbols_;
44b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
46b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  IDiagnostics* GetDiagnostics() override {
47b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return &diagnostics_;
48b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
50ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  const std::string& GetCompilationPackage() override {
51ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    CHECK(bool(compilation_package_)) << "package name not set";
52ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    return compilation_package_.value();
53cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
554ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski  void SetCompilationPackage(const android::StringPiece& package) {
564ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski    compilation_package_ = package.to_string();
574ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski  }
584ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski
59ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  uint8_t GetPackageId() override {
60ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    CHECK(bool(package_id_)) << "package ID not set";
61ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    return package_id_.value();
62cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
631ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
644ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski  void SetPackageId(uint8_t package_id) {
654ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski    package_id_ = package_id;
664ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski  }
674ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski
68b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  NameMangler* GetNameMangler() override {
69b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return &name_mangler_;
70b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
71355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski
724ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski  void SetNameManglerPolicy(const NameManglerPolicy& policy) {
734ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski    name_mangler_ = NameMangler(policy);
744ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski  }
754ca56978a9aea3f021a54ed9265de10811984d94Adam Lesinski
76b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  bool IsVerbose() override {
77b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return false;
78b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
7964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
80b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  int GetMinSdkVersion() override {
81b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return min_sdk_version_;
82b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
83fb6312fe93a8544e6a95d1c619c8cea3940cbe1aAdam Lesinski
84cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private:
85ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  DISALLOW_COPY_AND_ASSIGN(Context);
86ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
87cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  friend class ContextBuilder;
8864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
89b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  PackageType package_type_ = PackageType::kApp;
90ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Maybe<std::string> compilation_package_;
91ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  Maybe<uint8_t> package_id_;
92ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  StdErrDiagnostics diagnostics_;
93ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski  NameMangler name_mangler_;
94ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  SymbolTable symbols_;
95ceb9b2f80f853059233cdd29057f39a5960a74aeAdam Lesinski  int min_sdk_version_;
961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass ContextBuilder {
99cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
100b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  ContextBuilder& SetPackageType(PackageType type) {
101b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    context_->package_type_ = type;
102b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return *this;
103b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
104b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski
105d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  ContextBuilder& SetCompilationPackage(const android::StringPiece& package) {
106d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski    context_->compilation_package_ = package.to_string();
107cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
108cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
109cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
110ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ContextBuilder& SetPackageId(uint8_t id) {
111ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    context_->package_id_ = id;
112cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
113cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
114cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
115ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ContextBuilder& SetNameManglerPolicy(const NameManglerPolicy& policy) {
116ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    context_->name_mangler_ = NameMangler(policy);
117cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
118cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
119cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
120ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ContextBuilder& AddSymbolSource(std::unique_ptr<ISymbolSource> src) {
121ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    context_->GetExternalSymbols()->AppendSource(std::move(src));
122cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
123cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
124cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
125ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  ContextBuilder& SetMinSdkVersion(int min_sdk) {
126ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    context_->min_sdk_version_ = min_sdk;
127cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
128cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
129cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
130ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::unique_ptr<Context> Build() { return std::move(context_); }
131ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski
132ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski private:
133ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski  std::unique_ptr<Context> context_ = std::unique_ptr<Context>(new Context());
1341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1351ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
13664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinskiclass StaticSymbolSourceBuilder {
137cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski public:
138d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  StaticSymbolSourceBuilder& AddPublicSymbol(const android::StringPiece& name, ResourceId id,
139d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski                                             std::unique_ptr<Attribute> attr = {}) {
140cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    std::unique_ptr<SymbolTable::Symbol> symbol =
141cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski        util::make_unique<SymbolTable::Symbol>(id, std::move(attr), true);
142ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get();
143ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    symbol_source_->id_map_[id] = symbol.get();
144ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    symbol_source_->symbols_.push_back(std::move(symbol));
145cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
146cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
147cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
148d5083f6f6b9bc76bbe64052bcec639eee752a321Adam Lesinski  StaticSymbolSourceBuilder& AddSymbol(const android::StringPiece& name, ResourceId id,
149cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski                                       std::unique_ptr<Attribute> attr = {}) {
150cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    std::unique_ptr<SymbolTable::Symbol> symbol =
151cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski        util::make_unique<SymbolTable::Symbol>(id, std::move(attr), false);
152ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get();
153ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    symbol_source_->id_map_[id] = symbol.get();
154ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    symbol_source_->symbols_.push_back(std::move(symbol));
155cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    return *this;
156cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  }
157cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
158b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  std::unique_ptr<ISymbolSource> Build() {
159b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    return std::move(symbol_source_);
160b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  }
161cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
162cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski private:
163cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  class StaticSymbolSource : public ISymbolSource {
164cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   public:
165cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    StaticSymbolSource() = default;
166cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
167b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski    std::unique_ptr<SymbolTable::Symbol> FindByName(const ResourceName& name) override {
168ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      auto iter = name_map_.find(name);
169ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      if (iter != name_map_.end()) {
170ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski        return CloneSymbol(iter->second);
171cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      }
172cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      return nullptr;
173cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    }
174cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
175ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override {
176ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      auto iter = id_map_.find(id);
177ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      if (iter != id_map_.end()) {
178ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski        return CloneSymbol(iter->second);
179cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      }
180cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      return nullptr;
181cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    }
182cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
183ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    std::list<std::unique_ptr<SymbolTable::Symbol>> symbols_;
184ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    std::map<ResourceName, SymbolTable::Symbol*> name_map_;
185ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    std::map<ResourceId, SymbolTable::Symbol*> id_map_;
186cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
187cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski   private:
188ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski    std::unique_ptr<SymbolTable::Symbol> CloneSymbol(SymbolTable::Symbol* sym) {
189b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski      std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>();
190cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      clone->id = sym->id;
191cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      if (sym->attribute) {
192b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski        clone->attribute = std::unique_ptr<Attribute>(sym->attribute->Clone(nullptr));
193cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      }
194ce5e56e243d262a9b65459c3bd0bb9eaadd40628Adam Lesinski      clone->is_public = sym->is_public;
195cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski      return clone;
196cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    }
197cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
198cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski    DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource);
199cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski  };
200cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski
201b522f04bc2a581e2877bef4a44ac00b827f879edAdam Lesinski  std::unique_ptr<StaticSymbolSource> symbol_source_ = util::make_unique<StaticSymbolSource>();
2021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
2031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
204cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace test
205cacb28f2d60858106e2819cc7d95a65e8bda890bAdam Lesinski}  // namespace aapt
2061ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
2071ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#endif /* AAPT_TEST_CONTEXT_H */
208