1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef AAPT_RESOURCE_VALUES_H 18 #define AAPT_RESOURCE_VALUES_H 19 20 #include <array> 21 #include <limits> 22 #include <ostream> 23 #include <vector> 24 25 #include "androidfw/ResourceTypes.h" 26 #include "androidfw/StringPiece.h" 27 28 #include "Diagnostics.h" 29 #include "Resource.h" 30 #include "StringPool.h" 31 #include "ValueTransformer.h" 32 #include "io/File.h" 33 #include "text/Printer.h" 34 #include "util/Maybe.h" 35 36 namespace aapt { 37 38 class ValueVisitor; 39 class ConstValueVisitor; 40 41 // A resource value. This is an all-encompassing representation 42 // of Item and Map and their subclasses. The way to do 43 // type specific operations is to check the Value's type() and 44 // cast it to the appropriate subclass. This isn't super clean, 45 // but it is the simplest strategy. 46 class Value { 47 public: 48 virtual ~Value() = default; 49 50 // Whether this value is weak and can be overridden without warning or error. Default is false. IsWeak()51 bool IsWeak() const { 52 return weak_; 53 } 54 SetWeak(bool val)55 void SetWeak(bool val) { 56 weak_ = val; 57 } 58 59 // Whether the value is marked as translatable. This does not persist when flattened to binary. 60 // It is only used during compilation phase. SetTranslatable(bool val)61 void SetTranslatable(bool val) { 62 translatable_ = val; 63 } 64 65 // Default true. IsTranslatable()66 bool IsTranslatable() const { 67 return translatable_; 68 } 69 70 // Returns the source where this value was defined. GetSource()71 const Source& GetSource() const { 72 return source_; 73 } 74 SetSource(const Source & source)75 void SetSource(const Source& source) { 76 source_ = source; 77 } 78 SetSource(Source && source)79 void SetSource(Source&& source) { 80 source_ = std::move(source); 81 } 82 83 // Returns the comment that was associated with this resource. GetComment()84 const std::string& GetComment() const { 85 return comment_; 86 } 87 SetComment(const android::StringPiece & str)88 void SetComment(const android::StringPiece& str) { 89 comment_ = str.to_string(); 90 } 91 SetComment(std::string && str)92 void SetComment(std::string&& str) { 93 comment_ = std::move(str); 94 } 95 96 virtual bool Equals(const Value* value) const = 0; 97 98 // Calls the appropriate overload of ValueVisitor. 99 virtual void Accept(ValueVisitor* visitor) = 0; 100 101 // Calls the appropriate overload of ConstValueVisitor. 102 virtual void Accept(ConstValueVisitor* visitor) const = 0; 103 104 // Transform this Value into another Value using the transformer. 105 std::unique_ptr<Value> Transform(ValueTransformer& transformer) const; 106 107 // Human readable printout of this value. 108 virtual void Print(std::ostream* out) const = 0; 109 110 // Human readable printout of this value that may omit some information for the sake 111 // of brevity and readability. Default implementation just calls Print(). 112 virtual void PrettyPrint(text::Printer* printer) const; 113 114 friend std::ostream& operator<<(std::ostream& out, const Value& value); 115 116 protected: 117 Source source_; 118 std::string comment_; 119 bool weak_ = false; 120 bool translatable_ = true; 121 122 private: 123 virtual Value* TransformValueImpl(ValueTransformer& transformer) const = 0; 124 }; 125 126 // Inherit from this to get visitor accepting implementations for free. 127 template <typename Derived> 128 struct BaseValue : public Value { 129 void Accept(ValueVisitor* visitor) override; 130 void Accept(ConstValueVisitor* visitor) const override; 131 }; 132 133 // A resource item with a single value. This maps to android::ResTable_entry. 134 struct Item : public Value { 135 // Fills in an android::Res_value structure with this Item's binary representation. 136 // Returns false if an error occurred. 137 virtual bool Flatten(android::Res_value* out_value) const = 0; 138 139 // Transform this Item into another Item using the transformer. 140 std::unique_ptr<Item> Transform(ValueTransformer& transformer) const; 141 142 private: 143 virtual Item* TransformItemImpl(ValueTransformer& transformer) const = 0; 144 }; 145 146 // Inherit from this to get visitor accepting implementations for free. 147 template <typename Derived> 148 struct BaseItem : public Item { 149 void Accept(ValueVisitor* visitor) override; 150 void Accept(ConstValueVisitor* visitor) const override; 151 }; 152 153 // A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE. 154 // A reference can be symbolic (with the name set to a valid resource name) or be 155 // numeric (the id is set to a valid resource ID). 156 struct Reference : public TransformableItem<Reference, BaseItem<Reference>> { 157 enum class Type : uint8_t { 158 kResource, 159 kAttribute, 160 }; 161 162 Maybe<ResourceName> name; 163 Maybe<ResourceId> id; 164 std::optional<uint32_t> type_flags; 165 Reference::Type reference_type; 166 bool private_reference = false; 167 bool is_dynamic = false; 168 bool allow_raw = false; 169 170 Reference(); 171 explicit Reference(const ResourceNameRef& n, Type type = Type::kResource); 172 explicit Reference(const ResourceId& i, Type type = Type::kResource); 173 Reference(const ResourceNameRef& n, const ResourceId& i); 174 175 bool Equals(const Value* value) const override; 176 bool Flatten(android::Res_value* out_value) const override; 177 void Print(std::ostream* out) const override; 178 void PrettyPrint(text::Printer* printer) const override; 179 180 // Prints the reference without a package name if the package name matches the one given. 181 void PrettyPrint(const android::StringPiece& package, text::Printer* printer) const; 182 }; 183 184 bool operator<(const Reference&, const Reference&); 185 bool operator==(const Reference&, const Reference&); 186 187 // An ID resource. Has no real value, just a place holder. 188 struct Id : public TransformableItem<Id, BaseItem<Id>> { IdId189 Id() { 190 weak_ = true; 191 } 192 193 bool Equals(const Value* value) const override; 194 bool Flatten(android::Res_value* out) const override; 195 void Print(std::ostream* out) const override; 196 }; 197 198 // A raw, unprocessed string. This may contain quotations, escape sequences, and whitespace. 199 // This shall *NOT* end up in the final resource table. 200 struct RawString : public TransformableItem<RawString, BaseItem<RawString>> { 201 StringPool::Ref value; 202 203 explicit RawString(const StringPool::Ref& ref); 204 205 bool Equals(const Value* value) const override; 206 bool Flatten(android::Res_value* out_value) const override; 207 void Print(std::ostream* out) const override; 208 }; 209 210 // Identifies a range of characters in a string that are untranslatable. 211 // These should not be pseudolocalized. The start and end indices are measured in bytes. 212 struct UntranslatableSection { 213 // Start offset inclusive. 214 size_t start; 215 216 // End offset exclusive. 217 size_t end; 218 }; 219 220 inline bool operator==(const UntranslatableSection& a, const UntranslatableSection& b) { 221 return a.start == b.start && a.end == b.end; 222 } 223 224 inline bool operator!=(const UntranslatableSection& a, const UntranslatableSection& b) { 225 return a.start != b.start || a.end != b.end; 226 } 227 228 struct String : public TransformableItem<String, BaseItem<String>> { 229 StringPool::Ref value; 230 231 // Sections of the string to NOT translate. Mainly used 232 // for pseudolocalization. This data is NOT persisted 233 // in any format. 234 std::vector<UntranslatableSection> untranslatable_sections; 235 236 explicit String(const StringPool::Ref& ref); 237 238 bool Equals(const Value* value) const override; 239 bool Flatten(android::Res_value* out_value) const override; 240 void Print(std::ostream* out) const override; 241 void PrettyPrint(text::Printer* printer) const override; 242 }; 243 244 struct StyledString : public TransformableItem<StyledString, BaseItem<StyledString>> { 245 StringPool::StyleRef value; 246 247 // Sections of the string to NOT translate. Mainly used 248 // for pseudolocalization. This data is NOT persisted 249 // in any format. 250 std::vector<UntranslatableSection> untranslatable_sections; 251 252 explicit StyledString(const StringPool::StyleRef& ref); 253 254 bool Equals(const Value* value) const override; 255 bool Flatten(android::Res_value* out_value) const override; 256 void Print(std::ostream* out) const override; 257 }; 258 259 struct FileReference : public TransformableItem<FileReference, BaseItem<FileReference>> { 260 StringPool::Ref path; 261 262 // A handle to the file object from which this file can be read. 263 // This field is NOT persisted in any format. It is transient. 264 io::IFile* file = nullptr; 265 266 // FileType of the file pointed to by `file`. This is used to know how to inflate the file, 267 // or if to inflate at all (just copy). 268 ResourceFile::Type type = ResourceFile::Type::kUnknown; 269 270 FileReference() = default; 271 explicit FileReference(const StringPool::Ref& path); 272 273 bool Equals(const Value* value) const override; 274 bool Flatten(android::Res_value* out_value) const override; 275 void Print(std::ostream* out) const override; 276 }; 277 278 // Represents any other android::Res_value. 279 struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<BinaryPrimitive>> { 280 android::Res_value value; 281 282 BinaryPrimitive() = default; 283 explicit BinaryPrimitive(const android::Res_value& val); 284 BinaryPrimitive(uint8_t dataType, uint32_t data); 285 286 bool Equals(const Value* value) const override; 287 bool Flatten(android::Res_value* out_value) const override; 288 void Print(std::ostream* out) const override; 289 void PrettyPrint(text::Printer* printer) const override; 290 }; 291 292 struct Attribute : public TransformableValue<Attribute, BaseValue<Attribute>> { 293 struct Symbol { 294 Reference symbol; 295 uint32_t value; 296 uint8_t type; 297 298 friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol); 299 }; 300 301 uint32_t type_mask; 302 int32_t min_int; 303 int32_t max_int; 304 std::vector<Symbol> symbols; 305 306 explicit Attribute(uint32_t t = 0u); 307 308 bool Equals(const Value* value) const override; 309 310 // Returns true if this Attribute's format is compatible with the given Attribute. The basic 311 // rule is that TYPE_REFERENCE can be ignored for both of the Attributes, and TYPE_FLAGS and 312 // TYPE_ENUMS are never compatible. 313 bool IsCompatibleWith(const Attribute& attr) const; 314 315 std::string MaskString() const; 316 static std::string MaskString(uint32_t type_mask); 317 318 void Print(std::ostream* out) const override; 319 bool Matches(const Item& item, DiagMessage* out_msg = nullptr) const; 320 }; 321 322 struct Style : public TransformableValue<Style, BaseValue<Style>> { 323 struct Entry { 324 Reference key; 325 std::unique_ptr<Item> value; 326 327 friend std::ostream& operator<<(std::ostream& out, const Entry& entry); 328 }; 329 330 Maybe<Reference> parent; 331 332 // If set to true, the parent was auto inferred from the style's name. 333 bool parent_inferred = false; 334 335 std::vector<Entry> entries; 336 337 bool Equals(const Value* value) const override; 338 void Print(std::ostream* out) const override; 339 340 // Merges `style` into this Style. All identical attributes of `style` take precedence, including 341 // the parent, if there is one. 342 void MergeWith(Style* style, StringPool* pool); 343 }; 344 345 struct Array : public TransformableValue<Array, BaseValue<Array>> { 346 std::vector<std::unique_ptr<Item>> elements; 347 348 bool Equals(const Value* value) const override; 349 void Print(std::ostream* out) const override; 350 }; 351 352 struct Plural : public TransformableValue<Plural, BaseValue<Plural>> { 353 enum { Zero = 0, One, Two, Few, Many, Other, Count }; 354 355 std::array<std::unique_ptr<Item>, Count> values; 356 357 bool Equals(const Value* value) const override; 358 void Print(std::ostream* out) const override; 359 }; 360 361 struct Styleable : public TransformableValue<Styleable, BaseValue<Styleable>> { 362 std::vector<Reference> entries; 363 364 bool Equals(const Value* value) const override; 365 void Print(std::ostream* out) const override; 366 void MergeWith(Styleable* styleable); 367 }; 368 369 struct Macro : public TransformableValue<Macro, BaseValue<Macro>> { 370 std::string raw_value; 371 StyleString style_string; 372 std::vector<UntranslatableSection> untranslatable_sections; 373 374 struct Namespace { 375 std::string alias; 376 std::string package_name; 377 bool is_private; 378 379 bool operator==(const Namespace& right) const { 380 return alias == right.alias && package_name == right.package_name && 381 is_private == right.is_private; 382 } 383 }; 384 385 std::vector<Namespace> alias_namespaces; 386 387 bool Equals(const Value* value) const override; 388 void Print(std::ostream* out) const override; 389 }; 390 391 template <typename T> 392 typename std::enable_if<std::is_base_of<Value, T>::value, std::ostream&>::type operator<<( 393 std::ostream& out, const std::unique_ptr<T>& value) { 394 if (value == nullptr) { 395 out << "NULL"; 396 } else { 397 value->Print(&out); 398 } 399 return out; 400 } 401 402 struct CloningValueTransformer : public ValueTransformer { 403 explicit CloningValueTransformer(StringPool* new_pool); 404 405 std::unique_ptr<Reference> TransformDerived(const Reference* value) override; 406 std::unique_ptr<Id> TransformDerived(const Id* value) override; 407 std::unique_ptr<RawString> TransformDerived(const RawString* value) override; 408 std::unique_ptr<String> TransformDerived(const String* value) override; 409 std::unique_ptr<StyledString> TransformDerived(const StyledString* value) override; 410 std::unique_ptr<FileReference> TransformDerived(const FileReference* value) override; 411 std::unique_ptr<BinaryPrimitive> TransformDerived(const BinaryPrimitive* value) override; 412 std::unique_ptr<Attribute> TransformDerived(const Attribute* value) override; 413 std::unique_ptr<Style> TransformDerived(const Style* value) override; 414 std::unique_ptr<Array> TransformDerived(const Array* value) override; 415 std::unique_ptr<Plural> TransformDerived(const Plural* value) override; 416 std::unique_ptr<Styleable> TransformDerived(const Styleable* value) override; 417 std::unique_ptr<Macro> TransformDerived(const Macro* value) override; 418 }; 419 420 } // namespace aapt 421 422 #endif // AAPT_RESOURCE_VALUES_H 423