summaryrefslogtreecommitdiff
path: root/tools/aapt2/proto/TableProtoDeserializer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/aapt2/proto/TableProtoDeserializer.cpp')
-rw-r--r--tools/aapt2/proto/TableProtoDeserializer.cpp423
1 files changed, 0 insertions, 423 deletions
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp
deleted file mode 100644
index b9d5878f2f71..000000000000
--- a/tools/aapt2/proto/TableProtoDeserializer.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "proto/ProtoSerialize.h"
-
-#include "android-base/logging.h"
-#include "androidfw/ResourceTypes.h"
-
-#include "ResourceTable.h"
-#include "ResourceUtils.h"
-#include "ValueVisitor.h"
-#include "proto/ProtoHelpers.h"
-
-namespace aapt {
-
-namespace {
-
-class ReferenceIdToNameVisitor : public ValueVisitor {
- public:
- using ValueVisitor::Visit;
-
- explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping)
- : mapping_(mapping) {
- CHECK(mapping_ != nullptr);
- }
-
- void Visit(Reference* reference) override {
- if (!reference->id || !reference->id.value().is_valid()) {
- return;
- }
-
- ResourceId id = reference->id.value();
- auto cache_iter = mapping_->find(id);
- if (cache_iter != mapping_->end()) {
- reference->name = cache_iter->second.ToResourceName();
- }
- }
-
- private:
- const std::map<ResourceId, ResourceNameRef>* mapping_;
-};
-
-class PackagePbDeserializer {
- public:
- PackagePbDeserializer(const android::ResStringPool* sourcePool, const Source& source,
- IDiagnostics* diag)
- : source_pool_(sourcePool), source_(source), diag_(diag) {
- }
-
- public:
- bool DeserializeFromPb(const pb::Package& pb_package, ResourceTable* table) {
- Maybe<uint8_t> id;
- if (pb_package.has_package_id()) {
- id = static_cast<uint8_t>(pb_package.package_id());
- }
-
- std::map<ResourceId, ResourceNameRef> id_index;
-
- ResourceTablePackage* pkg = table->CreatePackage(pb_package.package_name(), id);
- for (const pb::Type& pb_type : pb_package.type()) {
- const ResourceType* res_type = ParseResourceType(pb_type.name());
- if (res_type == nullptr) {
- diag_->Error(DiagMessage(source_) << "unknown type '" << pb_type.name() << "'");
- return {};
- }
-
- ResourceTableType* type = pkg->FindOrCreateType(*res_type);
-
- for (const pb::Entry& pb_entry : pb_type.entry()) {
- ResourceEntry* entry = type->FindOrCreateEntry(pb_entry.name());
-
- // Deserialize the symbol status (public/private with source and comments).
- if (pb_entry.has_symbol_status()) {
- const pb::SymbolStatus& pb_status = pb_entry.symbol_status();
- if (pb_status.has_source()) {
- DeserializeSourceFromPb(pb_status.source(), *source_pool_,
- &entry->symbol_status.source);
- }
-
- if (pb_status.has_comment()) {
- entry->symbol_status.comment = pb_status.comment();
- }
-
- entry->symbol_status.allow_new = pb_status.allow_new();
-
- SymbolState visibility = DeserializeVisibilityFromPb(pb_status.visibility());
- entry->symbol_status.state = visibility;
-
- if (visibility == SymbolState::kPublic) {
- // This is a public symbol, we must encode the ID now if there is one.
- if (pb_entry.has_id()) {
- entry->id = static_cast<uint16_t>(pb_entry.id());
- }
-
- if (type->symbol_status.state != SymbolState::kPublic) {
- // If the type has not been made public, do so now.
- type->symbol_status.state = SymbolState::kPublic;
- if (pb_type.has_id()) {
- type->id = static_cast<uint8_t>(pb_type.id());
- }
- }
- } else if (visibility == SymbolState::kPrivate) {
- if (type->symbol_status.state == SymbolState::kUndefined) {
- type->symbol_status.state = SymbolState::kPrivate;
- }
- }
- }
-
- ResourceId resid(pb_package.package_id(), pb_type.id(), pb_entry.id());
- if (resid.is_valid()) {
- id_index[resid] = ResourceNameRef(pkg->name, type->type, entry->name);
- }
-
- for (const pb::ConfigValue& pb_config_value : pb_entry.config_value()) {
- const pb::ConfigDescription& pb_config = pb_config_value.config();
-
- ConfigDescription config;
- if (!DeserializeConfigDescriptionFromPb(pb_config, &config)) {
- diag_->Error(DiagMessage(source_) << "invalid configuration");
- return {};
- }
-
- ResourceConfigValue* config_value = entry->FindOrCreateValue(config, pb_config.product());
- if (config_value->value) {
- // Duplicate config.
- diag_->Error(DiagMessage(source_) << "duplicate configuration");
- return {};
- }
-
- config_value->value =
- DeserializeValueFromPb(pb_config_value.value(), config, &table->string_pool);
- if (!config_value->value) {
- return {};
- }
- }
- }
- }
-
- ReferenceIdToNameVisitor visitor(&id_index);
- VisitAllValuesInPackage(pkg, &visitor);
- return true;
- }
-
- private:
- std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
- const ConfigDescription& config, StringPool* pool) {
- if (pb_item.has_ref()) {
- const pb::Reference& pb_ref = pb_item.ref();
- std::unique_ptr<Reference> ref = util::make_unique<Reference>();
- if (!DeserializeReferenceFromPb(pb_ref, ref.get())) {
- return {};
- }
- return std::move(ref);
-
- } else if (pb_item.has_prim()) {
- const pb::Primitive& pb_prim = pb_item.prim();
- return util::make_unique<BinaryPrimitive>(static_cast<uint8_t>(pb_prim.type()),
- pb_prim.data());
-
- } else if (pb_item.has_id()) {
- return util::make_unique<Id>();
-
- } else if (pb_item.has_str()) {
- return util::make_unique<String>(
- pool->MakeRef(pb_item.str().value(), StringPool::Context(config)));
-
- } else if (pb_item.has_raw_str()) {
- return util::make_unique<RawString>(
- pool->MakeRef(pb_item.raw_str().value(), StringPool::Context(config)));
-
- } else if (pb_item.has_styled_str()) {
- const pb::StyledString& pb_str = pb_item.styled_str();
- StyleString style_str{pb_str.value()};
- for (const pb::StyledString::Span& pb_span : pb_str.span()) {
- style_str.spans.push_back(Span{pb_span.tag(), pb_span.first_char(), pb_span.last_char()});
- }
- return util::make_unique<StyledString>(pool->MakeRef(
- style_str, StringPool::Context(StringPool::Context::kNormalPriority, config)));
-
- } else if (pb_item.has_file()) {
- return util::make_unique<FileReference>(pool->MakeRef(
- pb_item.file().path(), StringPool::Context(StringPool::Context::kHighPriority, config)));
-
- } else {
- diag_->Error(DiagMessage(source_) << "unknown item");
- }
- return {};
- }
-
- std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
- const ConfigDescription& config,
- StringPool* pool) {
- std::unique_ptr<Value> value;
- if (pb_value.has_item()) {
- value = DeserializeItemFromPb(pb_value.item(), config, pool);
- if (!value) {
- return {};
- }
-
- } else if (pb_value.has_compound_value()) {
- const pb::CompoundValue& pb_compound_value = pb_value.compound_value();
- if (pb_compound_value.has_attr()) {
- const pb::Attribute& pb_attr = pb_compound_value.attr();
- std::unique_ptr<Attribute> attr = util::make_unique<Attribute>();
- attr->type_mask = pb_attr.format_flags();
- attr->min_int = pb_attr.min_int();
- attr->max_int = pb_attr.max_int();
- for (const pb::Attribute_Symbol& pb_symbol : pb_attr.symbol()) {
- Attribute::Symbol symbol;
- DeserializeItemCommon(pb_symbol, &symbol.symbol);
- if (!DeserializeReferenceFromPb(pb_symbol.name(), &symbol.symbol)) {
- return {};
- }
- symbol.value = pb_symbol.value();
- attr->symbols.push_back(std::move(symbol));
- }
- value = std::move(attr);
-
- } else if (pb_compound_value.has_style()) {
- const pb::Style& pb_style = pb_compound_value.style();
- std::unique_ptr<Style> style = util::make_unique<Style>();
- if (pb_style.has_parent()) {
- style->parent = Reference();
- if (!DeserializeReferenceFromPb(pb_style.parent(), &style->parent.value())) {
- return {};
- }
-
- if (pb_style.has_parent_source()) {
- Source parent_source;
- DeserializeSourceFromPb(pb_style.parent_source(), *source_pool_, &parent_source);
- style->parent.value().SetSource(std::move(parent_source));
- }
- }
-
- for (const pb::Style_Entry& pb_entry : pb_style.entry()) {
- Style::Entry entry;
- DeserializeItemCommon(pb_entry, &entry.key);
- if (!DeserializeReferenceFromPb(pb_entry.key(), &entry.key)) {
- return {};
- }
-
- entry.value = DeserializeItemFromPb(pb_entry.item(), config, pool);
- if (!entry.value) {
- return {};
- }
-
- DeserializeItemCommon(pb_entry, entry.value.get());
- style->entries.push_back(std::move(entry));
- }
- value = std::move(style);
-
- } else if (pb_compound_value.has_styleable()) {
- const pb::Styleable& pb_styleable = pb_compound_value.styleable();
- std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
- for (const pb::Styleable_Entry& pb_entry : pb_styleable.entry()) {
- Reference attr_ref;
- DeserializeItemCommon(pb_entry, &attr_ref);
- DeserializeReferenceFromPb(pb_entry.attr(), &attr_ref);
- styleable->entries.push_back(std::move(attr_ref));
- }
- value = std::move(styleable);
-
- } else if (pb_compound_value.has_array()) {
- const pb::Array& pb_array = pb_compound_value.array();
- std::unique_ptr<Array> array = util::make_unique<Array>();
- for (const pb::Array_Element& pb_entry : pb_array.element()) {
- std::unique_ptr<Item> item = DeserializeItemFromPb(pb_entry.item(), config, pool);
- if (!item) {
- return {};
- }
-
- DeserializeItemCommon(pb_entry, item.get());
- array->elements.push_back(std::move(item));
- }
- value = std::move(array);
-
- } else if (pb_compound_value.has_plural()) {
- const pb::Plural& pb_plural = pb_compound_value.plural();
- std::unique_ptr<Plural> plural = util::make_unique<Plural>();
- for (const pb::Plural_Entry& pb_entry : pb_plural.entry()) {
- size_t pluralIdx = DeserializePluralEnumFromPb(pb_entry.arity());
- plural->values[pluralIdx] = DeserializeItemFromPb(pb_entry.item(), config, pool);
- if (!plural->values[pluralIdx]) {
- return {};
- }
-
- DeserializeItemCommon(pb_entry, plural->values[pluralIdx].get());
- }
- value = std::move(plural);
-
- } else {
- diag_->Error(DiagMessage(source_) << "unknown compound value");
- return {};
- }
- } else {
- diag_->Error(DiagMessage(source_) << "unknown value");
- return {};
- }
-
- CHECK(value) << "forgot to set value";
-
- value->SetWeak(pb_value.weak());
- DeserializeItemCommon(pb_value, value.get());
- return value;
- }
-
- bool DeserializeReferenceFromPb(const pb::Reference& pb_ref, Reference* out_ref) {
- out_ref->reference_type = DeserializeReferenceTypeFromPb(pb_ref.type());
- out_ref->private_reference = pb_ref.private_();
-
- if (pb_ref.has_id()) {
- out_ref->id = ResourceId(pb_ref.id());
- }
-
- if (pb_ref.has_name()) {
- ResourceNameRef name_ref;
- if (!ResourceUtils::ParseResourceName(pb_ref.name(), &name_ref, nullptr)) {
- diag_->Error(DiagMessage(source_) << "invalid reference name '" << pb_ref.name() << "'");
- return false;
- }
-
- out_ref->name = name_ref.ToResourceName();
- }
- return true;
- }
-
- template <typename T>
- void DeserializeItemCommon(const T& pb_item, Value* out_value) {
- if (pb_item.has_source()) {
- Source source;
- DeserializeSourceFromPb(pb_item.source(), *source_pool_, &source);
- out_value->SetSource(std::move(source));
- }
-
- if (pb_item.has_comment()) {
- out_value->SetComment(pb_item.comment());
- }
- }
-
- private:
- const android::ResStringPool* source_pool_;
- const Source source_;
- IDiagnostics* diag_;
-};
-
-} // namespace
-
-std::unique_ptr<ResourceTable> DeserializeTableFromPb(const pb::ResourceTable& pb_table,
- const Source& source, IDiagnostics* diag) {
- // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
- // causes errors when qualifying it with android::
- using namespace android;
-
- std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
-
- ResStringPool source_pool;
- if (pb_table.has_source_pool()) {
- status_t result = source_pool.setTo(pb_table.source_pool().data().data(),
- pb_table.source_pool().data().size());
- if (result != NO_ERROR) {
- diag->Error(DiagMessage(source) << "invalid source pool");
- return {};
- }
- }
-
- PackagePbDeserializer package_pb_deserializer(&source_pool, source, diag);
- for (const pb::Package& pb_package : pb_table.package()) {
- if (!package_pb_deserializer.DeserializeFromPb(pb_package, table.get())) {
- return {};
- }
- }
- return table;
-}
-
-std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb(
- const pb::internal::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) {
- std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();
-
- ResourceNameRef name_ref;
-
- // Need to create an lvalue here so that nameRef can point to something real.
- if (!ResourceUtils::ParseResourceName(pb_file.resource_name(), &name_ref)) {
- diag->Error(DiagMessage(source)
- << "invalid resource name in compiled file header: "
- << pb_file.resource_name());
- return {};
- }
- file->name = name_ref.ToResourceName();
- file->source.path = pb_file.source_path();
- DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config);
-
- for (const pb::internal::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbol()) {
- // Need to create an lvalue here so that nameRef can point to something real.
- if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(), &name_ref)) {
- diag->Error(DiagMessage(source)
- << "invalid resource name for exported symbol in "
- "compiled file header: "
- << pb_file.resource_name());
- return {};
- }
- size_t line = 0u;
- if (pb_symbol.has_source()) {
- line = pb_symbol.source().line_number();
- }
- file->exported_symbols.push_back(SourcedResourceName{name_ref.ToResourceName(), line});
- }
- return file;
-}
-
-} // namespace aapt