// Copyright (c) 2021 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 "quiche/common/capsule.h"

#include <type_traits>

#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/common/quiche_data_writer.h"
#include "quiche/common/quiche_ip_address.h"
#include "quiche/web_transport/web_transport.h"

namespace quiche {

std::string CapsuleTypeToString(CapsuleType capsule_type) {
  switch (capsule_type) {
    case CapsuleType::DATAGRAM:
      return "DATAGRAM";
    case CapsuleType::LEGACY_DATAGRAM:
      return "LEGACY_DATAGRAM";
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      return "LEGACY_DATAGRAM_WITHOUT_CONTEXT";
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return "CLOSE_WEBTRANSPORT_SESSION";
    case CapsuleType::ADDRESS_REQUEST:
      return "ADDRESS_REQUEST";
    case CapsuleType::ADDRESS_ASSIGN:
      return "ADDRESS_ASSIGN";
    case CapsuleType::ROUTE_ADVERTISEMENT:
      return "ROUTE_ADVERTISEMENT";
  }
  return absl::StrCat("Unknown(", static_cast<uint64_t>(capsule_type), ")");
}

std::ostream& operator<<(std::ostream& os, const CapsuleType& capsule_type) {
  os << CapsuleTypeToString(capsule_type);
  return os;
}

Capsule::Capsule(CapsuleType capsule_type) : capsule_type_(capsule_type) {
  switch (capsule_type) {
    case CapsuleType::DATAGRAM:
      static_assert(std::is_standard_layout<DatagramCapsule>::value &&
                        std::is_trivially_destructible<DatagramCapsule>::value,
                    "All inline capsule structs must have these properties");
      datagram_capsule_ = DatagramCapsule();
      break;
    case CapsuleType::LEGACY_DATAGRAM:
      static_assert(
          std::is_standard_layout<LegacyDatagramCapsule>::value &&
              std::is_trivially_destructible<LegacyDatagramCapsule>::value,
          "All inline capsule structs must have these properties");
      legacy_datagram_capsule_ = LegacyDatagramCapsule();
      break;
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      static_assert(
          std::is_standard_layout<LegacyDatagramWithoutContextCapsule>::value &&
              std::is_trivially_destructible<
                  LegacyDatagramWithoutContextCapsule>::value,
          "All inline capsule structs must have these properties");
      legacy_datagram_without_context_capsule_ =
          LegacyDatagramWithoutContextCapsule();
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      static_assert(
          std::is_standard_layout<CloseWebTransportSessionCapsule>::value &&
              std::is_trivially_destructible<
                  CloseWebTransportSessionCapsule>::value,
          "All inline capsule structs must have these properties");
      close_web_transport_session_capsule_ = CloseWebTransportSessionCapsule();
      break;
    case CapsuleType::ADDRESS_REQUEST:
      address_request_capsule_ = new AddressRequestCapsule();
      break;
    case CapsuleType::ADDRESS_ASSIGN:
      address_assign_capsule_ = new AddressAssignCapsule();
      break;
    case CapsuleType::ROUTE_ADVERTISEMENT:
      route_advertisement_capsule_ = new RouteAdvertisementCapsule();
      break;
    default:
      unknown_capsule_data_ = absl::string_view();
      break;
  }
}

void Capsule::Free() {
  switch (capsule_type_) {
    // Inlined capsule types.
    case CapsuleType::DATAGRAM:
    case CapsuleType::LEGACY_DATAGRAM:
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      // Do nothing, these are guaranteed to be trivially destructible.
      break;
    // Out-of-line capsule types.
    case CapsuleType::ADDRESS_REQUEST:
      delete address_request_capsule_;
      break;
    case CapsuleType::ADDRESS_ASSIGN:
      delete address_assign_capsule_;
      break;
    case CapsuleType::ROUTE_ADVERTISEMENT:
      delete route_advertisement_capsule_;
      break;
  }
  capsule_type_ = static_cast<CapsuleType>(0x17);  // Reserved unknown value.
  unknown_capsule_data_ = absl::string_view();
}
Capsule::~Capsule() { Free(); }

// static
Capsule Capsule::Datagram(absl::string_view http_datagram_payload) {
  Capsule capsule(CapsuleType::DATAGRAM);
  capsule.datagram_capsule().http_datagram_payload = http_datagram_payload;
  return capsule;
}

// static
Capsule Capsule::LegacyDatagram(absl::string_view http_datagram_payload) {
  Capsule capsule(CapsuleType::LEGACY_DATAGRAM);
  capsule.legacy_datagram_capsule().http_datagram_payload =
      http_datagram_payload;
  return capsule;
}

// static
Capsule Capsule::LegacyDatagramWithoutContext(
    absl::string_view http_datagram_payload) {
  Capsule capsule(CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT);
  capsule.legacy_datagram_without_context_capsule().http_datagram_payload =
      http_datagram_payload;
  return capsule;
}

// static
Capsule Capsule::CloseWebTransportSession(
    webtransport::SessionErrorCode error_code,
    absl::string_view error_message) {
  Capsule capsule(CapsuleType::CLOSE_WEBTRANSPORT_SESSION);
  capsule.close_web_transport_session_capsule().error_code = error_code;
  capsule.close_web_transport_session_capsule().error_message = error_message;
  return capsule;
}

// static
Capsule Capsule::AddressRequest() {
  return Capsule(CapsuleType::ADDRESS_REQUEST);
}

// static
Capsule Capsule::AddressAssign() {
  return Capsule(CapsuleType::ADDRESS_ASSIGN);
}

// static
Capsule Capsule::RouteAdvertisement() {
  return Capsule(CapsuleType::ROUTE_ADVERTISEMENT);
}

// static
Capsule Capsule::Unknown(uint64_t capsule_type,
                         absl::string_view unknown_capsule_data) {
  Capsule capsule(static_cast<CapsuleType>(capsule_type));
  capsule.unknown_capsule_data() = unknown_capsule_data;
  return capsule;
}

Capsule& Capsule::operator=(const Capsule& other) {
  Free();
  capsule_type_ = other.capsule_type_;
  switch (capsule_type_) {
    case CapsuleType::DATAGRAM:
      datagram_capsule_ = other.datagram_capsule_;
      break;
    case CapsuleType::LEGACY_DATAGRAM:
      legacy_datagram_capsule_ = other.legacy_datagram_capsule_;
      break;
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      legacy_datagram_without_context_capsule_ =
          other.legacy_datagram_without_context_capsule_;
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      close_web_transport_session_capsule_ =
          other.close_web_transport_session_capsule_;
      break;
    case CapsuleType::ADDRESS_ASSIGN:
      address_assign_capsule_ = new AddressAssignCapsule();
      *address_assign_capsule_ = *other.address_assign_capsule_;
      break;
    case CapsuleType::ADDRESS_REQUEST:
      address_request_capsule_ = new AddressRequestCapsule();
      *address_request_capsule_ = *other.address_request_capsule_;
      break;
    case CapsuleType::ROUTE_ADVERTISEMENT:
      route_advertisement_capsule_ = new RouteAdvertisementCapsule();
      *route_advertisement_capsule_ = *other.route_advertisement_capsule_;
      break;
    default:
      unknown_capsule_data_ = other.unknown_capsule_data_;
      break;
  }
  return *this;
}

Capsule::Capsule(const Capsule& other) : Capsule(other.capsule_type_) {
  *this = other;
}

bool Capsule::operator==(const Capsule& other) const {
  if (capsule_type_ != other.capsule_type_) {
    return false;
  }
  switch (capsule_type_) {
    case CapsuleType::DATAGRAM:
      return datagram_capsule_.http_datagram_payload ==
             other.datagram_capsule_.http_datagram_payload;
    case CapsuleType::LEGACY_DATAGRAM:
      return legacy_datagram_capsule_.http_datagram_payload ==
             other.legacy_datagram_capsule_.http_datagram_payload;
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      return legacy_datagram_without_context_capsule_.http_datagram_payload ==
             other.legacy_datagram_without_context_capsule_
                 .http_datagram_payload;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return close_web_transport_session_capsule_.error_code ==
                 other.close_web_transport_session_capsule_.error_code &&
             close_web_transport_session_capsule_.error_message ==
                 other.close_web_transport_session_capsule_.error_message;
    case CapsuleType::ADDRESS_REQUEST:
      return address_request_capsule_->requested_addresses ==
             other.address_request_capsule_->requested_addresses;
    case CapsuleType::ADDRESS_ASSIGN:
      return address_assign_capsule_->assigned_addresses ==
             other.address_assign_capsule_->assigned_addresses;
    case CapsuleType::ROUTE_ADVERTISEMENT:
      return route_advertisement_capsule_->ip_address_ranges ==
             other.route_advertisement_capsule_->ip_address_ranges;
    default:
      return unknown_capsule_data_ == other.unknown_capsule_data_;
  }
}

std::string DatagramCapsule::ToString() const {
  return absl::StrCat("DATAGRAM[",
                      absl::BytesToHexString(http_datagram_payload), "]");
}

std::string LegacyDatagramCapsule::ToString() const {
  return absl::StrCat("LEGACY_DATAGRAM[",
                      absl::BytesToHexString(http_datagram_payload), "]");
}

std::string LegacyDatagramWithoutContextCapsule::ToString() const {
  return absl::StrCat("LEGACY_DATAGRAM_WITHOUT_CONTEXT[",
                      absl::BytesToHexString(http_datagram_payload), "]");
}

std::string CloseWebTransportSessionCapsule::ToString() const {
  return absl::StrCat("CLOSE_WEBTRANSPORT_SESSION(error_code=", error_code,
                      ",error_message=\"", error_message, "\")");
}

std::string AddressRequestCapsule::ToString() const {
  std::string rv = "ADDRESS_REQUEST[";
  for (auto requested_address : requested_addresses) {
    absl::StrAppend(&rv, "(", requested_address.request_id, "-",
                    requested_address.ip_prefix.ToString(), ")");
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::string AddressAssignCapsule::ToString() const {
  std::string rv = "ADDRESS_ASSIGN[";
  for (auto assigned_address : assigned_addresses) {
    absl::StrAppend(&rv, "(", assigned_address.request_id, "-",
                    assigned_address.ip_prefix.ToString(), ")");
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::string RouteAdvertisementCapsule::ToString() const {
  std::string rv = "ROUTE_ADVERTISEMENT[";
  for (auto ip_address_range : ip_address_ranges) {
    absl::StrAppend(&rv, "(", ip_address_range.start_ip_address.ToString(), "-",
                    ip_address_range.end_ip_address.ToString(), "-",
                    static_cast<int>(ip_address_range.ip_protocol), ")");
  }
  absl::StrAppend(&rv, "]");
  return rv;
}

std::string Capsule::ToString() const {
  switch (capsule_type_) {
    case CapsuleType::DATAGRAM:
      return datagram_capsule_.ToString();
    case CapsuleType::LEGACY_DATAGRAM:
      return legacy_datagram_capsule_.ToString();
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      return legacy_datagram_without_context_capsule_.ToString();
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      return close_web_transport_session_capsule_.ToString();
    case CapsuleType::ADDRESS_REQUEST:
      return address_request_capsule_->ToString();
    case CapsuleType::ADDRESS_ASSIGN:
      return address_assign_capsule_->ToString();
    case CapsuleType::ROUTE_ADVERTISEMENT:
      return route_advertisement_capsule_->ToString();
    default:
      return absl::StrCat(CapsuleTypeToString(capsule_type_), "[",
                          absl::BytesToHexString(unknown_capsule_data_), "]");
  }
}

std::ostream& operator<<(std::ostream& os, const Capsule& capsule) {
  os << capsule.ToString();
  return os;
}

CapsuleParser::CapsuleParser(Visitor* visitor) : visitor_(visitor) {
  QUICHE_DCHECK_NE(visitor_, nullptr);
}

quiche::QuicheBuffer SerializeCapsule(
    const Capsule& capsule, quiche::QuicheBufferAllocator* allocator) {
  size_t capsule_type_length = QuicheDataWriter::GetVarInt62Len(
      static_cast<uint64_t>(capsule.capsule_type()));
  size_t capsule_data_length;
  switch (capsule.capsule_type()) {
    case CapsuleType::DATAGRAM:
      capsule_data_length =
          capsule.datagram_capsule().http_datagram_payload.length();
      break;
    case CapsuleType::LEGACY_DATAGRAM:
      capsule_data_length =
          capsule.legacy_datagram_capsule().http_datagram_payload.length();
      break;
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      capsule_data_length = capsule.legacy_datagram_without_context_capsule()
                                .http_datagram_payload.length();
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      capsule_data_length =
          sizeof(webtransport::SessionErrorCode) +
          capsule.close_web_transport_session_capsule().error_message.size();
      break;
    case CapsuleType::ADDRESS_REQUEST:
      capsule_data_length = 0;
      for (auto requested_address :
           capsule.address_request_capsule().requested_addresses) {
        capsule_data_length +=
            QuicheDataWriter::GetVarInt62Len(requested_address.request_id) + 1 +
            (requested_address.ip_prefix.address().IsIPv4()
                 ? QuicheIpAddress::kIPv4AddressSize
                 : QuicheIpAddress::kIPv6AddressSize) +
            1;
      }
      break;
    case CapsuleType::ADDRESS_ASSIGN:
      capsule_data_length = 0;
      for (auto assigned_address :
           capsule.address_assign_capsule().assigned_addresses) {
        capsule_data_length +=
            QuicheDataWriter::GetVarInt62Len(assigned_address.request_id) + 1 +
            (assigned_address.ip_prefix.address().IsIPv4()
                 ? QuicheIpAddress::kIPv4AddressSize
                 : QuicheIpAddress::kIPv6AddressSize) +
            1;
      }
      break;
    case CapsuleType::ROUTE_ADVERTISEMENT:
      capsule_data_length = 0;
      for (auto ip_address_range :
           capsule.route_advertisement_capsule().ip_address_ranges) {
        capsule_data_length += 1 +
                               (ip_address_range.start_ip_address.IsIPv4()
                                    ? QuicheIpAddress::kIPv4AddressSize
                                    : QuicheIpAddress::kIPv6AddressSize) *
                                   2 +
                               1;
      }
      break;
    default:
      capsule_data_length = capsule.unknown_capsule_data().length();
      break;
  }
  size_t capsule_length_length =
      QuicheDataWriter::GetVarInt62Len(capsule_data_length);
  size_t total_capsule_length =
      capsule_type_length + capsule_length_length + capsule_data_length;
  quiche::QuicheBuffer buffer(allocator, total_capsule_length);
  QuicheDataWriter writer(buffer.size(), buffer.data());
  if (!writer.WriteVarInt62(static_cast<uint64_t>(capsule.capsule_type()))) {
    QUICHE_BUG(capsule type write fail) << "Failed to write CAPSULE type";
    return {};
  }
  if (!writer.WriteVarInt62(capsule_data_length)) {
    QUICHE_BUG(capsule length write fail) << "Failed to write CAPSULE length";
    return {};
  }
  switch (capsule.capsule_type()) {
    case CapsuleType::DATAGRAM:
      if (!writer.WriteStringPiece(
              capsule.datagram_capsule().http_datagram_payload)) {
        QUICHE_BUG(datagram capsule payload write fail)
            << "Failed to write DATAGRAM CAPSULE payload";
        return {};
      }
      break;
    case CapsuleType::LEGACY_DATAGRAM:
      if (!writer.WriteStringPiece(
              capsule.legacy_datagram_capsule().http_datagram_payload)) {
        QUICHE_BUG(datagram legacy capsule payload write fail)
            << "Failed to write LEGACY_DATAGRAM CAPSULE payload";
        return {};
      }
      break;
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      if (!writer.WriteStringPiece(
              capsule.legacy_datagram_without_context_capsule()
                  .http_datagram_payload)) {
        QUICHE_BUG(datagram legacy without context capsule payload write fail)
            << "Failed to write LEGACY_DATAGRAM_WITHOUT_CONTEXT CAPSULE "
               "payload";
        return {};
      }
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      if (!writer.WriteUInt32(
              capsule.close_web_transport_session_capsule().error_code)) {
        QUICHE_BUG(close webtransport session capsule error code write fail)
            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error code";
        return {};
      }
      if (!writer.WriteStringPiece(
              capsule.close_web_transport_session_capsule().error_message)) {
        QUICHE_BUG(close webtransport session capsule error message write fail)
            << "Failed to write CLOSE_WEBTRANSPORT_SESSION error message";
        return {};
      }
      break;
    case CapsuleType::ADDRESS_REQUEST:
      for (auto requested_address :
           capsule.address_request_capsule().requested_addresses) {
        if (!writer.WriteVarInt62(requested_address.request_id)) {
          QUICHE_BUG(address request capsule id write fail)
              << "Failed to write ADDRESS_REQUEST ID";
          return {};
        }
        if (!writer.WriteUInt8(
                requested_address.ip_prefix.address().IsIPv4() ? 4 : 6)) {
          QUICHE_BUG(address request capsule family write fail)
              << "Failed to write ADDRESS_REQUEST family";
          return {};
        }
        if (!writer.WriteStringPiece(
                requested_address.ip_prefix.address().ToPackedString())) {
          QUICHE_BUG(address request capsule address write fail)
              << "Failed to write ADDRESS_REQUEST address";
          return {};
        }
        if (!writer.WriteUInt8(requested_address.ip_prefix.prefix_length())) {
          QUICHE_BUG(address request capsule prefix length write fail)
              << "Failed to write ADDRESS_REQUEST prefix length";
          return {};
        }
      }
      break;
    case CapsuleType::ADDRESS_ASSIGN:
      for (auto assigned_address :
           capsule.address_assign_capsule().assigned_addresses) {
        if (!writer.WriteVarInt62(assigned_address.request_id)) {
          QUICHE_BUG(address request capsule id write fail)
              << "Failed to write ADDRESS_ASSIGN ID";
          return {};
        }
        if (!writer.WriteUInt8(
                assigned_address.ip_prefix.address().IsIPv4() ? 4 : 6)) {
          QUICHE_BUG(address request capsule family write fail)
              << "Failed to write ADDRESS_ASSIGN family";
          return {};
        }
        if (!writer.WriteStringPiece(
                assigned_address.ip_prefix.address().ToPackedString())) {
          QUICHE_BUG(address request capsule address write fail)
              << "Failed to write ADDRESS_ASSIGN address";
          return {};
        }
        if (!writer.WriteUInt8(assigned_address.ip_prefix.prefix_length())) {
          QUICHE_BUG(address request capsule prefix length write fail)
              << "Failed to write ADDRESS_ASSIGN prefix length";
          return {};
        }
      }
      break;
    case CapsuleType::ROUTE_ADVERTISEMENT:
      for (auto ip_address_range :
           capsule.route_advertisement_capsule().ip_address_ranges) {
        if (!writer.WriteUInt8(
                ip_address_range.start_ip_address.IsIPv4() ? 4 : 6)) {
          QUICHE_BUG(route advertisement capsule family write fail)
              << "Failed to write ROUTE_ADVERTISEMENT family";
          return {};
        }
        if (!writer.WriteStringPiece(
                ip_address_range.start_ip_address.ToPackedString())) {
          QUICHE_BUG(route advertisement capsule start address write fail)
              << "Failed to write ROUTE_ADVERTISEMENT start address";
          return {};
        }
        if (!writer.WriteStringPiece(
                ip_address_range.end_ip_address.ToPackedString())) {
          QUICHE_BUG(route advertisement capsule end address write fail)
              << "Failed to write ROUTE_ADVERTISEMENT end address";
          return {};
        }
        if (!writer.WriteUInt8(ip_address_range.ip_protocol)) {
          QUICHE_BUG(route advertisement capsule IP protocol write fail)
              << "Failed to write ROUTE_ADVERTISEMENT IP protocol";
          return {};
        }
      }
      break;
    default:
      if (!writer.WriteStringPiece(capsule.unknown_capsule_data())) {
        QUICHE_BUG(capsule data write fail) << "Failed to write CAPSULE data";
        return {};
      }
      break;
  }
  if (writer.remaining() != 0) {
    QUICHE_BUG(capsule write length mismatch)
        << "CAPSULE serialization wrote " << writer.length() << " instead of "
        << writer.capacity();
    return {};
  }
  return buffer;
}

bool CapsuleParser::IngestCapsuleFragment(absl::string_view capsule_fragment) {
  if (parsing_error_occurred_) {
    return false;
  }
  absl::StrAppend(&buffered_data_, capsule_fragment);
  while (true) {
    const size_t buffered_data_read = AttemptParseCapsule();
    if (parsing_error_occurred_) {
      QUICHE_DCHECK_EQ(buffered_data_read, 0u);
      buffered_data_.clear();
      return false;
    }
    if (buffered_data_read == 0) {
      break;
    }
    buffered_data_.erase(0, buffered_data_read);
  }
  static constexpr size_t kMaxCapsuleBufferSize = 1024 * 1024;
  if (buffered_data_.size() > kMaxCapsuleBufferSize) {
    buffered_data_.clear();
    ReportParseFailure("Refusing to buffer too much capsule data");
    return false;
  }
  return true;
}

size_t CapsuleParser::AttemptParseCapsule() {
  QUICHE_DCHECK(!parsing_error_occurred_);
  if (buffered_data_.empty()) {
    return 0;
  }
  QuicheDataReader capsule_fragment_reader(buffered_data_);
  uint64_t capsule_type64;
  if (!capsule_fragment_reader.ReadVarInt62(&capsule_type64)) {
    QUICHE_DVLOG(2) << "Partial read: not enough data to read capsule type";
    return 0;
  }
  absl::string_view capsule_data;
  if (!capsule_fragment_reader.ReadStringPieceVarInt62(&capsule_data)) {
    QUICHE_DVLOG(2)
        << "Partial read: not enough data to read capsule length or "
           "full capsule data";
    return 0;
  }
  QuicheDataReader capsule_data_reader(capsule_data);
  Capsule capsule(static_cast<CapsuleType>(capsule_type64));
  switch (capsule.capsule_type()) {
    case CapsuleType::DATAGRAM:
      capsule.datagram_capsule().http_datagram_payload =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::LEGACY_DATAGRAM:
      capsule.legacy_datagram_capsule().http_datagram_payload =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::LEGACY_DATAGRAM_WITHOUT_CONTEXT:
      capsule.legacy_datagram_without_context_capsule().http_datagram_payload =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
      if (!capsule_data_reader.ReadUInt32(
              &capsule.close_web_transport_session_capsule().error_code)) {
        ReportParseFailure(
            "Unable to parse capsule CLOSE_WEBTRANSPORT_SESSION error code");
        return 0;
      }
      capsule.close_web_transport_session_capsule().error_message =
          capsule_data_reader.ReadRemainingPayload();
      break;
    case CapsuleType::ADDRESS_REQUEST: {
      while (!capsule_data_reader.IsDoneReading()) {
        PrefixWithId requested_address;
        if (!capsule_data_reader.ReadVarInt62(&requested_address.request_id)) {
          ReportParseFailure(
              "Unable to parse capsule ADDRESS_REQUEST request ID");
          return 0;
        }
        uint8_t address_family;
        if (!capsule_data_reader.ReadUInt8(&address_family)) {
          ReportParseFailure("Unable to parse capsule ADDRESS_REQUEST family");
          return 0;
        }
        if (address_family != 4 && address_family != 6) {
          ReportParseFailure("Bad ADDRESS_REQUEST family");
          return 0;
        }
        absl::string_view ip_address_bytes;
        if (!capsule_data_reader.ReadStringPiece(
                &ip_address_bytes, address_family == 4
                                       ? QuicheIpAddress::kIPv4AddressSize
                                       : QuicheIpAddress::kIPv6AddressSize)) {
          ReportParseFailure("Unable to read capsule ADDRESS_REQUEST address");
          return 0;
        }
        quiche::QuicheIpAddress ip_address;
        if (!ip_address.FromPackedString(ip_address_bytes.data(),
                                         ip_address_bytes.size())) {
          ReportParseFailure("Unable to parse capsule ADDRESS_REQUEST address");
          return 0;
        }
        uint8_t ip_prefix_length;
        if (!capsule_data_reader.ReadUInt8(&ip_prefix_length)) {
          ReportParseFailure(
              "Unable to parse capsule ADDRESS_REQUEST IP prefix length");
          return 0;
        }
        if (ip_prefix_length >
            quiche::QuicheIpPrefix(ip_address).prefix_length()) {
          ReportParseFailure("Invalid IP prefix length");
          return 0;
        }
        requested_address.ip_prefix =
            quiche::QuicheIpPrefix(ip_address, ip_prefix_length);
        capsule.address_request_capsule().requested_addresses.push_back(
            requested_address);
      }
    } break;
    case CapsuleType::ADDRESS_ASSIGN: {
      while (!capsule_data_reader.IsDoneReading()) {
        PrefixWithId assigned_address;
        if (!capsule_data_reader.ReadVarInt62(&assigned_address.request_id)) {
          ReportParseFailure(
              "Unable to parse capsule ADDRESS_ASSIGN request ID");
          return 0;
        }
        uint8_t address_family;
        if (!capsule_data_reader.ReadUInt8(&address_family)) {
          ReportParseFailure("Unable to parse capsule ADDRESS_ASSIGN family");
          return 0;
        }
        if (address_family != 4 && address_family != 6) {
          ReportParseFailure("Bad ADDRESS_ASSIGN family");
          return 0;
        }
        absl::string_view ip_address_bytes;
        if (!capsule_data_reader.ReadStringPiece(
                &ip_address_bytes, address_family == 4
                                       ? QuicheIpAddress::kIPv4AddressSize
                                       : QuicheIpAddress::kIPv6AddressSize)) {
          ReportParseFailure("Unable to read capsule ADDRESS_ASSIGN address");
          return 0;
        }
        quiche::QuicheIpAddress ip_address;
        if (!ip_address.FromPackedString(ip_address_bytes.data(),
                                         ip_address_bytes.size())) {
          ReportParseFailure("Unable to parse capsule ADDRESS_ASSIGN address");
          return 0;
        }
        uint8_t ip_prefix_length;
        if (!capsule_data_reader.ReadUInt8(&ip_prefix_length)) {
          ReportParseFailure(
              "Unable to parse capsule ADDRESS_ASSIGN IP prefix length");
          return 0;
        }
        if (ip_prefix_length >
            quiche::QuicheIpPrefix(ip_address).prefix_length()) {
          ReportParseFailure("Invalid IP prefix length");
          return 0;
        }
        assigned_address.ip_prefix =
            quiche::QuicheIpPrefix(ip_address, ip_prefix_length);
        capsule.address_assign_capsule().assigned_addresses.push_back(
            assigned_address);
      }
    } break;
    case CapsuleType::ROUTE_ADVERTISEMENT: {
      while (!capsule_data_reader.IsDoneReading()) {
        uint8_t address_family;
        if (!capsule_data_reader.ReadUInt8(&address_family)) {
          ReportParseFailure(
              "Unable to parse capsule ROUTE_ADVERTISEMENT family");
          return 0;
        }
        if (address_family != 4 && address_family != 6) {
          ReportParseFailure("Bad ROUTE_ADVERTISEMENT family");
          return 0;
        }
        IpAddressRange ip_address_range;
        absl::string_view start_ip_address_bytes;
        if (!capsule_data_reader.ReadStringPiece(
                &start_ip_address_bytes,
                address_family == 4 ? QuicheIpAddress::kIPv4AddressSize
                                    : QuicheIpAddress::kIPv6AddressSize)) {
          ReportParseFailure(
              "Unable to read capsule ROUTE_ADVERTISEMENT start address");
          return 0;
        }
        if (!ip_address_range.start_ip_address.FromPackedString(
                start_ip_address_bytes.data(), start_ip_address_bytes.size())) {
          ReportParseFailure(
              "Unable to parse capsule ROUTE_ADVERTISEMENT start address");
          return 0;
        }
        absl::string_view end_ip_address_bytes;
        if (!capsule_data_reader.ReadStringPiece(
                &end_ip_address_bytes,
                address_family == 4 ? QuicheIpAddress::kIPv4AddressSize
                                    : QuicheIpAddress::kIPv6AddressSize)) {
          ReportParseFailure(
              "Unable to read capsule ROUTE_ADVERTISEMENT end address");
          return 0;
        }
        if (!ip_address_range.end_ip_address.FromPackedString(
                end_ip_address_bytes.data(), end_ip_address_bytes.size())) {
          ReportParseFailure(
              "Unable to parse capsule ROUTE_ADVERTISEMENT end address");
          return 0;
        }
        if (!capsule_data_reader.ReadUInt8(&ip_address_range.ip_protocol)) {
          ReportParseFailure(
              "Unable to parse capsule ROUTE_ADVERTISEMENT IP protocol");
          return 0;
        }
        capsule.route_advertisement_capsule().ip_address_ranges.push_back(
            ip_address_range);
      }
    } break;
    default:
      capsule.unknown_capsule_data() =
          capsule_data_reader.ReadRemainingPayload();
  }
  if (!visitor_->OnCapsule(capsule)) {
    ReportParseFailure("Visitor failed to process capsule");
    return 0;
  }
  return capsule_fragment_reader.PreviouslyReadPayload().length();
}

void CapsuleParser::ReportParseFailure(const std::string& error_message) {
  if (parsing_error_occurred_) {
    QUICHE_BUG(multiple parse errors) << "Experienced multiple parse failures";
    return;
  }
  parsing_error_occurred_ = true;
  visitor_->OnCapsuleParseFailure(error_message);
}

void CapsuleParser::ErrorIfThereIsRemainingBufferedData() {
  if (parsing_error_occurred_) {
    return;
  }
  if (!buffered_data_.empty()) {
    ReportParseFailure("Incomplete capsule left at the end of the stream");
  }
}

bool PrefixWithId::operator==(const PrefixWithId& other) const {
  return request_id == other.request_id && ip_prefix == other.ip_prefix;
}

bool IpAddressRange::operator==(const IpAddressRange& other) const {
  return start_ip_address == other.start_ip_address &&
         end_ip_address == other.end_ip_address &&
         ip_protocol == other.ip_protocol;
}

bool AddressAssignCapsule::operator==(const AddressAssignCapsule& other) const {
  return assigned_addresses == other.assigned_addresses;
}

bool AddressRequestCapsule::operator==(
    const AddressRequestCapsule& other) const {
  return requested_addresses == other.requested_addresses;
}

bool RouteAdvertisementCapsule::operator==(
    const RouteAdvertisementCapsule& other) const {
  return ip_address_ranges == other.ip_address_ranges;
}

}  // namespace quiche
