• 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 #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