/*
 * 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 "Debug.h"

#include <androidfw/TypeWrappers.h>
#include <androidfw/Util.h>
#include <format/binary/ResChunkPullParser.h>

#include <algorithm>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <vector>

#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
#include "idmap2/Policies.h"
#include "text/Printer.h"
#include "util/Util.h"

using ::aapt::text::Printer;
using ::android::StringPiece;
using ::android::base::StringPrintf;

using android::idmap2::policy::kPolicyStringToFlag;

using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;

namespace aapt {

namespace {

class ValueHeadlinePrinter : public ConstValueVisitor {
 public:
  using ConstValueVisitor::Visit;

  explicit ValueHeadlinePrinter(const std::string& package, Printer* printer)
      : package_(package), printer_(printer) {
  }

  void Visit(const Attribute* attr) override {
    printer_->Print("(attr) type=");
    printer_->Print(attr->MaskString());
    if (!attr->symbols.empty()) {
      printer_->Print(StringPrintf(" size=%zd", attr->symbols.size()));
    }
  }

  void Visit(const Style* style) override {
    printer_->Print(StringPrintf("(style) size=%zd", style->entries.size()));
    if (style->parent) {
      printer_->Print(" parent=");

      const Reference& parent_ref = style->parent.value();
      if (parent_ref.name) {
        if (parent_ref.private_reference) {
          printer_->Print("*");
        }

        const ResourceName& parent_name = parent_ref.name.value();
        if (package_ != parent_name.package) {
          printer_->Print(parent_name.package);
          printer_->Print(":");
        }
        printer_->Print(parent_name.type.to_string());
        printer_->Print("/");
        printer_->Print(parent_name.entry);
        if (parent_ref.id) {
          printer_->Print(" (");
          printer_->Print(parent_ref.id.value().to_string());
          printer_->Print(")");
        }
      } else if (parent_ref.id) {
        printer_->Print(parent_ref.id.value().to_string());
      } else {
        printer_->Print("???");
      }
    }
  }

  void Visit(const Array* array) override {
    printer_->Print(StringPrintf("(array) size=%zd", array->elements.size()));
  }

  void Visit(const Plural* plural) override {
    size_t count = std::count_if(plural->values.begin(), plural->values.end(),
                                 [](const std::unique_ptr<Item>& v) { return v != nullptr; });
    printer_->Print(StringPrintf("(plurals) size=%zd", count));
  }

  void Visit(const Styleable* styleable) override {
    printer_->Println(StringPrintf("(styleable) size=%zd", styleable->entries.size()));
  }

  void VisitItem(const Item* item) override {
    // Pretty much guaranteed to be one line.
    if (const Reference* ref = ValueCast<Reference>(item)) {
      // Special case Reference so that we can print local resources without a package name.
      ref->PrettyPrint(package_, printer_);
    } else {
      item->PrettyPrint(printer_);
    }
  }

 private:
  std::string package_;
  Printer* printer_;
};

class ValueBodyPrinter : public ConstValueVisitor {
 public:
  using ConstValueVisitor::Visit;

  explicit ValueBodyPrinter(const std::string& package, Printer* printer)
      : package_(package), printer_(printer) {
  }

  void Visit(const Attribute* attr) override {
    constexpr uint32_t kMask = android::ResTable_map::TYPE_ENUM | android::ResTable_map::TYPE_FLAGS;
    if (attr->type_mask & kMask) {
      for (const auto& symbol : attr->symbols) {
        if (symbol.symbol.name) {
          printer_->Print(symbol.symbol.name.value().entry);

          if (symbol.symbol.id) {
            printer_->Print("(");
            printer_->Print(symbol.symbol.id.value().to_string());
            printer_->Print(")");
          }
        } else if (symbol.symbol.id) {
          printer_->Print(symbol.symbol.id.value().to_string());
        } else {
          printer_->Print("???");
        }

        printer_->Println(StringPrintf("=0x%08x", symbol.value));
      }
    }
  }

  void Visit(const Style* style) override {
    for (const auto& entry : style->entries) {
      if (entry.key.name) {
        const ResourceName& name = entry.key.name.value();
        if (!name.package.empty() && name.package != package_) {
          printer_->Print(name.package);
          printer_->Print(":");
        }
        printer_->Print(name.entry);

        if (entry.key.id) {
          printer_->Print("(");
          printer_->Print(entry.key.id.value().to_string());
          printer_->Print(")");
        }
      } else if (entry.key.id) {
        printer_->Print(entry.key.id.value().to_string());
      } else {
        printer_->Print("???");
      }

      printer_->Print("=");
      PrintItem(*entry.value);
      printer_->Println();
    }
  }

  void Visit(const Array* array) override {
    const size_t count = array->elements.size();
    printer_->Print("[");
    for (size_t i = 0u; i < count; i++) {
      if (i != 0u && i % 4u == 0u) {
        printer_->Println();
        printer_->Print(" ");
      }
      PrintItem(*array->elements[i]);
      if (i != count - 1) {
        printer_->Print(", ");
      }
    }
    printer_->Println("]");
  }

  void Visit(const Plural* plural) override {
    constexpr std::array<const char*, Plural::Count> kPluralNames = {
        {"zero", "one", "two", "few", "many", "other"}};

    for (size_t i = 0; i < Plural::Count; i++) {
      if (plural->values[i] != nullptr) {
        printer_->Print(StringPrintf("%s=", kPluralNames[i]));
        PrintItem(*plural->values[i]);
        printer_->Println();
      }
    }
  }

  void Visit(const Styleable* styleable) override {
    for (const auto& attr : styleable->entries) {
      if (attr.name) {
        const ResourceName& name = attr.name.value();
        if (!name.package.empty() && name.package != package_) {
          printer_->Print(name.package);
          printer_->Print(":");
        }
        printer_->Print(name.entry);

        if (attr.id) {
          printer_->Print("(");
          printer_->Print(attr.id.value().to_string());
          printer_->Print(")");
        }
      }

      if (attr.id) {
        printer_->Print(attr.id.value().to_string());
      }
      printer_->Println();
    }
  }

  void VisitItem(const Item* item) override {
    // Intentionally left empty, we already printed the Items.
  }

 private:
  void PrintItem(const Item& item) {
    if (const Reference* ref = ValueCast<Reference>(&item)) {
      // Special case Reference so that we can print local resources without a package name.
      ref->PrettyPrint(package_, printer_);
    } else {
      item.PrettyPrint(printer_);
    }
  }

  std::string package_;
  Printer* printer_;
};

}  // namespace

void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options,
                       Printer* printer) {
  const auto table_view = table.GetPartitionedView();
  for (const auto& package : table_view.packages) {
    ValueHeadlinePrinter headline_printer(package.name, printer);
    ValueBodyPrinter body_printer(package.name, printer);

    printer->Print("Package name=");
    printer->Print(package.name);
    if (package.id) {
      printer->Print(StringPrintf(" id=%02x", package.id.value()));
    }
    printer->Println();

    printer->Indent();
    for (const auto& type : package.types) {
      printer->Print("type ");
      printer->Print(type.named_type.to_string());
      if (type.id) {
        printer->Print(StringPrintf(" id=%02x", type.id.value()));
      }
      printer->Println(StringPrintf(" entryCount=%zd", type.entries.size()));

      printer->Indent();
      for (const ResourceTableEntryView& entry : type.entries) {
        printer->Print("resource ");
        printer->Print(ResourceId(package.id.value_or(0), type.id.value_or(0), entry.id.value_or(0))
                           .to_string());
        printer->Print(" ");

        // Write the name without the package (this is obvious and too verbose).
        printer->Print(type.named_type.to_string());
        printer->Print("/");
        printer->Print(entry.name);

        switch (entry.visibility.level) {
          case Visibility::Level::kPublic:
            printer->Print(" PUBLIC");
            break;
          case Visibility::Level::kPrivate:
            printer->Print(" _PRIVATE_");
            break;
          case Visibility::Level::kUndefined:
            // Print nothing.
            break;
        }

        if (entry.visibility.staged_api) {
          printer->Print(" STAGED");
        }

        if (entry.overlayable_item) {
          printer->Print(" OVERLAYABLE");
        }

        if (entry.staged_id) {
          printer->Print(" STAGED_ID=");
          printer->Print(entry.staged_id.value().id.to_string());
        }

        printer->Println();

        if (options.show_values) {
          printer->Indent();
          for (const auto& value : entry.values) {
            printer->Print("(");
            printer->Print(value->config.to_string());
            printer->Print(") ");
            value->value->Accept(&headline_printer);
            if (options.show_sources && !value->value->GetSource().path.empty()) {
              printer->Print(" src=");
              printer->Print(value->value->GetSource().to_string());
            }
            printer->Println();
            printer->Indent();
            value->value->Accept(&body_printer);
            printer->Undent();
          }
          printer->Undent();
        }
      }
      printer->Undent();
    }
    printer->Undent();
  }
}

static size_t GetNodeIndex(const std::vector<ResourceName>& names, const ResourceName& name) {
  auto iter = std::lower_bound(names.begin(), names.end(), name);
  CHECK(iter != names.end());
  CHECK(*iter == name);
  return std::distance(names.begin(), iter);
}

void Debug::PrintStyleGraph(ResourceTable* table, const ResourceName& target_style) {
  std::map<ResourceName, std::set<ResourceName>> graph;

  std::queue<ResourceName> styles_to_visit;
  styles_to_visit.push(target_style);
  for (; !styles_to_visit.empty(); styles_to_visit.pop()) {
    const ResourceName& style_name = styles_to_visit.front();
    std::set<ResourceName>& parents = graph[style_name];
    if (!parents.empty()) {
      // We've already visited this style.
      continue;
    }

    std::optional<ResourceTable::SearchResult> result = table->FindResource(style_name);
    if (result) {
      ResourceEntry* entry = result.value().entry;
      for (const auto& value : entry->values) {
        if (Style* style = ValueCast<Style>(value->value.get())) {
          if (style->parent && style->parent.value().name) {
            parents.insert(style->parent.value().name.value());
            styles_to_visit.push(style->parent.value().name.value());
          }
        }
      }
    }
  }

  std::vector<ResourceName> names;
  for (const auto& entry : graph) {
    names.push_back(entry.first);
  }

  std::cout << "digraph styles {\n";
  for (const auto& name : names) {
    std::cout << "  node_" << GetNodeIndex(names, name) << " [label=\"" << name << "\"];\n";
  }

  for (const auto& entry : graph) {
    const ResourceName& style_name = entry.first;
    size_t style_node_index = GetNodeIndex(names, style_name);

    for (const auto& parent_name : entry.second) {
      std::cout << "  node_" << style_node_index << " -> "
                << "node_" << GetNodeIndex(names, parent_name) << ";\n";
    }
  }

  std::cout << "}" << std::endl;
}

void Debug::DumpHex(const void* data, size_t len) {
  const uint8_t* d = (const uint8_t*)data;
  for (size_t i = 0; i < len; i++) {
    std::cerr << std::hex << std::setfill('0') << std::setw(2) << (uint32_t)d[i] << " ";
    if (i % 8 == 7) {
      std::cerr << "\n";
    }
  }

  if (len - 1 % 8 != 7) {
    std::cerr << std::endl;
  }
}

void Debug::DumpResStringPool(const android::ResStringPool* pool, text::Printer* printer) {
  using namespace android;

  if (pool->getError() == NO_INIT) {
    printer->Print("String pool is unitialized.\n");
    return;
  } else if (pool->getError() != NO_ERROR) {
    printer->Print("String pool is corrupt/invalid.\n");
    return;
  }

  SortedVector<const void*> uniqueStrings;
  const size_t N = pool->size();
  for (size_t i=0; i<N; i++) {
    size_t len;
    if (pool->isUTF8()) {
      uniqueStrings.add(UnpackOptionalString(pool->string8At(i), &len));
    } else {
      uniqueStrings.add(UnpackOptionalString(pool->stringAt(i), &len));
    }
  }

  printer->Print(StringPrintf("String pool of %zd unique %s %s strings, %zd entries and %zd styles "
                              "using %zd bytes:\n", uniqueStrings.size(),
                              pool->isUTF8() ? "UTF-8" : "UTF-16",
                              pool->isSorted() ? "sorted" : "non-sorted", N, pool->styleCount(),
                              pool->bytes()));

  const size_t NS = pool->size();
  for (size_t s=0; s<NS; s++) {
    auto str = pool->string8ObjectAt(s);
    printer->Print(StringPrintf("String #%zd : %s\n", s, str.has_value() ? str->string() : ""));
  }
}

namespace {

class XmlPrinter : public xml::ConstVisitor {
 public:
  using xml::ConstVisitor::Visit;

  explicit XmlPrinter(Printer* printer) : printer_(printer) {
  }

  void Visit(const xml::Element* el) override {
    for (const xml::NamespaceDecl& decl : el->namespace_decls) {
      printer_->Println(StringPrintf("N: %s=%s (line=%zu)", decl.prefix.c_str(), decl.uri.c_str(),
                                     decl.line_number));
      printer_->Indent();
    }

    printer_->Print("E: ");
    if (!el->namespace_uri.empty()) {
      printer_->Print(el->namespace_uri);
      printer_->Print(":");
    }
    printer_->Println(StringPrintf("%s (line=%zu)", el->name.c_str(), el->line_number));
    printer_->Indent();

    for (const xml::Attribute& attr : el->attributes) {
      printer_->Print("A: ");
      if (!attr.namespace_uri.empty()) {
        printer_->Print(attr.namespace_uri);
        printer_->Print(":");
      }
      printer_->Print(attr.name);

      if (attr.compiled_attribute) {
        printer_->Print("(");
        printer_->Print(attr.compiled_attribute.value().id.value_or(ResourceId(0)).to_string());
        printer_->Print(")");
      }
      printer_->Print("=");
      if (attr.compiled_value != nullptr) {
        attr.compiled_value->PrettyPrint(printer_);
      } else {
        printer_->Print("\"");
        printer_->Print(attr.value);
        printer_->Print("\"");
      }

      if (!attr.value.empty()) {
        printer_->Print(" (Raw: \"");
        printer_->Print(attr.value);
        printer_->Print("\")");
      }
      printer_->Println();
    }

    printer_->Indent();
    xml::ConstVisitor::Visit(el);
    printer_->Undent();
    printer_->Undent();

    for (size_t i = 0; i < el->namespace_decls.size(); i++) {
      printer_->Undent();
    }
  }

  void Visit(const xml::Text* text) override {
    printer_->Println(StringPrintf("T: '%s'", text->text.c_str()));
  }

 private:
  Printer* printer_;
};

}  // namespace

void Debug::DumpXml(const xml::XmlResource& doc, Printer* printer) {
  XmlPrinter xml_visitor(printer);
  doc.root->Accept(&xml_visitor);
}

struct DumpOverlayableEntry {
  std::string overlayable_section;
  std::string policy_subsection;
  std::string resource_name;
};

void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer) {
  std::vector<DumpOverlayableEntry> items;
  for (const auto& package : table.packages) {
    for (const auto& type : package->types) {
      for (const auto& entry : type->entries) {
        if (entry->overlayable_item) {
          const auto& overlayable_item = entry->overlayable_item.value();
          const auto overlayable_section = StringPrintf(R"(name="%s" actor="%s")",
              overlayable_item.overlayable->name.c_str(),
              overlayable_item.overlayable->actor.c_str());
          const auto policy_subsection = StringPrintf(R"(policies="%s")",
              android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str());
          const auto value =
              StringPrintf("%s/%s", type->named_type.to_string().data(), entry->name.c_str());
          items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value});
        }
      }
    }
  }

  std::sort(items.begin(), items.end(),
      [](const DumpOverlayableEntry& a, const DumpOverlayableEntry& b) {
        if (a.overlayable_section != b.overlayable_section) {
          return a.overlayable_section < b.overlayable_section;
        }
        if (a.policy_subsection != b.policy_subsection) {
          return a.policy_subsection < b.policy_subsection;
        }
        return a.resource_name < b.resource_name;
      });

  std::string last_overlayable_section;
  std::string last_policy_subsection;
  for (const auto& item : items) {
    if (last_overlayable_section != item.overlayable_section) {
      printer->Println(item.overlayable_section);
      last_overlayable_section = item.overlayable_section;
    }
    if (last_policy_subsection != item.policy_subsection) {
      printer->Indent();
      printer->Println(item.policy_subsection);
      last_policy_subsection = item.policy_subsection;
      printer->Undent();
    }
    printer->Indent();
    printer->Indent();
    printer->Println(item.resource_name);
    printer->Undent();
    printer->Undent();
  }
}

namespace {

using namespace android;

class ChunkPrinter {
 public:
  ChunkPrinter(const void* data, size_t len, Printer* printer, android::IDiagnostics* diag)
      : data_(data), data_len_(len), printer_(printer), diag_(diag) {
  }

  void PrintChunkHeader(const ResChunk_header* chunk) {
    switch (android::util::DeviceToHost16(chunk->type)) {
      case RES_STRING_POOL_TYPE:
        printer_->Print("[RES_STRING_POOL_TYPE]");
        break;
      case RES_TABLE_LIBRARY_TYPE:
        printer_->Print("[RES_TABLE_LIBRARY_TYPE]");
        break;
      case RES_TABLE_TYPE:
        printer_->Print("[ResTable_header]");
        break;
      case RES_TABLE_PACKAGE_TYPE:
        printer_->Print("[ResTable_package]");
        break;
      case RES_TABLE_TYPE_TYPE:
        printer_->Print("[ResTable_type]");
        break;
      case RES_TABLE_TYPE_SPEC_TYPE:
        printer_->Print("[RES_TABLE_TYPE_SPEC_TYPE]");
        break;
      default:
        break;
    }

    printer_->Print(StringPrintf(" chunkSize: %u", android::util::DeviceToHost32(chunk->size)));
    printer_->Print(
        StringPrintf(" headerSize: %u", android::util::DeviceToHost32(chunk->headerSize)));
  }

  bool PrintTable(const ResTable_header* chunk) {
    printer_->Print(
        StringPrintf(" Package count: %u\n", android::util::DeviceToHost32(chunk->packageCount)));

    // Print the chunks contained within the table
    printer_->Indent();
    bool success = PrintChunk(
        ResChunkPullParser(GetChunkData(&chunk->header), GetChunkDataLen(&chunk->header)));
    printer_->Undent();
    return success;
  }

  void PrintResValue(const Res_value* value, const ConfigDescription& config,
                     const ResourceType* type) {
    printer_->Print("[Res_value]");
    printer_->Print(StringPrintf(" size: %u", android::util::DeviceToHost32(value->size)));
    printer_->Print(
        StringPrintf(" dataType: 0x%02x", android::util::DeviceToHost32(value->dataType)));
    printer_->Print(StringPrintf(" data: 0x%08x", android::util::DeviceToHost32(value->data)));

    if (type) {
      auto item =
          ResourceUtils::ParseBinaryResValue(*type, config, value_pool_, *value, &out_pool_);
      printer_->Print(" (");
      item->PrettyPrint(printer_);
      printer_->Print(")");
    }

    printer_->Print("\n");
  }

  bool PrintTableType(const ResTable_type* chunk) {
    printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));
    printer_->Print(StringPrintf(
        " name: %s",
        android::util::GetString(type_pool_, android::util::DeviceToHost32(chunk->id) - 1)
            .c_str()));
    printer_->Print(StringPrintf(" flags: 0x%02x", android::util::DeviceToHost32(chunk->flags)));
    printer_->Print(
        StringPrintf(" entryCount: %u", android::util::DeviceToHost32(chunk->entryCount)));
    printer_->Print(
        StringPrintf(" entryStart: %u", android::util::DeviceToHost32(chunk->entriesStart)));

    ConfigDescription config;
    config.copyFromDtoH(chunk->config);
    printer_->Print(StringPrintf(" config: %s\n", config.to_string().c_str()));

    const ResourceType* type = ParseResourceType(
        android::util::GetString(type_pool_, android::util::DeviceToHost32(chunk->id) - 1));

    printer_->Indent();

    TypeVariant tv(chunk);
    for (auto it = tv.beginEntries(); it != tv.endEntries(); ++it) {
      const ResTable_entry* entry = *it;
      if (!entry) {
        continue;
      }

      printer_->Print((entry->flags & ResTable_entry::FLAG_COMPLEX) ? "[ResTable_map_entry]"
                                                                    : "[ResTable_entry]");
      printer_->Print(StringPrintf(" id: 0x%04x", it.index()));
      printer_->Print(StringPrintf(
          " name: %s",
          android::util::GetString(key_pool_, android::util::DeviceToHost32(entry->key.index))
              .c_str()));
      printer_->Print(
          StringPrintf(" keyIndex: %u", android::util::DeviceToHost32(entry->key.index)));
      printer_->Print(StringPrintf(" size: %u", android::util::DeviceToHost32(entry->size)));
      printer_->Print(StringPrintf(" flags: 0x%04x", android::util::DeviceToHost32(entry->flags)));

      printer_->Indent();

      if (entry->flags & ResTable_entry::FLAG_COMPLEX) {
        auto map_entry = (const ResTable_map_entry*)entry;
        printer_->Print(
            StringPrintf(" count: 0x%04x", android::util::DeviceToHost32(map_entry->count)));
        printer_->Print(StringPrintf(" parent: 0x%08x\n",
                                     android::util::DeviceToHost32(map_entry->parent.ident)));

        // Print the name and value mappings
        auto maps = (const ResTable_map*)((const uint8_t*)entry +
                                          android::util::DeviceToHost32(entry->size));
        for (size_t i = 0, count = android::util::DeviceToHost32(map_entry->count); i < count;
             i++) {
          PrintResValue(&(maps[i].value), config, type);

          printer_->Print(StringPrintf(
              " name: %s name-id:%d\n",
              android::util::GetString(key_pool_, android::util::DeviceToHost32(maps[i].name.ident))
                  .c_str(),
              android::util::DeviceToHost32(maps[i].name.ident)));
        }
      } else {
        printer_->Print("\n");

        // Print the value of the entry
        auto value =
            (const Res_value*)((const uint8_t*)entry + android::util::DeviceToHost32(entry->size));
        PrintResValue(value, config, type);
      }

      printer_->Undent();
    }

    printer_->Undent();
    return true;
  }

  void PrintStringPool(const ResStringPool_header* chunk) {
    // Initialize the string pools

    ResStringPool* pool;
    if (value_pool_.getError() == NO_INIT) {
      pool = &value_pool_;
    } else if (type_pool_.getError() == NO_INIT) {
      pool = &type_pool_;
    } else if (key_pool_.getError() == NO_INIT) {
      pool = &key_pool_;
    } else {
      return;
    }

    pool->setTo(chunk, android::util::DeviceToHost32(
                           (reinterpret_cast<const ResChunk_header*>(chunk))->size));

    printer_->Print("\n");

    for (size_t i = 0; i < pool->size(); i++) {
      printer_->Print(StringPrintf("#%zd : %s\n", i, android::util::GetString(*pool, i).c_str()));
    }
  }

  bool PrintPackage(const ResTable_package* chunk) {
    printer_->Print(StringPrintf(" id: 0x%02x", android::util::DeviceToHost32(chunk->id)));

    size_t len = strnlen16((const char16_t*)chunk->name, std::size(chunk->name));
    std::u16string package_name(len, u'\0');
    package_name.resize(len);
    for (size_t i = 0; i < len; i++) {
      package_name[i] = android::util::DeviceToHost16(chunk->name[i]);
    }

    printer_->Print(StringPrintf("name: %s", String8(package_name.c_str()).c_str()));
    printer_->Print(
        StringPrintf(" typeStrings: %u", android::util::DeviceToHost32(chunk->typeStrings)));
    printer_->Print(
        StringPrintf(" lastPublicType: %u", android::util::DeviceToHost32(chunk->lastPublicType)));
    printer_->Print(
        StringPrintf(" keyStrings: %u", android::util::DeviceToHost32(chunk->keyStrings)));
    printer_->Print(
        StringPrintf(" lastPublicKey: %u", android::util::DeviceToHost32(chunk->lastPublicKey)));
    printer_->Print(
        StringPrintf(" typeIdOffset: %u\n", android::util::DeviceToHost32(chunk->typeIdOffset)));

    // Print the chunks contained within the table
    printer_->Indent();
    bool success = PrintChunk(
        ResChunkPullParser(GetChunkData(&chunk->header), GetChunkDataLen(&chunk->header)));
    printer_->Undent();
    return success;
  }

  bool PrintChunk(ResChunkPullParser&& parser) {
    while (ResChunkPullParser::IsGoodEvent(parser.Next())) {
      auto chunk = parser.chunk();
      PrintChunkHeader(chunk);

      switch (android::util::DeviceToHost16(chunk->type)) {
        case RES_STRING_POOL_TYPE:
          PrintStringPool(reinterpret_cast<const ResStringPool_header*>(chunk));
          break;

        case RES_TABLE_TYPE:
          PrintTable(reinterpret_cast<const ResTable_header*>(chunk));
          break;

        case RES_TABLE_PACKAGE_TYPE:
          type_pool_.uninit();
          key_pool_.uninit();
          PrintPackage(reinterpret_cast<const ResTable_package*>(chunk));
          break;

        case RES_TABLE_TYPE_TYPE:
          PrintTableType(reinterpret_cast<const ResTable_type*>(chunk));
          break;

        default:
          printer_->Print("\n");
          break;
      }
    }

    if (parser.event() == ResChunkPullParser::Event::kBadDocument) {
      diag_->Error(android::DiagMessage(source_) << "corrupt resource table: " << parser.error());
      return false;
    }

    return true;
  }

  void Print() {
    PrintChunk(ResChunkPullParser(data_, data_len_));
    printer_->Print("[End]\n");
  }

 private:
  const android::Source source_;
  const void* data_;
  const size_t data_len_;
  Printer* printer_;
  android::IDiagnostics* diag_;

  // The standard value string pool for resource values.
  ResStringPool value_pool_;

  // The string pool that holds the names of the types defined
  // in this table.
  ResStringPool type_pool_;

  // The string pool that holds the names of the entries defined
  // in this table.
  ResStringPool key_pool_;

  android::StringPool out_pool_;
};

}  // namespace

void Debug::DumpChunks(const void* data, size_t len, Printer* printer,
                       android::IDiagnostics* diag) {
  ChunkPrinter chunk_printer(data, len, printer, diag);
  chunk_printer.Print();
}

}  // namespace aapt
