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