// Copyright 2019 The Fuchsia 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 <lib/fidl/coding.h>
#include <lib/fidl/internal.h>
#include <lib/fidl/transformer.h>

#include <cassert>
#include <cinttypes>
#include <cstdio>
#include <cstring>
#include <string>

// Disable warning about implicit fallthrough, since it's intentionally used a
// lot in this code, and the switch()es end up being harder to read without it.
// Note that "#pragma GCC" works for both GCC & Clang.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"

namespace {

// This is an array of 32-bit ordinals that's intended to help debugging. The
// array is normally empty, but you can add an ordinal to this array in your
// local tree if you encounter a message in-the-field that the transformer is
// having issues with.
constexpr uint64_t kDebugOrdinals[] = {
    // 0x61f19458'00000000,  // example ordinal
};

enum struct WireFormat {
  kOld,
  kV1,
};

// Call this macro instead of assert() when inside a TransformerBase method: it
// will print out useful debugging information. This macro inlines the code in
// order to get precise line number information, and to know the assertion being
// evaluated.
#define TRANSFORMER_ASSERT(assertion, position)                       \
  {                                                                   \
    const auto ok = static_cast<bool>(assertion);                     \
    if (!ok) {                                                        \
      debug_info_->RecordFailure(__LINE__, (#assertion), (position)); \
      assert(assertion);                                              \
    }                                                                 \
  }

// Call this macro instead of the TransformerBase::Fail() method. This is a simple wrapper to pass
// the current __LINE__ number to Fail().
#define TRANSFORMER_FAIL(status, position, error_message) \
  Fail(status, position, __LINE__, error_message);

// Every Transform() method outputs a TraversalResult, which indicates how many out-of-line bytes
// that transform method consumed, and the actual (not max) number of handles that were encountered
// during the transformation. This is needed for writing the correct size and handle information in
// an envelope. (This isn't a great name. A better name would be welcome!)
struct TraversalResult {
  uint32_t src_out_of_line_size = 0u;
  uint32_t dst_out_of_line_size = 0u;
  uint32_t handle_count = 0u;

  TraversalResult& operator+=(const TraversalResult rhs) {
    src_out_of_line_size += rhs.src_out_of_line_size;
    dst_out_of_line_size += rhs.dst_out_of_line_size;
    handle_count += rhs.handle_count;

    return *this;
  }
};

constexpr uint32_t PrimitiveSize(const FidlCodedPrimitive primitive) {
  switch (primitive) {
    case kFidlCodedPrimitive_Bool:
    case kFidlCodedPrimitive_Int8:
    case kFidlCodedPrimitive_Uint8:
      return 1;
    case kFidlCodedPrimitive_Int16:
    case kFidlCodedPrimitive_Uint16:
      return 2;
    case kFidlCodedPrimitive_Int32:
    case kFidlCodedPrimitive_Uint32:
    case kFidlCodedPrimitive_Float32:
      return 4;
    case kFidlCodedPrimitive_Int64:
    case kFidlCodedPrimitive_Uint64:
    case kFidlCodedPrimitive_Float64:
      return 8;
  }
  __builtin_unreachable();
}

// This function is named UnsafeInlineSize since it assumes that |type| will be
// non-null. Don't call this function directly; instead, call
// TransformerBase::InlineSize().
uint32_t UnsafeInlineSize(const fidl_type_t* type, WireFormat wire_format) {
  assert(type);

  switch (type->type_tag) {
    case kFidlTypePrimitive:
      return PrimitiveSize(type->coded_primitive);
    case kFidlTypeEnum:
      return PrimitiveSize(type->coded_enum.underlying_type);
    case kFidlTypeBits:
      return PrimitiveSize(type->coded_bits.underlying_type);
    case kFidlTypeStructPointer:
      return 8;
    case kFidlTypeUnionPointer:
      assert(wire_format == WireFormat::kOld);
      return 8;
    case kFidlTypeVector:
    case kFidlTypeString:
      return 16;
    case kFidlTypeStruct:
      return type->coded_struct.size;
    case kFidlTypeUnion:
      assert(wire_format == WireFormat::kOld);
      return type->coded_union.size;
    case kFidlTypeArray:
      return type->coded_array.array_size;
    case kFidlTypeXUnion:
      return 24;
    case kFidlTypeHandle:
      return 4;
    case kFidlTypeTable:
      return 16;
  }

  // This is needed to suppress a GCC warning "control reaches end of non-void function", since GCC
  // treats switch() on enums as non-exhaustive without a default case.
  assert(false && "unexpected non-exhaustive switch on FidlTypeTag");
  return 0;
}

struct Position {
  uint32_t src_inline_offset = 0;
  uint32_t src_out_of_line_offset = 0;
  uint32_t dst_inline_offset = 0;
  uint32_t dst_out_of_line_offset = 0;

  Position(uint32_t src_inline_offset, uint32_t src_out_of_line_offset, uint32_t dst_inline_offset,
           uint32_t dst_out_of_line_offset)
      : src_inline_offset(src_inline_offset),
        src_out_of_line_offset(src_out_of_line_offset),
        dst_inline_offset(dst_inline_offset),
        dst_out_of_line_offset(dst_out_of_line_offset) {}

  Position(const Position&) = default;
  Position& operator=(const Position&) = default;

  inline Position IncreaseInlineOffset(uint32_t increase) const
      __attribute__((warn_unused_result)) {
    return IncreaseSrcInlineOffset(increase).IncreaseDstInlineOffset(increase);
  }

  inline Position IncreaseSrcInlineOffset(uint32_t increase) const
      __attribute__((warn_unused_result)) {
    return Position(src_inline_offset + increase, src_out_of_line_offset, dst_inline_offset,
                    dst_out_of_line_offset);
  }

  inline Position IncreaseSrcOutOfLineOffset(uint32_t increase) const
      __attribute__((warn_unused_result)) {
    return Position(src_inline_offset, src_out_of_line_offset + increase, dst_inline_offset,
                    dst_out_of_line_offset);
  }

  inline Position IncreaseDstInlineOffset(uint32_t increase) const
      __attribute__((warn_unused_result)) {
    return Position(src_inline_offset, src_out_of_line_offset, dst_inline_offset + increase,
                    dst_out_of_line_offset);
  }

  inline Position IncreaseDstOutOfLineOffset(uint32_t increase) const
      __attribute__((warn_unused_result)) {
    return Position(src_inline_offset, src_out_of_line_offset, dst_inline_offset,
                    dst_out_of_line_offset + increase);
  }

  std::string ToString() const {
    char buffer[32];

    snprintf(buffer, sizeof(buffer), "{0x%02x, 0x%02x, 0x%02x, 0x%02x}", src_inline_offset,
             src_out_of_line_offset, dst_inline_offset, dst_out_of_line_offset);
    return std::string(buffer);
  }
};

class SrcDst final {
 public:
  SrcDst(const uint8_t* src_bytes, const uint32_t src_num_bytes, uint8_t* dst_bytes,
         uint32_t dst_num_bytes_capacity)
      : src_bytes_(src_bytes),
        src_max_offset_(src_num_bytes),
        dst_bytes_(dst_bytes),
        dst_max_offset_(dst_num_bytes_capacity) {}
  SrcDst(const SrcDst&) = delete;

  // Reads |T| from |src_bytes|.
  // This may update the max src read offset if needed.
  template <typename T>
  const T* __attribute__((warn_unused_result)) Read(const Position& position) {
    return Read<T>(position, sizeof(T));
  }

  // Reads |size| bytes from |src_bytes|, but only returns a pointer to |T|
  // which may be smaller, i.e. |sizeof(T)| can be smaller than |size|.
  // This may update the max src read offset if needed.
  template <typename T>
  const T* __attribute__((warn_unused_result)) Read(const Position& position, uint32_t size) {
    assert(sizeof(T) <= size);
    const auto status = src_max_offset_.Update(position.src_inline_offset + size);
    if (status != ZX_OK) {
      return nullptr;
    }

    return reinterpret_cast<const T*>(src_bytes_ + position.src_inline_offset);
  }

  // Copies |size| bytes from |src_bytes| to |dst_bytes|.
  // This may update the max src read offset if needed.
  // This may update the max dst written offset if needed.
  zx_status_t __attribute__((warn_unused_result)) Copy(const Position& position, uint32_t size) {
    const auto src_status = src_max_offset_.Update(position.src_inline_offset + size);
    if (src_status != ZX_OK) {
      return src_status;
    }
    const auto dst_status = dst_max_offset_.Update(position.dst_inline_offset + size);
    if (dst_status != ZX_OK) {
      return dst_status;
    }

    memcpy(dst_bytes_ + position.dst_inline_offset, src_bytes_ + position.src_inline_offset, size);
    return ZX_OK;
  }

  // Pads |size| bytes in |dst_bytes|.
  // This may update the max dst written offset if needed.
  zx_status_t __attribute__((warn_unused_result)) Pad(const Position& position, uint32_t size) {
    const auto status = dst_max_offset_.Update(position.dst_inline_offset + size);
    if (status != ZX_OK) {
      return status;
    }
    memset(dst_bytes_ + position.dst_inline_offset, 0, size);
    return ZX_OK;
  }

  // Writes |value| in |dst_bytes|.
  // This may update the max dst written offset if needed.
  template <typename T>
  zx_status_t __attribute__((warn_unused_result)) Write(const Position& position, T value) {
    const auto size = static_cast<uint32_t>(sizeof(value));
    const auto status = dst_max_offset_.Update(position.dst_inline_offset + size);
    if (status != ZX_OK) {
      return status;
    }
    auto ptr = reinterpret_cast<T*>(dst_bytes_ + position.dst_inline_offset);
    *ptr = value;
    return ZX_OK;
  }

  const uint8_t* src_bytes() const { return src_bytes_; }
  uint32_t src_num_bytes() const { return src_max_offset_.capacity_; }
  uint32_t src_max_offset_read() const { return src_max_offset_.max_offset_; }

  uint8_t* dst_bytes() const { return dst_bytes_; }
  uint32_t dst_num_bytes_capacity() const { return dst_max_offset_.capacity_; }
  uint32_t dst_max_offset_written() const { return dst_max_offset_.max_offset_; }

 private:
  struct MaxOffset {
    MaxOffset(uint32_t capacity) : capacity_(capacity) {}
    const uint32_t capacity_;
    uint32_t max_offset_ = 0;

    zx_status_t __attribute__((warn_unused_result)) Update(uint32_t offset) {
      if (offset > capacity_) {
        return ZX_ERR_BAD_STATE;
      }
      if (offset > max_offset_) {
        max_offset_ = offset;
      }
      return ZX_OK;
    }
  };

  const uint8_t* src_bytes_;
  MaxOffset src_max_offset_;
  uint8_t* dst_bytes_;
  MaxOffset dst_max_offset_;
};

// Debug related information, which is set both on construction, and as we
// transform. On destruction, this object writes any collected error message
// if an |out_error_msg| is provided.
class DebugInfo final {
 public:
  DebugInfo(fidl_transformation_t transformation, const fidl_type_t* type, const SrcDst& src_dst,
            const char** out_error_msg)
      : transformation_(transformation),
        type_(type),
        src_dst_(src_dst),
        out_error_msg_(out_error_msg) {}
  DebugInfo(const DebugInfo&) = delete;

  ~DebugInfo() {
    if (has_failed_) {
      Print("ERROR");
    }
    if (out_error_msg_) {
      *out_error_msg_ = error_msg_;
    }
  }

  void RecordFailure(int line_number, const char* error_msg) {
    has_failed_ = true;
    error_msg_ = error_msg;
    line_number_ = line_number;
  }

  void RecordFailure(int line_number, const char* error_msg, const Position& position) {
    RecordFailure(line_number, error_msg);
    position_ = position;
  }

  void DebugPrint(int line_number, const char* error_msg, const Position& position) const {
    DebugInfo dup(transformation_, type_, src_dst_, nullptr);
    dup.RecordFailure(line_number, error_msg, position);
    dup.Print("INFO");
    // Avoid printing twice.
    dup.has_failed_ = false;
  }

 private:
  void Print(const std::string& failure_type) const {
    printf("=== TRANSFORMER %s ===\n", failure_type.c_str());

    char type_desc[256] = {};
    fidl_format_type_name(type_, type_desc, sizeof(type_desc));

    printf("src: " __FILE__ "\n");
    printf("direction: %s\n", direction().c_str());
    printf("transformer.cc:%d: %s\n", line_number_, error_msg_);
    printf("top level type: %s\n", type_desc);
    printf("position: %s\n", position_.ToString().c_str());

    auto print_bytes = [&](const uint8_t* buffer, uint32_t size, uint32_t out_of_line_offset) {
      for (uint32_t i = 0; i < size; i++) {
        if (i == out_of_line_offset) {
          printf("  // out-of-line\n");
        }

        if (i % 8 == 0) {
          printf("  ");
        }

        printf("0x%02x, ", buffer[i]);

        if (i % 0x10 == 0x07) {
          printf("  // 0x%02x\n", i - 7);
        } else if (i % 0x08 == 0x07) {
          printf("\n");
        }
      }
    };

    printf("uint8_t src_bytes[0x%02x] = {\n", src_dst_.src_num_bytes());
    print_bytes(src_dst_.src_bytes(), src_dst_.src_num_bytes(), position_.src_out_of_line_offset);
    printf("}\n");

    printf("uint8_t dst_bytes[0x%02x] = {  // capacity = 0x%02x\n",
           src_dst_.dst_max_offset_written(), src_dst_.dst_num_bytes_capacity());
    print_bytes(src_dst_.dst_bytes(), src_dst_.dst_max_offset_written(),
                position_.dst_out_of_line_offset);
    printf("}\n");

    printf("=== END TRANSFORMER %s ===\n", failure_type.c_str());
  }

  std::string direction() const {
    switch (transformation_) {
      case FIDL_TRANSFORMATION_NONE:
        return "none";
      case FIDL_TRANSFORMATION_V1_TO_OLD:
        return "v1 to old";
      case FIDL_TRANSFORMATION_OLD_TO_V1:
        return "old to v1";
      default:
        return "unknown";
    }
  }

  // Set on construction, and duplicated.
  const fidl_transformation_t transformation_;
  const fidl_type_t* type_;
  const SrcDst& src_dst_;

  // Set on construction, never duplicated.
  const char** out_error_msg_;

  // Set post construction, never duplicated.
  bool has_failed_ = false;
  const char* error_msg_ = nullptr;
  int line_number_ = -1;
  Position position_{0, 0, 0, 0};
};

class TransformerBase {
 public:
  TransformerBase(SrcDst* src_dst, const fidl_type_t* top_level_src_type, DebugInfo* debug_info)
      : src_dst(src_dst), debug_info_(debug_info), top_level_src_type_(top_level_src_type) {}
  virtual ~TransformerBase() = default;

  uint32_t InlineSize(const fidl_type_t* type, WireFormat wire_format, const Position& position) {
    TRANSFORMER_ASSERT(type, position);

    return UnsafeInlineSize(type, wire_format);
  }

  uint32_t AltInlineSize(const fidl_type_t* type, const Position& position) {
    TRANSFORMER_ASSERT(type, position);

    switch (type->type_tag) {
      case kFidlTypeStruct:
        return InlineSize(type->coded_struct.alt_type, To(), position);
      case kFidlTypeUnion:
        return InlineSize(type->coded_union.alt_type, To(), position);
      case kFidlTypeArray:
        return InlineSize(type->coded_array.alt_type, To(), position);
      case kFidlTypeXUnion:
        return InlineSize(type->coded_xunion.alt_type, To(), position);
      case kFidlTypePrimitive:
      case kFidlTypeEnum:
      case kFidlTypeBits:
      case kFidlTypeStructPointer:
      case kFidlTypeUnionPointer:
      case kFidlTypeVector:
      case kFidlTypeString:
      case kFidlTypeHandle:
      case kFidlTypeTable:
        return InlineSize(type, To(), position);
    }

    TRANSFORMER_ASSERT(false && "unexpected non-exhaustive switch on FidlTypeTag", position);
    return 0;
  }

  void MaybeDebugPrintTopLevelStruct(const Position& position) {
    if (sizeof(kDebugOrdinals) == 0) {
      return;
    }

    auto maybe_ordinal = src_dst->Read<uint64_t>(
        position.IncreaseSrcInlineOffset(offsetof(fidl_message_header_t, ordinal)));
    if (!maybe_ordinal) {
      return;
    }

    for (uint64_t debug_ordinal : kDebugOrdinals) {
      if (debug_ordinal != *maybe_ordinal) {
        continue;
      }

      char buffer[16];
      snprintf(buffer, sizeof(buffer), "0x%016" PRIx64, debug_ordinal);

      debug_info_->DebugPrint(__LINE__, buffer, position);
    }
  }

  zx_status_t TransformTopLevelStruct() {
    if (top_level_src_type_->type_tag != kFidlTypeStruct) {
      return TRANSFORMER_FAIL(ZX_ERR_INVALID_ARGS, (Position{0, 0, 0, 0}),
                              "only top-level structs supported");
    }

    const auto& src_coded_struct = top_level_src_type_->coded_struct;
    const auto& dst_coded_struct = src_coded_struct.alt_type->coded_struct;
    // Since this is the top-level struct, the first secondary object (i.e.
    // out-of-line offset) is exactly placed after this struct, i.e. the
    // struct's inline size.
    const auto start_position = Position(0, src_coded_struct.size, 0, dst_coded_struct.size);

    TraversalResult discarded_traversal_result;
    const zx_status_t status =
        TransformStruct(src_coded_struct, dst_coded_struct, start_position,
                        FIDL_ALIGN(dst_coded_struct.size), &discarded_traversal_result);
    MaybeDebugPrintTopLevelStruct(start_position);
    return status;
  }

 protected:
  zx_status_t Transform(const fidl_type_t* type, const Position& position, const uint32_t dst_size,
                        TraversalResult* out_traversal_result) {
    if (!type) {
      return src_dst->Copy(position, dst_size);
    }
    switch (type->type_tag) {
      case kFidlTypeHandle:
        return TransformHandle(position, dst_size, out_traversal_result);
      case kFidlTypePrimitive:
      case kFidlTypeEnum:
      case kFidlTypeBits:
        return src_dst->Copy(position, dst_size);
      case kFidlTypeStructPointer: {
        const auto& src_coded_struct = *type->coded_struct_pointer.struct_type;
        const auto& dst_coded_struct = src_coded_struct.alt_type->coded_struct;
        return TransformStructPointer(src_coded_struct, dst_coded_struct, position,
                                      out_traversal_result);
      }
      case kFidlTypeUnionPointer: {
        const auto& src_coded_union = *type->coded_union_pointer.union_type;
        const auto& dst_coded_xunion = src_coded_union.alt_type->coded_xunion;
        return TransformUnionPointerToOptionalXUnion(src_coded_union, dst_coded_xunion, position,
                                                     out_traversal_result);
      }
      case kFidlTypeStruct: {
        const auto& src_coded_struct = type->coded_struct;
        const auto& dst_coded_struct = src_coded_struct.alt_type->coded_struct;
        return TransformStruct(src_coded_struct, dst_coded_struct, position, dst_size,
                               out_traversal_result);
      }
      case kFidlTypeUnion: {
        const auto& src_coded_union = type->coded_union;
        const auto& dst_coded_union = src_coded_union.alt_type->coded_xunion;
        return TransformUnionToXUnion(src_coded_union, dst_coded_union, position, dst_size,
                                      out_traversal_result);
      }
      case kFidlTypeArray: {
        const auto convert = [](const FidlCodedArray& coded_array) {
          FidlCodedArrayNew result = {
              .element = coded_array.element,
              .element_count = coded_array.array_size / coded_array.element_size,
              .element_size = coded_array.element_size,
              .element_padding = 0,
              .alt_type = nullptr /* alt_type unused, we provide both src and dst */};
          return result;
        };
        auto src_coded_array = convert(type->coded_array);
        auto dst_coded_array = convert(type->coded_array.alt_type->coded_array);
        return TransformArray(src_coded_array, dst_coded_array, position, dst_size,
                              out_traversal_result);
      }
      case kFidlTypeString:
        return TransformString(position, out_traversal_result);
      case kFidlTypeVector: {
        const auto& src_coded_vector = type->coded_vector;
        const auto& dst_coded_vector = src_coded_vector.alt_type->coded_vector;
        return TransformVector(src_coded_vector, dst_coded_vector, position, out_traversal_result);
      }
      case kFidlTypeTable:
        return TransformTable(type->coded_table, position, out_traversal_result);
      case kFidlTypeXUnion:
        TRANSFORMER_ASSERT(type->coded_xunion.alt_type, position);

        switch (type->coded_xunion.alt_type->type_tag) {
          case kFidlTypeUnion:
            return TransformXUnionToUnion(type->coded_xunion,
                                          type->coded_xunion.alt_type->coded_union, position,
                                          dst_size, out_traversal_result);
          case kFidlTypeUnionPointer:
            return TransformOptionalXUnionToUnionPointer(
                type->coded_xunion, *type->coded_xunion.alt_type->coded_union_pointer.union_type,
                position, out_traversal_result);
          case kFidlTypeXUnion:
            // NOTE: after https://fuchsia-review.googlesource.com/c/fuchsia/+/365937,
            // the alt type of a xunion should always be a union, so this path should
            // never be exercised
            return TransformXUnion(type->coded_xunion, position, out_traversal_result);
          case kFidlTypePrimitive:
          case kFidlTypeEnum:
          case kFidlTypeBits:
          case kFidlTypeStruct:
          case kFidlTypeStructPointer:
          case kFidlTypeArray:
          case kFidlTypeString:
          case kFidlTypeHandle:
          case kFidlTypeVector:
          case kFidlTypeTable:
            TRANSFORMER_ASSERT(false && "Invalid src_xunion alt_type->type_tag", position);
            __builtin_unreachable();
        }
    }

    return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "unknown type tag");
  }

  zx_status_t TransformHandle(const Position& position, uint32_t dst_size,
                              TraversalResult* out_traversal_result) {
    auto presence = src_dst->Read<uint32_t>(position);
    if (!presence) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "handle presence missing");
    }
    switch (*presence) {
      case FIDL_HANDLE_ABSENT:
        // Ok
        break;
      case FIDL_HANDLE_PRESENT:
        out_traversal_result->handle_count++;
        break;
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "handle presence invalid");
    }
    return src_dst->Copy(position, dst_size);
  }

  zx_status_t TransformStructPointer(const FidlCodedStruct& src_coded_struct,
                                     const FidlCodedStruct& dst_coded_struct,
                                     const Position& position,
                                     TraversalResult* out_traversal_result) {
    auto presence = src_dst->Read<uint64_t>(position);
    if (!presence) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "struct pointer missing");
    }

    auto status_copy_struct_pointer = src_dst->Copy(position, sizeof(uint64_t));
    if (status_copy_struct_pointer != ZX_OK) {
      return status_copy_struct_pointer;
    }

    switch (*presence) {
      case FIDL_ALLOC_ABSENT:
        // Early exit on absent struct.
        return ZX_OK;
      case FIDL_ALLOC_PRESENT:
        // Ok
        break;
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "struct pointer invalid");
    }

    uint32_t src_aligned_size = FIDL_ALIGN(src_coded_struct.size);
    uint32_t dst_aligned_size = FIDL_ALIGN(dst_coded_struct.size);
    const auto struct_position = Position{
        position.src_out_of_line_offset,
        position.src_out_of_line_offset + src_aligned_size,
        position.dst_out_of_line_offset,
        position.dst_out_of_line_offset + dst_aligned_size,
    };

    out_traversal_result->src_out_of_line_size += src_aligned_size;
    out_traversal_result->dst_out_of_line_size += dst_aligned_size;

    return TransformStruct(src_coded_struct, dst_coded_struct, struct_position, dst_aligned_size,
                           out_traversal_result);
  }

  zx_status_t TransformStruct(const FidlCodedStruct& src_coded_struct,
                              const FidlCodedStruct& dst_coded_struct, const Position& position,
                              uint32_t dst_size, TraversalResult* out_traversal_result) {
    TRANSFORMER_ASSERT(src_coded_struct.field_count == dst_coded_struct.field_count, position);
    // Note: we cannot use dst_coded_struct.size, and must instead rely on
    // the provided dst_size since this struct could be placed in an alignment
    // context that is larger than its inherent size.

    // Copy structs without any coded fields, and done.
    if (src_coded_struct.field_count == 0) {
      return src_dst->Copy(position, dst_size);
    }

    const uint32_t src_start_of_struct = position.src_inline_offset;
    const uint32_t dst_start_of_struct = position.dst_inline_offset;

    auto current_position = position;
    for (uint32_t field_index = 0; field_index < src_coded_struct.field_count; field_index++) {
      const auto& src_field = src_coded_struct.fields[field_index];
      const auto& dst_field = dst_coded_struct.fields[field_index];

      if (!src_field.type) {
        const uint32_t dst_field_size =
            src_start_of_struct + src_field.padding_offset - current_position.src_inline_offset;
        const auto status_copy_field = src_dst->Copy(current_position, dst_field_size);
        if (status_copy_field != ZX_OK) {
          return status_copy_field;
        }
        current_position = current_position.IncreaseInlineOffset(dst_field_size);
      } else {
        // The only case where the amount we've written shouldn't match the specified offset is
        // for request/response structs, where the txn header is not specified in the coding table.
        if (current_position.src_inline_offset != src_start_of_struct + src_field.offset) {
          TRANSFORMER_ASSERT(src_field.offset == dst_field.offset, current_position);
          const auto status_copy_field = src_dst->Copy(current_position, src_field.offset);
          if (status_copy_field != ZX_OK) {
            return status_copy_field;
          }
          current_position = current_position.IncreaseInlineOffset(src_field.offset);
        }

        TRANSFORMER_ASSERT(
            current_position.src_inline_offset == src_start_of_struct + src_field.offset,
            current_position);
        TRANSFORMER_ASSERT(
            current_position.dst_inline_offset == dst_start_of_struct + dst_field.offset,
            current_position);

        // Transform field.
        uint32_t src_next_field_offset = current_position.src_inline_offset +
                                         InlineSize(src_field.type, From(), current_position);
        uint32_t dst_next_field_offset =
            current_position.dst_inline_offset + InlineSize(dst_field.type, To(), current_position);
        uint32_t dst_field_size = dst_next_field_offset - (dst_start_of_struct + dst_field.offset);

        TraversalResult field_traversal_result;
        const zx_status_t status =
            Transform(src_field.type, current_position, dst_field_size, &field_traversal_result);
        if (status != ZX_OK) {
          return status;
        }

        *out_traversal_result += field_traversal_result;

        // Update current position for next iteration.
        current_position.src_inline_offset = src_next_field_offset;
        current_position.dst_inline_offset = dst_next_field_offset;
        current_position.src_out_of_line_offset += field_traversal_result.src_out_of_line_size;
        current_position.dst_out_of_line_offset += field_traversal_result.dst_out_of_line_size;
      }

      // Pad (possibly with 0 bytes).
      const auto status_pad = src_dst->Pad(current_position, dst_field.padding);
      if (status_pad != ZX_OK) {
        return TRANSFORMER_FAIL(status_pad, current_position,
                                "unable to pad end of struct element");
      }
      current_position = current_position.IncreaseDstInlineOffset(dst_field.padding);
      current_position = current_position.IncreaseSrcInlineOffset(src_field.padding);
    }

    // Pad (possibly with 0 bytes).
    const uint32_t dst_end_of_struct = position.dst_inline_offset + dst_size;
    const auto status_pad =
        src_dst->Pad(current_position, dst_end_of_struct - current_position.dst_inline_offset);
    if (status_pad != ZX_OK) {
      return TRANSFORMER_FAIL(status_pad, current_position, "unable to pad end of struct");
    }

    return ZX_OK;
  }

  zx_status_t TransformVector(const FidlCodedVector& src_coded_vector,
                              const FidlCodedVector& dst_coded_vector, const Position& position,
                              TraversalResult* out_traversal_result) {
    const auto src_vector = src_dst->Read<fidl_vector_t>(position);
    if (!src_vector) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "vector missing");
    }

    // Copy vector header.
    const auto status_copy_vector_hdr = src_dst->Copy(position, sizeof(fidl_vector_t));
    if (status_copy_vector_hdr != ZX_OK) {
      return status_copy_vector_hdr;
    }

    const auto presence = reinterpret_cast<uint64_t>(src_vector->data);
    switch (presence) {
      case FIDL_ALLOC_ABSENT:
        // Early exit on nullable vectors.
        return ZX_OK;
      case FIDL_ALLOC_PRESENT:
        // OK
        break;
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "vector presence invalid");
    }

    const auto convert = [&](const FidlCodedVector& coded_vector) {
      FidlCodedArrayNew result = {
          .element = coded_vector.element,
          .element_count = static_cast<uint32_t>(src_vector->count),
          .element_size = coded_vector.element_size,
          .element_padding = 0,
          .alt_type = nullptr /* alt_type unused, we provide both src and dst */};
      return result;
    };
    const auto src_vector_data_as_coded_array = convert(src_coded_vector);
    const auto dst_vector_data_as_coded_array = convert(dst_coded_vector);

    // Calculate vector size. They fit in uint32_t due to automatic bounds.
    uint32_t src_vector_size =
        FIDL_ALIGN(static_cast<uint32_t>(src_vector->count * (src_coded_vector.element_size)));
    uint32_t dst_vector_size =
        FIDL_ALIGN(static_cast<uint32_t>(src_vector->count * (dst_coded_vector.element_size)));

    // Transform elements.
    auto vector_data_position = Position{
        position.src_out_of_line_offset, position.src_out_of_line_offset + src_vector_size,
        position.dst_out_of_line_offset, position.dst_out_of_line_offset + dst_vector_size};

    const zx_status_t status =
        TransformArray(src_vector_data_as_coded_array, dst_vector_data_as_coded_array,
                       vector_data_position, dst_vector_size, out_traversal_result);
    if (status != ZX_OK) {
      return status;
    }

    out_traversal_result->src_out_of_line_size += src_vector_size;
    out_traversal_result->dst_out_of_line_size += dst_vector_size;

    return ZX_OK;
  }

  zx_status_t TransformString(const Position& position, TraversalResult* out_traversal_result) {
    FidlCodedVector string_as_coded_vector = {
        .element = nullptr,
        .max_count = 0 /*unused*/,
        .element_size = 1,
        .nullable = kFidlNullability_Nullable, /* constraints are not checked, i.e. unused */
        .alt_type = nullptr /* alt_type unused, we provide both src and dst */};
    return TransformVector(string_as_coded_vector, string_as_coded_vector, position,
                           out_traversal_result);
  }

  zx_status_t TransformEnvelope(bool known_type, const fidl_type_t* type, const Position& position,
                                TraversalResult* out_traversal_result) {
    auto src_envelope = src_dst->Read<const fidl_envelope_t>(position);
    if (!src_envelope) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "envelope missing");
    }

    switch (src_envelope->presence) {
      case FIDL_ALLOC_ABSENT: {
        const auto status = src_dst->Copy(position, sizeof(fidl_envelope_t));
        if (status != ZX_OK) {
          return TRANSFORMER_FAIL(status, position, "unable to copy envelope header");
        }
        return ZX_OK;
      }
      case FIDL_ALLOC_PRESENT:
        // We write the transformed envelope after the transformation, since
        // the num_bytes may be different in the dst.
        break;
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "envelope presence invalid");
    }

    if (!known_type) {
      // When we encounter an unknown type, the best we can do is to copy the
      // envelope header (which includes the num_bytes and num_handles), and
      // copy the envelope's data. While it's possible that transformation was
      // needed, since we do not have the type, we cannot perform it.

      const auto status_copy_hdr = src_dst->Copy(position, sizeof(fidl_envelope_t));
      if (status_copy_hdr != ZX_OK) {
        return TRANSFORMER_FAIL(status_copy_hdr, position,
                                "unable to copy envelope header (unknown type)");
      }

      const auto data_position =
          Position{position.src_out_of_line_offset,
                   position.src_out_of_line_offset + src_envelope->num_bytes,
                   position.dst_out_of_line_offset,
                   position.dst_out_of_line_offset + src_envelope->num_bytes};
      const auto status_copy_data = src_dst->Copy(data_position, src_envelope->num_bytes);
      if (status_copy_data != ZX_OK) {
        return TRANSFORMER_FAIL(status_copy_data, data_position,
                                "unable to copy envelope data (unknown type)");
      }

      out_traversal_result->src_out_of_line_size += src_envelope->num_bytes;
      out_traversal_result->dst_out_of_line_size += src_envelope->num_bytes;
      out_traversal_result->handle_count += src_envelope->num_handles;

      return ZX_OK;
    }

    const uint32_t src_contents_inline_size = [&] {
      if (!type) {
        // The envelope contents are either a primitive or an array of primitives,
        // because |type| is nullptr. There's no size information
        // available for the type in the coding tables, but since the data is a
        // primitive or array of primitives, there can never be any out-of-line
        // data, so it's safe to use the envelope's num_bytes to determine the
        // content's inline size.
        return src_envelope->num_bytes;
      }

      return InlineSize(type, From(), position);
    }();

    const uint32_t dst_contents_inline_size = FIDL_ALIGN(AltInlineSize(type, position));
    Position data_position = Position{position.src_out_of_line_offset,
                                      position.src_out_of_line_offset + src_contents_inline_size,
                                      position.dst_out_of_line_offset,
                                      position.dst_out_of_line_offset + dst_contents_inline_size};
    TraversalResult contents_traversal_result;
    zx_status_t result =
        Transform(type, data_position, dst_contents_inline_size, &contents_traversal_result);
    if (result != ZX_OK) {
      return result;
    }

    const uint32_t src_contents_size =
        FIDL_ALIGN(src_contents_inline_size) + contents_traversal_result.src_out_of_line_size;
    const uint32_t dst_contents_size =
        dst_contents_inline_size + contents_traversal_result.dst_out_of_line_size;

    fidl_envelope_t dst_envelope = *src_envelope;
    dst_envelope.num_bytes = dst_contents_size;
    const auto status_write = src_dst->Write(position, dst_envelope);
    if (status_write != ZX_OK) {
      return TRANSFORMER_FAIL(status_write, position, "unable to write envelope");
    }

    out_traversal_result->src_out_of_line_size += src_contents_size;
    out_traversal_result->dst_out_of_line_size += dst_contents_size;
    out_traversal_result->handle_count += src_envelope->num_handles;

    return ZX_OK;
  }

  zx_status_t TransformXUnion(const FidlCodedXUnion& coded_xunion, const Position& position,
                              TraversalResult* out_traversal_result) {
    auto xunion = src_dst->Read<const fidl_xunion_t>(position);
    if (!xunion) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "xunion missing");
    }

    const auto status_copy_xunion_hdr = src_dst->Copy(position, sizeof(fidl_xunion_t));
    if (status_copy_xunion_hdr != ZX_OK) {
      return status_copy_xunion_hdr;
    }

    const FidlXUnionField* field = nullptr;
    for (uint32_t i = 0; i < coded_xunion.field_count; i++) {
      const FidlXUnionField* candidate_field = coded_xunion.fields + i;
      if (candidate_field->ordinal == xunion->tag) {
        field = candidate_field;
        break;
      }
    }

    const Position envelope_position = {
        position.src_inline_offset + static_cast<uint32_t>(offsetof(fidl_xunion_t, envelope)),
        position.src_out_of_line_offset,
        position.dst_inline_offset + static_cast<uint32_t>(offsetof(fidl_xunion_t, envelope)),
        position.dst_out_of_line_offset,
    };

    return TransformEnvelope(field != nullptr, field ? field->type : nullptr, envelope_position,
                             out_traversal_result);
  }

  zx_status_t TransformTable(const FidlCodedTable& coded_table, const Position& position,
                             TraversalResult* out_traversal_result) {
    auto table = src_dst->Read<const fidl_table_t>(position);
    if (!table) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "table header missing");
    }

    const auto status_copy_table_hdr = src_dst->Copy(position, sizeof(fidl_table_t));
    if (status_copy_table_hdr != ZX_OK) {
      return TRANSFORMER_FAIL(status_copy_table_hdr, position, "unable to copy table header");
    }

    const uint32_t envelopes_vector_size =
        static_cast<uint32_t>(table->envelopes.count * sizeof(fidl_envelope_t));
    out_traversal_result->src_out_of_line_size += envelopes_vector_size;
    out_traversal_result->dst_out_of_line_size += envelopes_vector_size;

    auto current_envelope_position = Position{
        position.src_out_of_line_offset,
        position.src_out_of_line_offset + envelopes_vector_size,
        position.dst_out_of_line_offset,
        position.dst_out_of_line_offset + envelopes_vector_size,
    };
    const auto max_field_index = coded_table.field_count - 1;
    for (uint32_t ordinal = 1, field_index = 0; ordinal <= table->envelopes.count; ordinal++) {
      const FidlTableField& field = coded_table.fields[field_index];

      const bool known_field = (ordinal == field.ordinal);
      if (known_field) {
        if (field_index < max_field_index)
          field_index++;
      }

      TraversalResult envelope_traversal_result;
      zx_status_t status = TransformEnvelope(known_field, known_field ? field.type : nullptr,
                                             current_envelope_position, &envelope_traversal_result);
      if (status != ZX_OK) {
        return status;
      }

      current_envelope_position.src_inline_offset += static_cast<uint32_t>(sizeof(fidl_envelope_t));
      current_envelope_position.dst_inline_offset += static_cast<uint32_t>(sizeof(fidl_envelope_t));
      current_envelope_position.src_out_of_line_offset +=
          envelope_traversal_result.src_out_of_line_size;
      current_envelope_position.dst_out_of_line_offset +=
          envelope_traversal_result.dst_out_of_line_size;

      *out_traversal_result += envelope_traversal_result;
    }

    return ZX_OK;
  }

  zx_status_t TransformArray(const FidlCodedArrayNew& src_coded_array,
                             const FidlCodedArrayNew& dst_coded_array, const Position& position,
                             uint32_t dst_array_size, TraversalResult* out_traversal_result) {
    TRANSFORMER_ASSERT(src_coded_array.element_count == dst_coded_array.element_count, position);

    // Fast path for elements without coding tables (e.g. strings).
    if (!src_coded_array.element) {
      return src_dst->Copy(position, dst_array_size);
    }

    // Slow path otherwise.
    auto current_element_position = position;
    for (uint32_t i = 0; i < src_coded_array.element_count; i++) {
      TraversalResult element_traversal_result;
      const zx_status_t status = Transform(src_coded_array.element, current_element_position,
                                           dst_coded_array.element_size, &element_traversal_result);

      if (status != ZX_OK) {
        return status;
      }

      // Pad end of an element.
      auto padding_position =
          current_element_position.IncreaseSrcInlineOffset(src_coded_array.element_size)
              .IncreaseDstInlineOffset(dst_coded_array.element_size);
      const auto status_pad = src_dst->Pad(padding_position, dst_coded_array.element_padding);
      if (status_pad != ZX_OK) {
        return TRANSFORMER_FAIL(status_pad, padding_position, "unable to pad array element");
      }

      current_element_position =
          padding_position.IncreaseSrcInlineOffset(src_coded_array.element_padding)
              .IncreaseDstInlineOffset(dst_coded_array.element_padding)
              .IncreaseSrcOutOfLineOffset(element_traversal_result.src_out_of_line_size)
              .IncreaseDstOutOfLineOffset(element_traversal_result.dst_out_of_line_size);

      *out_traversal_result += element_traversal_result;
    }

    // Pad end of elements.
    uint32_t padding =
        dst_array_size + position.dst_inline_offset - current_element_position.dst_inline_offset;
    const auto status_pad = src_dst->Pad(current_element_position, padding);
    if (status_pad != ZX_OK) {
      return TRANSFORMER_FAIL(status_pad, current_element_position, "unable to pad end of array");
    }

    return ZX_OK;
  }

  zx_status_t TransformUnionPointerToOptionalXUnion(const FidlCodedUnion& src_coded_union,
                                                    const FidlCodedXUnion& dst_coded_xunion,
                                                    const Position& position,
                                                    TraversalResult* out_traversal_result) {
    auto presence = src_dst->Read<uint64_t>(position);
    if (!presence) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union pointer missing");
    }

    switch (*presence) {
      case FIDL_ALLOC_ABSENT: {
        fidl_xunion_t absent = {};
        const auto status = src_dst->Write(position, absent);
        if (status != ZX_OK) {
          return TRANSFORMER_FAIL(status, position, "unable to write union pointer absense");
        }
        return ZX_OK;
      }
      case FIDL_ALLOC_PRESENT:
        // Ok
        break;
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union pointer invalid");
    }

    uint32_t src_aligned_size = FIDL_ALIGN(src_coded_union.size);
    const auto union_position = Position{
        position.src_out_of_line_offset,
        position.src_out_of_line_offset + src_aligned_size,
        position.dst_inline_offset,
        position.dst_out_of_line_offset,
    };

    out_traversal_result->src_out_of_line_size += src_aligned_size;
    return TransformUnionToXUnion(src_coded_union, dst_coded_xunion, union_position,
                                  0 /* unused: xunions are FIDL_ALIGNed */, out_traversal_result);
  }

  zx_status_t TransformUnionToXUnion(const FidlCodedUnion& src_coded_union,
                                     const FidlCodedXUnion& dst_coded_xunion,
                                     const Position& position, uint32_t /* unused: dst_size */,
                                     TraversalResult* out_traversal_result) {
    TRANSFORMER_ASSERT(src_coded_union.field_count == dst_coded_xunion.field_count, position);

    // Read: union tag.
    const auto union_tag_ptr =
        src_dst->Read<const fidl_union_tag_t>(position, src_coded_union.size);
    if (!union_tag_ptr) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union tag missing");
    }
    const auto union_tag = *union_tag_ptr;

    // Retrieve: union field/variant.
    if (union_tag >= src_coded_union.field_count) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "invalid union tag");
    }

    const FidlUnionField& src_field = src_coded_union.fields[union_tag];
    const FidlXUnionField& dst_field = dst_coded_xunion.fields[union_tag];

    // Write: xunion tag & envelope.
    const uint32_t dst_inline_field_size = [&] {
      if (src_field.type) {
        return AltInlineSize(src_field.type, position);
      } else {
        return src_coded_union.size - src_coded_union.data_offset - src_field.padding;
      }
    }();

    // Transform: static-union field to xunion field.
    auto field_position = Position{
        position.src_inline_offset + src_coded_union.data_offset,
        position.src_out_of_line_offset,
        position.dst_out_of_line_offset,
        position.dst_out_of_line_offset + FIDL_ALIGN(dst_inline_field_size),
    };
    TraversalResult field_traversal_result;
    zx_status_t status =
        Transform(src_field.type, field_position, dst_inline_field_size, &field_traversal_result);
    if (status != ZX_OK) {
      return status;
    }

    // Pad field (if needed).
    const uint32_t dst_field_size =
        dst_inline_field_size + field_traversal_result.dst_out_of_line_size;
    const uint32_t dst_padding = FIDL_ALIGN(dst_field_size) - dst_field_size;
    const auto status_pad_field =
        src_dst->Pad(field_position.IncreaseDstInlineOffset(dst_field_size), dst_padding);
    if (status_pad_field != ZX_OK) {
      return TRANSFORMER_FAIL(status_pad_field, field_position,
                              "unable to pad union-as-xunion variant");
    }

    // Write envelope header.
    fidl_xunion_t xunion;
    xunion.tag = dst_field.ordinal;
    xunion.envelope.num_bytes = FIDL_ALIGN(dst_field_size);
    xunion.envelope.num_handles = field_traversal_result.handle_count;
    xunion.envelope.presence = FIDL_ALLOC_PRESENT;
    const auto status_write_xunion = src_dst->Write(position, xunion);
    if (status_write_xunion != ZX_OK) {
      return TRANSFORMER_FAIL(status_write_xunion, position,
                              "unable to write union-as-xunion header");
    }

    out_traversal_result->src_out_of_line_size += field_traversal_result.src_out_of_line_size;
    out_traversal_result->dst_out_of_line_size += FIDL_ALIGN(dst_field_size);
    out_traversal_result->handle_count += field_traversal_result.handle_count;

    return ZX_OK;
  }

  zx_status_t TransformOptionalXUnionToUnionPointer(const FidlCodedXUnion& src_coded_xunion,
                                                    const FidlCodedUnion& dst_coded_union,
                                                    const Position& position,
                                                    TraversalResult* out_traversal_result) {
    auto src_xunion = src_dst->Read<const fidl_xunion_t>(position);
    if (!src_xunion) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union-as-xunion missing");
    }

    switch (src_xunion->envelope.presence) {
      case FIDL_ALLOC_ABSENT:
      case FIDL_ALLOC_PRESENT: {
        const auto status = src_dst->Write(position, src_xunion->envelope.presence);
        if (status != ZX_OK) {
          return TRANSFORMER_FAIL(status, position, "unable to write union pointer absence");
        }
        if (src_xunion->envelope.presence == FIDL_ALLOC_ABSENT) {
          return ZX_OK;
        }
        break;
      }
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position,
                                "union-as-xunion envelope presence invalid");
    }

    const uint32_t dst_aligned_size = FIDL_ALIGN(dst_coded_union.size);
    const auto union_position = Position{
        position.src_inline_offset,
        position.src_out_of_line_offset,
        position.dst_out_of_line_offset,
        position.dst_out_of_line_offset + dst_aligned_size,
    };

    out_traversal_result->dst_out_of_line_size += dst_aligned_size;

    return TransformXUnionToUnion(src_coded_xunion, dst_coded_union, union_position,
                                  FIDL_ALIGN(dst_coded_union.size), out_traversal_result);
  }

  zx_status_t TransformXUnionToUnion(const FidlCodedXUnion& src_coded_xunion,
                                     const FidlCodedUnion& dst_coded_union,
                                     const Position& position, uint32_t dst_size,
                                     TraversalResult* out_traversal_result) {
    TRANSFORMER_ASSERT(src_coded_xunion.field_count == dst_coded_union.field_count, position);

    // Read: extensible-union ordinal.
    const auto src_xunion = src_dst->Read<const fidl_xunion_t>(position);
    if (!src_xunion) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "union-as-xunion missing");
    }

    switch (src_xunion->envelope.presence) {
      case FIDL_ALLOC_PRESENT:
        // OK
        break;
      case FIDL_ALLOC_ABSENT:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position,
                                "union-as-xunion envelope is invalid FIDL_ALLOC_ABSENT");
      default:
        return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position,
                                "union-as-xunion envelope presence invalid");
    }

    // Retrieve: flexible-union field (or variant).
    bool src_field_found = false;
    uint32_t src_field_index = 0;
    const FidlXUnionField* src_field = nullptr;
    for (/* src_field_index needed after the loop */;
         src_field_index < src_coded_xunion.field_count; src_field_index++) {
      const FidlXUnionField* candidate_src_field = &src_coded_xunion.fields[src_field_index];
      if (candidate_src_field->ordinal == src_xunion->tag) {
        src_field_found = true;
        src_field = candidate_src_field;
        break;
      }
    }
    if (!src_field_found) {
      return TRANSFORMER_FAIL(ZX_ERR_BAD_STATE, position, "ordinal has no corresponding variant");
    }

    const FidlUnionField& dst_field = dst_coded_union.fields[src_field_index];

    // Write: static-union tag, and pad (if needed).
    switch (dst_coded_union.data_offset) {
      case 4: {
        const auto status = src_dst->Write(position, src_field_index);
        if (status != ZX_OK) {
          return TRANSFORMER_FAIL(status, position, "unable to write union tag");
        }
        break;
      }
      case 8: {
        const auto status = src_dst->Write(position, static_cast<uint64_t>(src_field_index));
        if (status != ZX_OK) {
          return TRANSFORMER_FAIL(status, position, "unable to write union tag");
        }
        break;
      }
      default:
        TRANSFORMER_ASSERT(false && "static-union data offset can only be 4 or 8", position);
    }

    const uint32_t src_field_inline_size = [&] {
      if (!src_field->type) {
        // src_field's type is either a primitive or an array of primitives,
        // because src_field->type is nullptr. There's no size information
        // available for the field in the coding tables, but since the data is a
        // primitive or array of primitives, there can never be any out-of-line
        // data, so it's safe to use the envelope's num_bytes to determine the
        // field's inline size.
        return src_xunion->envelope.num_bytes;
      }

      return FIDL_ALIGN(InlineSize(src_field->type, From(), position));
    }();

    // Transform: xunion field to static-union field (or variant).
    auto field_position = Position{
        position.src_out_of_line_offset,
        position.src_out_of_line_offset + src_field_inline_size,
        position.dst_inline_offset + dst_coded_union.data_offset,
        position.dst_out_of_line_offset,
    };
    uint32_t dst_field_unpadded_size =
        dst_coded_union.size - dst_coded_union.data_offset - dst_field.padding;

    zx_status_t status =
        Transform(src_field->type, field_position, dst_field_unpadded_size, out_traversal_result);
    if (status != ZX_OK) {
      return status;
    }

    // Pad after static-union data.
    auto field_padding_position = field_position.IncreaseDstInlineOffset(dst_field_unpadded_size);
    const auto dst_padding = (dst_size - dst_coded_union.size) + dst_field.padding;
    const auto status_pad_field = src_dst->Pad(field_padding_position, dst_padding);
    if (status_pad_field != ZX_OK) {
      return TRANSFORMER_FAIL(status_pad_field, field_padding_position,
                              "unable to pad union variant");
    }

    out_traversal_result->src_out_of_line_size += src_field_inline_size;
    return ZX_OK;
  }

  virtual WireFormat From() const = 0;
  virtual WireFormat To() const = 0;

  inline zx_status_t Fail(zx_status_t status, const Position& position, const int line_number,
                          const char* error_msg) {
    debug_info_->RecordFailure(line_number, error_msg, position);
    return status;
  }

  SrcDst* src_dst;
  DebugInfo* const debug_info_;

 private:
  const fidl_type_t* top_level_src_type_;
};

class V1ToOld final : public TransformerBase {
 public:
  V1ToOld(SrcDst* src_dst, const fidl_type_t* top_level_src_type, DebugInfo* debug_info)
      : TransformerBase(src_dst, top_level_src_type, debug_info) {}

  WireFormat From() const override { return WireFormat::kV1; }
  WireFormat To() const override { return WireFormat::kOld; }
};

class OldToV1 final : public TransformerBase {
 public:
  OldToV1(SrcDst* src_dst, const fidl_type_t* top_level_src_type, DebugInfo* debug_info)
      : TransformerBase(src_dst, top_level_src_type, debug_info) {}

 private:
  WireFormat From() const override { return WireFormat::kOld; }
  WireFormat To() const override { return WireFormat::kV1; }
};

}  // namespace

zx_status_t fidl_transform(fidl_transformation_t transformation, const fidl_type_t* src_type,
                           const uint8_t* src_bytes, uint32_t src_num_bytes, uint8_t* dst_bytes,
                           uint32_t dst_num_bytes_capacity, uint32_t* out_dst_num_bytes,
                           const char** out_error_msg) {
  if (!src_type || !src_bytes || !dst_bytes || !out_dst_num_bytes || !FidlIsAligned(src_bytes) ||
      !FidlIsAligned(dst_bytes)) {
    return ZX_ERR_INVALID_ARGS;
  }

  SrcDst src_dst(src_bytes, src_num_bytes, dst_bytes, dst_num_bytes_capacity);
  DebugInfo debug_info(transformation, src_type, src_dst, out_error_msg);

  const zx_status_t status = [&] {
    switch (transformation) {
      case FIDL_TRANSFORMATION_NONE: {
        const auto start = Position{
            0, UINT16_MAX, /* unused: src_out_of_line_offset */
            0, UINT16_MAX, /* unused: dst_out_of_line_offset */
        };
        return src_dst.Copy(start, src_num_bytes);
      }
      case FIDL_TRANSFORMATION_V1_TO_OLD:
        return V1ToOld(&src_dst, src_type, &debug_info).TransformTopLevelStruct();
      case FIDL_TRANSFORMATION_OLD_TO_V1:
        return OldToV1(&src_dst, src_type, &debug_info).TransformTopLevelStruct();
      default:
        debug_info.RecordFailure(__LINE__, "unsupported transformation");
        return ZX_ERR_INVALID_ARGS;
    }
  }();

  if (status != ZX_OK) {
    return status;
  }

  if (FIDL_ALIGN(src_dst.src_max_offset_read()) != src_num_bytes) {
    debug_info.RecordFailure(__LINE__, "did not read all provided bytes during transformation");
    return ZX_ERR_INVALID_ARGS;
  }

  *out_dst_num_bytes = src_dst.dst_max_offset_written();
  return ZX_OK;
}

#pragma GCC diagnostic pop  // "-Wimplicit-fallthrough"
