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
201ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "NameMangler.h"
211ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "util/Util.h"
221ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
231ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "process/IResourceTableConsumer.h"
241ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "process/SymbolTable.h"
251ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include "test/Common.h"
261ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
271ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <cassert>
281ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#include <list>
291ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace aapt {
311ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskinamespace test {
321ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
331ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass Context : public IAaptContext {
341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskipublic:
3564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    SymbolTable* getExternalSymbols() override {
3664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        return &mSymbols;
371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
381ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    IDiagnostics* getDiagnostics() override {
4064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        return &mDiagnostics;
411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
4364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    const std::u16string& getCompilationPackage() override {
441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        assert(mCompilationPackage && "package name not set");
451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return mCompilationPackage.value();
461ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    uint8_t getPackageId() override {
491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        assert(mPackageId && "package ID not set");
501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return mPackageId.value();
511ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
521ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
531ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    NameMangler* getNameMangler() override {
5464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        return &mNameMangler;
551ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
56355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski
57355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski    bool verbose() override {
58355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski        return false;
59355f285ffd000f6cfe76680eb22d010546d124bbAdam Lesinski    }
6064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
6164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinskiprivate:
6264587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    friend class ContextBuilder;
6364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
6464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    Context() : mNameMangler({}) {
6564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    }
6664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
6764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    Maybe<std::u16string> mCompilationPackage;
6864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    Maybe<uint8_t> mPackageId;
6964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    StdErrDiagnostics mDiagnostics;
7064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    SymbolTable mSymbols;
7164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    NameMangler mNameMangler;
721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
741ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiclass ContextBuilder {
751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate:
761ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    std::unique_ptr<Context> mContext = std::unique_ptr<Context>(new Context());
771ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
781ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskipublic:
791ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    ContextBuilder& setCompilationPackage(const StringPiece16& package) {
801ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        mContext->mCompilationPackage = package.toString();
811ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return *this;
821ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
831ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
841ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    ContextBuilder& setPackageId(uint8_t id) {
851ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        mContext->mPackageId = id;
861ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return *this;
871ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
881ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
8964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    ContextBuilder& setNameManglerPolicy(NameManglerPolicy policy) {
9064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mContext->mNameMangler = NameMangler(policy);
911ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return *this;
921ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
931ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
9464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    ContextBuilder& addSymbolSource(std::unique_ptr<ISymbolSource> src) {
9564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mContext->getExternalSymbols()->appendSource(std::move(src));
961ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return *this;
971ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
981ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
991ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    std::unique_ptr<Context> build() {
1001ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        return std::move(mContext);
1011ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski    }
1021ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1031ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
10464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinskiclass StaticSymbolSourceBuilder {
10564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinskipublic:
10664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    StaticSymbolSourceBuilder& addPublicSymbol(const StringPiece16& name, ResourceId id,
10764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                                               std::unique_ptr<Attribute> attr = {}) {
10864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>(
10964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                id, std::move(attr), true);
11064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get();
11164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mSymbolSource->mIdMap[id] = symbol.get();
11264587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mSymbolSource->mSymbols.push_back(std::move(symbol));
11364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        return *this;
11464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    }
11564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
11664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    StaticSymbolSourceBuilder& addSymbol(const StringPiece16& name, ResourceId id,
11764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                                         std::unique_ptr<Attribute> attr = {}) {
11864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>(
11964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                id, std::move(attr), false);
12064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mSymbolSource->mNameMap[parseNameOrDie(name)] = symbol.get();
12164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mSymbolSource->mIdMap[id] = symbol.get();
12264587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        mSymbolSource->mSymbols.push_back(std::move(symbol));
12364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        return *this;
12464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    }
12564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
12664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    std::unique_ptr<ISymbolSource> build() {
12764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        return std::move(mSymbolSource);
12864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    }
12964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski
1301ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinskiprivate:
13164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    class StaticSymbolSource : public ISymbolSource {
13264587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    public:
13364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        StaticSymbolSource() = default;
1341ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
13564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::unique_ptr<SymbolTable::Symbol> findByName(const ResourceName& name) override {
1361ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            auto iter = mNameMap.find(name);
1371ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            if (iter != mNameMap.end()) {
13864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                return cloneSymbol(iter->second);
1391ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            }
1401ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            return nullptr;
1411ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        }
1421ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
14364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override {
1441ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            auto iter = mIdMap.find(id);
1451ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            if (iter != mIdMap.end()) {
14664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                return cloneSymbol(iter->second);
1471ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            }
1481ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski            return nullptr;
1491ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski        }
1501ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
15164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::list<std::unique_ptr<SymbolTable::Symbol>> mSymbols;
15264587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::map<ResourceName, SymbolTable::Symbol*> mNameMap;
15364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::map<ResourceId, SymbolTable::Symbol*> mIdMap;
1541ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
15564587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    private:
15664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        std::unique_ptr<SymbolTable::Symbol> cloneSymbol(SymbolTable::Symbol* sym) {
15764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski            std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>();
15864587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski            clone->id = sym->id;
15964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski            if (sym->attribute) {
16064587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski                clone->attribute = std::unique_ptr<Attribute>(sym->attribute->clone(nullptr));
16164587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski            }
16264587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski            clone->isPublic = sym->isPublic;
16364587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski            return clone;
16464587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        }
165467f171315f9c2037fcd3eb5edcfabc40671bf7bAdam Lesinski
16664587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski        DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource);
16764587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    };
1681ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
16964587af8179affd38ee26543b748f2d63b7f67bbAdam Lesinski    std::unique_ptr<StaticSymbolSource> mSymbolSource = util::make_unique<StaticSymbolSource>();
1701ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski};
1711ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1721ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} // namespace test
1731ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski} // namespace aapt
1741ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski
1751ab598f46c3ff520a67f9d80194847741f3467abAdam Lesinski#endif /* AAPT_TEST_CONTEXT_H */
176