/*
 * Copyright (C) 2015 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.
 */

#include "Link.h"

#include <sys/stat.h>

#include <algorithm>
#include <cinttypes>
#include <queue>
#include <unordered_map>
#include <vector>

#include "AppInfo.h"
#include "Debug.h"
#include "LoadedApk.h"
#include "NameMangler.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "android-base/errors.h"
#include "android-base/expected.h"
#include "android-base/file.h"
#include "android-base/stringprintf.h"
#include "androidfw/BigBufferStream.h"
#include "androidfw/FileStream.h"
#include "androidfw/IDiagnostics.h"
#include "androidfw/Locale.h"
#include "androidfw/StringPiece.h"
#include "cmd/Util.h"
#include "compile/IdAssigner.h"
#include "compile/XmlIdCollector.h"
#include "filter/ConfigFilter.h"
#include "format/Archive.h"
#include "format/Container.h"
#include "format/binary/TableFlattener.h"
#include "format/binary/XmlFlattener.h"
#include "format/proto/ProtoDeserialize.h"
#include "format/proto/ProtoSerialize.h"
#include "io/FileSystem.h"
#include "io/Util.h"
#include "io/ZipArchive.h"
#include "java/JavaClassGenerator.h"
#include "java/ManifestClassGenerator.h"
#include "java/ProguardRules.h"
#include "link/FeatureFlagsFilter.h"
#include "link/Linkers.h"
#include "link/ManifestFixer.h"
#include "link/NoDefaultResourceRemover.h"
#include "link/ReferenceLinker.h"
#include "link/ResourceExcluder.h"
#include "link/TableMerger.h"
#include "link/XmlCompatVersioner.h"
#include "optimize/ResourceDeduper.h"
#include "optimize/VersionCollapser.h"
#include "process/IResourceTableConsumer.h"
#include "process/ProductFilter.h"
#include "process/SymbolTable.h"
#include "split/TableSplitter.h"
#include "trace/TraceBuffer.h"
#include "util/Files.h"
#include "xml/XmlDom.h"

using ::android::ConfigDescription;
using ::android::FileInputStream;
using ::android::StringPiece;
using ::android::base::expected;
using ::android::base::StringPrintf;
using ::android::base::unexpected;

namespace aapt {

namespace {

expected<ResourceTablePackage*, const char*> GetStaticLibraryPackage(ResourceTable* table) {
  // Resource tables built by aapt2 always contain one package. This is a post condition of
  // VerifyNoExternalPackages.
  if (table->packages.size() != 1u) {
    return unexpected("static library contains more than one package");
  }
  return table->packages.back().get();
}

}  // namespace

constexpr uint8_t kAndroidPackageId = 0x01;

class LinkContext : public IAaptContext {
 public:
  explicit LinkContext(android::IDiagnostics* diagnostics)
      : diagnostics_(diagnostics), name_mangler_({}), symbols_(&name_mangler_) {
  }

  PackageType GetPackageType() override {
    return package_type_;
  }

  void SetPackageType(PackageType type) {
    package_type_ = type;
  }

  android::IDiagnostics* GetDiagnostics() override {
    return diagnostics_;
  }

  NameMangler* GetNameMangler() override {
    return &name_mangler_;
  }

  void SetNameManglerPolicy(const NameManglerPolicy& policy) {
    name_mangler_ = NameMangler(policy);
  }

  const std::string& GetCompilationPackage() override {
    return compilation_package_;
  }

  void SetCompilationPackage(StringPiece package_name) {
    compilation_package_ = std::string(package_name);
  }

  uint8_t GetPackageId() override {
    return package_id_;
  }

  void SetPackageId(uint8_t id) {
    package_id_ = id;
  }

  SymbolTable* GetExternalSymbols() override {
    return &symbols_;
  }

  bool IsVerbose() override {
    return verbose_;
  }

  void SetVerbose(bool val) {
    verbose_ = val;
    diagnostics_->SetVerbose(val);
  }

  int GetMinSdkVersion() override {
    return min_sdk_version_;
  }

  void SetMinSdkVersion(int minSdk) {
    min_sdk_version_ = minSdk;
  }

  const std::set<std::string>& GetSplitNameDependencies() override {
    return split_name_dependencies_;
  }

  void SetSplitNameDependencies(const std::set<std::string>& split_name_dependencies) {
    split_name_dependencies_ = split_name_dependencies;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(LinkContext);

  PackageType package_type_ = PackageType::kApp;
  android::IDiagnostics* diagnostics_;
  NameMangler name_mangler_;
  std::string compilation_package_;
  uint8_t package_id_ = 0x0;
  SymbolTable symbols_;
  bool verbose_ = false;
  int min_sdk_version_ = 0;
  std::set<std::string> split_name_dependencies_;
};

// A custom delegate that generates compatible pre-O IDs for use with feature splits.
// Feature splits use package IDs > 7f, which in Java (since Java doesn't have unsigned ints)
// is interpreted as a negative number. Some verification was wrongly assuming negative values
// were invalid.
//
// This delegate will attempt to masquerade any '@id/' references with ID 0xPPTTEEEE,
// where PP > 7f, as 0x7fPPEEEE. Any potential overlapping is verified and an error occurs if such
// an overlap exists.
//
// See b/37498913.
class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate {
 public:
  explicit FeatureSplitSymbolTableDelegate(IAaptContext* context) : context_(context) {
  }

  virtual ~FeatureSplitSymbolTableDelegate() = default;

  virtual std::unique_ptr<SymbolTable::Symbol> FindByName(
      const ResourceName& name,
      const std::vector<std::unique_ptr<ISymbolSource>>& sources) override {
    std::unique_ptr<SymbolTable::Symbol> symbol =
        DefaultSymbolTableDelegate::FindByName(name, sources);
    if (symbol == nullptr) {
      return {};
    }

    // Check to see if this is an 'id' with the target package.
    if (name.type.type == ResourceType::kId && symbol->id) {
      ResourceId* id = &symbol->id.value();
      if (id->package_id() > kAppPackageId) {
        // Rewrite the resource ID to be compatible pre-O.
        ResourceId rewritten_id(kAppPackageId, id->package_id(), id->entry_id());

        // Check that this doesn't overlap another resource.
        if (DefaultSymbolTableDelegate::FindById(rewritten_id, sources) != nullptr) {
          // The ID overlaps, so log a message (since this is a weird failure) and fail.
          context_->GetDiagnostics()->Error(android::DiagMessage()
                                            << "Failed to rewrite " << name
                                            << " for pre-O feature split support");
          return {};
        }

        if (context_->IsVerbose()) {
          context_->GetDiagnostics()->Note(android::DiagMessage()
                                           << "rewriting " << name << " (" << *id << ") -> ("
                                           << rewritten_id << ")");
        }

        *id = rewritten_id;
      }
    }
    return symbol;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FeatureSplitSymbolTableDelegate);

  IAaptContext* context_;
};

static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res, StringPiece path,
                       bool keep_raw_values, bool utf16, OutputFormat format,
                       IArchiveWriter* writer) {
  TRACE_CALL();
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(android::DiagMessage(path)
                                    << "writing to archive (keep_raw_values="
                                    << (keep_raw_values ? "true" : "false") << ")");
  }

  switch (format) {
    case OutputFormat::kApk: {
      android::BigBuffer buffer(1024);
      XmlFlattenerOptions options = {};
      options.keep_raw_values = keep_raw_values;
      options.use_utf16 = utf16;
      XmlFlattener flattener(&buffer, options);
      if (!flattener.Consume(context, &xml_res)) {
        return false;
      }

      android::BigBufferInputStream input_stream(&buffer);
      return io::CopyInputStreamToArchive(context, &input_stream, path, ArchiveEntry::kCompress,
                                          writer);
    } break;

    case OutputFormat::kProto: {
      pb::XmlNode pb_node;
      // Strip whitespace text nodes from tha AndroidManifest.xml
      SerializeXmlOptions options;
      options.remove_empty_text_nodes = (path == kAndroidManifestPath);
      SerializeXmlResourceToPb(xml_res, &pb_node);
      return io::CopyProtoToArchive(context, &pb_node, path, ArchiveEntry::kCompress, writer);
    } break;
  }
  return false;
}

// Inflates an XML file from the source path.
static std::unique_ptr<xml::XmlResource> LoadXml(const std::string& path,
                                                 android::IDiagnostics* diag) {
  TRACE_CALL();
  android::FileInputStream fin(path);
  if (fin.HadError()) {
    diag->Error(android::DiagMessage(path) << "failed to load XML file: " << fin.GetError());
    return {};
  }
  return xml::Inflate(&fin, diag, android::Source(path));
}

struct ResourceFileFlattenerOptions {
  bool no_auto_version = false;
  bool no_version_vectors = false;
  bool no_version_transitions = false;
  bool no_xml_namespaces = false;
  bool keep_raw_values = false;
  bool do_not_compress_anything = false;
  bool update_proguard_spec = false;
  bool do_not_fail_on_missing_resources = false;
  OutputFormat output_format = OutputFormat::kApk;
  std::unordered_set<std::string> extensions_to_not_compress;
  std::optional<std::regex> regex_to_not_compress;
};

// A sampling of public framework resource IDs.
struct R {
  struct attr {
    enum : uint32_t {
      paddingLeft = 0x010100d6u,
      paddingRight = 0x010100d8u,
      paddingHorizontal = 0x0101053du,

      paddingTop = 0x010100d7u,
      paddingBottom = 0x010100d9u,
      paddingVertical = 0x0101053eu,

      layout_marginLeft = 0x010100f7u,
      layout_marginRight = 0x010100f9u,
      layout_marginHorizontal = 0x0101053bu,

      layout_marginTop = 0x010100f8u,
      layout_marginBottom = 0x010100fau,
      layout_marginVertical = 0x0101053cu,
    };
  };
};

template <typename T>
uint32_t GetCompressionFlags(StringPiece str, T options) {
  if (options.do_not_compress_anything) {
    return 0;
  }

  if (options.regex_to_not_compress &&
      std::regex_search(str.begin(), str.end(), options.regex_to_not_compress.value())) {
    return 0;
  }

  for (const std::string& extension : options.extensions_to_not_compress) {
    if (util::EndsWith(str, extension)) {
      return 0;
    }
  }
  return ArchiveEntry::kCompress;
}

class ResourceFileFlattener {
 public:
  ResourceFileFlattener(const ResourceFileFlattenerOptions& options, IAaptContext* context,
                        proguard::KeepSet* keep_set);

  bool Flatten(ResourceTable* table, IArchiveWriter* archive_writer);

 private:
  struct FileOperation {
    ConfigDescription config;

    // The entry this file came from.
    ResourceEntry* entry;

    // The file to copy as-is.
    io::IFile* file_to_copy;

    // The XML to process and flatten.
    std::unique_ptr<xml::XmlResource> xml_to_flatten;

    // The destination to write this file to.
    std::string dst_path;
  };

  std::vector<std::unique_ptr<xml::XmlResource>> LinkAndVersionXmlFile(ResourceTable* table,
                                                                       FileOperation* file_op);

  ResourceFileFlattenerOptions options_;
  IAaptContext* context_;
  proguard::KeepSet* keep_set_;
  XmlCompatVersioner::Rules rules_;
};

ResourceFileFlattener::ResourceFileFlattener(const ResourceFileFlattenerOptions& options,
                                             IAaptContext* context, proguard::KeepSet* keep_set)
    : options_(options), context_(context), keep_set_(keep_set) {
  SymbolTable* symm = context_->GetExternalSymbols();

  // Build up the rules for degrading newer attributes to older ones.
  // NOTE(adamlesinski): These rules are hardcoded right now, but they should be
  // generated from the attribute definitions themselves (b/62028956).
  if (symm->FindById(R::attr::paddingHorizontal)) {
    std::vector<ReplacementAttr> replacements{
        {"paddingLeft", R::attr::paddingLeft, Attribute(android::ResTable_map::TYPE_DIMENSION)},
        {"paddingRight", R::attr::paddingRight, Attribute(android::ResTable_map::TYPE_DIMENSION)},
    };
    rules_[R::attr::paddingHorizontal] =
        util::make_unique<DegradeToManyRule>(std::move(replacements));
  }

  if (symm->FindById(R::attr::paddingVertical)) {
    std::vector<ReplacementAttr> replacements{
        {"paddingTop", R::attr::paddingTop, Attribute(android::ResTable_map::TYPE_DIMENSION)},
        {"paddingBottom", R::attr::paddingBottom, Attribute(android::ResTable_map::TYPE_DIMENSION)},
    };
    rules_[R::attr::paddingVertical] =
        util::make_unique<DegradeToManyRule>(std::move(replacements));
  }

  if (symm->FindById(R::attr::layout_marginHorizontal)) {
    std::vector<ReplacementAttr> replacements{
        {"layout_marginLeft", R::attr::layout_marginLeft,
         Attribute(android::ResTable_map::TYPE_DIMENSION)},
        {"layout_marginRight", R::attr::layout_marginRight,
         Attribute(android::ResTable_map::TYPE_DIMENSION)},
    };
    rules_[R::attr::layout_marginHorizontal] =
        util::make_unique<DegradeToManyRule>(std::move(replacements));
  }

  if (symm->FindById(R::attr::layout_marginVertical)) {
    std::vector<ReplacementAttr> replacements{
        {"layout_marginTop", R::attr::layout_marginTop,
         Attribute(android::ResTable_map::TYPE_DIMENSION)},
        {"layout_marginBottom", R::attr::layout_marginBottom,
         Attribute(android::ResTable_map::TYPE_DIMENSION)},
    };
    rules_[R::attr::layout_marginVertical] =
        util::make_unique<DegradeToManyRule>(std::move(replacements));
  }
}

static bool IsTransitionElement(const std::string& name) {
  return name == "fade" || name == "changeBounds" || name == "slide" || name == "explode" ||
         name == "changeImageTransform" || name == "changeTransform" ||
         name == "changeClipBounds" || name == "autoTransition" || name == "recolor" ||
         name == "changeScroll" || name == "transitionSet" || name == "transition" ||
         name == "transitionManager";
}

static bool IsVectorElement(const std::string& name) {
  return name == "vector" || name == "animated-vector" || name == "pathInterpolator" ||
         name == "objectAnimator" || name == "gradient" || name == "animated-selector" ||
         name == "set";
}

template <typename T>
std::vector<T> make_singleton_vec(T&& val) {
  std::vector<T> vec;
  vec.emplace_back(std::forward<T>(val));
  return vec;
}

std::vector<std::unique_ptr<xml::XmlResource>> ResourceFileFlattener::LinkAndVersionXmlFile(
    ResourceTable* table, FileOperation* file_op) {
  TRACE_CALL();
  xml::XmlResource* doc = file_op->xml_to_flatten.get();
  const android::Source& src = doc->file.source;

  if (context_->IsVerbose()) {
    context_->GetDiagnostics()->Note(android::DiagMessage()
                                     << "linking " << src.path << " (" << doc->file.name << ")");
  }

  // First, strip out any tools namespace attributes. AAPT stripped them out early, which means
  // that existing projects have out-of-date references which pass compilation.
  xml::StripAndroidStudioAttributes(doc->root.get());

  XmlReferenceLinker xml_linker(table);
  if (!options_.do_not_fail_on_missing_resources && !xml_linker.Consume(context_, doc)) {
    return {};
  }

  if (options_.update_proguard_spec && !proguard::CollectProguardRules(context_, doc, keep_set_)) {
    return {};
  }

  if (options_.no_xml_namespaces) {
    XmlNamespaceRemover namespace_remover;
    if (!namespace_remover.Consume(context_, doc)) {
      return {};
    }
  }

  if (options_.no_auto_version) {
    return make_singleton_vec(std::move(file_op->xml_to_flatten));
  }

  if (options_.no_version_vectors || options_.no_version_transitions) {
    // Skip this if it is a vector or animated-vector.
    xml::Element* el = doc->root.get();
    if (el && el->namespace_uri.empty()) {
      if ((options_.no_version_vectors && IsVectorElement(el->name)) ||
          (options_.no_version_transitions && IsTransitionElement(el->name))) {
        return make_singleton_vec(std::move(file_op->xml_to_flatten));
      }
    }
  }

  const ConfigDescription& config = file_op->config;
  ResourceEntry* entry = file_op->entry;

  XmlCompatVersioner xml_compat_versioner(&rules_);
  const util::Range<ApiVersion> api_range{config.sdkVersion,
                                          FindNextApiVersionForConfig(entry, config)};
  return xml_compat_versioner.Process(context_, doc, api_range);
}

ResourceFile::Type XmlFileTypeForOutputFormat(OutputFormat format) {
  switch (format) {
    case OutputFormat::kApk:
      return ResourceFile::Type::kBinaryXml;
    case OutputFormat::kProto:
      return ResourceFile::Type::kProtoXml;
  }
  LOG_ALWAYS_FATAL("unreachable");
  return ResourceFile::Type::kUnknown;
}

static auto kDrawableVersions = std::map<std::string, ApiVersion>{
    { "adaptive-icon" , SDK_O },
};

bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archive_writer) {
  TRACE_CALL();
  bool error = false;
  std::map<std::pair<ConfigDescription, StringPiece>, FileOperation> config_sorted_files;

  proguard::CollectResourceReferences(context_, table, keep_set_);

  for (auto& pkg : table->packages) {
    CHECK(!pkg->name.empty()) << "Packages must have names when being linked";

    for (auto& type : pkg->types) {
      // Sort by config and name, so that we get better locality in the zip file.
      config_sorted_files.clear();
      std::queue<FileOperation> file_operations;

      // Populate the queue with all files in the ResourceTable.
      for (auto& entry : type->entries) {
        for (auto& config_value : entry->values) {
          // WARNING! Do not insert or remove any resources while executing in this scope. It will
          // corrupt the iteration order.

          FileReference* file_ref = ValueCast<FileReference>(config_value->value.get());
          if (!file_ref) {
            continue;
          }

          io::IFile* file = file_ref->file;
          if (!file) {
            context_->GetDiagnostics()->Error(android::DiagMessage(file_ref->GetSource())
                                              << "file not found");
            return false;
          }

          FileOperation file_op;
          file_op.entry = entry.get();
          file_op.dst_path = *file_ref->path;
          file_op.config = config_value->config;
          file_op.file_to_copy = file;

          if (type->named_type.type != ResourceType::kRaw &&
              (file_ref->type == ResourceFile::Type::kBinaryXml ||
               file_ref->type == ResourceFile::Type::kProtoXml)) {
            std::unique_ptr<io::IData> data = file->OpenAsData();
            if (!data) {
              context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                                << "failed to open file");
              return false;
            }

            if (file_ref->type == ResourceFile::Type::kProtoXml) {
              pb::XmlNode pb_xml_node;
              if (!pb_xml_node.ParseFromArray(data->data(), static_cast<int>(data->size()))) {
                context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                                  << "failed to parse proto XML");
                return false;
              }

              std::string error;
              file_op.xml_to_flatten = DeserializeXmlResourceFromPb(pb_xml_node, &error);
              if (file_op.xml_to_flatten == nullptr) {
                context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                                  << "failed to deserialize proto XML: " << error);
                return false;
              }
            } else {
              std::string error_str;
              file_op.xml_to_flatten = xml::Inflate(data->data(), data->size(), &error_str);
              if (file_op.xml_to_flatten == nullptr) {
                context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                                  << "failed to parse binary XML: " << error_str);
                return false;
              }
            }

            // Update the type that this file will be written as.
            file_ref->type = XmlFileTypeForOutputFormat(options_.output_format);

            file_op.xml_to_flatten->file.config = config_value->config;
            file_op.xml_to_flatten->file.source = file_ref->GetSource();
            file_op.xml_to_flatten->file.name =
                ResourceName(pkg->name, type->named_type, entry->name);
          }

          // NOTE(adamlesinski): Explicitly construct a StringPiece here, or
          // else we end up copying the string in the std::make_pair() method,
          // then creating a StringPiece from the copy, which would cause us
          // to end up referencing garbage in the map.
          const StringPiece entry_name(entry->name);
          config_sorted_files[std::make_pair(config_value->config, entry_name)] =
              std::move(file_op);
        }
      }

      // Now flatten the sorted values.
      for (auto& map_entry : config_sorted_files) {
        const ConfigDescription& config = map_entry.first.first;
        FileOperation& file_op = map_entry.second;

        if (file_op.xml_to_flatten) {
          // Check minimum sdk versions supported for drawables
          auto drawable_entry = kDrawableVersions.find(file_op.xml_to_flatten->root->name);
          if (drawable_entry != kDrawableVersions.end()) {
            if (drawable_entry->second > context_->GetMinSdkVersion()
                && drawable_entry->second > config.sdkVersion) {
              context_->GetDiagnostics()->Error(
                  android::DiagMessage(file_op.xml_to_flatten->file.source)
                  << "<" << drawable_entry->first << "> elements "
                  << "require a sdk version of at least " << (int16_t)drawable_entry->second);
              error = true;
              continue;
            }
          }

          std::vector<std::unique_ptr<xml::XmlResource>> versioned_docs =
              LinkAndVersionXmlFile(table, &file_op);
          if (versioned_docs.empty()) {
            error = true;
            continue;
          }

          for (std::unique_ptr<xml::XmlResource>& doc : versioned_docs) {
            std::string dst_path = file_op.dst_path;
            if (doc->file.config != file_op.config) {
              // Only add the new versioned configurations.
              if (context_->IsVerbose()) {
                context_->GetDiagnostics()->Note(android::DiagMessage(doc->file.source)
                                                 << "auto-versioning resource from config '"
                                                 << config << "' -> '" << doc->file.config << "'");
              }

              const ResourceFile& file = doc->file;
              dst_path = ResourceUtils::BuildResourceFileName(file, context_->GetNameMangler());

              auto file_ref =
                  util::make_unique<FileReference>(table->string_pool.MakeRef(dst_path));
              file_ref->SetSource(doc->file.source);

              // Update the output format of this XML file.
              file_ref->type = XmlFileTypeForOutputFormat(options_.output_format);
              bool result = table->AddResource(NewResourceBuilder(file.name)
                                                   .SetValue(std::move(file_ref), file.config)
                                                   .SetAllowMangled(true)
                                                   .Build(),
                                               context_->GetDiagnostics());
              if (!result) {
                return false;
              }
            }

            error |= !FlattenXml(context_, *doc, dst_path, options_.keep_raw_values,
                                 false /*utf16*/, options_.output_format, archive_writer);
          }
        } else {
          error |= !io::CopyFileToArchive(context_, file_op.file_to_copy, file_op.dst_path,
                                          GetCompressionFlags(file_op.dst_path, options_),
                                          archive_writer);
        }
      }
    }
  }
  return !error;
}

static bool WriteStableIdMapToPath(android::IDiagnostics* diag,
                                   const std::unordered_map<ResourceName, ResourceId>& id_map,
                                   const std::string& id_map_path) {
  android::FileOutputStream fout(id_map_path);
  if (fout.HadError()) {
    diag->Error(android::DiagMessage(id_map_path) << "failed to open: " << fout.GetError());
    return false;
  }

  text::Printer printer(&fout);
  for (const auto& entry : id_map) {
    const ResourceName& name = entry.first;
    const ResourceId& id = entry.second;
    printer.Print(name.to_string());
    printer.Print(" = ");
    printer.Println(id.to_string());
  }
  fout.Flush();

  if (fout.HadError()) {
    diag->Error(android::DiagMessage(id_map_path) << "failed writing to file: " << fout.GetError());
    return false;
  }
  return true;
}

static bool LoadStableIdMap(android::IDiagnostics* diag, const std::string& path,
                            std::unordered_map<ResourceName, ResourceId>* out_id_map) {
  std::string content;
  if (!android::base::ReadFileToString(path, &content, true /*follow_symlinks*/)) {
    diag->Error(android::DiagMessage(path) << "failed reading stable ID file");
    return false;
  }

  out_id_map->clear();
  size_t line_no = 0;
  for (StringPiece line : util::Tokenize(content, '\n')) {
    line_no++;
    line = util::TrimWhitespace(line);
    if (line.empty()) {
      continue;
    }

    auto iter = std::find(line.begin(), line.end(), '=');
    if (iter == line.end()) {
      diag->Error(android::DiagMessage(android::Source(path, line_no)) << "missing '='");
      return false;
    }

    ResourceNameRef name;
    StringPiece res_name_str =
        util::TrimWhitespace(line.substr(0, std::distance(line.begin(), iter)));
    if (!ResourceUtils::ParseResourceName(res_name_str, &name)) {
      diag->Error(android::DiagMessage(android::Source(path, line_no))
                  << "invalid resource name '" << res_name_str << "'");
      return false;
    }

    const size_t res_id_start_idx = std::distance(line.begin(), iter) + 1;
    const size_t res_id_str_len = line.size() - res_id_start_idx;
    StringPiece res_id_str = util::TrimWhitespace(line.substr(res_id_start_idx, res_id_str_len));

    std::optional<ResourceId> maybe_id = ResourceUtils::ParseResourceId(res_id_str);
    if (!maybe_id) {
      diag->Error(android::DiagMessage(android::Source(path, line_no))
                  << "invalid resource ID '" << res_id_str << "'");
      return false;
    }

    (*out_id_map)[name.ToResourceName()] = maybe_id.value();
  }
  return true;
}

class Linker {
 public:
  Linker(LinkContext* context, const LinkOptions& options)
      : options_(options),
        context_(context),
        final_table_(),
        file_collection_(util::make_unique<io::FileCollection>()) {
  }

  void ExtractCompileSdkVersions(android::AssetManager2* assets) {
    using namespace android;

    // Find the system package (0x01). AAPT always generates attributes with the type 0x01, so
    // we're looking for the first attribute resource in the system package.
    android::ApkAssetsCookie cookie;
    if (auto value = assets->GetResource(0x01010000, true /** may_be_bag */); value.has_value()) {
      cookie = value->cookie;
    } else {
      // No Framework assets loaded. Not a failure.
      return;
    }

    std::unique_ptr<Asset> manifest(
        assets->OpenNonAsset(kAndroidManifestPath, cookie, Asset::AccessMode::ACCESS_BUFFER));
    if (manifest == nullptr) {
      // No errors.
      return;
    }

    std::string error;
    std::unique_ptr<xml::XmlResource> manifest_xml =
        xml::Inflate(manifest->getBuffer(true /*wordAligned*/), manifest->getLength(), &error);
    if (manifest_xml == nullptr) {
      // No errors.
      return;
    }

    if (!options_.manifest_fixer_options.compile_sdk_version) {
      xml::Attribute* attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionCode");
      if (attr != nullptr) {
        auto& compile_sdk_version = options_.manifest_fixer_options.compile_sdk_version;
        if (BinaryPrimitive* prim = ValueCast<BinaryPrimitive>(attr->compiled_value.get())) {
          switch (prim->value.dataType) {
            case Res_value::TYPE_INT_DEC:
              compile_sdk_version = StringPrintf("%" PRId32, static_cast<int32_t>(prim->value.data));
              break;
            case Res_value::TYPE_INT_HEX:
              compile_sdk_version = StringPrintf("%" PRIx32, prim->value.data);
              break;
            default:
              break;
          }
        } else if (String* str = ValueCast<String>(attr->compiled_value.get())) {
          compile_sdk_version = *str->value;
        } else {
          compile_sdk_version = attr->value;
        }
      }
    }

    if (!options_.manifest_fixer_options.compile_sdk_version_codename) {
      xml::Attribute* attr = manifest_xml->root->FindAttribute(xml::kSchemaAndroid, "versionName");
      if (attr != nullptr) {
        std::optional<std::string>& compile_sdk_version_codename =
            options_.manifest_fixer_options.compile_sdk_version_codename;
        if (String* str = ValueCast<String>(attr->compiled_value.get())) {
          compile_sdk_version_codename = *str->value;
        } else {
          compile_sdk_version_codename = attr->value;
        }
      }
    }
  }

  // Creates a SymbolTable that loads symbols from the various APKs.
  // Pre-condition: context_->GetCompilationPackage() needs to be set.
  bool LoadSymbolsFromIncludePaths() {
    TRACE_NAME("LoadSymbolsFromIncludePaths: #" + std::to_string(options_.include_paths.size()));
    auto asset_source = util::make_unique<AssetManagerSymbolSource>();
    for (const std::string& path : options_.include_paths) {
      if (context_->IsVerbose()) {
        context_->GetDiagnostics()->Note(android::DiagMessage() << "including " << path);
      }

      std::string error;
      auto zip_collection = io::ZipFileCollection::Create(path, &error);
      if (zip_collection == nullptr) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed to open APK: " << error);
        return false;
      }

      if (zip_collection->FindFile(kProtoResourceTablePath) != nullptr) {
        // Load this as a static library include.
        std::unique_ptr<LoadedApk> static_apk = LoadedApk::LoadProtoApkFromFileCollection(
            android::Source(path), std::move(zip_collection), context_->GetDiagnostics());
        if (static_apk == nullptr) {
          return false;
        }

        if (context_->GetPackageType() != PackageType::kStaticLib) {
          // Can't include static libraries when not building a static library (they have no IDs
          // assigned).
          context_->GetDiagnostics()->Error(
              android::DiagMessage(path)
              << "can't include static library when not building a static lib");
          return false;
        }

        ResourceTable* table = static_apk->GetResourceTable();

        // If we are using --no-static-lib-packages, we need to rename the package of this table to
        // our compilation package so the symbol package name does not get mangled into the entry
        // name.
        if (options_.no_static_lib_packages && !table->packages.empty()) {
          auto lib_package_result = GetStaticLibraryPackage(table);
          if (!lib_package_result.has_value()) {
            context_->GetDiagnostics()->Error(android::DiagMessage(path)
                                              << lib_package_result.error());
            return false;
          }
          lib_package_result.value()->name = context_->GetCompilationPackage();
        }

        context_->GetExternalSymbols()->AppendSource(
            util::make_unique<ResourceTableSymbolSource>(table));
        static_library_includes_.push_back(std::move(static_apk));
      } else {
        if (!asset_source->AddAssetPath(path)) {
          context_->GetDiagnostics()->Error(android::DiagMessage()
                                            << "failed to load include path " << path);
          return false;
        }
      }
    }

    // Capture the shared libraries so that the final resource table can be properly flattened
    // with support for shared libraries.
    for (auto& entry : asset_source->GetAssignedPackageIds()) {
      if (entry.first == kAppPackageId) {
        // Capture the included base feature package.
        included_feature_base_ = entry.second;
      } else if (entry.first == kFrameworkPackageId) {
        // Try to embed which version of the framework we're compiling against.
        // First check if we should use compileSdkVersion at all. Otherwise compilation may fail
        // when linking our synthesized 'android:compileSdkVersion' attribute.
        std::unique_ptr<SymbolTable::Symbol> symbol = asset_source->FindByName(
            ResourceName("android", ResourceType::kAttr, "compileSdkVersion"));
        if (symbol != nullptr && symbol->is_public) {
          // The symbol is present and public, extract the android:versionName and
          // android:versionCode from the framework AndroidManifest.xml.
          ExtractCompileSdkVersions(asset_source->GetAssetManager());
        }
      } else if (asset_source->IsPackageDynamic(entry.first, entry.second)) {
        final_table_.included_packages_[entry.first] = entry.second;
      }
    }

    context_->GetExternalSymbols()->AppendSource(std::move(asset_source));
    return true;
  }

  std::optional<AppInfo> ExtractAppInfoFromManifest(xml::XmlResource* xml_res,
                                                    android::IDiagnostics* diag) {
    TRACE_CALL();
    // Make sure the first element is <manifest> with package attribute.
    xml::Element* manifest_el = xml::FindRootElement(xml_res->root.get());
    if (manifest_el == nullptr) {
      return {};
    }

    AppInfo app_info;

    if (!manifest_el->namespace_uri.empty() || manifest_el->name != "manifest") {
      diag->Error(android::DiagMessage(xml_res->file.source) << "root tag must be <manifest>");
      return {};
    }

    xml::Attribute* package_attr = manifest_el->FindAttribute({}, "package");
    if (!package_attr) {
      diag->Error(android::DiagMessage(xml_res->file.source)
                  << "<manifest> must have a 'package' attribute");
      return {};
    }
    app_info.package = package_attr->value;

    if (xml::Attribute* version_code_attr =
            manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCode")) {
      std::optional<uint32_t> maybe_code = ResourceUtils::ParseInt(version_code_attr->value);
      if (!maybe_code) {
        diag->Error(android::DiagMessage(xml_res->file.source.WithLine(manifest_el->line_number))
                    << "invalid android:versionCode '" << version_code_attr->value << "'");
        return {};
      }
      app_info.version_code = maybe_code.value();
    }

    if (xml::Attribute* version_code_major_attr =
        manifest_el->FindAttribute(xml::kSchemaAndroid, "versionCodeMajor")) {
      std::optional<uint32_t> maybe_code = ResourceUtils::ParseInt(version_code_major_attr->value);
      if (!maybe_code) {
        diag->Error(android::DiagMessage(xml_res->file.source.WithLine(manifest_el->line_number))
                    << "invalid android:versionCodeMajor '" << version_code_major_attr->value
                    << "'");
        return {};
      }
      app_info.version_code_major = maybe_code.value();
    }

    if (xml::Attribute* revision_code_attr =
            manifest_el->FindAttribute(xml::kSchemaAndroid, "revisionCode")) {
      std::optional<uint32_t> maybe_code = ResourceUtils::ParseInt(revision_code_attr->value);
      if (!maybe_code) {
        diag->Error(android::DiagMessage(xml_res->file.source.WithLine(manifest_el->line_number))
                    << "invalid android:revisionCode '" << revision_code_attr->value << "'");
        return {};
      }
      app_info.revision_code = maybe_code.value();
    }

    if (xml::Attribute* split_name_attr = manifest_el->FindAttribute({}, "split")) {
      if (!split_name_attr->value.empty()) {
        app_info.split_name = split_name_attr->value;
      }
    }

    if (xml::Element* uses_sdk_el = manifest_el->FindChild({}, "uses-sdk")) {
      if (xml::Attribute* min_sdk =
              uses_sdk_el->FindAttribute(xml::kSchemaAndroid, "minSdkVersion")) {
        app_info.min_sdk_version = ResourceUtils::ParseSdkVersion(min_sdk->value);
      }
    }

    for (const xml::Element* child_el : manifest_el->GetChildElements()) {
      if (child_el->namespace_uri.empty() && child_el->name == "uses-split") {
        if (const xml::Attribute* split_name =
            child_el->FindAttribute(xml::kSchemaAndroid, "name")) {
          if (!split_name->value.empty()) {
            app_info.split_name_dependencies.insert(split_name->value);
          }
        }
      }
    }
    return app_info;
  }

  // Precondition: ResourceTable doesn't have any IDs assigned yet, nor is it linked.
  // Postcondition: ResourceTable has only one package left. All others are
  // stripped, or there is an error and false is returned.
  bool VerifyNoExternalPackages() {
    auto is_ext_package_func = [&](const std::unique_ptr<ResourceTablePackage>& pkg) -> bool {
      return context_->GetCompilationPackage() != pkg->name;
    };

    bool error = false;
    for (const auto& package : final_table_.packages) {
      if (is_ext_package_func(package)) {
        // We have a package that is not related to the one we're building!
        for (const auto& type : package->types) {
          for (const auto& entry : type->entries) {
            ResourceNameRef res_name(package->name, type->named_type, entry->name);

            for (const auto& config_value : entry->values) {
              // Special case the occurrence of an ID that is being generated
              // for the 'android' package. This is due to legacy reasons.
              if (ValueCast<Id>(config_value->value.get()) && package->name == "android") {
                context_->GetDiagnostics()->Warn(
                    android::DiagMessage(config_value->value->GetSource())
                    << "generated id '" << res_name << "' for external package '" << package->name
                    << "'");
              } else {
                context_->GetDiagnostics()->Error(
                    android::DiagMessage(config_value->value->GetSource())
                    << "defined resource '" << res_name << "' for external package '"
                    << package->name << "'");
                error = true;
              }
            }
          }
        }
      }
    }

    auto new_end_iter = std::remove_if(final_table_.packages.begin(), final_table_.packages.end(),
                                       is_ext_package_func);
    final_table_.packages.erase(new_end_iter, final_table_.packages.end());
    return !error;
  }

  /**
   * Returns true if no IDs have been set, false otherwise.
   */
  bool VerifyNoIdsSet() {
    for (const auto& package : final_table_.packages) {
      for (const auto& type : package->types) {
        for (const auto& entry : type->entries) {
          if (entry->id) {
            ResourceNameRef res_name(package->name, type->named_type, entry->name);
            context_->GetDiagnostics()->Error(android::DiagMessage()
                                              << "resource " << res_name << " has ID "
                                              << entry->id.value() << " assigned");
            return false;
          }
        }
      }
    }
    return true;
  }

  bool VerifyLocaleFormat(xml::XmlResource* manifest, android::IDiagnostics* diag) {
    // Skip it if the Manifest doesn't declare the localeConfig attribute within the <application>
    // element.
    const xml::Element* application = manifest->root->FindChild("", "application");
    if (!application) {
      return true;
    }
    const xml::Attribute* localeConfig =
        application->FindAttribute(xml::kSchemaAndroid, "localeConfig");
    if (!localeConfig) {
      return true;
    }

    // Deserialize XML from the compiled file
    if (localeConfig->compiled_value) {
      const auto localeconfig_reference = ValueCast<Reference>(localeConfig->compiled_value.get());
      const auto localeconfig_entry =
          ResolveTableEntry(context_, &final_table_, localeconfig_reference);
      if (!localeconfig_entry) {
        // If locale config is resolved from external symbols - skip validation.
        if (context_->GetExternalSymbols()->FindByReference(*localeconfig_reference)) {
          return true;
        }
        context_->GetDiagnostics()->Error(
            android::DiagMessage(localeConfig->compiled_value->GetSource())
            << "no localeConfig entry");
        return false;
      }
      for (const auto& value : localeconfig_entry->values) {
        const FileReference* file_ref = ValueCast<FileReference>(value->value.get());
        if (!file_ref) {
          context_->GetDiagnostics()->Error(
              android::DiagMessage(localeConfig->compiled_value->GetSource())
              << "no file reference");
          return false;
        }
        io::IFile* file = file_ref->file;
        if (!file) {
          context_->GetDiagnostics()->Error(android::DiagMessage(file_ref->GetSource())
                                            << "file not found");
          return false;
        }
        std::unique_ptr<io::IData> data = file->OpenAsData();
        if (!data) {
          context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                            << "failed to open file");
          return false;
        }
        pb::XmlNode pb_xml_node;
        if (!pb_xml_node.ParseFromArray(data->data(), static_cast<int>(data->size()))) {
          context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                            << "failed to parse proto XML");
          return false;
        }

        std::string error;
        std::unique_ptr<xml::XmlResource> localeConfig_xml =
            DeserializeXmlResourceFromPb(pb_xml_node, &error);
        if (!localeConfig_xml) {
          context_->GetDiagnostics()->Error(android::DiagMessage(file->GetSource())
                                            << "failed to deserialize proto XML: " << error);
          return false;
        }
        xml::Element* localeConfig_el = xml::FindRootElement(localeConfig_xml->root.get());
        if (!localeConfig_el) {
          diag->Error(android::DiagMessage(file->GetSource()) << "no root tag defined");
          return false;
        }
        if (localeConfig_el->name != "locale-config") {
          diag->Error(android::DiagMessage(file->GetSource())
                      << "invalid element name: " << localeConfig_el->name
                      << ", expected: locale-config");
          return false;
        }
        for (const xml::Element* child_el : localeConfig_el->GetChildElements()) {
          if (child_el->name == "locale") {
            if (const xml::Attribute* locale_name_attr =
                    child_el->FindAttribute(xml::kSchemaAndroid, "name")) {
              const std::string& locale_name = locale_name_attr->value;
              const std::string valid_name = ConvertToBCP47Tag(locale_name);
              // Start to verify the locale format
              ConfigDescription config;
              if (!ConfigDescription::Parse(valid_name, &config)) {
                diag->Error(android::DiagMessage(file->GetSource())
                            << "invalid configuration: " << locale_name);
                return false;
              }
            } else {
              diag->Error(android::DiagMessage(file->GetSource())
                          << "the attribute android:name is not found");
              return false;
            }
          } else {
            diag->Error(android::DiagMessage(file->GetSource())
                        << "invalid element name: " << child_el->name << ", expected: locale");
            return false;
          }
        }
      }
    }
    return true;
  }

  std::string ConvertToBCP47Tag(const std::string& locale) {
    std::string bcp47tag = "b+";
    bcp47tag += locale;
    std::replace(bcp47tag.begin(), bcp47tag.end(), '-', '+');
    return bcp47tag;
  }

  std::unique_ptr<IArchiveWriter> MakeArchiveWriter(StringPiece out) {
    if (options_.output_to_directory) {
      return CreateDirectoryArchiveWriter(context_->GetDiagnostics(), out);
    } else {
      return CreateZipFileArchiveWriter(context_->GetDiagnostics(), out);
    }
  }

  bool FlattenTable(ResourceTable* table, OutputFormat format, IArchiveWriter* writer) {
    TRACE_CALL();
    switch (format) {
      case OutputFormat::kApk: {
        android::BigBuffer buffer(1024);
        TableFlattener flattener(options_.table_flattener_options, &buffer);
        if (!flattener.Consume(context_, table)) {
          context_->GetDiagnostics()->Error(android::DiagMessage()
                                            << "failed to flatten resource table");
          return false;
        }

        android::BigBufferInputStream input_stream(&buffer);
        return io::CopyInputStreamToArchive(context_, &input_stream, kApkResourceTablePath,
                                            ArchiveEntry::kAlign, writer);
      } break;

      case OutputFormat::kProto: {
        pb::ResourceTable pb_table;
        SerializeTableToPb(*table, &pb_table, context_->GetDiagnostics(),
                           options_.proto_table_flattener_options);
        return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath,
                                      ArchiveEntry::kCompress, writer);
      } break;
    }
    return false;
  }

  bool WriteJavaFile(ResourceTable* table, StringPiece package_name_to_generate,
                     StringPiece out_package, const JavaClassGeneratorOptions& java_options,
                     const std::optional<std::string>& out_text_symbols_path = {}) {
    if (!options_.generate_java_class_path && !out_text_symbols_path) {
      return true;
    }

    std::string out_path;
    std::unique_ptr<android::FileOutputStream> fout;
    if (options_.generate_java_class_path) {
      out_path = options_.generate_java_class_path.value();
      file::AppendPath(&out_path, file::PackageToPath(out_package));
      if (!file::mkdirs(out_path)) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed to create directory '" << out_path << "'");
        return false;
      }

      file::AppendPath(&out_path, "R.java");

      fout = util::make_unique<android::FileOutputStream>(out_path);
      if (fout->HadError()) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed writing to '" << out_path
                                          << "': " << fout->GetError());
        return false;
      }
    }

    std::unique_ptr<android::FileOutputStream> fout_text;
    if (out_text_symbols_path) {
      fout_text = util::make_unique<android::FileOutputStream>(out_text_symbols_path.value());
      if (fout_text->HadError()) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed writing to '" << out_text_symbols_path.value()
                                          << "': " << fout_text->GetError());
        return false;
      }
    }

    JavaClassGenerator generator(context_, table, java_options);
    if (!generator.Generate(package_name_to_generate, out_package, fout.get(), fout_text.get())) {
      context_->GetDiagnostics()->Error(android::DiagMessage(out_path) << generator.GetError());
      return false;
    }

    return true;
  }

  bool GenerateJavaClasses() {
    TRACE_CALL();
    // The set of packages whose R class to call in the main classes onResourcesLoaded callback.
    std::vector<std::string> packages_to_callback;

    JavaClassGeneratorOptions template_options;
    template_options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
    template_options.javadoc_annotations = options_.javadoc_annotations;

    if (context_->GetPackageType() == PackageType::kStaticLib || options_.generate_non_final_ids) {
      template_options.use_final = false;
    }

    if (context_->GetPackageType() == PackageType::kSharedLib) {
      template_options.use_final = false;
      template_options.rewrite_callback_options = OnResourcesLoadedCallbackOptions{};
    }

    const StringPiece actual_package = context_->GetCompilationPackage();
    StringPiece output_package = context_->GetCompilationPackage();
    if (options_.custom_java_package) {
      // Override the output java package to the custom one.
      output_package = options_.custom_java_package.value();
    }

    // Generate the private symbols if required.
    if (options_.private_symbols) {
      packages_to_callback.push_back(options_.private_symbols.value());

      // If we defined a private symbols package, we only emit Public symbols
      // to the original package, and private and public symbols to the private package.
      JavaClassGeneratorOptions options = template_options;
      options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate;
      if (!WriteJavaFile(&final_table_, actual_package, options_.private_symbols.value(),
                         options)) {
        return false;
      }
    }

    // Generate copies of the original package R class but with different package names.
    // This is to support non-namespaced builds.
    for (const std::string& extra_package : options_.extra_java_packages) {
      packages_to_callback.push_back(extra_package);

      JavaClassGeneratorOptions options = template_options;
      options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
      if (!WriteJavaFile(&final_table_, actual_package, extra_package, options)) {
        return false;
      }
    }

    // Generate R classes for each package that was merged (static library).
    // Use the actual package's resources only.
    for (const std::string& package : table_merger_->merged_packages()) {
      packages_to_callback.push_back(package);

      JavaClassGeneratorOptions options = template_options;
      options.types = JavaClassGeneratorOptions::SymbolTypes::kAll;
      if (!WriteJavaFile(&final_table_, package, package, options)) {
        return false;
      }
    }

    // Generate the main public R class.
    JavaClassGeneratorOptions options = template_options;

    // Only generate public symbols if we have a private package.
    if (options_.private_symbols) {
      options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic;
    }

    if (options.rewrite_callback_options) {
      options.rewrite_callback_options.value().packages_to_callback =
          std::move(packages_to_callback);
    }

    if (!WriteJavaFile(&final_table_, actual_package, output_package, options,
                       options_.generate_text_symbols_path)) {
      return false;
    }

    return true;
  }

  bool WriteManifestJavaFile(xml::XmlResource* manifest_xml) {
    TRACE_CALL();
    if (!options_.generate_java_class_path) {
      return true;
    }

    std::unique_ptr<ClassDefinition> manifest_class =
        GenerateManifestClass(context_->GetDiagnostics(), manifest_xml);

    if (!manifest_class) {
      // Something bad happened, but we already logged it, so exit.
      return false;
    }

    if (manifest_class->empty()) {
      // Empty Manifest class, no need to generate it.
      return true;
    }

    // Add any JavaDoc annotations to the generated class.
    for (const std::string& annotation : options_.javadoc_annotations) {
      std::string proper_annotation = "@";
      proper_annotation += annotation;
      manifest_class->GetCommentBuilder()->AppendComment(proper_annotation);
    }

    const std::string package_utf8 =
        options_.custom_java_package.value_or(context_->GetCompilationPackage());

    std::string out_path = options_.generate_java_class_path.value();
    file::AppendPath(&out_path, file::PackageToPath(package_utf8));

    if (!file::mkdirs(out_path)) {
      context_->GetDiagnostics()->Error(android::DiagMessage()
                                        << "failed to create directory '" << out_path << "'");
      return false;
    }

    file::AppendPath(&out_path, "Manifest.java");

    android::FileOutputStream fout(out_path);
    if (fout.HadError()) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed to open '" << out_path
                                                               << "': " << fout.GetError());
      return false;
    }

    ClassDefinition::WriteJavaFile(manifest_class.get(), package_utf8, true,
                                   false /* strip_api_annotations */, &fout);
    fout.Flush();

    if (fout.HadError()) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed writing to '" << out_path
                                                               << "': " << fout.GetError());
      return false;
    }
    return true;
  }

  bool WriteProguardFile(const std::optional<std::string>& out, const proguard::KeepSet& keep_set) {
    TRACE_CALL();
    if (!out) {
      return true;
    }

    const std::string& out_path = out.value();
    android::FileOutputStream fout(out_path);
    if (fout.HadError()) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed to open '" << out_path
                                                               << "': " << fout.GetError());
      return false;
    }

    proguard::WriteKeepSet(keep_set, &fout, options_.generate_minimal_proguard_rules,
                           options_.no_proguard_location_reference);
    fout.Flush();

    if (fout.HadError()) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed writing to '" << out_path
                                                               << "': " << fout.GetError());
      return false;
    }
    return true;
  }

  bool MergeStaticLibrary(const std::string& input, bool override) {
    TRACE_CALL();
    if (context_->IsVerbose()) {
      context_->GetDiagnostics()->Note(android::DiagMessage()
                                       << "merging static library " << input);
    }

    std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(input, context_->GetDiagnostics());
    if (apk == nullptr) {
      context_->GetDiagnostics()->Error(android::DiagMessage(input) << "invalid static library");
      return false;
    }

    ResourceTable* table = apk->GetResourceTable();
    if (table->packages.empty()) {
      return true;
    }

    auto lib_package_result = GetStaticLibraryPackage(table);
    if (!lib_package_result.has_value()) {
      context_->GetDiagnostics()->Error(android::DiagMessage(input) << lib_package_result.error());
      return false;
    }

    ResourceTablePackage* pkg = lib_package_result.value();
    bool result;
    if (options_.no_static_lib_packages) {
      // Merge all resources as if they were in the compilation package. This is the old behavior
      // of aapt.

      // Add the package to the set of --extra-packages so we emit an R.java for each library
      // package.
      if (!pkg->name.empty()) {
        options_.extra_java_packages.insert(pkg->name);
      }

      // Clear the package name, so as to make the resources look like they are coming from the
      // local package.
      pkg->name = "";
      result = table_merger_->Merge(android::Source(input), table, override);

    } else {
      // This is the proper way to merge libraries, where the package name is
      // preserved and resource names are mangled.
      result = table_merger_->MergeAndMangle(android::Source(input), pkg->name, table);
    }

    if (!result) {
      return false;
    }

    // Make sure to move the collection into the set of IFileCollections.
    merged_apks_.push_back(std::move(apk));
    return true;
  }

  bool MergeExportedSymbols(const android::Source& source,
                            const std::vector<SourcedResourceName>& exported_symbols) {
    TRACE_CALL();
    // Add the exports of this file to the table.
    for (const SourcedResourceName& exported_symbol : exported_symbols) {
      ResourceName res_name = exported_symbol.name;
      if (res_name.package.empty()) {
        res_name.package = context_->GetCompilationPackage();
      }

      std::optional<ResourceName> mangled_name = context_->GetNameMangler()->MangleName(res_name);
      if (mangled_name) {
        res_name = mangled_name.value();
      }

      auto id = util::make_unique<Id>();
      id->SetSource(source.WithLine(exported_symbol.line));
      bool result = final_table_.AddResource(
          NewResourceBuilder(res_name).SetValue(std::move(id)).SetAllowMangled(true).Build(),
          context_->GetDiagnostics());
      if (!result) {
        return false;
      }
    }
    return true;
  }

  bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) {
    TRACE_CALL();
    if (context_->IsVerbose()) {
      context_->GetDiagnostics()->Note(android::DiagMessage()
                                       << "merging '" << compiled_file.name
                                       << "' from compiled file " << compiled_file.source);
    }

    if (!table_merger_->MergeFile(compiled_file, override, file)) {
      return false;
    }
    return MergeExportedSymbols(compiled_file.source, compiled_file.exported_symbols);
  }

  // Takes a path to load as a ZIP file and merges the files within into the main ResourceTable.
  // If override is true, conflicting resources are allowed to override each other, in order of last
  // seen.
  // An io::IFileCollection is created from the ZIP file and added to the set of
  // io::IFileCollections that are open.
  bool MergeArchive(const std::string& input, bool override) {
    TRACE_CALL();
    if (context_->IsVerbose()) {
      context_->GetDiagnostics()->Note(android::DiagMessage() << "merging archive " << input);
    }

    std::string error_str;
    std::unique_ptr<io::ZipFileCollection> collection =
        io::ZipFileCollection::Create(input, &error_str);
    if (!collection) {
      context_->GetDiagnostics()->Error(android::DiagMessage(input) << error_str);
      return false;
    }

    bool error = false;
    for (auto iter = collection->Iterator(); iter->HasNext();) {
      if (!MergeFile(iter->Next(), override)) {
        error = true;
      }
    }

    // Make sure to move the collection into the set of IFileCollections.
    collections_.push_back(std::move(collection));
    return !error;
  }

  // Takes a path to load and merge into the main ResourceTable. If override is true,
  // conflicting resources are allowed to override each other, in order of last seen.
  // If the file path ends with .flata, .jar, .jack, or .zip the file is treated
  // as ZIP archive and the files within are merged individually.
  // Otherwise the file is processed on its own.
  bool MergePath(const std::string& path, bool override) {
    if (util::EndsWith(path, ".flata") || util::EndsWith(path, ".jar") ||
        util::EndsWith(path, ".jack") || util::EndsWith(path, ".zip")) {
      return MergeArchive(path, override);
    } else if (util::EndsWith(path, ".apk")) {
      return MergeStaticLibrary(path, override);
    }

    io::IFile* file = file_collection_->InsertFile(path);
    return MergeFile(file, override);
  }

  // Takes an AAPT Container file (.apc/.flat) to load and merge into the main ResourceTable.
  // If override is true, conflicting resources are allowed to override each other, in order of last
  // seen.
  // All other file types are ignored. This is because these files could be coming from a zip,
  // where we could have other files like classes.dex.
  bool MergeFile(io::IFile* file, bool override) {
    TRACE_CALL();
    const android::Source& src = file->GetSource();

    if (util::EndsWith(src.path, ".xml") || util::EndsWith(src.path, ".png")) {
      // Since AAPT compiles these file types and appends .flat to them, seeing
      // their raw extensions is a sign that they weren't compiled.
      const StringPiece file_type = util::EndsWith(src.path, ".xml") ? "XML" : "PNG";
      context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                        << "uncompiled " << file_type
                                        << " file passed as argument. Must be "
                                           "compiled first into .flat file.");
      return false;
    } else if (!util::EndsWith(src.path, ".apc") && !util::EndsWith(src.path, ".flat")) {
      if (context_->IsVerbose()) {
        context_->GetDiagnostics()->Warn(android::DiagMessage(src) << "ignoring unrecognized file");
        return true;
      }
    }

    std::unique_ptr<android::InputStream> input_stream = file->OpenInputStream();
    if (input_stream == nullptr) {
      context_->GetDiagnostics()->Error(android::DiagMessage(src) << "failed to open file");
      return false;
    }

    if (input_stream->HadError()) {
      context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                        << "failed to open file: " << input_stream->GetError());
      return false;
    }

    ContainerReaderEntry* entry;
    ContainerReader reader(input_stream.get());

    if (reader.HadError()) {
      context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                        << "failed to read file: " << reader.GetError());
      return false;
    }

    while ((entry = reader.Next()) != nullptr) {
      if (entry->Type() == ContainerEntryType::kResTable) {
        TRACE_NAME(std::string("Process ResTable:") + file->GetSource().path);
        pb::ResourceTable pb_table;
        if (!entry->GetResTable(&pb_table)) {
          context_->GetDiagnostics()->Error(
              android::DiagMessage(src) << "failed to read resource table: " << entry->GetError());
          return false;
        }

        ResourceTable table;
        std::string error;
        if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
          context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                            << "failed to deserialize resource table: " << error);
          return false;
        }

        if (!table_merger_->Merge(src, &table, override)) {
          context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                            << "failed to merge resource table");
          return false;
        }
      } else if (entry->Type() == ContainerEntryType::kResFile) {
        TRACE_NAME(std::string("Process ResFile") + file->GetSource().path);
        pb::internal::CompiledFile pb_compiled_file;
        off64_t offset;
        size_t len;
        if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &len)) {
          context_->GetDiagnostics()->Error(
              android::DiagMessage(src) << "failed to get resource file: " << entry->GetError());
          return false;
        }

        ResourceFile resource_file;
        std::string error;
        if (!DeserializeCompiledFileFromPb(pb_compiled_file, &resource_file, &error)) {
          context_->GetDiagnostics()->Error(android::DiagMessage(src)
                                            << "failed to read compiled header: " << error);
          return false;
        }

        if (!MergeCompiledFile(resource_file, file->CreateFileSegment(offset, len), override)) {
          return false;
        }
      }
    }
    return true;
  }

  bool CopyAssetsDirsToApk(IArchiveWriter* writer) {
    std::map<std::string, std::unique_ptr<io::RegularFile>> merged_assets;
    for (const std::string& assets_dir : options_.assets_dirs) {
      std::optional<std::vector<std::string>> files =
          file::FindFiles(assets_dir, context_->GetDiagnostics(), nullptr);
      if (!files) {
        return false;
      }

      for (const std::string& file : files.value()) {
        std::string full_key = "assets/" + file;
        std::string full_path = assets_dir;
        file::AppendPath(&full_path, file);

        auto iter = merged_assets.find(full_key);
        if (iter == merged_assets.end()) {
          merged_assets.emplace(std::move(full_key), util::make_unique<io::RegularFile>(
                                                         android::Source(std::move(full_path))));
        } else if (context_->IsVerbose()) {
          context_->GetDiagnostics()->Warn(android::DiagMessage(iter->second->GetSource())
                                           << "asset file overrides '" << full_path << "'");
        }
      }
    }

    for (auto& entry : merged_assets) {
      uint32_t compression_flags = GetCompressionFlags(entry.first, options_);
      if (!io::CopyFileToArchive(context_, entry.second.get(), entry.first, compression_flags,
                                 writer)) {
        return false;
      }
    }
    return true;
  }

  ResourceEntry* ResolveTableEntry(LinkContext* context, ResourceTable* table,
                                   Reference* reference) {
    if (!reference || !reference->name) {
      return nullptr;
    }
    auto name_ref = ResourceNameRef(reference->name.value());
    if (name_ref.package.empty()) {
      name_ref.package = context->GetCompilationPackage();
    }
    const auto search_result = table->FindResource(name_ref);
    if (!search_result) {
      return nullptr;
    }
    return search_result.value().entry;
  }

  void AliasAdaptiveIcon(xml::XmlResource* manifest, ResourceTable* table) {
    const xml::Element* application = manifest->root->FindChild("", "application");
    if (!application) {
      return;
    }

    const xml::Attribute* icon = application->FindAttribute(xml::kSchemaAndroid, "icon");
    const xml::Attribute* round_icon = application->FindAttribute(xml::kSchemaAndroid, "roundIcon");
    if (!icon || !round_icon) {
      return;
    }

    // Find the icon resource defined within the application.
    const auto icon_reference = ValueCast<Reference>(icon->compiled_value.get());
    const auto icon_entry = ResolveTableEntry(context_, table, icon_reference);
    if (!icon_entry) {
      return;
    }

    int icon_max_sdk = 0;
    for (auto& config_value : icon_entry->values) {
      icon_max_sdk = (icon_max_sdk < config_value->config.sdkVersion)
          ? config_value->config.sdkVersion : icon_max_sdk;
    }
    if (icon_max_sdk < SDK_O) {
      // Adaptive icons must be versioned with v26 qualifiers, so this is not an adaptive icon.
      return;
    }

    // Find the roundIcon resource defined within the application.
    const auto round_icon_reference = ValueCast<Reference>(round_icon->compiled_value.get());
    const auto round_icon_entry = ResolveTableEntry(context_, table, round_icon_reference);
    if (!round_icon_entry) {
      return;
    }

    int round_icon_max_sdk = 0;
    for (auto& config_value : round_icon_entry->values) {
      round_icon_max_sdk = (round_icon_max_sdk < config_value->config.sdkVersion)
                     ? config_value->config.sdkVersion : round_icon_max_sdk;
    }
    if (round_icon_max_sdk >= SDK_O) {
      // The developer explicitly used a v26 compatible drawable as the roundIcon, meaning we should
      // not generate an alias to the icon drawable.
      return;
    }

    // Add an equivalent v26 entry to the roundIcon for each v26 variant of the regular icon.
    for (auto& config_value : icon_entry->values) {
      if (config_value->config.sdkVersion < SDK_O) {
        continue;
      }

      context_->GetDiagnostics()->Note(android::DiagMessage()
                                       << "generating " << round_icon_reference->name.value()
                                       << " with config \"" << config_value->config
                                       << "\" for round icon compatibility");

      CloningValueTransformer cloner(&table->string_pool);
      auto value = icon_reference->Transform(cloner);
      auto round_config_value =
          round_icon_entry->FindOrCreateValue(config_value->config, config_value->product);
      round_config_value->value = std::move(value);
    }
  }

  bool VerifySharedUserId(xml::XmlResource* manifest, ResourceTable* table) {
    const xml::Element* manifest_el = xml::FindRootElement(manifest->root.get());
    if (manifest_el == nullptr) {
      return true;
    }
    if (!manifest_el->namespace_uri.empty() || manifest_el->name != "manifest") {
      return true;
    }
    const xml::Attribute* attr = manifest_el->FindAttribute(xml::kSchemaAndroid, "sharedUserId");
    if (!attr) {
      return true;
    }
    const auto validate = [&](const std::string& shared_user_id) -> bool {
      if (util::IsAndroidSharedUserId(context_->GetCompilationPackage(), shared_user_id)) {
        return true;
      }
      android::DiagMessage error_msg(manifest_el->line_number);
      error_msg << "attribute 'sharedUserId' in <manifest> tag is not a valid shared user id: '"
                << shared_user_id << "'";
      if (options_.manifest_fixer_options.warn_validation) {
        // Treat the error only as a warning.
        context_->GetDiagnostics()->Warn(error_msg);
        return true;
      }
      context_->GetDiagnostics()->Error(error_msg);
      return false;
    };
    // If attr->compiled_value is not null, check if it is a ref
    if (attr->compiled_value) {
      const auto ref = ValueCast<Reference>(attr->compiled_value.get());
      if (ref == nullptr) {
        return true;
      }
      const auto shared_user_id_entry = ResolveTableEntry(context_, table, ref);
      if (!shared_user_id_entry) {
        return true;
      }
      for (const auto& value : shared_user_id_entry->values) {
        const auto str_value = ValueCast<String>(value->value.get());
        if (str_value != nullptr && !validate(*str_value->value)) {
          return false;
        }
      }
      return true;
    }

    // Fallback to checking the raw value
    return validate(attr->value);
  }

  // Writes the AndroidManifest, ResourceTable, and all XML files referenced by the ResourceTable
  // to the IArchiveWriter.
  bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest,
                ResourceTable* table) {
    TRACE_CALL();
    const bool keep_raw_values = (context_->GetPackageType() == PackageType::kStaticLib)
                                 || options_.keep_raw_values;
    bool result = FlattenXml(context_, *manifest, kAndroidManifestPath, keep_raw_values,
                             true /*utf16*/, options_.output_format, writer);
    if (!result) {
      return false;
    }

    // When a developer specifies an adaptive application icon, and a non-adaptive round application
    // icon, create an alias from the round icon to the regular icon for v26 APIs and up. We do this
    // because certain devices prefer android:roundIcon over android:icon regardless of the API
    // levels of the drawables set for either. This auto-aliasing behaviour allows an app to prefer
    // the android:roundIcon on API 25 devices, and prefer the adaptive icon on API 26 devices.
    // See (b/34829129)
    AliasAdaptiveIcon(manifest, table);

    // Verify the shared user id here to handle the case of reference value.
    if (!VerifySharedUserId(manifest, table)) {
      return false;
    }

    ResourceFileFlattenerOptions file_flattener_options;
    file_flattener_options.keep_raw_values = keep_raw_values;
    file_flattener_options.do_not_compress_anything = options_.do_not_compress_anything;
    file_flattener_options.extensions_to_not_compress = options_.extensions_to_not_compress;
    file_flattener_options.regex_to_not_compress = options_.regex_to_not_compress;
    file_flattener_options.no_auto_version = options_.no_auto_version;
    file_flattener_options.no_version_vectors = options_.no_version_vectors;
    file_flattener_options.no_version_transitions = options_.no_version_transitions;
    file_flattener_options.no_xml_namespaces = options_.no_xml_namespaces;
    file_flattener_options.update_proguard_spec =
        static_cast<bool>(options_.generate_proguard_rules_path);
    file_flattener_options.output_format = options_.output_format;
    file_flattener_options.do_not_fail_on_missing_resources = options_.merge_only;

    ResourceFileFlattener file_flattener(file_flattener_options, context_, keep_set);
    if (!file_flattener.Flatten(table, writer)) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed linking file resources");
      return false;
    }

    // Hack to fix b/68820737.
    // We need to modify the ResourceTable's package name, but that should NOT affect
    // anything else being generated, which includes the Java classes.
    // If required, the package name is modifed before flattening, and then modified back
    // to its original name.
    ResourceTablePackage* package_to_rewrite = nullptr;
    // Pre-O, the platform treats negative resource IDs [those with a package ID of 0x80
    // or higher] as invalid. In order to work around this limitation, we allow the use
    // of traditionally reserved resource IDs [those between 0x02 and 0x7E]. Allow the
    // definition of what a valid "split" package ID is to account for this.
    const bool isSplitPackage = (options_.allow_reserved_package_id &&
          context_->GetPackageId() != kAppPackageId &&
          context_->GetPackageId() != kFrameworkPackageId)
        || (!options_.allow_reserved_package_id && context_->GetPackageId() > kAppPackageId);
    if (isSplitPackage && included_feature_base_ == context_->GetCompilationPackage()) {
      // The base APK is included, and this is a feature split. If the base package is
      // the same as this package, then we are building an old style Android Instant Apps feature
      // split and must apply this workaround to avoid requiring namespaces support.
      if (!table->packages.empty() &&
          table->packages.back()->name == context_->GetCompilationPackage()) {
        package_to_rewrite = table->packages.back().get();
        std::string new_package_name =
            StringPrintf("%s.%s", package_to_rewrite->name.c_str(),
                         app_info_.split_name.value_or("feature").c_str());

        if (context_->IsVerbose()) {
          context_->GetDiagnostics()->Note(
              android::DiagMessage() << "rewriting resource package name for feature split to '"
                                     << new_package_name << "'");
        }
        package_to_rewrite->name = new_package_name;
      }
    }

    bool success = FlattenTable(table, options_.output_format, writer);

    if (package_to_rewrite != nullptr) {
      // Change the name back.
      package_to_rewrite->name = context_->GetCompilationPackage();

      // TableFlattener creates an `included_packages_` mapping entry for each package with a
      // non-standard package id (not 0x01 or 0x7f). Since this is a feature split and not a shared
      // library, do not include a mapping from the feature package name to the feature package id
      // in the feature's dynamic reference table.
      table->included_packages_.erase(context_->GetPackageId());
    }

    if (!success) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed to write resource table");
    }
    return success;
  }

  int Run(const std::vector<std::string>& input_files) {
    TRACE_CALL();
    // Load the AndroidManifest.xml
    std::unique_ptr<xml::XmlResource> manifest_xml =
        LoadXml(options_.manifest_path, context_->GetDiagnostics());
    if (!manifest_xml) {
      return 1;
    }

    // First extract the Package name without modifying it (via --rename-manifest-package).
    if (std::optional<AppInfo> maybe_app_info =
            ExtractAppInfoFromManifest(manifest_xml.get(), context_->GetDiagnostics())) {
      const AppInfo& app_info = maybe_app_info.value();
      context_->SetCompilationPackage(app_info.package);
    }

    // Determine the package name under which to merge resources.
    if (options_.rename_resources_package) {
      if (!options_.custom_java_package) {
        // Generate the R.java under the original package name instead of the package name specified
        // through --rename-resources-package.
        options_.custom_java_package = context_->GetCompilationPackage();
      }
      context_->SetCompilationPackage(options_.rename_resources_package.value());
    }

    // Now that the compilation package is set, load the dependencies. This will also extract
    // the Android framework's versionCode and versionName, if they exist.
    if (!LoadSymbolsFromIncludePaths()) {
      return 1;
    }

    ManifestFixer manifest_fixer(options_.manifest_fixer_options);
    if (!manifest_fixer.Consume(context_, manifest_xml.get())) {
      return 1;
    }

    std::optional<AppInfo> maybe_app_info =
        ExtractAppInfoFromManifest(manifest_xml.get(), context_->GetDiagnostics());
    if (!maybe_app_info) {
      return 1;
    }

    app_info_ = maybe_app_info.value();
    context_->SetMinSdkVersion(app_info_.min_sdk_version.value_or(0));

    context_->SetNameManglerPolicy(NameManglerPolicy{context_->GetCompilationPackage()});
    context_->SetSplitNameDependencies(app_info_.split_name_dependencies);

    FeatureFlagsFilterOptions flags_filter_options;
    if (context_->GetMinSdkVersion() > SDK_UPSIDE_DOWN_CAKE) {
      // For API version > U, PackageManager will dynamically read the flag values and disable
      // manifest elements accordingly when parsing the manifest.
      // For API version <= U, we remove disabled elements from the manifest with the filter.
      flags_filter_options.remove_disabled_elements = false;
      flags_filter_options.flags_must_have_value = false;
    }
    FeatureFlagsFilter flags_filter(options_.feature_flag_values, flags_filter_options);
    if (!flags_filter.Consume(context_, manifest_xml.get())) {
      return 1;
    }

    // Override the package ID when it is "android".
    if (context_->GetCompilationPackage() == "android") {
      context_->SetPackageId(kAndroidPackageId);

      // Verify we're building a regular app.
      if (context_->GetPackageType() != PackageType::kApp) {
        context_->GetDiagnostics()->Error(
            android::DiagMessage() << "package 'android' can only be built as a regular app");
        return 1;
      }
    }

    TableMergerOptions table_merger_options;
    table_merger_options.auto_add_overlay = options_.auto_add_overlay;
    table_merger_options.override_styles_instead_of_overlaying =
        options_.override_styles_instead_of_overlaying;
    table_merger_options.strict_visibility = options_.strict_visibility;
    table_merger_ = util::make_unique<TableMerger>(context_, &final_table_, table_merger_options);

    if (context_->IsVerbose()) {
      context_->GetDiagnostics()->Note(android::DiagMessage()
                                       << StringPrintf("linking package '%s' using package ID %02x",
                                                       context_->GetCompilationPackage().data(),
                                                       context_->GetPackageId()));
    }

    // Extract symbols from AndroidManifest.xml, since this isn't merged like the other XML files
    // in res/**/*.
    {
      XmlIdCollector collector;
      if (!collector.Consume(context_, manifest_xml.get())) {
        return false;
      }

      if (!MergeExportedSymbols(manifest_xml->file.source, manifest_xml->file.exported_symbols)) {
        return false;
      }
    }

    for (const std::string& input : input_files) {
      if (!MergePath(input, false)) {
        context_->GetDiagnostics()->Error(android::DiagMessage() << "failed parsing input");
        return 1;
      }
    }

    for (const std::string& input : options_.overlay_files) {
      if (!MergePath(input, true)) {
        context_->GetDiagnostics()->Error(android::DiagMessage() << "failed parsing overlays");
        return 1;
      }
    }

    if (!VerifyNoExternalPackages()) {
      return 1;
    }

    if (context_->GetPackageType() != PackageType::kStaticLib) {
      PrivateAttributeMover mover;
      if (context_->GetPackageId() == kAndroidPackageId &&
          !mover.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed moving private attributes");
        return 1;
      }

      // Assign IDs if we are building a regular app.
      IdAssigner id_assigner(&options_.stable_id_map);
      if (!id_assigner.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage() << "failed assigning IDs");
        return 1;
      }

      // Now grab each ID and emit it as a file.
      if (options_.resource_id_map_path) {
        for (auto& package : final_table_.packages) {
          for (auto& type : package->types) {
            for (auto& entry : type->entries) {
              ResourceName name(package->name, type->named_type, entry->name);
              // The IDs are guaranteed to exist.
              options_.stable_id_map[std::move(name)] = entry->id.value();
            }
          }
        }

        if (!WriteStableIdMapToPath(context_->GetDiagnostics(), options_.stable_id_map,
                                    options_.resource_id_map_path.value())) {
          return 1;
        }
      }
    } else {
      // Static libs are merged with other apps, and ID collisions are bad, so
      // verify that
      // no IDs have been set.
      if (!VerifyNoIdsSet()) {
        return 1;
      }
    }

    // Add the names to mangle based on our source merge earlier.
    context_->SetNameManglerPolicy(
        NameManglerPolicy{context_->GetCompilationPackage(), table_merger_->merged_packages()});

    // Add our table to the symbol table.
    context_->GetExternalSymbols()->PrependSource(
        util::make_unique<ResourceTableSymbolSource>(&final_table_));

    // Workaround for pre-O runtime that would treat negative resource IDs
    // (any ID with a package ID > 7f) as invalid. Intercept any ID (PPTTEEEE) with PP > 0x7f
    // and type == 'id', and return the ID 0x7fPPEEEE. IDs don't need to be real resources, they
    // are just identifiers.
    if (context_->GetMinSdkVersion() < SDK_O && context_->GetPackageType() == PackageType::kApp) {
      if (context_->IsVerbose()) {
        context_->GetDiagnostics()->Note(android::DiagMessage()
                                         << "enabling pre-O feature split ID rewriting");
      }
      context_->GetExternalSymbols()->SetDelegate(
          util::make_unique<FeatureSplitSymbolTableDelegate>(context_));
    }

    // Before we process anything, remove the resources whose default values don't exist.
    // We want to force any references to these to fail the build.
    if (!options_.no_resource_removal) {
      if (!NoDefaultResourceRemover{}.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed removing resources with no defaults");
        return 1;
      }
    }

    ReferenceLinker linker;
    if (!options_.merge_only && !linker.Consume(context_, &final_table_)) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed linking references");
      return 1;
    }

    if (context_->GetPackageType() == PackageType::kStaticLib) {
      if (!options_.products.empty()) {
        context_->GetDiagnostics()->Warn(android::DiagMessage()
                                         << "can't select products when building static library");
      }
    } else {
      ProductFilter product_filter(options_.products, /* remove_default_config_values = */ false);
      if (!product_filter.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage() << "failed stripping products");
        return 1;
      }
    }

    if (!options_.no_auto_version) {
      AutoVersioner versioner;
      if (!versioner.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage() << "failed versioning styles");
        return 1;
      }
    }

    if (context_->GetPackageType() != PackageType::kStaticLib && context_->GetMinSdkVersion() > 0) {
      if (context_->IsVerbose()) {
        context_->GetDiagnostics()->Note(android::DiagMessage()
                                         << "collapsing resource versions for minimum SDK "
                                         << context_->GetMinSdkVersion());
      }

      VersionCollapser collapser;
      if (!collapser.Consume(context_, &final_table_)) {
        return 1;
      }
    }

    if (!options_.exclude_configs_.empty()) {
      std::vector<ConfigDescription> excluded_configs;

      for (auto& config_string : options_.exclude_configs_) {
        TRACE_NAME("ConfigDescription::Parse");
        ConfigDescription config_description;

        if (!ConfigDescription::Parse(config_string, &config_description)) {
          context_->GetDiagnostics()->Error(
              android::DiagMessage() << "failed to parse --excluded-configs " << config_string);
          return 1;
        }

        excluded_configs.push_back(config_description);
      }

      ResourceExcluder excluder(excluded_configs);
      if (!excluder.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage()
                                          << "failed excluding configurations");
        return 1;
      }
    }

    if (!options_.no_resource_deduping) {
      ResourceDeduper deduper;
      if (!deduper.Consume(context_, &final_table_)) {
        context_->GetDiagnostics()->Error(android::DiagMessage() << "failed deduping resources");
        return 1;
      }
    }

    proguard::KeepSet proguard_keep_set =
        proguard::KeepSet(options_.generate_conditional_proguard_rules);
    proguard::KeepSet proguard_main_dex_keep_set;

    if (context_->GetPackageType() == PackageType::kStaticLib) {
      if (options_.table_splitter_options.config_filter != nullptr ||
          !options_.table_splitter_options.preferred_densities.empty()) {
        context_->GetDiagnostics()->Warn(android::DiagMessage()
                                         << "can't strip resources when building static library");
      }
    } else {
      // Adjust the SplitConstraints so that their SDK version is stripped if it is less than or
      // equal to the minSdk.
      const size_t origConstraintSize = options_.split_constraints.size();
      options_.split_constraints =
          AdjustSplitConstraintsForMinSdk(context_->GetMinSdkVersion(), options_.split_constraints);

      if (origConstraintSize != options_.split_constraints.size()) {
        context_->GetDiagnostics()->Warn(android::DiagMessage()
                                         << "requested to split resources prior to min sdk of "
                                         << context_->GetMinSdkVersion());
      }
      TableSplitter table_splitter(options_.split_constraints, options_.table_splitter_options);
      if (!table_splitter.VerifySplitConstraints(context_)) {
        return 1;
      }
      table_splitter.SplitTable(&final_table_);

      // Now we need to write out the Split APKs.
      auto path_iter = options_.split_paths.begin();
      auto split_constraints_iter = options_.split_constraints.begin();
      for (std::unique_ptr<ResourceTable>& split_table : table_splitter.splits()) {
        if (context_->IsVerbose()) {
          context_->GetDiagnostics()->Note(android::DiagMessage(*path_iter)
                                           << "generating split with configurations '"
                                           << util::Joiner(split_constraints_iter->configs, ", ")
                                           << "'");
        }

        std::unique_ptr<IArchiveWriter> archive_writer = MakeArchiveWriter(*path_iter);
        if (!archive_writer) {
          context_->GetDiagnostics()->Error(android::DiagMessage() << "failed to create archive");
          return 1;
        }

        // Generate an AndroidManifest.xml for each split.
        std::unique_ptr<xml::XmlResource> split_manifest =
            GenerateSplitManifest(app_info_, *split_constraints_iter);

        XmlReferenceLinker linker(&final_table_);
        if (!linker.Consume(context_, split_manifest.get())) {
          context_->GetDiagnostics()->Error(android::DiagMessage()
                                            << "failed to create Split AndroidManifest.xml");
          return 1;
        }

        if (!WriteApk(archive_writer.get(), &proguard_keep_set, split_manifest.get(),
                      split_table.get())) {
          return 1;
        }

        ++path_iter;
        ++split_constraints_iter;
      }
    }

    // Start writing the base APK.
    std::unique_ptr<IArchiveWriter> archive_writer = MakeArchiveWriter(options_.output_path);
    if (!archive_writer) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed to create archive");
      return 1;
    }

    bool error = false;
    {
      // AndroidManifest.xml has no resource name, but the CallSite is built from the name
      // (aka, which package the AndroidManifest.xml is coming from).
      // So we give it a package name so it can see local resources.
      manifest_xml->file.name.package = context_->GetCompilationPackage();

      XmlReferenceLinker manifest_linker(&final_table_);
      if (options_.merge_only || manifest_linker.Consume(context_, manifest_xml.get())) {
        if (options_.generate_proguard_rules_path &&
            !proguard::CollectProguardRulesForManifest(manifest_xml.get(), &proguard_keep_set)) {
          error = true;
        }

        if (options_.generate_main_dex_proguard_rules_path &&
            !proguard::CollectProguardRulesForManifest(manifest_xml.get(),
                                                       &proguard_main_dex_keep_set, true)) {
          error = true;
        }

        if (options_.generate_java_class_path) {
          if (!WriteManifestJavaFile(manifest_xml.get())) {
            error = true;
          }
        }

        if (options_.no_xml_namespaces) {
          // PackageParser will fail if URIs are removed from
          // AndroidManifest.xml.
          XmlNamespaceRemover namespace_remover(true /* keepUris */);
          if (!namespace_remover.Consume(context_, manifest_xml.get())) {
            error = true;
          }
        }
      } else {
        error = true;
      }
    }

    if (error) {
      context_->GetDiagnostics()->Error(android::DiagMessage() << "failed processing manifest");
      return 1;
    }

    if (!VerifyLocaleFormat(manifest_xml.get(), context_->GetDiagnostics())) {
      return 1;
    };

    if (!WriteApk(archive_writer.get(), &proguard_keep_set, manifest_xml.get(), &final_table_)) {
      return 1;
    }

    if (!CopyAssetsDirsToApk(archive_writer.get())) {
      return 1;
    }

    if (options_.generate_java_class_path || options_.generate_text_symbols_path) {
      if (!GenerateJavaClasses()) {
        return 1;
      }
    }

    if (!WriteProguardFile(options_.generate_proguard_rules_path, proguard_keep_set)) {
      return 1;
    }

    if (!WriteProguardFile(options_.generate_main_dex_proguard_rules_path,
                           proguard_main_dex_keep_set)) {
      return 1;
    }
    return 0;
  }

 private:
  LinkOptions options_;
  LinkContext* context_;
  ResourceTable final_table_;

  AppInfo app_info_;

  std::unique_ptr<TableMerger> table_merger_;

  // A pointer to the FileCollection representing the filesystem (not archives).
  std::unique_ptr<io::FileCollection> file_collection_;

  // A vector of IFileCollections. This is mainly here to retain ownership of the
  // collections.
  std::vector<std::unique_ptr<io::IFileCollection>> collections_;

  // The set of merged APKs. This is mainly here to retain ownership of the APKs.
  std::vector<std::unique_ptr<LoadedApk>> merged_apks_;

  // The set of included APKs (not merged). This is mainly here to retain ownership of the APKs.
  std::vector<std::unique_ptr<LoadedApk>> static_library_includes_;

  // The set of shared libraries being used, mapping their assigned package ID to package name.
  std::map<size_t, std::string> shared_libs_;

  // The package name of the base application, if it is included.
  std::optional<std::string> included_feature_base_;
};

int LinkCommand::Action(const std::vector<std::string>& args) {
  TRACE_FLUSH(trace_folder_ ? trace_folder_.value() : "", "LinkCommand::Action");
  LinkContext context(diag_);

  // Expand all argument-files passed into the command line. These start with '@'.
  std::vector<std::string> arg_list;
  for (const std::string& arg : args) {
    if (util::StartsWith(arg, "@")) {
      const std::string path = arg.substr(1, arg.size() - 1);
      std::string error;
      if (!file::AppendArgsFromFile(path, &arg_list, &error)) {
        context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
        return 1;
      }
    } else {
      arg_list.push_back(arg);
    }
  }

  // Expand all argument-files passed to -R.
  for (const std::string& arg : overlay_arg_list_) {
    if (util::StartsWith(arg, "@")) {
      const std::string path = arg.substr(1, arg.size() - 1);
      std::string error;
      if (!file::AppendArgsFromFile(path, &options_.overlay_files, &error)) {
        context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
        return 1;
      }
    } else {
      options_.overlay_files.push_back(arg);
    }
  }

  if (verbose_) {
    context.SetVerbose(verbose_);
  }

  if (int{shared_lib_} + int{static_lib_} + int{proto_format_} > 1) {
    context.GetDiagnostics()
        ->Error(android::DiagMessage()
                << "only one of --shared-lib, --static-lib, or --proto_format can be defined");
    return 1;
  }

  if (shared_lib_ && options_.private_symbols) {
    // If a shared library styleable in a public R.java uses a private attribute, attempting to
    // reference the private attribute within the styleable array will cause a link error because
    // the private attribute will not be emitted in the public R.java.
    context.GetDiagnostics()->Error(android::DiagMessage()
                                    << "--shared-lib cannot currently be used in combination with"
                                    << " --private-symbols");
    return 1;
  }

  if (options_.merge_only && !static_lib_) {
    context.GetDiagnostics()
        ->Error(android::DiagMessage()
                << "the --merge-only flag can be only used when building a static library");
    return 1;
  }
  if (options_.use_sparse_encoding) {
    options_.table_flattener_options.sparse_entries = SparseEntriesMode::Enabled;
  }

  // The default build type.
  context.SetPackageType(PackageType::kApp);
  context.SetPackageId(kAppPackageId);

  if (shared_lib_) {
    context.SetPackageType(PackageType::kSharedLib);
    context.SetPackageId(0x00);
  } else if (static_lib_) {
    context.SetPackageType(PackageType::kStaticLib);
    options_.output_format = OutputFormat::kProto;
  } else if (proto_format_) {
    options_.output_format = OutputFormat::kProto;
  }

  if (package_id_) {
    if (context.GetPackageType() != PackageType::kApp) {
      context.GetDiagnostics()->Error(
          android::DiagMessage() << "can't specify --package-id when not building a regular app");
      return 1;
    }

    const std::optional<uint32_t> maybe_package_id_int =
        ResourceUtils::ParseInt(package_id_.value());
    if (!maybe_package_id_int) {
      context.GetDiagnostics()->Error(android::DiagMessage()
                                      << "package ID '" << package_id_.value()
                                      << "' is not a valid integer");
      return 1;
    }

    const uint32_t package_id_int = maybe_package_id_int.value();
    if (package_id_int > std::numeric_limits<uint8_t>::max()
        || package_id_int == kFrameworkPackageId
        || (!options_.allow_reserved_package_id && package_id_int < kAppPackageId)) {
      context.GetDiagnostics()->Error(
          android::DiagMessage() << StringPrintf(
              "invalid package ID 0x%02x. Must be in the range 0x7f-0xff.", package_id_int));
      return 1;
    }
    context.SetPackageId(static_cast<uint8_t>(package_id_int));
  }

  // Populate the set of extra packages for which to generate R.java.
  for (std::string& extra_package : extra_java_packages_) {
    // A given package can actually be a colon separated list of packages.
    for (StringPiece package : util::Split(extra_package, ':')) {
      options_.extra_java_packages.emplace(package);
    }
  }

  if (product_list_) {
    for (StringPiece product : util::Tokenize(product_list_.value(), ',')) {
      if (product != "" && product != "default") {
        options_.products.emplace(product);
      }
    }
  }

  std::unique_ptr<IConfigFilter> filter;
  if (!configs_.empty()) {
    filter = ParseConfigFilterParameters(configs_, context.GetDiagnostics());
    if (filter == nullptr) {
      return 1;
    }
    options_.table_splitter_options.config_filter = filter.get();
  }

  if (preferred_density_) {
    std::optional<uint16_t> density =
        ParseTargetDensityParameter(preferred_density_.value(), context.GetDiagnostics());
    if (!density) {
      return 1;
    }
    options_.table_splitter_options.preferred_densities.push_back(density.value());
  }

  // Parse the split parameters.
  for (const std::string& split_arg : split_args_) {
    options_.split_paths.push_back({});
    options_.split_constraints.push_back({});
    if (!ParseSplitParameter(split_arg, context.GetDiagnostics(), &options_.split_paths.back(),
        &options_.split_constraints.back())) {
      return 1;
    }
  }

  // Parse the feature flag values. An argument that starts with '@' points to a file to read flag
  // values from.
  std::vector<std::string> all_feature_flags_args;
  for (const std::string& arg : feature_flags_args_) {
    if (util::StartsWith(arg, "@")) {
      const std::string path = arg.substr(1, arg.size() - 1);
      std::string error;
      if (!file::AppendArgsFromFile(path, &all_feature_flags_args, &error)) {
        context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
        return 1;
      }
    } else {
      all_feature_flags_args.push_back(arg);
    }
  }

  for (const std::string& arg : all_feature_flags_args) {
    if (!ParseFeatureFlagsParameter(arg, context.GetDiagnostics(), &options_.feature_flag_values)) {
      return 1;
    }
  }

  if (context.GetPackageType() != PackageType::kStaticLib && stable_id_file_path_) {
    if (!LoadStableIdMap(context.GetDiagnostics(), stable_id_file_path_.value(),
        &options_.stable_id_map)) {
      return 1;
    }
  }

  if (no_compress_regex) {
    std::string regex = no_compress_regex.value();
    if (util::StartsWith(regex, "@")) {
      const std::string path = regex.substr(1, regex.size() -1);
      std::string error;
      if (!file::AppendSetArgsFromFile(path, &options_.extensions_to_not_compress, &error)) {
        context.GetDiagnostics()->Error(android::DiagMessage(path) << error);
        return 1;
      }
    } else {
      options_.regex_to_not_compress = GetRegularExpression(no_compress_regex.value());
    }
  }

  // Populate some default no-compress extensions that are already compressed.
  options_.extensions_to_not_compress.insert({
      // Image extensions
      ".jpg", ".jpeg", ".png", ".gif", ".webp",
      // Audio extensions
      ".wav", ".mp2", ".mp3", ".ogg", ".aac", ".mid", ".midi", ".smf", ".jet", ".rtttl", ".imy",
      ".xmf", ".amr", ".awb",
      // Audio/video extensions
      ".mpg", ".mpeg", ".mp4", ".m4a", ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", ".wma", ".wmv",
      ".webm", ".mkv"});

  // Turn off auto versioning for static-libs.
  if (context.GetPackageType() == PackageType::kStaticLib) {
    options_.no_auto_version = true;
    options_.no_version_vectors = true;
    options_.no_version_transitions = true;
  }

  Linker cmd(&context, options_);
  return cmd.Run(arg_list);
}

}  // namespace aapt
