diff options
Diffstat (limited to 'tools/aapt2/proto/TableProtoDeserializer.cpp')
-rw-r--r-- | tools/aapt2/proto/TableProtoDeserializer.cpp | 229 |
1 files changed, 88 insertions, 141 deletions
diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp index 37d5ed0cf59d..b9d5878f2f71 100644 --- a/tools/aapt2/proto/TableProtoDeserializer.cpp +++ b/tools/aapt2/proto/TableProtoDeserializer.cpp @@ -55,66 +55,61 @@ class ReferenceIdToNameVisitor : public ValueVisitor { class PackagePbDeserializer { public: - PackagePbDeserializer(const android::ResStringPool* valuePool, - const android::ResStringPool* sourcePool, - const android::ResStringPool* symbolPool, - const Source& source, IDiagnostics* diag) - : value_pool_(valuePool), - source_pool_(sourcePool), - symbol_pool_(symbolPool), - source_(source), - diag_(diag) {} + PackagePbDeserializer(const android::ResStringPool* sourcePool, const Source& source, + IDiagnostics* diag) + : source_pool_(sourcePool), source_(source), diag_(diag) { + } public: - bool DeserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) { + bool DeserializeFromPb(const pb::Package& pb_package, ResourceTable* table) { Maybe<uint8_t> id; - if (pbPackage.has_package_id()) { - id = static_cast<uint8_t>(pbPackage.package_id()); + if (pb_package.has_package_id()) { + id = static_cast<uint8_t>(pb_package.package_id()); } - std::map<ResourceId, ResourceNameRef> idIndex; + std::map<ResourceId, ResourceNameRef> id_index; - ResourceTablePackage* pkg = table->CreatePackage(pbPackage.package_name(), id); - for (const pb::Type& pbType : pbPackage.types()) { - const ResourceType* resType = ParseResourceType(pbType.name()); - if (!resType) { - diag_->Error(DiagMessage(source_) << "unknown type '" << pbType.name() << "'"); + 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(*resType); + ResourceTableType* type = pkg->FindOrCreateType(*res_type); - for (const pb::Entry& pbEntry : pbType.entries()) { - ResourceEntry* entry = type->FindOrCreateEntry(pbEntry.name()); + 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 (pbEntry.has_symbol_status()) { - const pb::SymbolStatus& pbStatus = pbEntry.symbol_status(); - if (pbStatus.has_source()) { - DeserializeSourceFromPb(pbStatus.source(), *source_pool_, &entry->symbol_status.source); + // 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 (pbStatus.has_comment()) { - entry->symbol_status.comment = pbStatus.comment(); + if (pb_status.has_comment()) { + entry->symbol_status.comment = pb_status.comment(); } - entry->symbol_status.allow_new = pbStatus.allow_new(); + entry->symbol_status.allow_new = pb_status.allow_new(); - SymbolState visibility = DeserializeVisibilityFromPb(pbStatus.visibility()); + 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 (pbEntry.has_id()) { - entry->id = static_cast<uint16_t>(pbEntry.id()); + 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 (pbType.has_id()) { - type->id = static_cast<uint8_t>(pbType.id()); + if (pb_type.has_id()) { + type->id = static_cast<uint8_t>(pb_type.id()); } } } else if (visibility == SymbolState::kPrivate) { @@ -124,45 +119,44 @@ class PackagePbDeserializer { } } - ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id()); - if (resId.is_valid()) { - idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name); + 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& pbConfigValue : pbEntry.config_values()) { - const pb::ConfigDescription& pbConfig = pbConfigValue.config(); + for (const pb::ConfigValue& pb_config_value : pb_entry.config_value()) { + const pb::ConfigDescription& pb_config = pb_config_value.config(); ConfigDescription config; - if (!DeserializeConfigDescriptionFromPb(pbConfig, &config)) { + if (!DeserializeConfigDescriptionFromPb(pb_config, &config)) { diag_->Error(DiagMessage(source_) << "invalid configuration"); return {}; } - ResourceConfigValue* configValue = entry->FindOrCreateValue(config, pbConfig.product()); - if (configValue->value) { + ResourceConfigValue* config_value = entry->FindOrCreateValue(config, pb_config.product()); + if (config_value->value) { // Duplicate config. diag_->Error(DiagMessage(source_) << "duplicate configuration"); return {}; } - configValue->value = - DeserializeValueFromPb(pbConfigValue.value(), config, &table->string_pool); - if (!configValue->value) { + config_value->value = + DeserializeValueFromPb(pb_config_value.value(), config, &table->string_pool); + if (!config_value->value) { return {}; } } } } - ReferenceIdToNameVisitor visitor(&idIndex); + 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) { + 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>(); @@ -173,45 +167,32 @@ class PackagePbDeserializer { } else if (pb_item.has_prim()) { const pb::Primitive& pb_prim = pb_item.prim(); - android::Res_value prim = {}; - prim.dataType = static_cast<uint8_t>(pb_prim.type()); - prim.data = pb_prim.data(); - return util::make_unique<BinaryPrimitive>(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()) { - const uint32_t idx = pb_item.str().idx(); - const std::string str = util::GetString(*value_pool_, idx); - - const android::ResStringPool_span* spans = value_pool_->styleAt(idx); - if (spans && spans->name.index != android::ResStringPool_span::END) { - StyleString style_str = {str}; - while (spans->name.index != android::ResStringPool_span::END) { - style_str.spans.push_back( - Span{util::GetString(*value_pool_, spans->name.index), - spans->firstChar, spans->lastChar}); - spans++; - } - return util::make_unique<StyledString>(pool->MakeRef( - style_str, StringPool::Context(StringPool::Context::kNormalPriority, config))); - } return util::make_unique<String>( - pool->MakeRef(str, StringPool::Context(config))); + pool->MakeRef(pb_item.str().value(), StringPool::Context(config))); } else if (pb_item.has_raw_str()) { - const uint32_t idx = pb_item.raw_str().idx(); - const std::string str = util::GetString(*value_pool_, idx); return util::make_unique<RawString>( - pool->MakeRef(str, StringPool::Context(config))); + 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()) { - const uint32_t idx = pb_item.file().path_idx(); - const std::string str = util::GetString(*value_pool_, idx); return util::make_unique<FileReference>(pool->MakeRef( - str, - StringPool::Context(StringPool::Context::kHighPriority, config))); + pb_item.file().path(), StringPool::Context(StringPool::Context::kHighPriority, config))); } else { diag_->Error(DiagMessage(source_) << "unknown item"); @@ -222,8 +203,6 @@ class PackagePbDeserializer { std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value, const ConfigDescription& config, StringPool* pool) { - const bool is_weak = pb_value.has_weak() ? pb_value.weak() : false; - std::unique_ptr<Value> value; if (pb_value.has_item()) { value = DeserializeItemFromPb(pb_value.item(), config, pool); @@ -235,11 +214,11 @@ class PackagePbDeserializer { 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>(is_weak); + 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.symbols()) { + 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)) { @@ -255,20 +234,18 @@ class PackagePbDeserializer { 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())) { + 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); + 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.entries()) { + 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)) { @@ -288,7 +265,7 @@ class PackagePbDeserializer { } 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.entries()) { + for (const pb::Styleable_Entry& pb_entry : pb_styleable.entry()) { Reference attr_ref; DeserializeItemCommon(pb_entry, &attr_ref); DeserializeReferenceFromPb(pb_entry.attr(), &attr_ref); @@ -299,25 +276,23 @@ class PackagePbDeserializer { } 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_Entry& pb_entry : pb_array.entries()) { - std::unique_ptr<Item> item = - DeserializeItemFromPb(pb_entry.item(), config, pool); + 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->items.push_back(std::move(item)); + 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.entries()) { + 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); + plural->values[pluralIdx] = DeserializeItemFromPb(pb_entry.item(), config, pool); if (!plural->values[pluralIdx]) { return {}; } @@ -337,7 +312,7 @@ class PackagePbDeserializer { CHECK(value) << "forgot to set value"; - value->SetWeak(is_weak); + value->SetWeak(pb_value.weak()); DeserializeItemCommon(pb_value, value.get()); return value; } @@ -350,11 +325,10 @@ class PackagePbDeserializer { out_ref->id = ResourceId(pb_ref.id()); } - if (pb_ref.has_symbol_idx()) { - const std::string str_symbol = util::GetString(*symbol_pool_, pb_ref.symbol_idx()); + if (pb_ref.has_name()) { ResourceNameRef name_ref; - if (!ResourceUtils::ParseResourceName(str_symbol, &name_ref, nullptr)) { - diag_->Error(DiagMessage(source_) << "invalid reference name '" << str_symbol << "'"); + if (!ResourceUtils::ParseResourceName(pb_ref.name(), &name_ref, nullptr)) { + diag_->Error(DiagMessage(source_) << "invalid reference name '" << pb_ref.name() << "'"); return false; } @@ -377,61 +351,33 @@ class PackagePbDeserializer { } private: - const android::ResStringPool* value_pool_; const android::ResStringPool* source_pool_; - const android::ResStringPool* symbol_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 +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>(); - if (!pb_table.has_string_pool()) { - diag->Error(DiagMessage(source) << "no string pool found"); - return {}; - } - - ResStringPool value_pool; - status_t result = value_pool.setTo(pb_table.string_pool().data().data(), - pb_table.string_pool().data().size()); - if (result != NO_ERROR) { - diag->Error(DiagMessage(source) << "invalid string pool"); - return {}; - } - ResStringPool source_pool; if (pb_table.has_source_pool()) { - result = source_pool.setTo(pb_table.source_pool().data().data(), - pb_table.source_pool().data().size()); + 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 {}; } } - ResStringPool symbol_pool; - if (pb_table.has_symbol_pool()) { - result = symbol_pool.setTo(pb_table.symbol_pool().data().data(), - pb_table.symbol_pool().data().size()); - if (result != NO_ERROR) { - diag->Error(DiagMessage(source) << "invalid symbol pool"); - return {}; - } - } - - PackagePbDeserializer package_pb_deserializer(&value_pool, &source_pool, - &symbol_pool, source, diag); - for (const pb::Package& pb_package : pb_table.packages()) { + 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 {}; } @@ -440,7 +386,7 @@ std::unique_ptr<ResourceTable> DeserializeTableFromPb( } std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb( - const pb::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) { + const pb::internal::CompiledFile& pb_file, const Source& source, IDiagnostics* diag) { std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>(); ResourceNameRef name_ref; @@ -456,19 +402,20 @@ std::unique_ptr<ResourceFile> DeserializeCompiledFileFromPb( file->source.path = pb_file.source_path(); DeserializeConfigDescriptionFromPb(pb_file.config(), &file->config); - for (const pb::CompiledFile_Symbol& pb_symbol : pb_file.exported_symbols()) { - // Need to create an lvalue here so that nameRef can point to something - // real. - if (!ResourceUtils::ParseResourceName(pb_symbol.resource_name(), - &name_ref)) { + 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 {}; } - file->exported_symbols.push_back( - SourcedResourceName{name_ref.ToResourceName(), pb_symbol.line_no()}); + 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; } |