// Copyright 2018 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 <zircon/availability.h>

// This file is always in the GN sources list, but its contents should not be
// used for API levels other than HEAD where images2 and sysmem2 are supported.

#if __Fuchsia_API_level__ < 19
// Enable a subset of functionality. See https://fxbug.dev/42085119.
#define __ALLOW_IMAGES2_AND_SYSMEM2_TYPES_ONLY__
#endif

#include "lib/sysmem-version/sysmem-version.h"

#if defined(__ALLOW_IMAGES2_AND_SYSMEM2_TYPES_ONLY__)
#undef __ALLOW_IMAGES2_AND_SYSMEM2_TYPES_ONLY__
#endif

#include <fidl/fuchsia.images2/cpp/fidl.h>
#include <fidl/fuchsia.sysmem/cpp/fidl.h>
#include <fidl/fuchsia.sysmem2/cpp/fidl.h>
#include <inttypes.h>
#include <lib/fidl/cpp/wire/traits.h>
#include <zircon/assert.h>

#include <map>
#include <set>

#include <bind/fuchsia/amlogic/platform/sysmem/heap/cpp/bind.h>
#include <bind/fuchsia/goldfish/platform/sysmem/heap/cpp/bind.h>
#include <bind/fuchsia/sysmem/heap/cpp/bind.h>
#include <safemath/safe_math.h>

#include "log.h"

using safemath::CheckAdd;
using safemath::CheckDiv;
using safemath::CheckMul;
using safemath::CheckSub;

namespace sysmem {

#if __Fuchsia_API_level__ < 19
// Normally, this is declared by the header before use below.
fuchsia_images2::ColorSpace V2CopyFromV1ColorSpace(const fuchsia_sysmem::ColorSpace& v1);
#endif

namespace {

// Can be replaced with std::remove_cvref<> when C++20.
template <typename T>
struct RemoveCVRef : internal::TypeIdentity<std::remove_cv_t<std::remove_reference_t<T>>> {};
template <typename T>
using RemoveCVRef_t = typename RemoveCVRef<T>::type;

// The meaning of "fidl scalar" here includes flexible enums, which are actually just final classes
// with a single private scalar field after codegen, but the have an operator uint32_t() or
// operator uint64_t() (the ones we care about here) so we detect that way (at least for now).
template <typename T, typename Enable = void>
struct IsFidlScalar : std::false_type {};
template <typename T>
struct IsFidlScalar<
    T, typename std::enable_if<fidl::IsFidlType<T>::value &&
                               (std::is_arithmetic<T>::value || std::is_enum<T>::value)>::type>
    : std::true_type {};
template <typename T>
struct IsFidlScalar<T, typename std::enable_if<fidl::IsFidlType<T>::value &&
                                               (internal::HasOperatorUInt32<T>::value ||
                                                internal::HasOperatorUInt64<T>::value)>::type>
    : std::true_type {};

template <typename DstType, typename SrcType, bool allow_bigger_src, typename Enable = void>
struct IsCompatibleAssignmentFidlScalarTypes : std::false_type {};
template <typename DstType, typename SrcType, bool allow_bigger_src>
struct IsCompatibleAssignmentFidlScalarTypes<
    DstType, SrcType, allow_bigger_src,
    typename std::enable_if<
        // must be able to write to v2
        !std::is_const<typename std::remove_reference_t<DstType>>::value &&
        IsFidlScalar<RemoveCVRef_t<DstType>>::value &&
        IsFidlScalar<RemoveCVRef_t<SrcType>>::value &&
        (std::is_same<FidlUnderlyingTypeOrType_t<RemoveCVRef_t<DstType>>,
                      FidlUnderlyingTypeOrType_t<RemoveCVRef_t<SrcType>>>::value ||
         (std::is_same<RemoveCVRef_t<DstType>, uint64_t>::value &&
          std::is_same<RemoveCVRef_t<SrcType>, uint32_t>::value) ||
         (allow_bigger_src && std::is_same<RemoveCVRef_t<DstType>, uint32_t>::value &&
          std::is_same<RemoveCVRef_t<SrcType>, uint64_t>::value))>::type> : std::true_type {};
template <typename DstType, typename SrcType, bool allow_bigger_src = false>
inline constexpr bool IsCompatibleAssignmentFidlScalarTypes_v =
    IsCompatibleAssignmentFidlScalarTypes<DstType, SrcType, allow_bigger_src>::value;

// The C++ style guide discourages macros, but does not prohibit them.  To operate on a bunch of
// separate fields with different names, it's a choice among tons of error-prone repetitive
// verbosity, macros, or more abstraction than I think anyone would want.  Macros are the least-bad
// option (among those options considred so far).  Feel free to propose another option.

// This macro is needed to cut down on the noise from the exact same error check occurring every
// place we might early return a failure.
#define OK_OR_RET_ERROR(foo)    \
  do {                          \
    if (!(foo).is_ok()) {       \
      LOG(ERROR, "!is_ok()");   \
      return fpromise::error(); \
    }                           \
  } while (false)

// This macro is needed to ensure that we don't cross-wire fields as we're converting from V1 to V2
// and to cut down on the noise from the exact same code structure for most fields.  Also, this way
// we can include a static check that the type of the v2 field exactly matches the type of the v1
// field, which doesn't generate any actual code, yet needs to be repeated for each field being
// converted.
//
// This handles scalar fields, including enum fields.  It doesn't handle vector fields, tensor
// fields, struct fields, or table fields.
//
// All bool fields are set regardless of false or true.  Other scalar fields are only set if not
// equal to zero.
#define PROCESS_SCALAR_FIELD_V1(field_name)                                                \
  do {                                                                                     \
    using V2FieldType = std::remove_reference_t<decltype(v2b.field_name().value())>;       \
    /* double parens are significant here */                                               \
    using V1FieldType = std::remove_reference_t<decltype((v1.field_name()))>;              \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V2FieldType, V1FieldType>);      \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                      \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                      \
    if (std::is_same<bool, RemoveCVRef_t<V1FieldType>>::value ||                           \
        static_cast<bool>(v1.field_name())) {                                              \
      v2b.field_name().emplace(static_cast<V2FieldType>(                                   \
          static_cast<V2UnderlyingType>(static_cast<V1UnderlyingType>(v1.field_name())))); \
    }                                                                                      \
  } while (false)

#if __Fuchsia_API_level__ >= 19

#define PROCESS_WIRE_SCALAR_FIELD_V1(field_name)                                         \
  do {                                                                                   \
    using V2FieldType = std::remove_reference_t<decltype(v2b.field_name())>;             \
    /* double parens are significant here */                                             \
    using V1FieldType = std::remove_reference_t<decltype((v1.field_name))>;              \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V2FieldType, V1FieldType>);    \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                    \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                    \
    if (std::is_same<bool, RemoveCVRef_t<V1FieldType>>::value ||                         \
        static_cast<bool>(v1.field_name)) {                                              \
      /* This intentionally allows for implicit conversions for flexible enums */        \
      v2b.set_##field_name(static_cast<V2FieldType>(                                     \
          static_cast<V2UnderlyingType>(static_cast<V1UnderlyingType>(v1.field_name)))); \
    }                                                                                    \
  } while (false)

#define PROCESS_WIRE_SCALAR_FIELD_V1_WITH_ALLOCATOR(field_name)                               \
  do {                                                                                        \
    using V2FieldType = std::remove_reference_t<decltype(v2b.field_name())>;                  \
    /* double parens are significant here */                                                  \
    using V1FieldType = std::remove_reference_t<decltype((v1.field_name))>;                   \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V2FieldType, V1FieldType>);         \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                         \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                         \
    if (std::is_same<bool, RemoveCVRef_t<V1FieldType>>::value ||                              \
        static_cast<bool>(v1.field_name)) {                                                   \
      /* This intentionally allows for implicit conversions for flexible enums */             \
      v2b.set_##field_name(allocator, static_cast<V2FieldType>(static_cast<V2UnderlyingType>( \
                                          static_cast<V1UnderlyingType>(v1.field_name))));    \
    }                                                                                         \
  } while (false)

#endif  // __Fuchsia_API_level__ >= 19

#define PROCESS_SCALAR_FIELD_V2(field_name)                                                       \
  do {                                                                                            \
    using V1FieldType = std::remove_reference_t<decltype(v1.field_name())>;                       \
    using V2FieldType = std::remove_reference_t<decltype(v2.field_name().value())>;               \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V1FieldType, V2FieldType>);             \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                             \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                             \
    if (v2.field_name().has_value()) {                                                            \
      v1.field_name() = static_cast<V1FieldType>(                                                 \
          static_cast<V1UnderlyingType>(static_cast<V2UnderlyingType>(v2.field_name().value()))); \
    } else {                                                                                      \
      v1.field_name() = static_cast<V1FieldType>(0);                                              \
    }                                                                                             \
  } while (false)

#if __Fuchsia_API_level__ >= 19

#define PROCESS_SCALAR_FIELD_V2_BIGGER(field_name)                                                 \
  do {                                                                                             \
    using V1FieldType = std::remove_reference_t<decltype(v1.field_name())>;                        \
    using V2FieldType = std::remove_reference_t<decltype(v2.field_name().value())>;                \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V1FieldType, V2FieldType, true>);        \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                              \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                              \
    if (v2.field_name().has_value()) {                                                             \
      if (*v2.field_name() == std::numeric_limits<V2FieldType>::max()) {                           \
        v1.field_name() = std::numeric_limits<V1FieldType>::max();                                 \
      } else if (*v2.field_name() > std::numeric_limits<V1FieldType>::max()) {                     \
        LOG(ERROR, "V2 field value too large for V1: %s %" PRIu64, #field_name, *v2.field_name()); \
        return fpromise::error();                                                                  \
      } else {                                                                                     \
        v1.field_name() = static_cast<V1FieldType>(static_cast<V1UnderlyingType>(                  \
            static_cast<V2UnderlyingType>(v2.field_name().value())));                              \
      }                                                                                            \
    } else {                                                                                       \
      v1.field_name() = static_cast<V1FieldType>(0);                                               \
    }                                                                                              \
  } while (false)

#define PROCESS_WIRE_SCALAR_FIELD_V2(field_name)                                          \
  do {                                                                                    \
    using V1FieldType = decltype(v1.field_name);                                          \
    using V2FieldType = std::remove_reference_t<decltype(v2.field_name())>;               \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V1FieldType, V2FieldType>);     \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                     \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                     \
    if (v2.has_##field_name()) {                                                          \
      /* This intentionally allows for implicit conversions for flexible enums */         \
      v1.field_name = static_cast<V1FieldType>(                                           \
          static_cast<V1UnderlyingType>(static_cast<V2UnderlyingType>(v2.field_name()))); \
    } else {                                                                              \
      v1.field_name = static_cast<V1FieldType>(0);                                        \
    }                                                                                     \
  } while (false)

#define PROCESS_WIRE_SCALAR_FIELD_V2_BIGGER(field_name)                                           \
  do {                                                                                            \
    using V1FieldType = decltype(v1.field_name);                                                  \
    using V2FieldType = std::remove_reference_t<decltype(v2.field_name())>;                       \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<V1FieldType, V2FieldType, true>);       \
    using V1UnderlyingType = FidlUnderlyingTypeOrType_t<V1FieldType>;                             \
    using V2UnderlyingType = FidlUnderlyingTypeOrType_t<V2FieldType>;                             \
    if (v2.has_##field_name()) {                                                                  \
      if (v2.field_name() == std::numeric_limits<V2FieldType>::max()) {                           \
        v1.field_name = std::numeric_limits<V1FieldType>::max();                                  \
      } else if (v2.field_name() >                                                                \
                 std::numeric_limits<std::remove_reference_t<decltype(v1.field_name)>>::max()) {  \
        LOG(ERROR, "V2 field value too large for V1: %s %" PRIu64, #field_name, v2.field_name()); \
        return fpromise::error();                                                                 \
      } else {                                                                                    \
        /* This intentionally allows for implicit conversions for flexible enums */               \
        v1.field_name = static_cast<V1FieldType>(                                                 \
            static_cast<V1UnderlyingType>(static_cast<V2UnderlyingType>(v2.field_name())));       \
      }                                                                                           \
    } else {                                                                                      \
      v1.field_name = static_cast<V1FieldType>(0);                                                \
    }                                                                                             \
  } while (false)

#define ASSIGN_SCALAR(dst, src)                                                                    \
  do {                                                                                             \
    using DstType = typename std::remove_reference_t<decltype((dst))>;                             \
    using SrcType = typename std::remove_reference_t<decltype((src))>;                             \
    static_assert(IsCompatibleAssignmentFidlScalarTypes_v<DstType, SrcType>);                      \
    using DstUnderlyingType = FidlUnderlyingTypeOrType_t<DstType>;                                 \
    using SrcUnderlyingType = FidlUnderlyingTypeOrType_t<SrcType>;                                 \
    /* This intentionally allows for implicit conversions for flexible enums */                    \
    (dst) =                                                                                        \
        static_cast<DstType>(static_cast<DstUnderlyingType>(static_cast<SrcUnderlyingType>(src))); \
  } while (false)

// In V1, there's not any out-of-band allocation since V1 only uses flat structs, but fidl::ToWire()
// still requires an arena. For sysmem-version.h function prototypes, we don't require an arena from
// the caller since it'd be pointless for V1. UnusedArena smooths over the difference by being an
// arena for API parameter / function signature purposes when calling fidl::ToWire, but panicing if
// it's ever actually used (it isn't).
class UnusedArena : public fidl::AnyArena {
  uint8_t* Allocate(size_t item_size, size_t count,
                    void (*destructor_function)(uint8_t* data, size_t count)) override {
    ZX_PANIC("Unexpected usage of UnusedArena::Allocate()");
  }
};

template <size_t N>
fpromise::result<std::vector<fuchsia_sysmem2::Heap>> V2CopyFromV1HeapPermittedArrayNatural(
    const std::array<fuchsia_sysmem::HeapType, N>& v1a, const uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fpromise::error();
  }
  std::vector<fuchsia_sysmem2::Heap> v2a(v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    auto v2_heap_type_result = V2CopyFromV1HeapType(v1a[i]);
    if (v2_heap_type_result.is_error()) {
      // no way to correctly convert an unrecognized heap type
      return fpromise::error();
    }
    auto v2_heap_type = v2_heap_type_result.value();
    v2a[i].heap_type() = v2_heap_type;
    v2a[i].id() = 0;
  }
  return fpromise::ok(std::move(v2a));
}

template <size_t N>
fpromise::result<fidl::VectorView<fuchsia_sysmem2::wire::Heap>> V2CopyFromV1HeapPermittedArray(
    fidl::AnyArena& allocator, const fidl::Array<fuchsia_sysmem::wire::HeapType, N>& v1a,
    const uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fpromise::error();
  }
  fidl::VectorView<fuchsia_sysmem2::wire::Heap> v2a(allocator, v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    v2a[i].Allocate(allocator);
    auto v2_heap_type_result = V2CopyFromV1WireHeapType(v1a[i]);
    if (v2_heap_type_result.is_error()) {
      // no way to correctly convert an unrecognized heap type
      return fpromise::error();
    }
    auto& v2_heap_type = v2_heap_type_result.value();
    v2a[i].set_heap_type(allocator, fidl::StringView(allocator, v2_heap_type));
    v2a[i].set_id(allocator, 0);
  }
  return fpromise::ok(v2a);
}

#endif  // __Fuchsia_API_level__ >= 19

template <size_t N>
fpromise::result<std::vector<fuchsia_images2::ColorSpace>> V2CopyFromV1ColorSpaceArrayNatural(
    const std::array<fuchsia_sysmem::ColorSpace, N>& v1a, uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fpromise::error();
  }
  std::vector<fuchsia_images2::ColorSpace> v2a(v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    v2a[i] = V2CopyFromV1ColorSpace(v1a[i]);
  }
  return fpromise::ok(std::move(v2a));
}

#if __Fuchsia_API_level__ >= 19

template <size_t N>
fpromise::result<fidl::VectorView<fuchsia_images2::wire::ColorSpace>> V2CopyFromV1ColorSpaceArray(
    fidl::AnyArena& allocator, const fidl::Array<fuchsia_sysmem::wire::ColorSpace, N>& v1a,
    uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fpromise::error();
  }
  fidl::VectorView<fuchsia_images2::wire::ColorSpace> v2a(allocator, v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    v2a[i] = V2CopyFromV1ColorSpace(allocator, v1a[i]);
  }
  return fpromise::ok(v2a);
}

template <size_t N>
fpromise::result<std::vector<fuchsia_sysmem2::ImageFormatConstraints>>
V2CopyFromV1ImageFormatConstraintsArrayNatural(
    const std::array<fuchsia_sysmem::ImageFormatConstraints, N>& v1a, const uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fpromise::error();
  }
  std::vector<fuchsia_sysmem2::ImageFormatConstraints> v2a(v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    auto result = V2CopyFromV1ImageFormatConstraints(v1a[i]);
    OK_OR_RET_ERROR(result);
    v2a[i] = result.take_value();
  }
  return fpromise::ok(std::move(v2a));
}

template <size_t N>
fpromise::result<fidl::VectorView<fuchsia_sysmem2::wire::ImageFormatConstraints>>
V2CopyFromV1ImageFormatConstraintsArray(
    fidl::AnyArena& allocator,
    const fidl::Array<fuchsia_sysmem::wire::ImageFormatConstraints, N>& v1a,
    const uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fpromise::error();
  }
  fidl::VectorView<fuchsia_sysmem2::wire::ImageFormatConstraints> v2a(allocator, v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    auto result = V2CopyFromV1ImageFormatConstraints(allocator, v1a[i]);
    OK_OR_RET_ERROR(result);
    v2a[i] = result.take_value();
  }
  return fpromise::ok(v2a);
}

fpromise::result<> V2CopyFromV1BufferCollectionConstraintsMain(
    fuchsia_sysmem2::BufferCollectionConstraints* v2b_param,
    const fuchsia_sysmem::BufferCollectionConstraints& v1) {
  ZX_DEBUG_ASSERT(v2b_param);
  fuchsia_sysmem2::BufferCollectionConstraints& v2b = *v2b_param;

  // This sets usage regardless of whether the client set any usage bits within usage.  That's
  // checked later (regardless of v1 or v2 client).  If a v1 client said !has_constraints, we
  // won't call the current method and usage field will remain un-set so that
  // Constraints2.IsEmpty() overall.
  {
    auto result = V2CopyFromV1BufferUsage(v1.usage());
    OK_OR_RET_ERROR(result);
    v2b.usage() = result.take_value();
  }

  PROCESS_SCALAR_FIELD_V1(min_buffer_count_for_camping);
  PROCESS_SCALAR_FIELD_V1(min_buffer_count_for_dedicated_slack);
  PROCESS_SCALAR_FIELD_V1(min_buffer_count_for_shared_slack);
  PROCESS_SCALAR_FIELD_V1(min_buffer_count);
  PROCESS_SCALAR_FIELD_V1(max_buffer_count);
  if (v1.has_buffer_memory_constraints()) {
    auto result = V2CopyFromV1BufferMemoryConstraints(v1.buffer_memory_constraints());
    OK_OR_RET_ERROR(result);
    v2b.buffer_memory_constraints() = result.take_value();
  }
  if (v1.image_format_constraints_count()) {
    auto result = V2CopyFromV1ImageFormatConstraintsArrayNatural(
        v1.image_format_constraints(), v1.image_format_constraints_count());
    OK_OR_RET_ERROR(result);
    v2b.image_format_constraints() = result.take_value();
  }
  return fpromise::ok();
}

fpromise::result<> V2CopyFromV1BufferCollectionConstraintsMain(
    fidl::AnyArena& allocator, fuchsia_sysmem2::wire::BufferCollectionConstraints* v2b_param,
    const fuchsia_sysmem::wire::BufferCollectionConstraints& v1) {
  ZX_DEBUG_ASSERT(v2b_param);
  fuchsia_sysmem2::wire::BufferCollectionConstraints& v2b = *v2b_param;

  // This sets usage regardless of whether the client set any usage bits within usage.  That's
  // checked later (regardless of v1 or v2 client).  If a v1 client said !has_constraints, we
  // won't call the current method and usage field will remain un-set so that
  // Constraints2.IsEmpty() overall.
  {
    auto result = V2CopyFromV1BufferUsage(allocator, v1.usage);
    OK_OR_RET_ERROR(result);
    v2b.set_usage(allocator, result.take_value());
  }

  PROCESS_WIRE_SCALAR_FIELD_V1(min_buffer_count_for_camping);
  PROCESS_WIRE_SCALAR_FIELD_V1(min_buffer_count_for_dedicated_slack);
  PROCESS_WIRE_SCALAR_FIELD_V1(min_buffer_count_for_shared_slack);
  PROCESS_WIRE_SCALAR_FIELD_V1(min_buffer_count);
  PROCESS_WIRE_SCALAR_FIELD_V1(max_buffer_count);
  if (v1.has_buffer_memory_constraints) {
    auto result = V2CopyFromV1BufferMemoryConstraints(allocator, v1.buffer_memory_constraints);
    OK_OR_RET_ERROR(result);
    v2b.set_buffer_memory_constraints(allocator, result.take_value());
  }
  if (v1.image_format_constraints_count) {
    auto result = V2CopyFromV1ImageFormatConstraintsArray(allocator, v1.image_format_constraints,
                                                          v1.image_format_constraints_count);
    OK_OR_RET_ERROR(result);
    v2b.set_image_format_constraints(allocator, result.take_value());
  }
  return fpromise::ok();
}

#endif  // __Fuchsia_API_level__ >= 19

}  // namespace

fuchsia_images2::PixelFormat V2CopyFromV1PixelFormatType(
    const fuchsia_sysmem::PixelFormatType& v1) {
  return static_cast<fuchsia_images2::PixelFormat>(static_cast<uint32_t>(v1));
}

fuchsia_images2::PixelFormatModifier V2ConvertFromV1PixelFormatModifier(
    uint64_t v1_pixel_format_modifier) {
  if (v1_pixel_format_modifier == fuchsia_sysmem::kFormatModifierGoogleGoldfishOptimal) {
    return fuchsia_images2::PixelFormatModifier::kGoogleGoldfishOptimal;
  }
  return static_cast<fuchsia_images2::PixelFormatModifier>(v1_pixel_format_modifier);
}

uint64_t V1ConvertFromV2PixelFormatModifier(
    fuchsia_images2::PixelFormatModifier v2_pixel_format_modifier) {
  if (v2_pixel_format_modifier == fuchsia_images2::PixelFormatModifier::kGoogleGoldfishOptimal) {
    return fuchsia_sysmem::kFormatModifierGoogleGoldfishOptimal;
  }
  return fidl::ToUnderlying(v2_pixel_format_modifier);
}

PixelFormatAndModifier V2CopyFromV1PixelFormat(const fuchsia_sysmem::PixelFormat& v1) {
  PixelFormatAndModifier v2b;
  v2b.pixel_format = V2CopyFromV1PixelFormatType(v1.type());
  if (v1.has_format_modifier()) {
    v2b.pixel_format_modifier = V2ConvertFromV1PixelFormatModifier(v1.format_modifier().value());
  }
  return v2b;
}

#if __Fuchsia_API_level__ >= 19

PixelFormatAndModifier V2CopyFromV1PixelFormat(const fuchsia_sysmem::wire::PixelFormat& v1) {
  PixelFormatAndModifier v2b;
  v2b.pixel_format = V2CopyFromV1PixelFormatType(v1.type);
  if (v1.has_format_modifier) {
    v2b.pixel_format_modifier = V2ConvertFromV1PixelFormatModifier(v1.format_modifier.value);
  }
  return V2CopyFromV1PixelFormat(fidl::ToNatural(v1));
}

#endif  // __Fuchsia_API_level__ >= 19

fuchsia_images2::ColorSpace V2CopyFromV1ColorSpace(const fuchsia_sysmem::ColorSpace& v1) {
  return static_cast<fuchsia_images2::ColorSpace>(static_cast<uint32_t>(v1.type()));
}

#if __Fuchsia_API_level__ >= 19

fuchsia_images2::wire::ColorSpace V2CopyFromV1ColorSpace(
    const fuchsia_sysmem::wire::ColorSpace& v1) {
  return static_cast<fuchsia_images2::wire::ColorSpace>(static_cast<uint32_t>(v1.type));
}

#endif  // __Fuchsia_API_level__ >= 19

fpromise::result<fuchsia_sysmem2::ImageFormatConstraints> V2CopyFromV1ImageFormatConstraints(
    const fuchsia_sysmem::ImageFormatConstraints& v1) {
  fuchsia_sysmem2::ImageFormatConstraints v2b;

  PixelFormatAndModifier v2_pixel_format = V2CopyFromV1PixelFormat(v1.pixel_format());
  // Below, we only use stride_bytes_per_width_pixel_result.value() if the result is ok, since we
  // only need the value for some less-critical version translation fixups, and the method only
  // fails for INVALID, DO_NOT_CARE, and MJPEG, for which those fixups are not relevant.

  v2b.pixel_format() = v2_pixel_format.pixel_format;
  v2b.pixel_format_modifier() = v2_pixel_format.pixel_format_modifier;
  if (v1.color_spaces_count()) {
    auto result = V2CopyFromV1ColorSpaceArrayNatural(v1.color_space(), v1.color_spaces_count());
    OK_OR_RET_ERROR(result);
    v2b.color_spaces() = result.take_value();
  }

  if (v1.min_coded_width() != 0 || v1.min_coded_height() != 0) {
    v2b.min_size() = {v1.min_coded_width(), v1.min_coded_height()};
  }

  if (v1.max_coded_width() != 0 || v1.max_coded_height() != 0) {
    v2b.max_size() = {v1.max_coded_width(), v1.max_coded_height()};
  }

  PROCESS_SCALAR_FIELD_V1(min_bytes_per_row);
  PROCESS_SCALAR_FIELD_V1(max_bytes_per_row);

  if (v1.max_coded_width_times_coded_height() != 0) {
    v2b.max_width_times_height() = v1.max_coded_width_times_coded_height();
  }

  // v2 ImageFormatConstraints intentionally doesn't have the layers field. In practice this v1
  // field is always either 0 implying a default of 1, or 1.
  if (v1.layers()) {
    if (v1.layers() > 1) {
      LOG(ERROR, "v1.layers > 1");
      return fpromise::error();
    }
  }

  if (v1.coded_width_divisor() != 0 || v1.coded_height_divisor() != 0) {
    ZX_DEBUG_ASSERT(!v2b.size_alignment().has_value());
    v2b.size_alignment() = {1, 1};
    v2b.size_alignment()->width() =
        std::max(v2b.size_alignment()->width(), v1.coded_width_divisor());
    v2b.size_alignment()->height() =
        std::max(v2b.size_alignment()->height(), v1.coded_height_divisor());
  }

  PROCESS_SCALAR_FIELD_V1(bytes_per_row_divisor);
  PROCESS_SCALAR_FIELD_V1(start_offset_divisor);

  if (v1.display_width_divisor() != 0 || v1.display_height_divisor() != 0) {
    ZX_DEBUG_ASSERT(!v2b.display_rect_alignment().has_value());
    v2b.display_rect_alignment() = {1, 1};
    v2b.display_rect_alignment()->width() =
        std::max(v2b.display_rect_alignment()->width(), v1.display_width_divisor());
    v2b.display_rect_alignment()->height() =
        std::max(v2b.display_rect_alignment()->height(), v1.display_height_divisor());
  }

  if (v1.required_min_coded_width() != 0 || v1.required_min_coded_height() != 0) {
    if (v1.required_min_coded_width() == 0 || v1.required_min_coded_height() == 0) {
      LOG(ERROR,
          "required_min_coded_width and required_min_coded_height must both be set or both be un-set");
      return fpromise::error();
    }
    ZX_DEBUG_ASSERT(!v2b.required_min_size().has_value());
    v2b.required_min_size() = {v1.required_min_coded_width(), v1.required_min_coded_height()};
  }

  if (v1.required_max_coded_width() != 0 || v1.required_max_coded_height() != 0) {
    if (v1.required_max_coded_width() == 0 || v1.required_max_coded_height() == 0) {
      LOG(ERROR,
          "required_max_coded_width and required_max_coded_height must both be set or both be un-set");
      return fpromise::error();
    }
    ZX_DEBUG_ASSERT(!v2b.required_max_size().has_value());
    v2b.required_max_size() = {v1.required_max_coded_width(), v1.required_max_coded_height()};
  }

  return fpromise::ok(std::move(v2b));
}

#if __Fuchsia_API_level__ >= 19

fpromise::result<fuchsia_sysmem2::wire::ImageFormatConstraints> V2CopyFromV1ImageFormatConstraints(
    fidl::AnyArena& allocator, const fuchsia_sysmem::wire::ImageFormatConstraints& v1) {
  // While most of the conversion routines convert directly, this conversion is complicated enough
  // that we convert to natural, do the convert, convert back to wire.
  auto v1_natural = fidl::ToNatural(std::move(v1));
  auto v2_natural_result = V2CopyFromV1ImageFormatConstraints(std::move(v1_natural));
  if (v2_natural_result.is_error()) {
    return fpromise::error();
  }
  return fpromise::ok(fidl::ToWire(allocator, v2_natural_result.take_value()));
}

fpromise::result<fuchsia_sysmem2::BufferUsage> V2CopyFromV1BufferUsage(
    const fuchsia_sysmem::BufferUsage& v1) {
  fuchsia_sysmem2::BufferUsage v2b;
  PROCESS_SCALAR_FIELD_V1(none);
  PROCESS_SCALAR_FIELD_V1(cpu);
  PROCESS_SCALAR_FIELD_V1(vulkan);
  PROCESS_SCALAR_FIELD_V1(display);
  PROCESS_SCALAR_FIELD_V1(video);
  return fpromise::ok(std::move(v2b));
}

fpromise::result<fuchsia_sysmem2::wire::BufferUsage> V2CopyFromV1BufferUsage(
    fidl::AnyArena& allocator, const fuchsia_sysmem::wire::BufferUsage& v1) {
  fuchsia_sysmem2::wire::BufferUsage v2b(allocator);
  using foo = std::remove_reference_t<decltype((v1.none))>;
  static_assert(std::is_const<foo>::value);
  PROCESS_WIRE_SCALAR_FIELD_V1(none);
  PROCESS_WIRE_SCALAR_FIELD_V1(cpu);
  PROCESS_WIRE_SCALAR_FIELD_V1(vulkan);
  PROCESS_WIRE_SCALAR_FIELD_V1(display);
  PROCESS_WIRE_SCALAR_FIELD_V1(video);
  return fpromise::ok(v2b);
}

fpromise::result<fuchsia_sysmem2::BufferMemoryConstraints> V2CopyFromV1BufferMemoryConstraints(
    const fuchsia_sysmem::BufferMemoryConstraints& v1) {
  fuchsia_sysmem2::BufferMemoryConstraints v2b;
  PROCESS_SCALAR_FIELD_V1(min_size_bytes);
  PROCESS_SCALAR_FIELD_V1(max_size_bytes);
  PROCESS_SCALAR_FIELD_V1(physically_contiguous_required);
  PROCESS_SCALAR_FIELD_V1(secure_required);
  PROCESS_SCALAR_FIELD_V1(ram_domain_supported);
  PROCESS_SCALAR_FIELD_V1(cpu_domain_supported);
  PROCESS_SCALAR_FIELD_V1(inaccessible_domain_supported);
  if (v1.heap_permitted_count()) {
    auto result =
        V2CopyFromV1HeapPermittedArrayNatural(v1.heap_permitted(), v1.heap_permitted_count());
    OK_OR_RET_ERROR(result);
    v2b.permitted_heaps() = result.take_value();
  }
  return fpromise::ok(std::move(v2b));
}

fpromise::result<fuchsia_sysmem2::wire::BufferMemoryConstraints>
V2CopyFromV1BufferMemoryConstraints(fidl::AnyArena& allocator,
                                    const fuchsia_sysmem::wire::BufferMemoryConstraints& v1) {
  fuchsia_sysmem2::wire::BufferMemoryConstraints v2b(allocator);
  PROCESS_WIRE_SCALAR_FIELD_V1_WITH_ALLOCATOR(min_size_bytes);
  PROCESS_WIRE_SCALAR_FIELD_V1_WITH_ALLOCATOR(max_size_bytes);
  PROCESS_WIRE_SCALAR_FIELD_V1(physically_contiguous_required);
  PROCESS_WIRE_SCALAR_FIELD_V1(secure_required);
  PROCESS_WIRE_SCALAR_FIELD_V1(ram_domain_supported);
  PROCESS_WIRE_SCALAR_FIELD_V1(cpu_domain_supported);
  PROCESS_WIRE_SCALAR_FIELD_V1(inaccessible_domain_supported);
  if (v1.heap_permitted_count) {
    auto result =
        V2CopyFromV1HeapPermittedArray(allocator, v1.heap_permitted, v1.heap_permitted_count);
    OK_OR_RET_ERROR(result);
    v2b.set_permitted_heaps(allocator, result.take_value());
  }
  return fpromise::ok(v2b);
}

// If !v1, the result will be fit::is_ok(), but result.value().IsEmpty().
fpromise::result<fuchsia_sysmem2::BufferCollectionConstraints>
V2CopyFromV1BufferCollectionConstraints(const fuchsia_sysmem::BufferCollectionConstraints* v1) {
  fuchsia_sysmem2::BufferCollectionConstraints v2b;

  if (v1) {
    auto result = V2CopyFromV1BufferCollectionConstraintsMain(&v2b, *v1);
    OK_OR_RET_ERROR(result);
  }

  return fpromise::ok(std::move(v2b));
}

// If !v1, the result will be fit::is_ok(), but result.value().IsEmpty().
fpromise::result<fuchsia_sysmem2::wire::BufferCollectionConstraints>
V2CopyFromV1BufferCollectionConstraints(
    fidl::AnyArena& allocator, const fuchsia_sysmem::wire::BufferCollectionConstraints* v1) {
  fuchsia_sysmem2::wire::BufferCollectionConstraints v2b(allocator);

  if (v1) {
    auto result = V2CopyFromV1BufferCollectionConstraintsMain(allocator, &v2b, *v1);
    OK_OR_RET_ERROR(result);
  }

  return fpromise::ok(v2b);
}

#endif  // __Fuchsia_API_level__ >= 19

fpromise::result<fuchsia_images2::ImageFormat> V2CopyFromV1ImageFormat(
    const fuchsia_sysmem::ImageFormat2& v1) {
  if (v1.layers() > 1) {
    LOG(ERROR, "v1.layers > 1");
    return fpromise::error();
  }

  fuchsia_images2::ImageFormat v2b;
  PixelFormatAndModifier v2_pixel_format = V2CopyFromV1PixelFormat(v1.pixel_format());
  v2b.pixel_format() = v2_pixel_format.pixel_format;
  if (v1.pixel_format().has_format_modifier()) {
    v2b.pixel_format_modifier() = v2_pixel_format.pixel_format_modifier;
  }

  v2b.color_space() = V2CopyFromV1ColorSpace(v1.color_space());

  // V2 is more expressive in these fields, so the conversion is intentionally
  // asymmetric.
  v2b.size() = {v1.coded_width(), v1.coded_height()};
  PROCESS_SCALAR_FIELD_V1(bytes_per_row);
  v2b.display_rect() = {0, 0, v1.display_width(), v1.display_height()};

  // The coded_width and coded_height may or may not actually be the "valid" pixels from a video
  // decoder.  V2 allows us to be more precise here.  Since output from a video decoder will
  // _typically_ have size == valid_size, and because coded_width,coded_height is documented
  // to be the valid non-padding actual pixels, which can include some that are outside the
  // display_rect, we go ahead and place coded_width,coded_height in valid_size as well as in
  // size above.  The ability to be more precise here in V2 is one of the reasons to switch
  // to V2.  V1 lacks any way to specify the UV plane offset separately from the coded_height, so
  // there can be situations in which coded_height is artificially larger than the valid_size.height
  // as the only way to make the UV offset correct, which sacrifices the ability to specify the real
  // valid_size.height (in the V1 struct; in V2 it's conveyed separately).
  v2b.valid_size() = {v1.coded_width(), v1.coded_height()};

  if (v1.has_pixel_aspect_ratio()) {
    v2b.pixel_aspect_ratio() = {v1.pixel_aspect_ratio_width(), v1.pixel_aspect_ratio_height()};
  } else {
    ZX_DEBUG_ASSERT(!v2b.pixel_aspect_ratio().has_value());
  }

  return fpromise::ok(std::move(v2b));
}

#if __Fuchsia_API_level__ >= 19

fpromise::result<fuchsia_images2::wire::ImageFormat> V2CopyFromV1ImageFormat(
    fidl::AnyArena& allocator, const fuchsia_sysmem::wire::ImageFormat2& v1) {
  auto v1_natural = fidl::ToNatural(v1);
  auto v2_natural_result = V2CopyFromV1ImageFormat(v1_natural);
  if (v2_natural_result.is_error()) {
    return fpromise::error();
  }
  return fpromise::ok(fidl::ToWire(allocator, v2_natural_result.value()));
}

fuchsia_sysmem2::BufferMemorySettings V2CopyFromV1BufferMemorySettings(
    const fuchsia_sysmem::BufferMemorySettings& v1) {
  fuchsia_sysmem2::BufferMemorySettings v2b;
  PROCESS_SCALAR_FIELD_V1(size_bytes);
  PROCESS_SCALAR_FIELD_V1(is_physically_contiguous);
  PROCESS_SCALAR_FIELD_V1(is_secure);
  PROCESS_SCALAR_FIELD_V1(coherency_domain);

  auto heap_type_result = V2CopyFromV1HeapType(v1.heap());
  // BufferMemorySettings are from sysmem so must be a valid fuchsia_sysmem::HeapType.
  ZX_ASSERT(heap_type_result.is_ok());
  v2b.heap().emplace();
  v2b.heap()->heap_type() = heap_type_result.value();
  // v1 HeapType can only refer to singleton heaps
  v2b.heap()->id() = 0;

  return v2b;
}

fuchsia_sysmem2::wire::BufferMemorySettings V2CopyFromV1BufferMemorySettings(
    fidl::AnyArena& allocator, const fuchsia_sysmem::wire::BufferMemorySettings& v1) {
  fuchsia_sysmem2::wire::BufferMemorySettings v2b(allocator);
  PROCESS_WIRE_SCALAR_FIELD_V1_WITH_ALLOCATOR(size_bytes);
  PROCESS_WIRE_SCALAR_FIELD_V1(is_physically_contiguous);
  PROCESS_WIRE_SCALAR_FIELD_V1(is_secure);
  PROCESS_WIRE_SCALAR_FIELD_V1(coherency_domain);

  auto heap_type_result = V2CopyFromV1WireHeapType(v1.heap);
  // BufferMemorySettings are from sysmem so must be a valid fuchsia_sysmem::HeapType.
  ZX_ASSERT(heap_type_result.is_ok());
  fuchsia_sysmem2::wire::Heap v2_heap(allocator);
  v2_heap.set_heap_type(allocator, fidl::StringView(allocator, heap_type_result.value()));
  v2_heap.set_id(allocator, 0);
  v2b.set_heap(allocator, std::move(v2_heap));

  return v2b;
}

fpromise::result<fuchsia_sysmem2::SingleBufferSettings> V2CopyFromV1SingleBufferSettings(
    const fuchsia_sysmem::SingleBufferSettings& v1) {
  fuchsia_sysmem2::SingleBufferSettings v2b;
  v2b.buffer_settings() = V2CopyFromV1BufferMemorySettings(v1.buffer_settings());
  if (v1.has_image_format_constraints()) {
    auto image_format_constraints_result =
        V2CopyFromV1ImageFormatConstraints(v1.image_format_constraints());
    if (!image_format_constraints_result.is_ok()) {
      LOG(ERROR, "!image_format_constraints_result.is_ok()");
      return fpromise::error();
    }
    v2b.image_format_constraints() = image_format_constraints_result.take_value();
  }
  return fpromise::ok(std::move(v2b));
}

fpromise::result<fuchsia_sysmem2::wire::SingleBufferSettings> V2CopyFromV1SingleBufferSettings(
    fidl::AnyArena& allocator, const fuchsia_sysmem::wire::SingleBufferSettings& v1) {
  fuchsia_sysmem2::wire::SingleBufferSettings v2b(allocator);
  v2b.set_buffer_settings(allocator,
                          V2CopyFromV1BufferMemorySettings(allocator, v1.buffer_settings));
  if (v1.has_image_format_constraints) {
    auto image_format_constraints_result =
        V2CopyFromV1ImageFormatConstraints(allocator, v1.image_format_constraints);
    if (!image_format_constraints_result.is_ok()) {
      LOG(ERROR, "!image_format_constraints_result.is_ok()");
      return fpromise::error();
    }
    v2b.set_image_format_constraints(allocator, image_format_constraints_result.take_value());
  }
  return fpromise::ok(v2b);
}

fuchsia_sysmem2::VmoBuffer V2MoveFromV1VmoBuffer(fuchsia_sysmem::VmoBuffer v1) {
  fuchsia_sysmem2::VmoBuffer v2b;
  if (v1.vmo().is_valid()) {
    v2b.vmo() = std::move(v1.vmo());
  }
  PROCESS_SCALAR_FIELD_V1(vmo_usable_start);
  return v2b;
}

fuchsia_sysmem2::wire::VmoBuffer V2MoveFromV1VmoBuffer(fidl::AnyArena& allocator,
                                                       fuchsia_sysmem::wire::VmoBuffer v1) {
  fuchsia_sysmem2::wire::VmoBuffer v2b(allocator);
  if (v1.vmo) {
    v2b.set_vmo(std::move(v1.vmo));
  }
  PROCESS_WIRE_SCALAR_FIELD_V1_WITH_ALLOCATOR(vmo_usable_start);
  return v2b;
}

fpromise::result<fuchsia_sysmem2::BufferCollectionInfo> V2MoveFromV1BufferCollectionInfo(
    fuchsia_sysmem::BufferCollectionInfo2 v1) {
  fuchsia_sysmem2::BufferCollectionInfo v2b;
  auto settings_result = V2CopyFromV1SingleBufferSettings(v1.settings());
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fpromise::error();
  }
  v2b.settings() = settings_result.take_value();
  if (v1.buffer_count()) {
    v2b.buffers().emplace(v1.buffer_count());
    for (uint32_t i = 0; i < v1.buffer_count(); ++i) {
      v2b.buffers()->at(i) = V2MoveFromV1VmoBuffer(std::move(v1.buffers()[i]));
    }
  }
  return fpromise::ok(std::move(v2b));
}

fpromise::result<fuchsia_sysmem2::wire::BufferCollectionInfo> V2MoveFromV1BufferCollectionInfo(
    fidl::AnyArena& allocator, fuchsia_sysmem::wire::BufferCollectionInfo2 v1) {
  fuchsia_sysmem2::wire::BufferCollectionInfo v2b(allocator);
  auto settings_result = V2CopyFromV1SingleBufferSettings(allocator, v1.settings);
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fpromise::error();
  }
  v2b.set_settings(allocator, settings_result.take_value());
  if (v1.buffer_count) {
    v2b.set_buffers(allocator, allocator, v1.buffer_count);
    for (uint32_t i = 0; i < v1.buffer_count; ++i) {
      v2b.buffers()[i] = V2MoveFromV1VmoBuffer(allocator, std::move(v1.buffers[i]));
    }
  }
  return fpromise::ok(v2b);
}

fpromise::result<fuchsia_sysmem::HeapType> V1CopyFromV2HeapType(const std::string& heap_type) {
  const static std::unordered_map<std::string, fuchsia_sysmem::HeapType> kTable = {
      {bind_fuchsia_sysmem_heap::HEAP_TYPE_SYSTEM_RAM, fuchsia_sysmem::HeapType::kSystemRam},
      {bind_fuchsia_amlogic_platform_sysmem_heap::HEAP_TYPE_SECURE,
       fuchsia_sysmem::HeapType::kAmlogicSecure},
      {bind_fuchsia_amlogic_platform_sysmem_heap::HEAP_TYPE_SECURE_VDEC,
       fuchsia_sysmem::HeapType::kAmlogicSecureVdec},
      {bind_fuchsia_goldfish_platform_sysmem_heap::HEAP_TYPE_DEVICE_LOCAL,
       fuchsia_sysmem::HeapType::kGoldfishDeviceLocal},
      {bind_fuchsia_goldfish_platform_sysmem_heap::HEAP_TYPE_HOST_VISIBLE,
       fuchsia_sysmem::HeapType::kGoldfishHostVisible},
      {bind_fuchsia_sysmem_heap::HEAP_TYPE_FRAMEBUFFER, fuchsia_sysmem::HeapType::kFramebuffer},
  };
  auto iter = kTable.find(heap_type);
  if (iter == kTable.end()) {
    return fpromise::error();
  }
  return fpromise::ok(iter->second);
}

fpromise::result<fuchsia_sysmem::wire::HeapType> V1WireCopyFromV2HeapType(
    const std::string& heap_type) {
  auto result = V1CopyFromV2HeapType(heap_type);
  if (result.is_error()) {
    return result.take_error_result();
  }
  auto v1_wire_heap_type = static_cast<fuchsia_sysmem::wire::HeapType>(result.value());
  return fpromise::ok(v1_wire_heap_type);
}

fpromise::result<std::string> V2CopyFromV1HeapType(fuchsia_sysmem::HeapType heap_type) {
  const static std::unordered_map<fuchsia_sysmem::HeapType, std::string> kTable = {
      {fuchsia_sysmem::HeapType::kSystemRam, bind_fuchsia_sysmem_heap::HEAP_TYPE_SYSTEM_RAM},
      {fuchsia_sysmem::HeapType::kAmlogicSecure,
       bind_fuchsia_amlogic_platform_sysmem_heap::HEAP_TYPE_SECURE},
      {fuchsia_sysmem::HeapType::kAmlogicSecureVdec,
       bind_fuchsia_amlogic_platform_sysmem_heap::HEAP_TYPE_SECURE_VDEC},
      {fuchsia_sysmem::HeapType::kGoldfishDeviceLocal,
       bind_fuchsia_goldfish_platform_sysmem_heap::HEAP_TYPE_DEVICE_LOCAL},
      {fuchsia_sysmem::HeapType::kGoldfishHostVisible,
       bind_fuchsia_goldfish_platform_sysmem_heap::HEAP_TYPE_HOST_VISIBLE},
      {fuchsia_sysmem::HeapType::kFramebuffer, bind_fuchsia_sysmem_heap::HEAP_TYPE_FRAMEBUFFER},
  };
  auto iter = kTable.find(heap_type);
  if (iter == kTable.end()) {
    return fpromise::error();
  }
  return fpromise::ok(iter->second);
}

fpromise::result<std::string> V2CopyFromV1WireHeapType(fuchsia_sysmem::wire::HeapType heap_type) {
  auto v1_natural_heap_type = static_cast<fuchsia_sysmem::HeapType>(heap_type);
  auto result = V2CopyFromV1HeapType(v1_natural_heap_type);
  if (result.is_error()) {
    return result.take_error_result();
  }
  return result.take_ok_result();
}

fpromise::result<std::optional<fuchsia_sysmem::BufferCollectionConstraints>>
V1CopyFromV2BufferCollectionConstraints(const fuchsia_sysmem2::BufferCollectionConstraints& v2) {
  fuchsia_sysmem::BufferCollectionConstraints v1;
  if (v2.IsEmpty()) {
    return fpromise::ok(std::optional<fuchsia_sysmem::BufferCollectionConstraints>());
  }
  if (v2.usage().has_value()) {
    v1.usage() = V1CopyFromV2BufferUsage(v2.usage().value());
  }
  PROCESS_SCALAR_FIELD_V2(min_buffer_count_for_camping);
  PROCESS_SCALAR_FIELD_V2(min_buffer_count_for_dedicated_slack);
  PROCESS_SCALAR_FIELD_V2(min_buffer_count_for_shared_slack);
  PROCESS_SCALAR_FIELD_V2(min_buffer_count);
  PROCESS_SCALAR_FIELD_V2(max_buffer_count);
  ZX_DEBUG_ASSERT(!v1.has_buffer_memory_constraints());
  if (v2.buffer_memory_constraints().has_value()) {
    v1.has_buffer_memory_constraints() = true;
    auto buffer_memory_constraints_result =
        V1CopyFromV2BufferMemoryConstraints(v2.buffer_memory_constraints().value());
    if (!buffer_memory_constraints_result.is_ok()) {
      LOG(ERROR, "!buffer_memory_constraints_result.is_ok()");
      return fpromise::error();
    }
    v1.buffer_memory_constraints() = buffer_memory_constraints_result.take_value();
  }
  ZX_DEBUG_ASSERT(!v1.image_format_constraints_count());
  if (v2.image_format_constraints().has_value()) {
    if (v2.image_format_constraints()->size() >
        fuchsia_sysmem::wire::kMaxCountBufferCollectionConstraintsImageFormatConstraints) {
      LOG(ERROR,
          "v2 image_format_constraints count > v1 "
          "MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS");
      return fpromise::error();
    }
    v1.image_format_constraints_count() =
        static_cast<uint32_t>(v2.image_format_constraints()->size());
    for (uint32_t i = 0; i < v2.image_format_constraints()->size(); ++i) {
      auto image_format_constraints_result =
          V1CopyFromV2ImageFormatConstraints(v2.image_format_constraints()->at(i));
      if (!image_format_constraints_result.is_ok()) {
        LOG(ERROR, "!image_format_constraints_result.is_ok()");
        return fpromise::error();
      }
      v1.image_format_constraints()[i] = image_format_constraints_result.take_value();
    }
  }

  return fpromise::ok(std::move(v1));
}

fpromise::result<std::optional<fuchsia_sysmem::wire::BufferCollectionConstraints>>
V1CopyFromV2BufferCollectionConstraints(
    const fuchsia_sysmem2::wire::BufferCollectionConstraints& v2) {
  fuchsia_sysmem::wire::BufferCollectionConstraints v1{};
  if (v2.IsEmpty()) {
    return fpromise::ok(std::optional<fuchsia_sysmem::wire::BufferCollectionConstraints>());
  }
  if (v2.has_usage()) {
    v1.usage = V1CopyFromV2BufferUsage(v2.usage());
  }
  PROCESS_WIRE_SCALAR_FIELD_V2(min_buffer_count_for_camping);
  PROCESS_WIRE_SCALAR_FIELD_V2(min_buffer_count_for_dedicated_slack);
  PROCESS_WIRE_SCALAR_FIELD_V2(min_buffer_count_for_shared_slack);
  PROCESS_WIRE_SCALAR_FIELD_V2(min_buffer_count);
  PROCESS_WIRE_SCALAR_FIELD_V2(max_buffer_count);
  ZX_DEBUG_ASSERT(!v1.has_buffer_memory_constraints);
  if (v2.has_buffer_memory_constraints()) {
    v1.has_buffer_memory_constraints = true;
    auto buffer_memory_constraints_result =
        V1CopyFromV2BufferMemoryConstraints(v2.buffer_memory_constraints());
    if (!buffer_memory_constraints_result.is_ok()) {
      LOG(ERROR, "!buffer_memory_constraints_result.is_ok()");
      return fpromise::error();
    }
    v1.buffer_memory_constraints = buffer_memory_constraints_result.take_value();
  }
  ZX_DEBUG_ASSERT(!v1.image_format_constraints_count);
  if (v2.has_image_format_constraints()) {
    if (v2.image_format_constraints().count() >
        fuchsia_sysmem::wire::kMaxCountBufferCollectionConstraintsImageFormatConstraints) {
      LOG(ERROR,
          "v2 image_format_constraints count > v1 "
          "MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS");
      return fpromise::error();
    }
    v1.image_format_constraints_count =
        static_cast<uint32_t>(v2.image_format_constraints().count());
    for (uint32_t i = 0; i < v2.image_format_constraints().count(); ++i) {
      auto image_format_constraints_result =
          V1CopyFromV2ImageFormatConstraints(v2.image_format_constraints()[i]);
      if (!image_format_constraints_result.is_ok()) {
        LOG(ERROR, "!image_format_constraints_result.is_ok()");
        return fpromise::error();
      }
      v1.image_format_constraints[i] = image_format_constraints_result.take_value();
    }
  }

  return fpromise::ok(v1);
}

fpromise::result<fuchsia_sysmem::BufferMemoryConstraints> V1CopyFromV2BufferMemoryConstraints(
    const fuchsia_sysmem2::BufferMemoryConstraints& v2) {
  fuchsia_sysmem::BufferMemoryConstraints v1;
  PROCESS_SCALAR_FIELD_V2_BIGGER(min_size_bytes);
  PROCESS_SCALAR_FIELD_V2_BIGGER(max_size_bytes);
  PROCESS_SCALAR_FIELD_V2(physically_contiguous_required);
  PROCESS_SCALAR_FIELD_V2(secure_required);
  PROCESS_SCALAR_FIELD_V2(ram_domain_supported);
  PROCESS_SCALAR_FIELD_V2(cpu_domain_supported);
  PROCESS_SCALAR_FIELD_V2(inaccessible_domain_supported);
  ZX_DEBUG_ASSERT(!v1.heap_permitted_count());
  if (v2.permitted_heaps().has_value()) {
    if (v2.permitted_heaps()->size() >
        fuchsia_sysmem::wire::kMaxCountBufferMemoryConstraintsHeapPermitted) {
      LOG(ERROR,
          "v2 permitted_heaps count > v1 MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED");
      return fpromise::error();
    }
    v1.heap_permitted_count() = static_cast<uint32_t>(v2.permitted_heaps()->size());
    for (uint32_t i = 0; i < v2.permitted_heaps()->size(); ++i) {
      if (!v2.permitted_heaps()->at(i).heap_type().has_value()) {
        LOG(ERROR, "v2 heap_type not set");
        return fpromise::error();
      }
      if (v2.permitted_heaps()->at(i).id().has_value() &&
          v2.permitted_heaps()->at(i).id().value() != 0) {
        LOG(ERROR, "v2 heap id != 0 can't convert to v1");
        return fpromise::error();
      }
      auto v1_heap_type_result =
          V1CopyFromV2HeapType(v2.permitted_heaps()->at(i).heap_type().value());
      if (v1_heap_type_result.is_error()) {
        LOG(ERROR, "v2 heap_type failed conversion to v1: %s",
            v2.permitted_heaps()->at(i).heap_type().value().c_str());
        return fpromise::error();
      }
      v1.heap_permitted()[i] = v1_heap_type_result.value();
    }
  }
  return fpromise::ok(std::move(v1));
}

fpromise::result<fuchsia_sysmem::wire::BufferMemoryConstraints> V1CopyFromV2BufferMemoryConstraints(
    const fuchsia_sysmem2::wire::BufferMemoryConstraints& v2) {
  fuchsia_sysmem::wire::BufferMemoryConstraints v1{};
  PROCESS_WIRE_SCALAR_FIELD_V2_BIGGER(min_size_bytes);
  PROCESS_WIRE_SCALAR_FIELD_V2_BIGGER(max_size_bytes);
  PROCESS_WIRE_SCALAR_FIELD_V2(physically_contiguous_required);
  PROCESS_WIRE_SCALAR_FIELD_V2(secure_required);
  PROCESS_WIRE_SCALAR_FIELD_V2(ram_domain_supported);
  PROCESS_WIRE_SCALAR_FIELD_V2(cpu_domain_supported);
  PROCESS_WIRE_SCALAR_FIELD_V2(inaccessible_domain_supported);
  ZX_DEBUG_ASSERT(!v1.heap_permitted_count);
  if (v2.has_permitted_heaps()) {
    if (v2.permitted_heaps().count() >
        fuchsia_sysmem::wire::kMaxCountBufferMemoryConstraintsHeapPermitted) {
      LOG(ERROR,
          "v2 permitted_heaps count > v1 MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED");
      return fpromise::error();
    }
    v1.heap_permitted_count = static_cast<uint32_t>(v2.permitted_heaps().count());
    for (uint32_t i = 0; i < v2.permitted_heaps().count(); ++i) {
      if (!v2.permitted_heaps().at(i).has_heap_type()) {
        LOG(ERROR, "v2 heap_type not set");
        return fpromise::error();
      }
      if (v2.permitted_heaps().at(i).has_id() && v2.permitted_heaps().at(i).id() != 0) {
        LOG(ERROR, "v2 heap id != 0 can't convert to v1");
        return fpromise::error();
      }
      auto v2_heap_type = std::string(v2.permitted_heaps().at(i).heap_type().data(),
                                      v2.permitted_heaps().at(i).heap_type().size());
      auto v1_heap_type_result = V1CopyFromV2HeapType(v2_heap_type);
      if (v1_heap_type_result.is_error()) {
        LOG(ERROR, "v2 heap_type failed conversion to v1: %s", v2_heap_type.c_str());
        return fpromise::error();
      }
      v1.heap_permitted[i] = v1_heap_type_result.value();
    }
  }
  return fpromise::ok(v1);
}

fuchsia_sysmem::BufferUsage V1CopyFromV2BufferUsage(const fuchsia_sysmem2::BufferUsage& v2) {
  fuchsia_sysmem::BufferUsage v1;
  PROCESS_SCALAR_FIELD_V2(none);
  PROCESS_SCALAR_FIELD_V2(cpu);
  PROCESS_SCALAR_FIELD_V2(vulkan);
  PROCESS_SCALAR_FIELD_V2(display);
  PROCESS_SCALAR_FIELD_V2(video);
  return v1;
}

fuchsia_sysmem::wire::BufferUsage V1CopyFromV2BufferUsage(
    const fuchsia_sysmem2::wire::BufferUsage& v2) {
  fuchsia_sysmem::wire::BufferUsage v1{};
  PROCESS_WIRE_SCALAR_FIELD_V2(none);
  PROCESS_WIRE_SCALAR_FIELD_V2(cpu);
  PROCESS_WIRE_SCALAR_FIELD_V2(vulkan);
  PROCESS_WIRE_SCALAR_FIELD_V2(display);
  PROCESS_WIRE_SCALAR_FIELD_V2(video);
  return v1;
}

// v2 must have all fields set.
fpromise::result<fuchsia_sysmem::BufferMemorySettings> V1CopyFromV2BufferMemorySettings(
    const fuchsia_sysmem2::BufferMemorySettings& v2) {
  fuchsia_sysmem::BufferMemorySettings v1;
  PROCESS_SCALAR_FIELD_V2_BIGGER(size_bytes);
  PROCESS_SCALAR_FIELD_V2(is_physically_contiguous);
  PROCESS_SCALAR_FIELD_V2(is_secure);
  PROCESS_SCALAR_FIELD_V2(coherency_domain);

  if (!v2.heap().has_value()) {
    return fpromise::error();
  }
  if (!v2.heap()->heap_type().has_value()) {
    return fpromise::error();
  }
  if (!v2.heap()->id().has_value()) {
    return fpromise::error();
  }
  if (*v2.heap()->id() != 0) {
    // sysmem(1) doesn't have heap id so can't represent this
    return fpromise::error();
  }
  auto heap_type_result = V1CopyFromV2HeapType(*v2.heap()->heap_type());
  if (heap_type_result.is_error()) {
    return heap_type_result.take_error_result();
  }
  v1.heap() = heap_type_result.value();

  return fpromise::ok(v1);
}

// v2 must have all fields set.
fpromise::result<fuchsia_sysmem::wire::BufferMemorySettings> V1CopyFromV2BufferMemorySettings(
    const fuchsia_sysmem2::wire::BufferMemorySettings& v2) {
  fuchsia_sysmem::wire::BufferMemorySettings v1{};
  PROCESS_WIRE_SCALAR_FIELD_V2_BIGGER(size_bytes);
  PROCESS_WIRE_SCALAR_FIELD_V2(is_physically_contiguous);
  PROCESS_WIRE_SCALAR_FIELD_V2(is_secure);
  PROCESS_WIRE_SCALAR_FIELD_V2(coherency_domain);

  if (!v2.has_heap()) {
    return fpromise::error();
  }
  if (!v2.heap().has_heap_type()) {
    return fpromise::error();
  }
  if (!v2.heap().has_id()) {
    return fpromise::error();
  }
  if (v2.heap().id() != 0) {
    // sysmem(1) doesn't have heap id so can't represent this
    return fpromise::error();
  }
  auto v2_heap_type = std::string(v2.heap().heap_type().data(), v2.heap().heap_type().size());
  auto heap_type_result = V1CopyFromV2HeapType(v2_heap_type);
  if (heap_type_result.is_error()) {
    return heap_type_result.take_error_result();
  }
  v1.heap = heap_type_result.value();

  return fpromise::ok(v1);
}

#endif  // __Fuchsia_API_level__ >= 19

fuchsia_sysmem::PixelFormatType V1CopyFromV2PixelFormatType(
    const fuchsia_images2::PixelFormat& v2) {
  return static_cast<fuchsia_sysmem::PixelFormatType>(static_cast<uint32_t>(v2));
}

fuchsia_sysmem::PixelFormat V1CopyFromV2PixelFormat(const PixelFormatAndModifier& v2) {
  fuchsia_sysmem::PixelFormat v1;
  v1.type() = V1CopyFromV2PixelFormatType(v2.pixel_format);
  v1.has_format_modifier() = true;
  v1.format_modifier().value() = V1ConvertFromV2PixelFormatModifier(v2.pixel_format_modifier);
  return v1;
}

#if __Fuchsia_API_level__ >= 19
fuchsia_sysmem::wire::PixelFormat V1WireCopyFromV2PixelFormat(const PixelFormatAndModifier& v2) {
  fuchsia_sysmem::wire::PixelFormat v1;
  v1.type = V1CopyFromV2PixelFormatType(v2.pixel_format);
  v1.has_format_modifier = true;
  v1.format_modifier.value = V1ConvertFromV2PixelFormatModifier(v2.pixel_format_modifier);
  return v1;
}
#endif  // __Fuchsia_API_level__ >= 19

fuchsia_sysmem::ColorSpace V1CopyFromV2ColorSpace(const fuchsia_images2::ColorSpace& v2) {
  fuchsia_sysmem::ColorSpace v1;
  v1.type() = static_cast<fuchsia_sysmem::ColorSpaceType>(static_cast<uint32_t>(v2));
  return v1;
}

#if __Fuchsia_API_level__ >= 19
fuchsia_sysmem::wire::ColorSpace V1WireCopyFromV2ColorSpace(
    const fuchsia_images2::wire::ColorSpace& v2) {
  fuchsia_sysmem::wire::ColorSpace v1;
  v1.type = static_cast<fuchsia_sysmem::wire::ColorSpaceType>(static_cast<uint32_t>(v2));
  return v1;
}

fpromise::result<fuchsia_sysmem::ImageFormatConstraints> V1CopyFromV2ImageFormatConstraints(
    const fuchsia_sysmem2::ImageFormatConstraints& v2) {
  fuchsia_sysmem::ImageFormatConstraints v1;

  if (!v2.pixel_format().has_value()) {
    LOG(ERROR, "!v2.pixel_format().has_value()");
    return fpromise::error();
  }
  auto v2_pixel_format = PixelFormatAndModifierFromConstraints(v2);
  v1.pixel_format() = V1CopyFromV2PixelFormat(v2_pixel_format);

  ZX_DEBUG_ASSERT(!v1.color_spaces_count());
  if (v2.color_spaces().has_value()) {
    if (v2.color_spaces()->size() >
        fuchsia_sysmem::wire::kMaxCountImageFormatConstraintsColorSpaces) {
      LOG(ERROR,
          "v2.color_spaces().count() > "
          "fuchsia_sysmem::wire::kMaxCountImageFormatConstraintsColorSpaces");
      return fpromise::error();
    }
    v1.color_spaces_count() = static_cast<uint32_t>(v2.color_spaces()->size());
    for (uint32_t i = 0; i < v2.color_spaces()->size(); ++i) {
      v1.color_space()[i] = V1CopyFromV2ColorSpace(v2.color_spaces()->at(i));
    }
  }

  if (v2.min_size().has_value()) {
    v1.min_coded_width() = v2.min_size()->width();
    v1.min_coded_height() = v2.min_size()->height();
  }
  if (v2.max_size().has_value()) {
    v1.max_coded_width() = v2.max_size()->width();
    v1.max_coded_height() = v2.max_size()->height();
  }

  PROCESS_SCALAR_FIELD_V2(min_bytes_per_row);
  PROCESS_SCALAR_FIELD_V2(max_bytes_per_row);

  if (v2.max_width_times_height().has_value()) {
    using V1Type = std::remove_reference_t<decltype(v1.max_coded_width_times_coded_height())>;
    using V2Type = std::remove_reference_t<decltype(*v2.max_width_times_height())>;
    if (*v2.max_width_times_height() == std::numeric_limits<V2Type>::max()) {
      v1.max_coded_width_times_coded_height() = std::numeric_limits<V1Type>::max();
    } else if (*v2.max_width_times_height() > std::numeric_limits<V1Type>::max()) {
      LOG(ERROR, "max_width_times_height too large for v1");
      return fpromise::error();
    }
    v1.max_coded_width_times_coded_height() = static_cast<V1Type>(*v2.max_width_times_height());
  }
  v1.layers() = 1;

  if (v2.size_alignment().has_value()) {
    v1.coded_width_divisor() = v2.size_alignment()->width();
    v1.coded_height_divisor() = v2.size_alignment()->height();
  }

  PROCESS_SCALAR_FIELD_V2(bytes_per_row_divisor);
  PROCESS_SCALAR_FIELD_V2(start_offset_divisor);

  if (v2.display_rect_alignment().has_value()) {
    v1.display_width_divisor() = v2.display_rect_alignment()->width();
    v1.display_height_divisor() = v2.display_rect_alignment()->height();
  }

  if (v2.required_min_size().has_value()) {
    v1.required_min_coded_width() = v2.required_min_size()->width();
    v1.required_min_coded_height() = v2.required_min_size()->height();
  }

  if (v2.required_max_size().has_value()) {
    v1.required_max_coded_width() = v2.required_max_size()->width();
    v1.required_max_coded_height() = v2.required_max_size()->height();
  }

  // V2 doesn't have these fields.  A similar constraint, though not exactly the same, can be
  // achieved with required_min_size.width, required_max_size.width.
  v1.required_min_bytes_per_row() = 0;
  v1.required_max_bytes_per_row() = 0;

  return fpromise::ok(std::move(v1));
}

fpromise::result<fuchsia_sysmem::wire::ImageFormatConstraints> V1CopyFromV2ImageFormatConstraints(
    const fuchsia_sysmem2::wire::ImageFormatConstraints& v2) {
  auto v2_natural = fidl::ToNatural(v2);
  auto v1_result = V1CopyFromV2ImageFormatConstraints(v2_natural);
  if (v1_result.is_error()) {
    return fpromise::error();
  }
  UnusedArena unused_arena;
  auto v1_wire = fidl::ToWire(unused_arena, v1_result.take_value());
  return fpromise::ok(std::move(v1_wire));
}

#endif  // __Fuchsia_API_level__ >= 19

fpromise::result<fuchsia_sysmem::ImageFormat2> V1CopyFromV2ImageFormat(
    fuchsia_images2::ImageFormat& v2) {
  fuchsia_sysmem::ImageFormat2 v1{};

  if (!v2.pixel_format().has_value()) {
    LOG(ERROR, "!v2.pixel_format().has_value()");
    return fpromise::error();
  }
  auto v2_pixel_format = PixelFormatAndModifierFromImageFormat(v2);
  v1.pixel_format() = V1CopyFromV2PixelFormat(v2_pixel_format);
  // Preserve round-trip "has" bit for pixel_format_modifier conversion from V1 to V2 and back.
  if (!v2.pixel_format_modifier().has_value()) {
    v1.pixel_format().has_format_modifier() = false;
  }

  // The conversion is intentionally asymmetric, in that conversion from V2 to V1 loses the ability
  // to have valid_size different from size. The conversion is based mostly on typical usage
  // of V1 fields, and to a lesser extent, V1 field comments in the V1 FIDL file.
  //
  // Specifically, in typical usage, coded_width and coded_height are actually conveying the
  // size.width and size.height, not the valid_size.width and valid_size.height,
  // because in V1, coded_height being larger than the actual valid pixels height is the only way to
  // indicate a UV plane offset that's larger than the minimum required to hold the valid pixels. In
  // contrast to the height situation, re. width, both V1 and V2 have the ability to indicate the
  // bytes_per_row separately from the width in pixels, so it's possible in V1 to indicate
  // coded_width * bytes per pixel substantially smaller than bytes_per_row. In other words, in V1,
  // for width, it's possible to indicate the amount of padding between valid pixels width and
  // bytes_per_row, so it's possible to convey both valid_size.width and a larger bytes_per_row
  // (with width converted to bytes for "larger" comparison purposes). In V1 this can mean that
  // coded_height is unnaturally larger than it "should be" per V1 doc comments because it's the
  // only way to indicate UV plane offset, while coded_width is the valid pixels width as it "should
  // be" per V1 doc comments. In V2 the situation is cleaned up by providing a way to specify
  // valid_size and size separately, both with width and height in pixels, and retain
  // bytes_per_row since that's still needed for formats like BGR24 (3 bytes per pixel but fairly
  // often 4 byte aligned row start offsets), where the row start alignment isn't a multiple of the
  // bytes per pixel * width in valid pixels.
  //
  // In practice, V1 coded_height is size.height, despite the V1 FIDL comments making it
  // sound like coded_height holds valid_size.height. Essentially, in V1 it's not actually possible
  // to convey the valid_size.height in all situations, as the coded_height is the only way to
  // specify the UV plane offset, so coded_height must be used to define the UV plane offset, not
  // the valid_size.height.
  //
  // In practice, V1 coded_width can be size.width (typically with little or no padding
  // implied by bytes_per_row) or can be valid_size.width (sometimes with a lot more padding implied
  // by bytes_per_row). In this V2 -> V1 conversion we choose to store V2 size.width in
  // coded_width, partly for consistency with coded_height being size.height, partly so that
  // we're eliminating both parts of valid_size instead of trying to keep only one part of it, and
  // partly because the more typical V1 usage is for coded_width and coded_height to store the
  // size.width and size.height (in contrast to splitting them and "leaning harder"
  // on bytes_per_row), so we go with that more typical V1 usage pattern here, despite some
  // unfortunate mismatch with V1 FIDL doc comments stemming from V1 limitations.
  if (v2.size().has_value()) {
    v1.coded_width() = v2.size()->width();
    v1.coded_height() = v2.size()->height();
  }

  PROCESS_SCALAR_FIELD_V2(bytes_per_row);

  if (v2.display_rect().has_value()) {
    if (v2.display_rect()->x() != 0 || v2.display_rect()->y() != 0) {
      LOG(ERROR, "v2.display_rect.x != 0 || v2.display_rect.y != 0 can't convert to v1");
      return fpromise::error();
    }
    v1.display_width() = v2.display_rect()->width();
    v1.display_height() = v2.display_rect()->height();
  }

  v1.layers() = 1;

  if (v2.color_space().has_value()) {
    v1.color_space() = V1CopyFromV2ColorSpace(v2.color_space().value());
  }
  v1.has_pixel_aspect_ratio() = v2.pixel_aspect_ratio().has_value();
  if (v1.has_pixel_aspect_ratio()) {
    v1.pixel_aspect_ratio_width() = v2.pixel_aspect_ratio()->width();
    v1.pixel_aspect_ratio_height() = v2.pixel_aspect_ratio()->height();
  }

  return fpromise::ok(std::move(v1));
}

#if __Fuchsia_API_level__ >= 19

fpromise::result<fuchsia_sysmem::wire::ImageFormat2> V1CopyFromV2ImageFormat(
    fuchsia_images2::wire::ImageFormat& v2) {
  auto v2_natural = fidl::ToNatural(v2);
  auto v1_natural_result = V1CopyFromV2ImageFormat(v2_natural);
  if (v1_natural_result.is_error()) {
    return fpromise::error();
  }
  UnusedArena unused_arena;
  return fpromise::ok(fidl::ToWire(unused_arena, v1_natural_result.value()));
}

fpromise::result<fuchsia_sysmem::SingleBufferSettings> V1CopyFromV2SingleBufferSettings(
    const fuchsia_sysmem2::SingleBufferSettings& v2) {
  fuchsia_sysmem::SingleBufferSettings v1;
  auto buffer_settings_result = V1CopyFromV2BufferMemorySettings(v2.buffer_settings().value());
  if (buffer_settings_result.is_error()) {
    return fpromise::error();
  }
  v1.buffer_settings() = std::move(buffer_settings_result.value());
  v1.has_image_format_constraints() = v2.image_format_constraints().has_value();
  if (v2.image_format_constraints().has_value()) {
    auto image_format_constraints_result =
        V1CopyFromV2ImageFormatConstraints(v2.image_format_constraints().value());
    if (!image_format_constraints_result.is_ok()) {
      LOG(ERROR, "!image_format_constraints_result.is_ok()");
      return fpromise::error();
    }
    v1.image_format_constraints() = image_format_constraints_result.take_value();
  }
  return fpromise::ok(std::move(v1));
}

fpromise::result<fuchsia_sysmem::wire::SingleBufferSettings> V1CopyFromV2SingleBufferSettings(
    const fuchsia_sysmem2::wire::SingleBufferSettings& v2) {
  fuchsia_sysmem::wire::SingleBufferSettings v1{};
  auto buffer_settings_result = V1CopyFromV2BufferMemorySettings(v2.buffer_settings());
  if (buffer_settings_result.is_error()) {
    return fpromise::error();
  }
  v1.buffer_settings = std::move(buffer_settings_result.value());
  v1.has_image_format_constraints = v2.has_image_format_constraints();
  if (v2.has_image_format_constraints()) {
    auto image_format_constraints_result =
        V1CopyFromV2ImageFormatConstraints(v2.image_format_constraints());
    if (!image_format_constraints_result.is_ok()) {
      LOG(ERROR, "!image_format_constraints_result.is_ok()");
      return fpromise::error();
    }
    v1.image_format_constraints = image_format_constraints_result.take_value();
  }
  return fpromise::ok(v1);
}

fuchsia_sysmem::VmoBuffer V1MoveFromV2VmoBuffer(fuchsia_sysmem2::VmoBuffer v2) {
  fuchsia_sysmem::VmoBuffer v1;
  if (v2.vmo().has_value()) {
    v1.vmo() = std::move(v2.vmo().value());
  }
  PROCESS_SCALAR_FIELD_V2(vmo_usable_start);
  return v1;
}

fuchsia_sysmem::wire::VmoBuffer V1MoveFromV2VmoBuffer(fuchsia_sysmem2::wire::VmoBuffer v2) {
  fuchsia_sysmem::wire::VmoBuffer v1;
  if (v2.has_vmo()) {
    v1.vmo = std::move(v2.vmo());
  }
  PROCESS_WIRE_SCALAR_FIELD_V2(vmo_usable_start);
  return v1;
}

fpromise::result<fuchsia_sysmem::BufferCollectionInfo2> V1MoveFromV2BufferCollectionInfo(
    fuchsia_sysmem2::BufferCollectionInfo v2) {
  fuchsia_sysmem::BufferCollectionInfo2 v1;
  if (v2.buffers().has_value()) {
    if (v2.buffers()->size() > fuchsia_sysmem::wire::kMaxCountBufferCollectionInfoBuffers) {
      LOG(ERROR,
          "v2.buffers().count() > "
          "fuchsia_sysmem::wire::kMaxCountBufferCollectionInfoBuffers");
      return fpromise::error();
    }
    v1.buffer_count() = static_cast<uint32_t>(v2.buffers()->size());
    for (uint32_t i = 0; i < v2.buffers()->size(); ++i) {
      v1.buffers()[i] = V1MoveFromV2VmoBuffer(std::move(v2.buffers()->at(i)));
    }
  }
  auto settings_result = V1CopyFromV2SingleBufferSettings(v2.settings().value());
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fpromise::error();
  }
  v1.settings() = settings_result.take_value();
  return fpromise::ok(std::move(v1));
}

fpromise::result<fuchsia_sysmem::wire::BufferCollectionInfo2> V1MoveFromV2BufferCollectionInfo(
    fuchsia_sysmem2::wire::BufferCollectionInfo v2) {
  fuchsia_sysmem::wire::BufferCollectionInfo2 v1;
  if (v2.has_buffers()) {
    if (v2.buffers().count() > fuchsia_sysmem::wire::kMaxCountBufferCollectionInfoBuffers) {
      LOG(ERROR,
          "v2.buffers().count() > "
          "fuchsia_sysmem::wire::kMaxCountBufferCollectionInfoBuffers");
      return fpromise::error();
    }
    v1.buffer_count = static_cast<uint32_t>(v2.buffers().count());
    for (uint32_t i = 0; i < v2.buffers().count(); ++i) {
      v1.buffers[i] = V1MoveFromV2VmoBuffer(v2.buffers()[i]);
    }
  }
  auto settings_result = V1CopyFromV2SingleBufferSettings(v2.settings());
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fpromise::error();
  }
  v1.settings = settings_result.take_value();
  return fpromise::ok(std::move(v1));
}

fuchsia_sysmem2::wire::BufferMemorySettings V2CloneBufferMemorySettings(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::BufferMemorySettings& src) {
  // FIDL wire codegen doesn't have clone, but it does have conversion to/from natural types which
  // accomplishes a clone overall. This probably isn't the fastest way but should be smaller code
  // size than a custom clone, and avoids maintenance when adding a field.
  auto src_natural = fidl::ToNatural(src);
  return fidl::ToWire(allocator, src_natural);
}

fuchsia_sysmem2::wire::ImageFormatConstraints V2CloneImageFormatConstraints(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::ImageFormatConstraints& src) {
  // FIDL wire codegen doesn't have clone, but it does have conversion to/from natural types which
  // accomplishes a clone overall. This probably isn't the fastest way but should be smaller code
  // size than a custom clone, and avoids maintenance when adding a field.
  auto src_natural = fidl::ToNatural(src);
  return fidl::ToWire(allocator, src_natural);
}

fuchsia_sysmem2::wire::SingleBufferSettings V2CloneSingleBufferSettings(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::SingleBufferSettings& src) {
  // FIDL wire codegen doesn't have clone, but it does have conversion to/from natural types which
  // accomplishes a clone overall. This probably isn't the fastest way but should be smaller code
  // size than a custom clone, and avoids maintenance when adding a field.
  auto src_natural = fidl::ToNatural(src);
  return fidl::ToWire(allocator, src_natural);
}

fpromise::result<fuchsia_sysmem2::VmoBuffer, zx_status_t> V2CloneVmoBuffer(
    const fuchsia_sysmem2::VmoBuffer& src, uint32_t vmo_rights_mask) {
  fuchsia_sysmem2::VmoBuffer vmo_buffer;
  if (src.vmo().has_value()) {
    if (src.vmo().value().get() != ZX_HANDLE_INVALID && vmo_rights_mask != 0) {
      zx::vmo clone_vmo;
      zx_info_handle_basic_t info{};
      zx_status_t get_info_status =
          src.vmo().value().get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
      if (get_info_status != ZX_OK) {
        LOG(ERROR, "get_info_status: %d", get_info_status);
        return fpromise::error(get_info_status);
      }
      zx_status_t duplicate_status =
          src.vmo().value().duplicate(info.rights & vmo_rights_mask, &clone_vmo);
      if (duplicate_status != ZX_OK) {
        LOG(ERROR, "duplicate_status: %d", duplicate_status);
        return fpromise::error(duplicate_status);
      }
      vmo_buffer.vmo() = std::move(clone_vmo);
    } else {
      ZX_DEBUG_ASSERT(!vmo_buffer.vmo().has_value());
    }
  }
  if (src.vmo_usable_start().has_value()) {
    vmo_buffer.vmo_usable_start() = src.vmo_usable_start().value();
  }
  if (src.close_weak_asap().has_value()) {
    zx::eventpair clone_eventpair;
    zx_status_t duplicate_status =
        src.close_weak_asap().value().duplicate(ZX_RIGHT_SAME_RIGHTS, &clone_eventpair);
    if (duplicate_status != ZX_OK) {
      LOG(ERROR, "duplicate_status: %d", duplicate_status);
      return fpromise::error(duplicate_status);
    }
    vmo_buffer.close_weak_asap() = std::move(clone_eventpair);
  }
  return fpromise::ok(std::move(vmo_buffer));
}

fpromise::result<fuchsia_sysmem2::wire::VmoBuffer, zx_status_t> V2CloneVmoBuffer(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::VmoBuffer& src,
    uint32_t vmo_rights_mask) {
  fuchsia_sysmem2::wire::VmoBuffer vmo_buffer(allocator);
  if (src.has_vmo()) {
    zx::vmo clone_vmo;
    if (src.vmo().get() != ZX_HANDLE_INVALID) {
      zx_info_handle_basic_t info{};
      zx_status_t get_info_status =
          src.vmo().get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
      if (get_info_status != ZX_OK) {
        LOG(ERROR, "get_info_status: %d", get_info_status);
        return fpromise::error(get_info_status);
      }
      zx_status_t duplicate_status = src.vmo().duplicate(info.rights & vmo_rights_mask, &clone_vmo);
      if (duplicate_status != ZX_OK) {
        LOG(ERROR, "duplicate_status: %d", duplicate_status);
        return fpromise::error(duplicate_status);
      }
    } else {
      ZX_DEBUG_ASSERT(clone_vmo.get() == ZX_HANDLE_INVALID);
    }
    vmo_buffer.set_vmo(std::move(clone_vmo));
  }
  if (src.has_vmo_usable_start()) {
    vmo_buffer.set_vmo_usable_start(allocator, src.vmo_usable_start());
  }
  return fpromise::ok(vmo_buffer);
}

fpromise::result<fuchsia_sysmem2::BufferCollectionInfo, zx_status_t> V2CloneBufferCollectionInfo(
    const fuchsia_sysmem2::BufferCollectionInfo& src, uint32_t vmo_rights_mask) {
  fuchsia_sysmem2::BufferCollectionInfo buffer_collection_info;
  if (src.settings().has_value()) {
    // clone via generated copy
    buffer_collection_info.settings() = src.settings().value();
  }
  if (src.buffers().has_value()) {
    buffer_collection_info.buffers().emplace(src.buffers()->size());
    for (uint32_t i = 0; i < src.buffers()->size(); ++i) {
      auto clone_result = V2CloneVmoBuffer(src.buffers()->at(i), vmo_rights_mask);
      if (!clone_result.is_ok()) {
        return clone_result.take_error_result();
      }
      buffer_collection_info.buffers()->at(i) = clone_result.take_value();
    }
  }
  if (src.buffer_collection_id().has_value()) {
    buffer_collection_info.buffer_collection_id() = src.buffer_collection_id().value();
  }
  return fpromise::ok(std::move(buffer_collection_info));
}

fpromise::result<fuchsia_sysmem2::wire::BufferCollectionInfo, zx_status_t>
V2CloneBufferCollectionInfo(fidl::AnyArena& allocator,
                            const fuchsia_sysmem2::wire::BufferCollectionInfo& src,
                            uint32_t vmo_rights_mask) {
  fuchsia_sysmem2::wire::BufferCollectionInfo buffer_collection_info(allocator);
  if (src.has_settings()) {
    buffer_collection_info.set_settings(allocator,
                                        V2CloneSingleBufferSettings(allocator, src.settings()));
  }
  if (src.has_buffers()) {
    buffer_collection_info.set_buffers(allocator, allocator, src.buffers().count());
    for (uint32_t i = 0; i < src.buffers().count(); ++i) {
      auto clone_result = V2CloneVmoBuffer(allocator, src.buffers()[i], vmo_rights_mask);
      if (!clone_result.is_ok()) {
        return clone_result.take_error_result();
      }
      buffer_collection_info.buffers()[i] = clone_result.take_value();
    }
  }
  if (src.has_buffer_collection_id()) {
    buffer_collection_info.set_buffer_collection_id(allocator, src.buffer_collection_id());
  }
  return fpromise::ok(buffer_collection_info);
}

fuchsia_sysmem2::wire::BufferCollectionConstraints V2CloneBufferCollectionConstraints(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::BufferCollectionConstraints& src) {
  // FIDL wire codegen doesn't have clone, but it does have conversion to/from natural types which
  // accomplishes a clone overall. This probably isn't the fastest way but should be smaller code
  // size than a custom clone, and avoids maintenance when adding a field.
  auto src_natural = fidl::ToNatural(src);
  return fidl::ToWire(allocator, src_natural);
}

fuchsia_sysmem2::wire::BufferUsage V2CloneBufferUsage(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::BufferUsage& src) {
  // FIDL wire codegen doesn't have clone, but it does have conversion to/from natural types which
  // accomplishes a clone overall. This probably isn't the fastest way but should be smaller code
  // size than a custom clone, and avoids maintenance when adding a field.
  auto src_natural = fidl::ToNatural(src);
  return fidl::ToWire(allocator, src_natural);
}

fuchsia_sysmem2::wire::BufferMemoryConstraints V2CloneBufferMemoryConstraints(
    fidl::AnyArena& allocator, const fuchsia_sysmem2::wire::BufferMemoryConstraints& src) {
  // FIDL wire codegen doesn't have clone, but it does have conversion to/from natural types which
  // accomplishes a clone overall. This probably isn't the fastest way but should be smaller code
  // size than a custom clone, and avoids maintenance when adding a field.
  auto src_natural = fidl::ToNatural(src);
  return fidl::ToWire(allocator, src_natural);
}

zx_status_t V1CopyFromV2Error(fuchsia_sysmem2::Error error) {
  // Caller must specify a valid error code. This translates to ZX_ERR_INTERNAL
  // in release, but asserts in debug.
  ZX_DEBUG_ASSERT(error != fuchsia_sysmem2::Error::kInvalid);
  switch (error) {
    case fuchsia_sysmem2::Error::kProtocolDeviation:
      return ZX_ERR_INVALID_ARGS;
    case fuchsia_sysmem2::Error::kNotFound:
      return ZX_ERR_NOT_FOUND;
    case fuchsia_sysmem2::Error::kHandleAccessDenied:
      return ZX_ERR_ACCESS_DENIED;
    case fuchsia_sysmem2::Error::kNoMemory:
      return ZX_ERR_NO_MEMORY;
    case fuchsia_sysmem2::Error::kConstraintsIntersectionEmpty:
      return ZX_ERR_NOT_SUPPORTED;
    case fuchsia_sysmem2::Error::kPending:
      return ZX_ERR_UNAVAILABLE;
    case fuchsia_sysmem2::Error::kTooManyGroupChildCombinations:
      return ZX_ERR_OUT_OF_RANGE;
    case fuchsia_sysmem2::Error::kInvalid:
    case fuchsia_sysmem2::Error::kUnspecified:
    default:
      return ZX_ERR_INTERNAL;
  }
}

fuchsia_sysmem2::Error V2CopyFromV1Error(zx_status_t error) {
  // This function must never be passed a success code. It's only for errors.
  // We assert rather than returning failure from an error translation function,
  // just because returning failure from an error translation function would get
  // confusing enough that it seems as likely as not to result in another bug
  // anyway.
  ZX_ASSERT(error != ZX_OK);
  switch (error) {
    case ZX_ERR_INTERNAL:
      return fuchsia_sysmem2::Error::kUnspecified;
    case ZX_ERR_INVALID_ARGS:
      return fuchsia_sysmem2::Error::kProtocolDeviation;
    case ZX_ERR_NOT_FOUND:
      return fuchsia_sysmem2::Error::kNotFound;
    case ZX_ERR_ACCESS_DENIED:
      return fuchsia_sysmem2::Error::kHandleAccessDenied;
    case ZX_ERR_NO_MEMORY:
      return fuchsia_sysmem2::Error::kNoMemory;
    case ZX_ERR_NOT_SUPPORTED:
      return fuchsia_sysmem2::Error::kConstraintsIntersectionEmpty;
    case ZX_ERR_UNAVAILABLE:
      return fuchsia_sysmem2::Error::kPending;
    case ZX_ERR_OUT_OF_RANGE:
      return fuchsia_sysmem2::Error::kTooManyGroupChildCombinations;
    default:
      // This also happens if the caller passes in ZX_OK in release.
      return fuchsia_sysmem2::Error::kInvalid;
  }
}

fuchsia_sysmem2::Heap MakeHeap(std::string heap_type, uint64_t heap_id) {
  fuchsia_sysmem2::Heap heap;
  heap.heap_type() = std::move(heap_type);
  heap.id() = heap_id;
  return heap;
}

#endif  // __Fuchsia_API_level__ >= 19

}  // namespace sysmem
