// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/data_decoder/web_bundle_parser.h"

#include <algorithm>

#include "base/big_endian.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/containers/span.h"
#include "base/memory/weak_ptr.h"
#include "base/numerics/checked_math.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "components/cbor/reader.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/http/http_util.h"

namespace data_decoder {

namespace {

// The maximum length of the CBOR item header (type and argument).
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#parse-type-argument
constexpr uint64_t kMaxCBORItemHeaderSize = 9;

// The maximum size of the section-lengths CBOR item.
constexpr uint64_t kMaxSectionLengthsCBORSize = 8192;

// The maximum size of a metadata section allowed in this implementation.
constexpr uint64_t kMaxMetadataSectionSize = 1 * 1024 * 1024;

// The maximum size of the response header CBOR.
constexpr uint64_t kMaxResponseHeaderLength = 512 * 1024;

// The initial buffer size for reading an item from the response section.
constexpr uint64_t kInitialBufferSizeForResponse = 4096;

// Step 2. of
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
const uint8_t kBundleMagicBytes[] = {
    0x86, 0x48, 0xF0, 0x9F, 0x8C, 0x90, 0xF0, 0x9F, 0x93, 0xA6,
};

// Step 7. of
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
// We use an implementation-specific version string "b1\0\0".
const uint8_t kVersionB1MagicBytes[] = {
    0x44, 0x62, 0x31, 0x00, 0x00,
};

// Section names.
constexpr char kCriticalSection[] = "critical";
constexpr char kIndexSection[] = "index";
constexpr char kManifestSection[] = "manifest";
constexpr char kResponsesSection[] = "responses";
constexpr char kSignaturesSection[] = "signatures";

// https://tools.ietf.org/html/draft-ietf-cbor-7049bis-05#section-3.1
enum class CBORType {
  kByteString = 2,
  kTextString = 3,
  kArray = 4,
};

// A list of (section-name, length) pairs.
using SectionLengths = std::vector<std::pair<std::string, uint64_t>>;

// A map from section name to (offset, length) pair.
using SectionOffsets = std::map<std::string, std::pair<uint64_t, uint64_t>>;

bool IsMetadataSection(const std::string& name) {
  return (name == kCriticalSection || name == kIndexSection ||
          name == kManifestSection || name == kSignaturesSection);
}

// Parses a `section-lengths` CBOR item.
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
base::Optional<SectionLengths> ParseSectionLengths(
    base::span<const uint8_t> data) {
  cbor::Reader::DecoderError error;
  base::Optional<cbor::Value> value = cbor::Reader::Read(data, &error);
  if (!value.has_value() || !value->is_array())
    return base::nullopt;

  const cbor::Value::ArrayValue& array = value->GetArray();
  if (array.size() % 2 != 0)
    return base::nullopt;

  SectionLengths result;
  for (size_t i = 0; i < array.size(); i += 2) {
    if (!array[i].is_string() || !array[i + 1].is_unsigned())
      return base::nullopt;
    result.emplace_back(array[i].GetString(), array[i + 1].GetUnsigned());
  }
  return result;
}

struct ParsedHeaders {
  base::flat_map<std::string, std::string> headers;
  base::flat_map<std::string, std::string> pseudos;
};

// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#cbor-headers
base::Optional<ParsedHeaders> ConvertCBORValueToHeaders(
    const cbor::Value& headers_value) {
  // Step 1. If item doesn’t match the headers rule in the above CDDL, return
  // an error.
  if (!headers_value.is_map())
    return base::nullopt;

  // Step 2. Let headers be a new header list ([FETCH]).
  // Step 3. Let pseudos be an empty map ([INFRA]).
  ParsedHeaders result;

  // Step 4. For each pair (name, value) in item:
  for (const auto& item : headers_value.GetMap()) {
    if (!item.first.is_bytestring() || !item.second.is_bytestring())
      return base::nullopt;
    base::StringPiece name = item.first.GetBytestringAsString();
    base::StringPiece value = item.second.GetBytestringAsString();

    // Step 4.1. If name contains any upper-case or non-ASCII characters, return
    // an error. This matches the requirement in Section 8.1.2 of [RFC7540].
    if (!base::IsStringASCII(name) ||
        std::any_of(name.begin(), name.end(), base::IsAsciiUpper<char>))
      return base::nullopt;

    // Step 4.2. If name starts with a ‘:’:
    if (!name.empty() && name[0] == ':') {
      // Step 4.2.1. Assert: pseudos[name] does not exist, because CBOR maps
      // cannot contain duplicate keys.
      // This is ensured by cbor::Reader.
      DCHECK(!result.pseudos.contains(name));
      // Step 4.2.2. Set pseudos[name] to value.
      result.pseudos.insert(
          std::make_pair(name.as_string(), value.as_string()));
      // Step 4.3.3. Continue.
      continue;
    }

    // Step 4.3. If name or value doesn’t satisfy the requirements for a header
    // in [FETCH], return an error.
    if (!net::HttpUtil::IsValidHeaderName(name) ||
        !net::HttpUtil::IsValidHeaderValue(value))
      return base::nullopt;

    // Step 4.4. Assert: headers does not contain ([FETCH]) name, because CBOR
    // maps cannot contain duplicate keys and an earlier step rejected
    // upper-case bytes.
    // This is ensured by cbor::Reader.
    DCHECK(!result.headers.contains(name));

    // Step 4.5. Append (name, value) to headers.
    result.headers.insert(std::make_pair(name.as_string(), value.as_string()));
  }

  // Step 5. Return (headers, pseudos).
  return result;
}

// A utility class for reading various values from input buffer.
class InputReader {
 public:
  explicit InputReader(base::span<const uint8_t> buf) : buf_(buf) {}

  uint64_t CurrentOffset() const { return current_offset_; }
  size_t Size() const { return buf_.size(); }

  base::Optional<uint8_t> ReadByte() {
    if (buf_.empty())
      return base::nullopt;
    uint8_t byte = buf_[0];
    Advance(1);
    return byte;
  }

  template <typename T>
  bool ReadBigEndian(T* out) {
    auto bytes = ReadBytes(sizeof(T));
    if (!bytes)
      return false;
    base::ReadBigEndian(reinterpret_cast<const char*>(bytes->data()), out);
    return true;
  }

  base::Optional<base::span<const uint8_t>> ReadBytes(size_t n) {
    if (buf_.size() < n)
      return base::nullopt;
    auto result = buf_.subspan(0, n);
    Advance(n);
    return result;
  }

  base::Optional<base::StringPiece> ReadString(size_t n) {
    auto bytes = ReadBytes(n);
    if (!bytes)
      return base::nullopt;
    base::StringPiece str(reinterpret_cast<const char*>(bytes->data()),
                          bytes->size());
    if (!base::IsStringUTF8(str))
      return base::nullopt;
    return str;
  }

  // Parses the type and argument of a CBOR item from the input head. If parsed
  // successfully and the type matches |expected_type|, returns the argument.
  // Otherwise returns nullopt.
  base::Optional<uint64_t> ReadCBORHeader(CBORType expected_type) {
    auto pair = ReadTypeAndArgument();
    if (!pair || pair->first != expected_type)
      return base::nullopt;
    return pair->second;
  }

 private:
  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#parse-type-argument
  base::Optional<std::pair<CBORType, uint64_t>> ReadTypeAndArgument() {
    base::Optional<uint8_t> first_byte = ReadByte();
    if (!first_byte)
      return base::nullopt;

    CBORType type = static_cast<CBORType>((*first_byte & 0xE0) / 0x20);
    uint8_t b = *first_byte & 0x1F;

    if (b <= 23)
      return std::make_pair(type, b);
    if (b == 24) {
      auto content = ReadByte();
      if (!content || *content < 24)
        return base::nullopt;
      return std::make_pair(type, *content);
    }
    if (b == 25) {
      uint16_t content;
      if (!ReadBigEndian(&content) || content >> 8 == 0)
        return base::nullopt;
      return std::make_pair(type, content);
    }
    if (b == 26) {
      uint32_t content;
      if (!ReadBigEndian(&content) || content >> 16 == 0)
        return base::nullopt;
      return std::make_pair(type, content);
    }
    if (b == 27) {
      uint64_t content;
      if (!ReadBigEndian(&content) || content >> 32 == 0)
        return base::nullopt;
      return std::make_pair(type, content);
    }
    return base::nullopt;
  }

  void Advance(size_t n) {
    DCHECK_LE(n, buf_.size());
    buf_ = buf_.subspan(n);
    current_offset_ += n;
  }

  base::span<const uint8_t> buf_;
  uint64_t current_offset_ = 0;

  DISALLOW_COPY_AND_ASSIGN(InputReader);
};

GURL ParseExchangeURL(base::StringPiece str) {
  if (!base::IsStringUTF8(str))
    return GURL();

  GURL url(str);
  if (!url.is_valid())
    return GURL();

  // Exchange URL must not have a fragment or credentials.
  if (url.has_ref() || url.has_username() || url.has_password())
    return GURL();

  // For now, we allow only http: and https: schemes in Web Bundle URLs.
  // TODO(crbug.com/966753): Revisit this once
  // https://github.com/WICG/webpackage/issues/468 is resolved.
  if (!url.SchemeIsHTTPOrHTTPS())
    return GURL();

  return url;
}

}  // namespace

class WebBundleParser::SharedBundleDataSource::Observer {
 public:
  Observer() {}
  virtual ~Observer() {}
  virtual void OnDisconnect() = 0;

  DISALLOW_COPY_AND_ASSIGN(Observer);
};

// A parser for bundle's metadata. This class owns itself and will self destruct
// after calling the ParseMetadataCallback.
class WebBundleParser::MetadataParser
    : WebBundleParser::SharedBundleDataSource::Observer {
 public:
  MetadataParser(scoped_refptr<SharedBundleDataSource> data_source,
                 ParseMetadataCallback callback)
      : data_source_(data_source), callback_(std::move(callback)) {
    data_source_->AddObserver(this);
  }
  ~MetadataParser() override { data_source_->RemoveObserver(this); }

  void Start() {
    data_source_->GetSize(base::BindOnce(&MetadataParser::DidGetSize,
                                         weak_factory_.GetWeakPtr()));
  }

 private:
  void DidGetSize(uint64_t size) {
    size_ = size;

    // In the next step, we will parse `magic`, `version`, and the CBOR
    // header of `primary-url`.
    // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#top-level
    const uint64_t length = std::min(size, sizeof(kBundleMagicBytes) +
                                               sizeof(kVersionB1MagicBytes) +
                                               kMaxCBORItemHeaderSize);
    data_source_->Read(0, length,
                       base::BindOnce(&MetadataParser::ParseMagicBytes,
                                      weak_factory_.GetWeakPtr(), length));
  }

  // Step 1-4 of
  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
  void ParseMagicBytes(uint64_t expected_data_length,
                       const base::Optional<std::vector<uint8_t>>& data) {
    if (!data || data->size() != expected_data_length) {
      RunErrorCallbackAndDestroy("Error reading bundle magic bytes.");
      return;
    }

    // Step 1. "Seek to offset 0 in stream. Assert: this operation doesn't
    // fail."
    InputReader input(*data);

    // Step 2. "If reading 10 bytes from stream returns an error or doesn't
    // return the bytes with hex encoding "86 48 F0 9F 8C 90 F0 9F 93 A6"
    // (the CBOR encoding of the 6-item array initial byte and 8-byte bytestring
    // initial byte, followed by 🌐📦 in UTF-8), return a "format error"."
    const auto magic = input.ReadBytes(sizeof(kBundleMagicBytes));
    if (!magic ||
        !std::equal(magic->begin(), magic->end(), std::begin(kBundleMagicBytes),
                    std::end(kBundleMagicBytes))) {
      RunErrorCallbackAndDestroy("Wrong magic bytes.");
      return;
    }

    // Step 3. "Let version be the result of reading 5 bytes from stream. If
    // this is an error, return a "format error"."
    const auto version = input.ReadBytes(sizeof(kVersionB1MagicBytes));
    if (!version) {
      RunErrorCallbackAndDestroy("Cannot read version bytes.");
      return;
    }
    if (!std::equal(version->begin(), version->end(),
                    std::begin(kVersionB1MagicBytes),
                    std::end(kVersionB1MagicBytes))) {
      version_mismatch_ = true;
      // Continue parsing until Step 7 where we get a fallback URL, and
      // then return "version error" with the fallback URL.
    }

    // Step 4. "Let urlType and urlLength be the result of reading the type and
    // argument of a CBOR item from stream (Section 3.5.3). If this is an error
    // or urlType is not 3 (a CBOR text string), return a "format error"."
    const auto url_length = input.ReadCBORHeader(CBORType::kTextString);
    if (!url_length) {
      RunErrorCallbackAndDestroy("Cannot parse the size of fallback URL.");
      return;
    }

    // In the next step, we will parse the content of `primary-url`,
    // `section-lengths`, and the CBOR header of `sections`.
    const uint64_t length = std::min(
        size_ - input.CurrentOffset(),
        *url_length + kMaxSectionLengthsCBORSize + kMaxCBORItemHeaderSize * 2);
    data_source_->Read(input.CurrentOffset(), length,
                       base::BindOnce(&MetadataParser::ParseBundleHeader,
                                      weak_factory_.GetWeakPtr(), length,
                                      *url_length, input.CurrentOffset()));
  }

  // Step 5-21 of
  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
  void ParseBundleHeader(uint64_t expected_data_length,
                         uint64_t url_length,
                         uint64_t offset_in_stream,
                         const base::Optional<std::vector<uint8_t>>& data) {
    if (!data || data->size() != expected_data_length) {
      RunErrorCallbackAndDestroy("Error reading bundle header.");
      return;
    }
    InputReader input(*data);

    // Step 5. "Let fallbackUrlBytes be the result of reading urlLength bytes
    // from stream. If this is an error, return a "format error"."
    const auto fallback_url_string = input.ReadString(url_length);
    if (!fallback_url_string) {
      RunErrorCallbackAndDestroy("Cannot read fallback URL.");
      return;
    }

    // Step 6. "Let fallbackUrl be the result of parsing ([URL]) the UTF-8
    // decoding of fallbackUrlBytes with no base URL. If either the UTF-8
    // decoding or parsing fails, return a "format error"."
    // For now, we enforce the same restriction as exchages' request URL.
    // TODO(crbug.com/966753): Revisit URL requirements here once
    // https://github.com/WICG/webpackage/issues/469 is resolved.
    GURL fallback_url = ParseExchangeURL(*fallback_url_string);
    if (!fallback_url.is_valid()) {
      RunErrorCallbackAndDestroy("Cannot parse fallback URL.");
      return;
    }

    // "Note: From this point forward, errors also include the fallback URL to
    // help clients recover."
    fallback_url_ = std::move(fallback_url);

    // Step 7. "If version does not have the hex encoding "44 31 00 00 00" (the
    // CBOR encoding of a 4-byte byte string holding an ASCII "1" followed by
    // three 0 bytes), return a "version error" with fallbackUrl. "
    // Note: We use an implementation-specific version string
    // kVersionB1MagicBytes.
    if (version_mismatch_) {
      RunErrorCallbackAndDestroy(
          "Version error: this implementation only supports "
          "bundle format of version b1.",
          mojom::BundleParseErrorType::kVersionError);
      return;
    }

    // Step 8. "Let sectionLengthsLength be the result of getting the length of
    // the CBOR bytestring header from stream (Section 3.5.2). If this is an
    // error, return a "format error" with fallbackUrl."
    const auto section_lengths_length =
        input.ReadCBORHeader(CBORType::kByteString);
    if (!section_lengths_length) {
      RunErrorCallbackAndDestroy("Cannot parse the size of section-lengths.");
      return;
    }
    // Step 9. "If sectionLengthsLength is 8192 (8*1024) or greater, return a
    // "format error" with fallbackUrl."
    if (*section_lengths_length >= kMaxSectionLengthsCBORSize) {
      RunErrorCallbackAndDestroy(
          "The section-lengths CBOR must be smaller than 8192 bytes.");
      return;
    }

    // Step 10. "Let sectionLengthsBytes be the result of reading
    // sectionLengthsLength bytes from stream. If sectionLengthsBytes is an
    // error, return a "format error" with fallbackUrl."
    const auto section_lengths_bytes = input.ReadBytes(*section_lengths_length);
    if (!section_lengths_bytes) {
      RunErrorCallbackAndDestroy("Cannot read section-lengths.");
      return;
    }

    // Step 11. "Let sectionLengths be the result of parsing one CBOR item
    // (Section 3.5) from sectionLengthsBytes, matching the section-lengths
    // rule in the CDDL ([I-D.ietf-cbor-cddl]) above. If sectionLengths is an
    // error, return a "format error" with fallbackUrl."
    const auto section_lengths = ParseSectionLengths(*section_lengths_bytes);
    if (!section_lengths) {
      RunErrorCallbackAndDestroy("Cannot parse section-lengths.");
      return;
    }

    // Step 12. "Let (sectionsType, numSections) be the result of parsing the
    // type and argument of a CBOR item from stream (Section 3.5.3)."
    const auto num_sections = input.ReadCBORHeader(CBORType::kArray);
    if (!num_sections) {
      RunErrorCallbackAndDestroy("Cannot parse the number of sections.");
      return;
    }

    // Step 13. "If sectionsType is not 4 (a CBOR array) or numSections is not
    // half of the length of sectionLengths, return a "format error" with
    // fallbackUrl."
    if (*num_sections != section_lengths->size()) {
      RunErrorCallbackAndDestroy("Unexpected number of sections.");
      return;
    }

    // Step 14. "Let sectionsStart be the current offset within stream."
    // Note: This doesn't exceed |size_|.
    const uint64_t sections_start = offset_in_stream + input.CurrentOffset();

    // Step 15. "Let knownSections be the subset of the Section 6.2 that this
    // client has implemented."
    // Step 16. "Let ignoredSections be an empty set."

    // This implementation doesn't use knownSections nor ignoredSections.

    // Step 17. "Let sectionOffsets be an empty map ([INFRA]) from section names
    // to (offset, length) pairs. These offsets are relative to the start of
    // stream."

    // |section_offsets_| is defined as a class member field.

    // Step 18. "Let currentOffset be sectionsStart."
    uint64_t current_offset = sections_start;

    // Step 19. "For each ("name", length) pair of adjacent elements in
    // sectionLengths:"
    for (const auto& pair : *section_lengths) {
      const std::string& name = pair.first;
      const uint64_t length = pair.second;
      // Step 19.1. "If "name"'s specification in knownSections says not to
      // process other sections, add those sections' names to ignoredSections."

      // There're no such sections at the moment.

      // Step 19.2. "If sectionOffsets["name"] exists, return a "format error"
      // with fallbackUrl. That is, duplicate sections are forbidden."
      // Step 19.3. "Set sectionOffsets["name"] to (currentOffset, length)."
      bool added = section_offsets_
                       .insert(std::make_pair(
                           name, std::make_pair(current_offset, length)))
                       .second;
      if (!added) {
        RunErrorCallbackAndDestroy("Duplicated section.");
        return;
      }

      // Step 19.4. "Set currentOffset to currentOffset + length."
      if (!base::CheckAdd(current_offset, length)
               .AssignIfValid(&current_offset) ||
          current_offset > size_) {
        RunErrorCallbackAndDestroy("Section doesn't fit in the bundle.");
        return;
      }
    }

    // Step 20. "If the "responses" section is not last in sectionLengths,
    // return a "format error" with fallbackUrl. This allows a streaming parser
    // to assume that it'll know the requests by the time their responses
    // arrive."
    if (section_lengths->empty() ||
        section_lengths->back().first != kResponsesSection) {
      RunErrorCallbackAndDestroy(
          "Responses section is not the last in section-lengths.");
      return;
    }

    // Step 21. "Let metadata be a map ([INFRA]) initially containing the single
    // key/value pair "primaryUrl"/fallbackUrl."
    metadata_ = mojom::BundleMetadata::New();
    metadata_->primary_url = fallback_url_;

    ReadMetadataSections(section_offsets_.begin());
  }

  // Step 22-25 of
  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
  void ReadMetadataSections(SectionOffsets::const_iterator section_iter) {
    // Step 22. "For each "name" -> (offset, length) triple in sectionOffsets:"
    for (; section_iter != section_offsets_.end(); ++section_iter) {
      const auto& name = section_iter->first;
      // Step 22.1. "If "name" isn't in knownSections, continue to the next
      // triple."
      // Step 22.2. "If "name"'s Metadata field (Section 6.2) is "No", continue
      // to the next triple."
      if (!IsMetadataSection(name))
        continue;

      // Step 22.3. "If "name" is in ignoredSections, continue to the next
      // triple."
      // In the current spec, ignoredSections is always empty.

      const uint64_t section_offset = section_iter->second.first;
      const uint64_t section_length = section_iter->second.second;
      if (section_length > kMaxMetadataSectionSize) {
        RunErrorCallbackAndDestroy(
            "Metadata sections larger than 1MB are not supported.");
        return;
      }

      data_source_->Read(section_offset, section_length,
                         base::BindOnce(&MetadataParser::ParseMetadataSection,
                                        weak_factory_.GetWeakPtr(),
                                        section_iter, section_length));
      // This loop will be resumed by ParseMetadataSection().
      return;
    }

    // Step 23. "Assert: metadata has an entry with the key "primaryUrl"."
    DCHECK(!metadata_->primary_url.is_empty());

    // Step 24. "If metadata doesn't have an entry with the key "requests",
    // return a "format error" with fallbackUrl."
    if (metadata_->requests.empty()) {
      RunErrorCallbackAndDestroy("Bundle must have an index section.");
      return;
    }

    // Step 25. "Return metadata."
    RunSuccessCallbackAndDestroy();
  }

  void ParseMetadataSection(SectionOffsets::const_iterator section_iter,
                            uint64_t expected_data_length,
                            const base::Optional<std::vector<uint8_t>>& data) {
    if (!data || data->size() != expected_data_length) {
      RunErrorCallbackAndDestroy("Error reading section content.");
      return;
    }

    // Parse the section contents as a CBOR item.
    cbor::Reader::DecoderError error;
    base::Optional<cbor::Value> section_value =
        cbor::Reader::Read(*data, &error);
    if (!section_value) {
      RunErrorCallbackAndDestroy(
          std::string("Error parsing section contents as CBOR: ") +
          cbor::Reader::ErrorCodeToString(error));
      return;
    }

    // Step 22.6. "Follow "name"'s specification from knownSections to process
    // the section, passing sectionContents, stream, sectionOffsets, and
    // metadata. If this returns an error, return a "format error" with
    // fallbackUrl."
    const auto& name = section_iter->first;
    // Note: Parse*Section() delete |this| on failure.
    if (name == kIndexSection) {
      if (!ParseIndexSection(*section_value))
        return;
    } else if (name == kManifestSection) {
      if (!ParseManifestSection(*section_value))
        return;
    } else if (name == kSignaturesSection) {
      if (!ParseSignaturesSection(*section_value))
        return;
    } else if (name == kCriticalSection) {
      if (!ParseCriticalSection(*section_value))
        return;
    } else {
      NOTREACHED();
    }
    // Resume the loop of Step 22.
    ReadMetadataSections(++section_iter);
  }

  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#index-section
  bool ParseIndexSection(const cbor::Value& section_value) {
    // Step 1. "Let index be the result of parsing sectionContents as a CBOR
    // item matching the index rule in the above CDDL (Section 3.5). If index is
    // an error, return an error."
    if (!section_value.is_map()) {
      RunErrorCallbackAndDestroy("Index section must be a map.");
      return false;
    }

    // Step 2. "Let requests be an initially-empty map ([INFRA]) from URLs to
    // response descriptions, each of which is either a single
    // location-in-stream value or a pair of a Variants header field value
    // ([I-D.ietf-httpbis-variants]) and a map from that value's possible
    // Variant-Keys to location-in-stream values, as described in Section 2.2."
    base::flat_map<GURL, mojom::BundleIndexValuePtr> requests;

    // Step 3. "Let MakeRelativeToStream be a function that takes a
    // location-in-responses value (offset, length) and returns a
    // ResponseMetadata struct or error by running the following
    // sub-steps:"
    // The logic of MakeRelativeToStream is inlined at the callsite below.
    auto responses_section = section_offsets_.find(kResponsesSection);
    DCHECK(responses_section != section_offsets_.end());
    const uint64_t responses_section_offset = responses_section->second.first;
    const uint64_t responses_section_length = responses_section->second.second;

    // Step 4. "For each (url, responses) entry in the index map:"
    for (const auto& item : section_value.GetMap()) {
      if (!item.first.is_string()) {
        RunErrorCallbackAndDestroy("Index section: key must be a string.");
        return false;
      }
      if (!item.second.is_array()) {
        RunErrorCallbackAndDestroy("Index section: value must be an array.");
        return false;
      }
      const std::string& url = item.first.GetString();
      const cbor::Value::ArrayValue& responses_array = item.second.GetArray();

      // Step 4.1. "Let parsedUrl be the result of parsing ([URL]) url with no
      // base URL."
      GURL parsed_url = ParseExchangeURL(url);

      // Step 4.2. "If parsedUrl is a failure, its fragment is not null, or it
      // includes credentials, return an error."
      if (!parsed_url.is_valid()) {
        RunErrorCallbackAndDestroy("Index section: exchange URL is not valid.");
        return false;
      }

      // Step 4.3. "If the first element of responses is the empty string:"
      if (responses_array.empty() || !responses_array[0].is_bytestring()) {
        RunErrorCallbackAndDestroy(
            "Index section: the first element of responses array must be a "
            "bytestring.");
        return false;
      }
      base::StringPiece variants_value =
          responses_array[0].GetBytestringAsString();
      if (variants_value.empty()) {
        // Step 4.3.1. "If the length of responses is not 3 (i.e. there is more
        // than one location-in-responses in responses), return an error."
        if (responses_array.size() != 3) {
          RunErrorCallbackAndDestroy(
              "Index section: unexpected size of responses array.");
          return false;
        }
      } else {
        // Step 4.4. "Otherwise:"
        // TODO(crbug.com/969596): Parse variants_value to compute the number of
        // variantKeys, and check that responses_array has
        // (2 * #variantKeys + 1) elements.
        if (responses_array.size() < 3 || responses_array.size() % 2 != 1) {
          RunErrorCallbackAndDestroy(
              "Index section: unexpected size of responses array.");
          return false;
        }
      }
      // Instead of constructing a map from Variant-Keys to location-in-stream,
      // this implementation just returns the responses array's structure as
      // a BundleIndexValue.
      std::vector<mojom::BundleResponseLocationPtr> response_locations;
      for (size_t i = 1; i < responses_array.size(); i += 2) {
        if (!responses_array[i].is_unsigned() ||
            !responses_array[i + 1].is_unsigned()) {
          RunErrorCallbackAndDestroy(
              "Index section: offset and length values must be unsigned.");
          return false;
        }
        uint64_t offset = responses_array[i].GetUnsigned();
        uint64_t length = responses_array[i + 1].GetUnsigned();

        // MakeRelativeToStream (Step 3.) is inlined here.
        // Step 3.1. "If offset + length is larger than
        // sectionOffsets["responses"].length, return an error."
        uint64_t response_end;
        if (!base::CheckAdd(offset, length).AssignIfValid(&response_end) ||
            response_end > responses_section_length) {
          RunErrorCallbackAndDestroy("Index section: response out of range.");
          return false;
        }
        // Step 3.2. "Otherwise, return a ResponseMetadata struct whose offset
        // is sectionOffsets["responses"].offset + offset and whose length is
        // length."

        // This doesn't wrap because (offset <= responses_section_length) and
        // (responses_section_offset + responses_section_length) doesn't wrap.
        uint64_t offset_within_stream = responses_section_offset + offset;

        response_locations.push_back(
            mojom::BundleResponseLocation::New(offset_within_stream, length));
      }
      requests.insert(std::make_pair(
          parsed_url,
          mojom::BundleIndexValue::New(variants_value.as_string(),
                                       std::move(response_locations))));
    }

    // Step 5. "Set metadata["requests"] to requests."
    metadata_->requests = std::move(requests);
    return true;
  }

  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#manifest-section
  bool ParseManifestSection(const cbor::Value& section_value) {
    // Step 1. "Let urlString be the result of parsing sectionContents as a CBOR
    // item matching the above manifest rule (Section 3.5). If urlString is an
    // error, return that error."
    if (!section_value.is_string()) {
      RunErrorCallbackAndDestroy("Manifest section must be a string.");
      return false;
    }
    // Step 2. "Let url be the result of parsing ([URL]) urlString with no base
    // URL."
    GURL parsed_url = ParseExchangeURL(section_value.GetString());

    // Step 3. "If url is a failure, its fragment is not null, or it includes
    // credentials, return an error."
    if (!parsed_url.is_valid()) {
      RunErrorCallbackAndDestroy("Manifest URL is not a valid exchange URL.");
      return false;
    }
    // Step 4. "Set metadata["manifest"] to url."
    metadata_->manifest_url = std::move(parsed_url);
    return true;
  }

  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#signatures-section
  bool ParseSignaturesSection(const cbor::Value& section_value) {
    // Step 1. "Let signatures be the result of parsing sectionContents as a
    // CBOR item matching the signatures rule in the above CDDL (Section 3.5)."
    if (!section_value.is_array() || section_value.GetArray().size() != 2) {
      RunErrorCallbackAndDestroy(
          "Signatures section must be an array of size 2.");
      return false;
    }
    const cbor::Value& authorities_value = section_value.GetArray()[0];
    const cbor::Value& vouched_subsets_value = section_value.GetArray()[1];

    if (!authorities_value.is_array()) {
      RunErrorCallbackAndDestroy("Authorities must be an array.");
      return false;
    }
    std::vector<mojom::AugmentedCertificatePtr> authorities;
    for (const cbor::Value& value : authorities_value.GetArray()) {
      // ParseAugmentedCertificate deletes |this| on failure.
      auto authority = ParseAugmentedCertificate(value);
      if (!authority)
        return false;
      authorities.push_back(std::move(authority));
    }

    if (!vouched_subsets_value.is_array()) {
      RunErrorCallbackAndDestroy("Vouched-subsets must be an array.");
      return false;
    }
    std::vector<mojom::VouchedSubsetPtr> vouched_subsets;
    for (const cbor::Value& value : vouched_subsets_value.GetArray()) {
      if (!value.is_map()) {
        RunErrorCallbackAndDestroy(
            "An element of vouched-subsets must be a map.");
        return false;
      }
      const cbor::Value::MapValue& item_map = value.GetMap();

      auto* authority_value = Lookup(item_map, "authority");
      if (!authority_value || !authority_value->is_unsigned()) {
        RunErrorCallbackAndDestroy(
            "authority is not found in vouched-subsets map, or not an "
            "unsigned.");
        return false;
      }
      int64_t authority = authority_value->GetUnsigned();

      auto* sig_value = Lookup(item_map, "sig");
      if (!sig_value || !sig_value->is_bytestring()) {
        RunErrorCallbackAndDestroy(
            "sig is not found in vouched-subsets map, or not a bytestring.");
        return false;
      }
      const cbor::Value::BinaryValue& sig = sig_value->GetBytestring();

      auto* signed_value = Lookup(item_map, "signed");
      if (!signed_value || !signed_value->is_bytestring()) {
        RunErrorCallbackAndDestroy(
            "signed is not found in vouched-subsets map, or not a bytestring.");
        return false;
      }
      const cbor::Value::BinaryValue& raw_signed =
          signed_value->GetBytestring();

      // ParseSignedSubset deletes |this| on failure.
      auto parsed_signed = ParseSignedSubset(raw_signed);
      if (!parsed_signed)
        return false;

      vouched_subsets.push_back(mojom::VouchedSubset::New(
          authority, sig, raw_signed, std::move(parsed_signed)));
    }

    // Step 2. "Set metadata["authorities"] to the list of authorities in the
    // first element of the signatures array."
    metadata_->authorities = std::move(authorities);

    // Step 3. "Set metadata["vouched-subsets"] to the second element of the
    // signatures array."
    metadata_->vouched_subsets = std::move(vouched_subsets);

    return true;
  }

  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#critical-section
  bool ParseCriticalSection(const cbor::Value& section_value) {
    // Step 1. "Let critical be the result of parsing sectionContents as a CBOR
    // item matching the above critical rule (Section 3.5). If critical is an
    // error, return that error."
    if (!section_value.is_array()) {
      RunErrorCallbackAndDestroy("Critical section must be an array.");
      return false;
    }
    // Step 2. "For each value sectionName in the critical list, if the client
    // has not implemented sections named sectionName, return an error."
    for (const cbor::Value& elem : section_value.GetArray()) {
      if (!elem.is_string()) {
        RunErrorCallbackAndDestroy(
            "Non-string element in the critical section.");
        return false;
      }
      const auto& section_name = elem.GetString();
      if (!IsMetadataSection(section_name) &&
          section_name != kResponsesSection) {
        RunErrorCallbackAndDestroy("Unknown critical section.");
        return false;
      }
    }
    return true;
  }

  // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#cert-chain-format
  mojom::AugmentedCertificatePtr ParseAugmentedCertificate(
      const cbor::Value& value) {
    if (!value.is_map()) {
      RunErrorCallbackAndDestroy("augmented-certificate must be a map.");
      return nullptr;
    }
    const cbor::Value::MapValue& item_map = value.GetMap();
    mojom::AugmentedCertificatePtr authority =
        mojom::AugmentedCertificate::New();

    auto* cert_value = Lookup(item_map, "cert");
    if (!cert_value || !cert_value->is_bytestring()) {
      RunErrorCallbackAndDestroy(
          "cert is not found in augmented-certificate, or not a bytestring.");
      return nullptr;
    }
    authority->cert = cert_value->GetBytestring();

    if (auto* ocsp_value = Lookup(item_map, "ocsp")) {
      if (!ocsp_value->is_bytestring()) {
        RunErrorCallbackAndDestroy("ocsp is not a bytestring.");
        return nullptr;
      }
      authority->ocsp = ocsp_value->GetBytestring();
    }

    if (auto* sct_value = Lookup(item_map, "sct")) {
      if (!sct_value->is_bytestring()) {
        RunErrorCallbackAndDestroy("sct is not a bytestring.");
        return nullptr;
      }
      authority->sct = sct_value->GetBytestring();
    }
    return authority;
  }

  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#signatures-section
  mojom::SignedSubsetPtr ParseSignedSubset(
      const cbor::Value::BinaryValue& signed_bytes) {
    // Parse |signed_bytes| as a CBOR item.
    cbor::Reader::DecoderError error;
    base::Optional<cbor::Value> value =
        cbor::Reader::Read(signed_bytes, &error);
    if (!value) {
      RunErrorCallbackAndDestroy(
          std::string("Error parsing signed bytes as CBOR: ") +
          cbor::Reader::ErrorCodeToString(error));
      return nullptr;
    }

    if (!value->is_map()) {
      RunErrorCallbackAndDestroy("signed-subset must be a CBOR map");
      return nullptr;
    }
    const cbor::Value::MapValue& value_map = value->GetMap();

    auto* validity_url_value = Lookup(value_map, "validity-url");
    if (!validity_url_value || !validity_url_value->is_string()) {
      RunErrorCallbackAndDestroy(
          "validity-url is not found in signed-subset, or not a string.");
      return nullptr;
    }
    // TODO(crbug.com/966753): Revisit this once requirements for validity URL
    // are speced.
    GURL validity_url(validity_url_value->GetString());
    if (!validity_url.is_valid()) {
      RunErrorCallbackAndDestroy("Cannot parse validity-url.");
      return nullptr;
    }

    auto* auth_sha256_value = Lookup(value_map, "auth-sha256");
    if (!auth_sha256_value || !auth_sha256_value->is_bytestring()) {
      RunErrorCallbackAndDestroy(
          "auth-sha256 is not found in signed-subset, or not a bytestring.");
      return nullptr;
    }
    auto auth_sha256 = auth_sha256_value->GetBytestring();

    auto* date_value = Lookup(value_map, "date");
    if (!date_value || !date_value->is_unsigned()) {
      RunErrorCallbackAndDestroy(
          "date is not found in signed-subset, or not an unsigned.");
      return nullptr;
    }
    auto date = date_value->GetUnsigned();

    auto* expires_value = Lookup(value_map, "expires");
    if (!expires_value || !expires_value->is_unsigned()) {
      RunErrorCallbackAndDestroy(
          "expires is not found in signed-subset, or not an unsigned.");
      return nullptr;
    }
    auto expires = expires_value->GetUnsigned();

    auto* subset_hashes_value = Lookup(value_map, "subset-hashes");
    if (!subset_hashes_value || !subset_hashes_value->is_map()) {
      RunErrorCallbackAndDestroy(
          "subset-hashes is not found in signed-subset, or not a map.");
      return nullptr;
    }
    base::flat_map<GURL, mojom::SubsetHashesValuePtr> subset_hashes;

    for (const auto& item : subset_hashes_value->GetMap()) {
      if (!item.first.is_string()) {
        RunErrorCallbackAndDestroy("subset-hashes: key must be a string.");
        return nullptr;
      }
      if (!item.second.is_array()) {
        RunErrorCallbackAndDestroy("subset-hashes: value must be an array.");
        return nullptr;
      }
      const std::string& url = item.first.GetString();
      const cbor::Value::ArrayValue& value_array = item.second.GetArray();

      GURL parsed_url = ParseExchangeURL(url);
      if (!parsed_url.is_valid()) {
        RunErrorCallbackAndDestroy("subset-hashes: exchange URL is not valid.");
        return nullptr;
      }

      if (value_array.empty() || !value_array[0].is_bytestring()) {
        RunErrorCallbackAndDestroy(
            "subset-hashes: the first element of array must be a bytestring.");
        return nullptr;
      }
      base::StringPiece variants_value = value_array[0].GetBytestringAsString();
      if (value_array.size() < 3 || value_array.size() % 2 != 1) {
        RunErrorCallbackAndDestroy(
            "subset-hashes: unexpected size of value array.");
        return nullptr;
      }
      std::vector<mojom::ResourceIntegrityPtr> resource_integrities;
      for (size_t i = 1; i < value_array.size(); i += 2) {
        if (!value_array[i].is_bytestring()) {
          RunErrorCallbackAndDestroy(
              "subset-hashes: header-sha256 must be a byte string.");
          return nullptr;
        }
        if (!value_array[i + 1].is_string()) {
          RunErrorCallbackAndDestroy(
              "subset-hashes: payload-integrity-header must be a string.");
          return nullptr;
        }
        resource_integrities.push_back(mojom::ResourceIntegrity::New(
            value_array[i].GetBytestring(), value_array[i + 1].GetString()));
      }
      subset_hashes.insert(std::make_pair(
          parsed_url,
          mojom::SubsetHashesValue::New(variants_value.as_string(),
                                        std::move(resource_integrities))));
    }

    return mojom::SignedSubset::New(validity_url, auth_sha256, date, expires,
                                    std::move(subset_hashes));
  }

  // Returns nullptr if |key| is not in |map|.
  const cbor::Value* Lookup(const cbor::Value::MapValue& map, const char* key) {
    auto iter = map.find(cbor::Value(key));
    if (iter == map.end())
      return nullptr;
    return &iter->second;
  }

  void RunSuccessCallbackAndDestroy() {
    std::move(callback_).Run(std::move(metadata_), nullptr);
    delete this;
  }

  void RunErrorCallbackAndDestroy(
      const std::string& message,
      mojom::BundleParseErrorType error_type =
          mojom::BundleParseErrorType::kFormatError) {
    mojom::BundleMetadataParseErrorPtr err =
        mojom::BundleMetadataParseError::New(error_type, fallback_url_,
                                             message);
    std::move(callback_).Run(nullptr, std::move(err));
    delete this;
  }

  // Implements SharedBundleDataSource::Observer.
  void OnDisconnect() override {
    RunErrorCallbackAndDestroy("Data source disconnected.");
  }

  scoped_refptr<SharedBundleDataSource> data_source_;
  ParseMetadataCallback callback_;
  uint64_t size_;
  bool version_mismatch_ = false;
  GURL fallback_url_;
  SectionOffsets section_offsets_;
  mojom::BundleMetadataPtr metadata_;

  base::WeakPtrFactory<MetadataParser> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(MetadataParser);
};

// A parser for reading single item from the responses section. This class owns
// itself and will self destruct after calling the ParseResponseCallback.
class WebBundleParser::ResponseParser
    : public WebBundleParser::SharedBundleDataSource::Observer {
 public:
  ResponseParser(scoped_refptr<SharedBundleDataSource> data_source,
                 uint64_t response_offset,
                 uint64_t response_length,
                 WebBundleParser::ParseResponseCallback callback)
      : data_source_(data_source),
        response_offset_(response_offset),
        response_length_(response_length),
        callback_(std::move(callback)) {
    data_source_->AddObserver(this);
  }
  ~ResponseParser() override { data_source_->RemoveObserver(this); }

  void Start(uint64_t buffer_size = kInitialBufferSizeForResponse) {
    const uint64_t length = std::min(response_length_, buffer_size);
    data_source_->Read(response_offset_, length,
                       base::BindOnce(&ResponseParser::ParseResponseHeader,
                                      weak_factory_.GetWeakPtr(), length));
  }

 private:
  // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-response
  void ParseResponseHeader(uint64_t expected_data_length,
                           const base::Optional<std::vector<uint8_t>>& data) {
    // Step 1. "Seek to offset requestMetadata.offset in stream. If this fails,
    // return an error."
    if (!data || data->size() != expected_data_length) {
      RunErrorCallbackAndDestroy("Error reading response header.");
      return;
    }
    InputReader input(*data);

    // Step 2. "Read 1 byte from stream. If this is an error or isn't 0x82,
    // return an error."
    auto num_elements = input.ReadCBORHeader(CBORType::kArray);
    if (!num_elements || *num_elements != 2) {
      RunErrorCallbackAndDestroy("Array size of response must be 2.");
      return;
    }

    // Step 3. "Let headerLength be the result of getting the length of a CBOR
    // bytestring header from stream (Section 3.5.2). If headerLength is an
    // error, return that error."
    auto header_length = input.ReadCBORHeader(CBORType::kByteString);
    if (!header_length) {
      RunErrorCallbackAndDestroy("Cannot parse response header length.");
      return;
    }

    // Step 4. "If headerLength is 524288 (512*1024) or greater, return an
    // error."
    if (*header_length >= kMaxResponseHeaderLength) {
      RunErrorCallbackAndDestroy("Response header is too big.");
      return;
    }

    // If we don't have enough data for the headers and the CBOR header of the
    // payload, re-read with a larger buffer size.
    const uint64_t required_buffer_size = std::min(
        input.CurrentOffset() + *header_length + kMaxCBORItemHeaderSize,
        response_length_);
    if (data->size() < required_buffer_size) {
      DVLOG(1) << "Re-reading response header with a buffer of size "
               << required_buffer_size;
      Start(required_buffer_size);
      return;
    }

    // Step 5. "Let headerCbor be the result of reading headerLength bytes from
    // stream and parsing a CBOR item from them matching the headers CDDL rule.
    // If either the read or parse returns an error, return that error."
    auto headers_bytes = input.ReadBytes(*header_length);
    if (!headers_bytes) {
      RunErrorCallbackAndDestroy("Cannot read response headers.");
      return;
    }
    cbor::Reader::DecoderError error;
    base::Optional<cbor::Value> headers_value =
        cbor::Reader::Read(*headers_bytes, &error);
    if (!headers_value) {
      RunErrorCallbackAndDestroy("Cannot parse response headers.");
      return;
    }

    // Step 6. "Let (headers, pseudos) be the result of converting headerCbor
    // to a header list and pseudoheaders using the algorithm in Section 3.6.
    // If this returns an error, return that error."
    auto parsed_headers = ConvertCBORValueToHeaders(*headers_value);
    if (!parsed_headers) {
      RunErrorCallbackAndDestroy("Cannot parse response headers.");
      return;
    }

    // Step 7. "If pseudos does not have a key named ':status' or its size
    // isn't 1, return an error."
    const auto pseudo_status = parsed_headers->pseudos.find(":status");
    if (parsed_headers->pseudos.size() != 1 ||
        pseudo_status == parsed_headers->pseudos.end()) {
      RunErrorCallbackAndDestroy(
          "Response headers map must have exactly one pseudo-header, :status.");
      return;
    }

    // Step 8. "If pseudos[':status'] isn't exactly 3 ASCII decimal digits,
    // return an error."
    int status;
    const auto& status_str = pseudo_status->second;
    if (status_str.size() != 3 ||
        !std::all_of(status_str.begin(), status_str.end(),
                     base::IsAsciiDigit<char>) ||
        !base::StringToInt(status_str, &status)) {
      RunErrorCallbackAndDestroy(":status must be 3 ASCII decimal digits.");
      return;
    }

    // Step 9. "Let payloadLength be the result of getting the length of a CBOR
    // bytestring header from stream (Section 3.5.2). If payloadLength is an
    // error, return that error."
    auto payload_length = input.ReadCBORHeader(CBORType::kByteString);
    if (!payload_length) {
      RunErrorCallbackAndDestroy("Cannot parse response payload length.");
      return;
    }

    // Step 10. "If payloadLength is greater than 0 and headers does not contain
    // a Content-Type header, return an error."
    if (*payload_length > 0 &&
        !parsed_headers->headers.contains("content-type")) {
      RunErrorCallbackAndDestroy(
          "Non-empty response must have a content-type header.");
      return;
    }

    // Step 11. "If stream.currentOffset + payloadLength !=
    // requestMetadata.offset + requestMetadata.length, return an error."
    if (input.CurrentOffset() + *payload_length != response_length_) {
      RunErrorCallbackAndDestroy("Unexpected payload length.");
      return;
    }

    // Step 12. "Let body be a new body ([FETCH]) whose stream is a tee'd copy
    // of stream starting at the current offset and ending after payloadLength
    // bytes."

    // Step 13. "Let response be a new response ([FETCH]) whose:
    // - Url list is request's url list,
    // - status is pseudos[':status'],
    // - header list is headers, and
    // - body is body."
    mojom::BundleResponsePtr response = mojom::BundleResponse::New();
    response->response_code = status;
    response->response_headers = std::move(parsed_headers->headers);
    response->payload_offset = response_offset_ + input.CurrentOffset();
    response->payload_length = *payload_length;
    RunSuccessCallbackAndDestroy(std::move(response));
  }

  void RunSuccessCallbackAndDestroy(mojom::BundleResponsePtr response) {
    std::move(callback_).Run(std::move(response), nullptr);
    delete this;
  }

  void RunErrorCallbackAndDestroy(
      const std::string& message,
      mojom::BundleParseErrorType error_type =
          mojom::BundleParseErrorType::kFormatError) {
    std::move(callback_).Run(
        nullptr, mojom::BundleResponseParseError::New(error_type, message));
    delete this;
  }

  // Implements SharedBundleDataSource::Observer.
  void OnDisconnect() override {
    RunErrorCallbackAndDestroy("Data source disconnected.");
  }

  scoped_refptr<SharedBundleDataSource> data_source_;
  uint64_t response_offset_;
  uint64_t response_length_;
  ParseResponseCallback callback_;

  base::WeakPtrFactory<ResponseParser> weak_factory_{this};

  DISALLOW_COPY_AND_ASSIGN(ResponseParser);
};

WebBundleParser::SharedBundleDataSource::SharedBundleDataSource(
    mojo::PendingRemote<mojom::BundleDataSource> pending_data_source)
    : data_source_(std::move(pending_data_source)) {
  data_source_.set_disconnect_handler(base::BindOnce(
      &SharedBundleDataSource::OnDisconnect, base::Unretained(this)));
}

void WebBundleParser::SharedBundleDataSource::AddObserver(Observer* observer) {
  DCHECK(observers_.end() == observers_.find(observer));
  observers_.insert(observer);
}

void WebBundleParser::SharedBundleDataSource::RemoveObserver(
    Observer* observer) {
  auto it = observers_.find(observer);
  DCHECK(observers_.end() != it);
  observers_.erase(it);
}

WebBundleParser::SharedBundleDataSource::~SharedBundleDataSource() = default;

void WebBundleParser::SharedBundleDataSource::OnDisconnect() {
  for (auto* observer : observers_)
    observer->OnDisconnect();
}

void WebBundleParser::SharedBundleDataSource::GetSize(
    GetSizeCallback callback) {
  data_source_->GetSize(std::move(callback));
}

void WebBundleParser::SharedBundleDataSource::Read(uint64_t offset,
                                                   uint64_t length,
                                                   ReadCallback callback) {
  data_source_->Read(offset, length, std::move(callback));
}

WebBundleParser::WebBundleParser(
    mojo::PendingReceiver<mojom::WebBundleParser> receiver,
    mojo::PendingRemote<mojom::BundleDataSource> data_source)
    : receiver_(this, std::move(receiver)),
      data_source_(base::MakeRefCounted<SharedBundleDataSource>(
          std::move(data_source))) {
  receiver_.set_disconnect_handler(base::BindOnce(
      &base::DeletePointer<WebBundleParser>, base::Unretained(this)));
}

WebBundleParser::~WebBundleParser() = default;

void WebBundleParser::ParseMetadata(ParseMetadataCallback callback) {
  MetadataParser* parser =
      new MetadataParser(data_source_, std::move(callback));
  parser->Start();
}

void WebBundleParser::ParseResponse(uint64_t response_offset,
                                    uint64_t response_length,
                                    ParseResponseCallback callback) {
  ResponseParser* parser = new ResponseParser(
      data_source_, response_offset, response_length, std::move(callback));
  parser->Start();
}

}  // namespace data_decoder
