From 5b6ee115489ce93dafce57d7f5ac33564cd6ef52 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 28 Jul 2017 17:10:35 -0700 Subject: AAPT2: Ensure style strings are always first in StringPool Move the styled strings to a separate section of the StringPool so that sorting can never mess up the order of Styles. Bug: 63570514 Test: make aapt2_tests Change-Id: Id2ce1355b92be1bb31ce0daa7e54ae9b5b6c2ffe --- tools/aapt2/ResourceParser.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'tools/aapt2/ResourceParser.cpp') diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 9a37913f0edc..a5783a532e23 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -268,8 +268,7 @@ bool ResourceParser::Parse(xml::XmlPullParser* parser) { continue; } - if (!parser->element_namespace().empty() || - parser->element_name() != "resources") { + if (!parser->element_namespace().empty() || parser->element_name() != "resources") { diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) << "root element must be "); return false; @@ -328,8 +327,7 @@ bool ResourceParser::ParseResources(xml::XmlPullParser* parser) { parsed_resource.comment = std::move(comment); // Extract the product name if it exists. - if (Maybe maybe_product = - xml::FindNonEmptyAttribute(parser, "product")) { + if (Maybe maybe_product = xml::FindNonEmptyAttribute(parser, "product")) { parsed_resource.product = maybe_product.value().to_string(); } @@ -348,10 +346,8 @@ bool ResourceParser::ParseResources(xml::XmlPullParser* parser) { for (const ResourceName& stripped_resource : stripped_resources) { if (!table_->FindResource(stripped_resource)) { // Failed to find the resource. - diag_->Error(DiagMessage(source_) - << "resource '" << stripped_resource - << "' " - "was filtered out but no product variant remains"); + diag_->Error(DiagMessage(source_) << "resource '" << stripped_resource + << "' was filtered out but no product variant remains"); error = true; } } @@ -589,7 +585,7 @@ std::unique_ptr ResourceParser::ParseXml(xml::XmlPullParser* parser, // This can only be a StyledString. std::unique_ptr styled_string = util::make_unique(table_->string_pool.MakeRef( - style_string, StringPool::Context(StringPool::Context::kStylePriority, config_))); + style_string, StringPool::Context(StringPool::Context::kNormalPriority, config_))); styled_string->untranslatable_sections = std::move(untranslatable_sections); return std::move(styled_string); } -- cgit v1.2.3-59-g8ed1b From b791721cd1a6154e5582d824f5d20b2c8b8d5ac5 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Thu, 10 Aug 2017 15:37:28 -0700 Subject: AAPT2: Define intermediate compiled XML proto This proto format is meant to encapsulate more information that is specific to Android and allows for easier validation and manipulation across tools. Test: make aapt2_tests Bug: 65645766 Change-Id: I13bc34a460671fc0a36246be0d287a3d37d244d6 Merged-In: I13bc34a460671fc0a36246be0d287a3d37d244d6 --- tools/aapt2/Android.bp | 3 +- tools/aapt2/Format.proto | 414 --------------------- tools/aapt2/ResourceParser.cpp | 2 +- tools/aapt2/ResourceParser_test.cpp | 12 +- tools/aapt2/ResourceValues.cpp | 13 +- tools/aapt2/ResourceValues.h | 2 +- tools/aapt2/ResourceValues_test.cpp | 18 +- tools/aapt2/Resources.proto | 471 ++++++++++++++++++++++++ tools/aapt2/ResourcesInternal.proto | 52 +++ tools/aapt2/ValueVisitor.h | 2 +- tools/aapt2/cmd/Compile.cpp | 7 +- tools/aapt2/cmd/Dump.cpp | 6 +- tools/aapt2/cmd/Link.cpp | 2 +- tools/aapt2/flatten/TableFlattener.cpp | 2 +- tools/aapt2/proto/ProtoHelpers.cpp | 51 ++- tools/aapt2/proto/ProtoHelpers.h | 3 +- tools/aapt2/proto/ProtoSerialize.h | 16 +- tools/aapt2/proto/TableProtoDeserializer.cpp | 110 +++--- tools/aapt2/proto/TableProtoSerializer.cpp | 49 ++- tools/aapt2/proto/TableProtoSerializer_test.cpp | 10 +- tools/aapt2/unflatten/BinaryResourceParser.cpp | 2 +- 21 files changed, 677 insertions(+), 570 deletions(-) delete mode 100644 tools/aapt2/Format.proto create mode 100644 tools/aapt2/Resources.proto create mode 100644 tools/aapt2/ResourcesInternal.proto (limited to 'tools/aapt2/ResourceParser.cpp') diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index 53794e641b0f..2ae2e496f25d 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -142,7 +142,8 @@ cc_library_host_static { "xml/XmlDom.cpp", "xml/XmlPullParser.cpp", "xml/XmlUtil.cpp", - "Format.proto", + "Resources.proto", + "ResourcesInternal.proto", ], proto: { export_proto_headers: true, diff --git a/tools/aapt2/Format.proto b/tools/aapt2/Format.proto deleted file mode 100644 index 6be7f02dc7d2..000000000000 --- a/tools/aapt2/Format.proto +++ /dev/null @@ -1,414 +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. - */ - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package aapt.pb; - -// A configuration description that wraps the binary form of the C++ class -// aapt::ConfigDescription, with an added product definition. -message ConfigDescription { - optional bytes data = 1; - optional string product = 2; -} - -// A string pool that wraps the binary form of the C++ class android::ResStringPool. -message StringPool { - optional bytes data = 1; -} - -// Developer friendly source file information for an entity in the resource table. -message Source { - // The index of the string path within the source string pool of a ResourceTable. - optional uint32 path_idx = 1; - - optional uint32 line_no = 2; - optional uint32 col_no = 3; -} - -// The top level message representing an external resource file (layout XML, PNG, etc). -message CompiledFile { - message Symbol { - // The name of the symbol (in the form package:type/name). - optional string resource_name = 1; - - // Line number in the file at which this symbol is defined. For debug use. - optional uint32 line_no = 2; - } - - // The name of the resource (in the form package:type/name). - optional string resource_name = 1; - - // The configuration for which the resource is defined. - optional ConfigDescription config = 2; - - // The filesystem path to where the source file originated. - // Mainly used to display helpful error messages. - optional string source_path = 3; - - // Any symbols this file auto-generates/exports (eg. @+id/foo in an XML file). - repeated Symbol exported_symbols = 4; -} - -// Top level message representing a resource table. -message ResourceTable { - // The string pool containing source paths referenced throughout the resource table. This does - // not end up in the final binary ARSC file. - optional StringPool source_pool = 1; - - // Resource definitions corresponding to an Android package. - repeated Package packages = 2; -} - -// Defines resources for an Android package. -message Package { - // The package ID of this package, in the range [0x00, 0xff]. - // The ID 0x00 is reserved for shared libraries, or when the ID is assigned at run-time. - // The ID 0x01 is reserved for the 'android' package (framework). - // The ID range [0x02, 0x7f) is reserved for auto-assignment to shared libraries at run-time. - // The ID 0x7f is reserved for the application package. - // IDs > 0x7f are reserved for the application as well and are treated as feature splits. - optional uint32 package_id = 1; - - // The Java compatible Android package name of the app. - optional string package_name = 2; - - // The series of types defined by the package. - repeated Type types = 3; -} - -// A set of resources grouped under a common type. Such types include string, layout, xml, dimen, -// attr, etc. This maps to the second part of a resource identifier in Java (R.type.entry). -message Type { - // The ID of the type. This may be 0, which indicates no ID is set. - optional uint32 id = 1; - - // The name of the type. This corresponds to the 'type' part of a full resource name of the form - // package:type/entry. The set of legal type names is listed in Resource.cpp. - optional string name = 2; - - // The entries defined for this type. - repeated Entry entries = 3; -} - -// The status of a symbol/entry. This contains information like visibility (public/private), -// comments, and whether the entry can be overridden. -message SymbolStatus { - // The visibility of the resource outside of its package. - enum Visibility { - // No visibility was explicitly specified. This is typically treated as private. - // The distinction is important when two separate R.java files are generated: a public and - // private one. An unknown visibility, in this case, would cause the resource to be omitted - // from either R.java. - Unknown = 0; - - // A resource was explicitly marked as private. This means the resource can not be accessed - // outside of its package unless the @*package:type/entry notation is used (the asterisk being - // the private accessor). If two R.java files are generated (private + public), the resource - // will only be emitted to the private R.java file. - Private = 1; - - // A resource was explicitly marked as public. This means the resource can be accessed - // from any package, and is emitted into all R.java files, public and private. - Public = 2; - } - - optional Visibility visibility = 1; - - // The path at which this entry's visibility was defined (eg. public.xml). - optional Source source = 2; - - // The comment associated with the tag. - optional string comment = 3; - - // Whether the symbol can be merged into another resource table without there being an existing - // definition to override. Used for overlays and set to true when is specified. - optional bool allow_new = 4; -} - -// An entry declaration. An entry has a full resource ID that is the combination of package ID, -// type ID, and its own entry ID. An entry on its own has no value, but values are defined for -// various configurations/variants. -message Entry { - // The ID of this entry. Together with the package ID and type ID, this forms a full resource ID - // of the form 0xPPTTEEEE, where PP is the package ID, TT is the type ID, and EEEE is the entry - // ID. - optional uint32 id = 1; - - // The name of this entry. This corresponds to the 'entry' part of a full resource name of the - // form package:type/entry. - optional string name = 2; - - // The symbol status of this entry, which includes visibility information. - optional SymbolStatus symbol_status = 3; - - // The set of values defined for this entry, each corresponding to a different - // configuration/variant. - repeated ConfigValue config_values = 4; -} - -// A Configuration/Value pair. -message ConfigValue { - optional ConfigDescription config = 1; - optional Value value = 2; -} - -// The generic meta-data for every value in a resource table. -message Value { - // Where the value was defined. - optional Source source = 1; - - // Any comment associated with the value. - optional string comment = 2; - - // Whether the value can be overridden. - optional bool weak = 3; - - // If the value is an Item, this is set. - optional Item item = 4; - - // If the value is a CompoundValue, this is set. - optional CompoundValue compound_value = 5; -} - -// An Item is an abstract type. It represents a value that can appear inline in many places, such -// as XML attribute values or on the right hand side of style attribute definitions. The concrete -// type is one of the types below. Only one can be set. -message Item { - optional Reference ref = 1; - optional String str = 2; - optional RawString raw_str = 3; - optional StyledString styled_str = 4; - optional FileReference file = 5; - optional Id id = 6; - optional Primitive prim = 7; -} - -// A CompoundValue is an abstract type. It represents a value that is a made of other values. -// These can only usually appear as top-level resources. The concrete type is one of the types -// below. Only one can be set. -message CompoundValue { - optional Attribute attr = 1; - optional Style style = 2; - optional Styleable styleable = 3; - optional Array array = 4; - optional Plural plural = 5; -} - -// A value that is a reference to another resource. This reference can be by name or resource ID. -message Reference { - enum Type { - // A plain reference (@package:type/entry). - Ref = 0; - - // A reference to a theme attribute (?package:type/entry). - Attr = 1; - } - - optional Type type = 1; - - // The resource ID (0xPPTTEEEE) of the resource being referred. - optional uint32 id = 2; - - // The optional resource name. - optional string name = 3; - - // Whether this reference is referencing a private resource (@*package:type/entry). - optional bool private = 4; -} - -// A value that represents an ID. This is just a placeholder, as ID values are used to occupy a -// resource ID (0xPPTTEEEE) as a unique identifier. Their value is unimportant. -message Id { -} - -// A value that is a string. -message String { - optional string value = 1; -} - -// A value that is a raw string, which is unescaped/uninterpreted. This is typically used to -// represent the value of a style attribute before the attribute is compiled and the set of -// allowed values is known. -message RawString { - optional string value = 1; -} - -// A string with styling information, like html tags that specify boldness, italics, etc. -message StyledString { - // The raw text of the string. - optional string value = 1; - - // A Span marks a region of the string text that is styled. - message Span { - // The name of the tag, and its attributes, encoded as follows: - // tag_name;attr1=value1;attr2=value2;[...] - optional string tag = 1; - - // The first character position this span applies to, in UTF-16 offset. - optional uint32 first_char = 2; - - // The last character position this span applies to, in UTF-16 offset. - optional uint32 last_char = 3; - } - - repeated Span span = 2; -} - -// A value that is a reference to an external entity, like an XML file or a PNG. -message FileReference { - // Path to a file within the APK (typically res/type-config/entry.ext). - optional string path = 1; -} - -// A value that represents a primitive data type (float, int, boolean, etc.). -// Corresponds to the fields (type/data) of the C struct android::Res_value. -message Primitive { - optional uint32 type = 1; - optional uint32 data = 2; -} - -// A value that represents an XML attribute and what values it accepts. -message Attribute { - // A Symbol used to represent an enum or a flag. - message Symbol { - // Where the enum/flag item was defined. - optional Source source = 1; - - // Any comments associated with the enum or flag. - optional string comment = 2; - - // The name of the enum/flag as a reference. Enums/flag items are generated as ID resource - // values. - optional Reference name = 3; - - // The value of the enum/flag. - optional uint32 value = 4; - } - - // A bitmask of types that this XML attribute accepts. Corresponds to the flags in the C struct - // android::ResTable_map. - optional uint32 format_flags = 1; - - // The smallest integer allowed for this XML attribute. Only makes sense if the format includes - // TYPE_INTEGER. - optional int32 min_int = 2; - - // The largest integer allowed for this XML attribute. Only makes sense if the format includes - // TYPE_INTEGER. - optional int32 max_int = 3; - - // The set of enums/flags defined in this attribute. Only makes sense if the format includes - // either TYPE_ENUM or TYPE_FLAGS. Having both is an error. - repeated Symbol symbols = 4; -} - -// A value that represents a style. -message Style { - // An XML attribute/value pair defined in the style. - message Entry { - // Where the entry was defined. - optional Source source = 1; - - // Any comments associated with the entry. - optional string comment = 2; - - // A reference to the XML attribute. - optional Reference key = 3; - - // The Item defined for this XML attribute. - optional Item item = 4; - } - - // The optinal style from which this style inherits attributes. - optional Reference parent = 1; - - // The source file information of the parent inheritance declaration. - optional Source parent_source = 2; - - // The set of XML attribute/value pairs for this style. - repeated Entry entries = 3; -} - -// A value that represents a XML resource. These are not real resources and -// only end up as Java fields in the generated R.java. They do not end up in the binary ARSC file. -message Styleable { - // An attribute defined for this styleable. - message Entry { - // Where the attribute was defined within the block. - optional Source source = 1; - - // Any comments associated with the declaration. - optional string comment = 2; - - // The reference to the attribute. - optional Reference attr = 3; - } - - // The set of attribute declarations. - repeated Entry entries = 1; -} - -// A value that represents an array of resource values. -message Array { - // A single element of the array. - message Entry { - // Where the element was defined. - optional Source source = 1; - - // Any comments associated with the element. - optional string comment = 2; - - // The value assigned to this element. - optional Item item = 3; - } - - // The list of array elements. - repeated Entry entries = 1; -} - -// A value that represents a string and its many variations based on plurality. -message Plural { - // The arity of the plural. - enum Arity { - Zero = 0; - One = 1; - Two = 2; - Few = 3; - Many = 4; - Other = 5; - } - - // The plural value for a given arity. - message Entry { - // Where the plural was defined. - optional Source source = 1; - - // Any comments associated with the plural. - optional string comment = 2; - - // The arity of the plural. - optional Arity arity = 3; - - // The value assigned to this plural. - optional Item item = 4; - } - - // The set of arity/plural mappings. - repeated Entry entries = 1; -} diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index a5783a532e23..1c3ac2ad4f17 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -1219,7 +1219,7 @@ bool ResourceParser::ParseArrayImpl(xml::XmlPullParser* parser, continue; } item->SetSource(item_source); - array->items.emplace_back(std::move(item)); + array->elements.emplace_back(std::move(item)); } else if (!ShouldIgnoreElement(element_namespace, element_name)) { diag_->Error(DiagMessage(source_.WithLine(parser->line_number())) diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index 971b45eff35f..144ebd22e105 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -540,11 +540,11 @@ TEST_F(ResourceParserTest, ParseArray) { Array* array = test::GetValue(&table_, "array/foo"); ASSERT_THAT(array, NotNull()); - ASSERT_THAT(array->items, SizeIs(3)); + ASSERT_THAT(array->elements, SizeIs(3)); - EXPECT_THAT(ValueCast(array->items[0].get()), NotNull()); - EXPECT_THAT(ValueCast(array->items[1].get()), NotNull()); - EXPECT_THAT(ValueCast(array->items[2].get()), NotNull()); + EXPECT_THAT(ValueCast(array->elements[0].get()), NotNull()); + EXPECT_THAT(ValueCast(array->elements[1].get()), NotNull()); + EXPECT_THAT(ValueCast(array->elements[2].get()), NotNull()); } TEST_F(ResourceParserTest, ParseStringArray) { @@ -565,9 +565,9 @@ TEST_F(ResourceParserTest, ParseArrayWithFormat) { Array* array = test::GetValue(&table_, "array/foo"); ASSERT_THAT(array, NotNull()); - ASSERT_THAT(array->items, SizeIs(1)); + ASSERT_THAT(array->elements, SizeIs(1)); - String* str = ValueCast(array->items[0].get()); + String* str = ValueCast(array->elements[0].get()); ASSERT_THAT(str, NotNull()); EXPECT_THAT(*str, StrValueEq("100")); } diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp index eb59175edf3b..1cba19462839 100644 --- a/tools/aapt2/ResourceValues.cpp +++ b/tools/aapt2/ResourceValues.cpp @@ -805,13 +805,12 @@ bool Array::Equals(const Value* value) const { return false; } - if (items.size() != other->items.size()) { + if (elements.size() != other->elements.size()) { return false; } - return std::equal(items.begin(), items.end(), other->items.begin(), - [](const std::unique_ptr& a, - const std::unique_ptr& b) -> bool { + return std::equal(elements.begin(), elements.end(), other->elements.begin(), + [](const std::unique_ptr& a, const std::unique_ptr& b) -> bool { return a->Equals(b.get()); }); } @@ -820,14 +819,14 @@ Array* Array::Clone(StringPool* new_pool) const { Array* array = new Array(); array->comment_ = comment_; array->source_ = source_; - for (auto& item : items) { - array->items.emplace_back(std::unique_ptr(item->Clone(new_pool))); + for (auto& item : elements) { + array->elements.emplace_back(std::unique_ptr(item->Clone(new_pool))); } return array; } void Array::Print(std::ostream* out) const { - *out << "(array) [" << util::Joiner(items, ", ") << "]"; + *out << "(array) [" << util::Joiner(elements, ", ") << "]"; } bool Plural::Equals(const Value* value) const { diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h index 7e7547fc1b94..275864bbcd3e 100644 --- a/tools/aapt2/ResourceValues.h +++ b/tools/aapt2/ResourceValues.h @@ -292,7 +292,7 @@ struct Style : public BaseValue