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_XML_XMLUTIL_H
18#define AAPT_XML_XMLUTIL_H
19
20#include <string>
21
22#include "ResourceValues.h"
23#include "util/Maybe.h"
24
25namespace aapt {
26namespace xml {
27
28constexpr const char* kSchemaAuto = "http://schemas.android.com/apk/res-auto";
29constexpr const char* kSchemaPublicPrefix = "http://schemas.android.com/apk/res/";
30constexpr const char* kSchemaPrivatePrefix = "http://schemas.android.com/apk/prv/res/";
31constexpr const char* kSchemaAndroid = "http://schemas.android.com/apk/res/android";
32constexpr const char* kSchemaTools = "http://schemas.android.com/tools";
33constexpr const char* kSchemaAapt = "http://schemas.android.com/aapt";
34
35// Result of extracting a package name from a namespace URI declaration.
36struct ExtractedPackage {
37  // The name of the package. This can be the empty string, which means that the package
38  // should be assumed to be the same as the CallSite it was defined in.
39  std::string package;
40
41  // True if the package's private namespace was declared. This means that private resources
42  // are made visible.
43  bool private_namespace;
44
45  friend inline bool operator==(const ExtractedPackage& a, const ExtractedPackage& b) {
46    return a.package == b.package && a.private_namespace == b.private_namespace;
47  }
48};
49
50// Returns an ExtractedPackage struct if the namespace URI is of the form:
51//   http://schemas.android.com/apk/res/<package> or
52//   http://schemas.android.com/apk/prv/res/<package>
53//
54// Special case: if namespaceUri is http://schemas.android.com/apk/res-auto, returns an empty
55// package name.
56Maybe<ExtractedPackage> ExtractPackageFromNamespace(const std::string& namespace_uri);
57
58// Returns an XML Android namespace for the given package of the form:
59//   http://schemas.android.com/apk/res/<package>
60//
61// If privateReference == true, the package will be of the form:
62//   http://schemas.android.com/apk/prv/res/<package>
63std::string BuildPackageNamespace(const android::StringPiece& package,
64                                  bool private_reference = false);
65
66// Interface representing a stack of XML namespace declarations. When looking up the package for a
67// namespace prefix, the stack is checked from top to bottom.
68struct IPackageDeclStack {
69  virtual ~IPackageDeclStack() = default;
70
71  // Returns an ExtractedPackage struct if the alias given corresponds with a package declaration.
72  virtual Maybe<ExtractedPackage> TransformPackageAlias(
73      const android::StringPiece& alias) const = 0;
74};
75
76// Helper function for transforming the original Reference inRef to a fully qualified reference
77// via the IPackageDeclStack. This will also mark the Reference as private if the namespace of the
78// package declaration was private.
79void ResolvePackage(const IPackageDeclStack* decl_stack, Reference* in_ref);
80
81class Element;
82
83// Strips out any attributes in the http://schemas.android.com/tools namespace, which is owned by
84// Android Studio and should not make it to the final APK.
85void StripAndroidStudioAttributes(Element* el);
86
87}  // namespace xml
88}  // namespace aapt
89
90#endif /* AAPT_XML_XMLUTIL_H */
91