#ifndef THIRD_PARTY_UPB_WASM_ABI_MINI_TABLE_CONTAINER_ENCODE_H_
#define THIRD_PARTY_UPB_WASM_ABI_MINI_TABLE_CONTAINER_ENCODE_H_

#include <cstdint>
#include <optional>
#include <tuple>
#include <vector>

#include "third_party/absl/status/status.h"
#include "third_party/absl/strings/string_view.h"

namespace upb::wasm {

void EncodeVarint(uint32_t val, std::vector<char>& target);

// Utility struct for gathering MiniDescriptors and encoding into a Container.
// Intended for use in tests.
struct DescriptorContainer {
  // Enum minidescriptors.
  std::vector<absl::string_view> enums;
  // Message minidescriptors.
  std::vector<absl::string_view> messages;
  // Extension minidescriptors grouped by parent message index, paired with
  // linkage (a valid enum or message index) if relevant.
  using ExtensionEntry = std::tuple<absl::string_view, std::optional<uint32_t>>;
  using PackedExtensions = std::tuple<uint32_t, std::vector<ExtensionEntry>>;
  std::vector<PackedExtensions> extensions;
  // Links from a parent message, defined via message index, to its subs,
  // defined via enum or message index as relevant.
  std::vector<std::tuple<uint32_t, std::vector<uint32_t>>> links;

  // Verify the links section:
  // * Every field in the parent that needs a link has one.
  // * Every link points to a valid index in the appropriate section.
  absl::Status ValidateLinks() const;

  // Encode the gathered set of minidescriptors and linkage into a Container.
  // Note: does not perform validation of e.g. linkage.
  std::vector<char> Encode() const;
};

}  // namespace upb::wasm

#endif  // THIRD_PARTY_UPB_WASM_ABI_MINI_TABLE_CONTAINER_ENCODE_H_
