// WARNING: This file is machine generated by fidlgen.

#pragma once

#include <fidl/test/protocols/cpp/fidl.h>

#include "lib/fidl/cpp/fuzzing/traits.h"
#include "lib/fidl/cpp/internal/header.h"
// For ::std::max_element().
#include <algorithm>
// For uint64_t.
#include <stdint.h>

namespace fuzzing {

using obj_type = ::fidl::test::protocols::obj_type;
using WithErrorSyntax_ResponseAsStruct_Response =
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Response;
using WithErrorSyntax_ResponseAsStruct_Result =
    ::fidl::test::protocols::WithErrorSyntax_ResponseAsStruct_Result;
using WithErrorSyntax_ErrorAsPrimitive_Response =
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Response;
using WithErrorSyntax_ErrorAsPrimitive_Result =
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsPrimitive_Result;
using WithErrorSyntax_ErrorAsEnum_Response =
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response;
using ErrorEnun = ::fidl::test::protocols::ErrorEnun;
using WithErrorSyntax_ErrorAsEnum_Result =
    ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Result;

template <>
struct MinSize<obj_type> {
  operator size_t() { return sizeof(uint64_t); }
};
template <>
struct Allocate<obj_type> {
  obj_type operator()(FuzzInput* src, size_t* size) {
    obj_type out;
    uint64_t selector;
    ZX_ASSERT(*size >= sizeof(uint64_t));
    ZX_ASSERT(src->CopyObject(&selector));
    *size = sizeof(uint64_t);

    switch (selector % 2) {
      case 0:
        out = obj_type::NONE;
        break;
      case 1:
        out = obj_type::SOCKET;
        break;
    }

    return out;
  }
};
template <>
struct MinSize<WithErrorSyntax_ResponseAsStruct_Response> {
  operator size_t() {
    return MinSize<int64_t>() + MinSize<int64_t>() + MinSize<int64_t>();
  }
};
template <>
struct Allocate<WithErrorSyntax_ResponseAsStruct_Response> {
  WithErrorSyntax_ResponseAsStruct_Response operator()(FuzzInput* src,
                                                       size_t* size) {
    ZX_ASSERT(*size >= MinSize<WithErrorSyntax_ResponseAsStruct_Response>());
    WithErrorSyntax_ResponseAsStruct_Response out;
    const size_t slack_per_member =
        (*size - MinSize<WithErrorSyntax_ResponseAsStruct_Response>()) / 3;
    size_t out_size;
    out_size = MinSize<int64_t>() + slack_per_member;
    out.a = Allocate<int64_t>{}(src, &out_size);
    out_size = MinSize<int64_t>() + slack_per_member;
    out.b = Allocate<int64_t>{}(src, &out_size);
    out_size = MinSize<int64_t>() + slack_per_member;
    out.c = Allocate<int64_t>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<WithErrorSyntax_ResponseAsStruct_Result> {
  operator size_t() {
    size_t sizes[] = {0,
                      MinSize<::fidl::test::protocols::
                                  WithErrorSyntax_ResponseAsStruct_Response>(),
                      MinSize<uint32_t>()};
    return 1 + *std::max_element(sizes, sizes + 2 + 1);
  }
};
template <>
struct Allocate<WithErrorSyntax_ResponseAsStruct_Result> {
  static_assert(2 > 0, "xunion must have at least one member");

  WithErrorSyntax_ResponseAsStruct_Result operator()(FuzzInput* src,
                                                     size_t* size) {
    ZX_ASSERT(*size >= MinSize<WithErrorSyntax_ResponseAsStruct_Result>());

    uint8_t selector;
    ZX_ASSERT(src->CopyBytes(&selector, 1));
    (*size)++;

    WithErrorSyntax_ResponseAsStruct_Result out;
    switch (selector % 2) {
      case 0: {
        out.set_response(
            Allocate<::fidl::test::protocols::
                         WithErrorSyntax_ResponseAsStruct_Response>{}(src,
                                                                      size));
        break;
      }
      case 1: {
        out.set_err(Allocate<uint32_t>{}(src, size));
        break;
      }
    }

    return out;
  }
};
template <>
struct MinSize<WithErrorSyntax_ErrorAsPrimitive_Response> {
  operator size_t() { return MinSize<uint8_t>(); }
};
template <>
struct Allocate<WithErrorSyntax_ErrorAsPrimitive_Response> {
  WithErrorSyntax_ErrorAsPrimitive_Response operator()(FuzzInput* src,
                                                       size_t* size) {
    ZX_ASSERT(*size >= MinSize<WithErrorSyntax_ErrorAsPrimitive_Response>());
    WithErrorSyntax_ErrorAsPrimitive_Response out;
    const size_t slack_per_member =
        (*size - MinSize<WithErrorSyntax_ErrorAsPrimitive_Response>()) / 1;
    size_t out_size;
    out_size = MinSize<uint8_t>() + slack_per_member;
    out.__reserved = Allocate<uint8_t>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<WithErrorSyntax_ErrorAsPrimitive_Result> {
  operator size_t() {
    size_t sizes[] = {0,
                      MinSize<::fidl::test::protocols::
                                  WithErrorSyntax_ErrorAsPrimitive_Response>(),
                      MinSize<uint32_t>()};
    return 1 + *std::max_element(sizes, sizes + 2 + 1);
  }
};
template <>
struct Allocate<WithErrorSyntax_ErrorAsPrimitive_Result> {
  static_assert(2 > 0, "xunion must have at least one member");

  WithErrorSyntax_ErrorAsPrimitive_Result operator()(FuzzInput* src,
                                                     size_t* size) {
    ZX_ASSERT(*size >= MinSize<WithErrorSyntax_ErrorAsPrimitive_Result>());

    uint8_t selector;
    ZX_ASSERT(src->CopyBytes(&selector, 1));
    (*size)++;

    WithErrorSyntax_ErrorAsPrimitive_Result out;
    switch (selector % 2) {
      case 0: {
        out.set_response(
            Allocate<::fidl::test::protocols::
                         WithErrorSyntax_ErrorAsPrimitive_Response>{}(src,
                                                                      size));
        break;
      }
      case 1: {
        out.set_err(Allocate<uint32_t>{}(src, size));
        break;
      }
    }

    return out;
  }
};
template <>
struct MinSize<WithErrorSyntax_ErrorAsEnum_Response> {
  operator size_t() { return MinSize<uint8_t>(); }
};
template <>
struct Allocate<WithErrorSyntax_ErrorAsEnum_Response> {
  WithErrorSyntax_ErrorAsEnum_Response operator()(FuzzInput* src,
                                                  size_t* size) {
    ZX_ASSERT(*size >= MinSize<WithErrorSyntax_ErrorAsEnum_Response>());
    WithErrorSyntax_ErrorAsEnum_Response out;
    const size_t slack_per_member =
        (*size - MinSize<WithErrorSyntax_ErrorAsEnum_Response>()) / 1;
    size_t out_size;
    out_size = MinSize<uint8_t>() + slack_per_member;
    out.__reserved = Allocate<uint8_t>{}(src, &out_size);
    return out;
  }
};
template <>
struct MinSize<ErrorEnun> {
  operator size_t() { return sizeof(uint64_t); }
};
template <>
struct Allocate<ErrorEnun> {
  ErrorEnun operator()(FuzzInput* src, size_t* size) {
    ErrorEnun out;
    uint64_t selector;
    ZX_ASSERT(*size >= sizeof(uint64_t));
    ZX_ASSERT(src->CopyObject(&selector));
    *size = sizeof(uint64_t);

    switch (selector % 2) {
      case 0:
        out = ErrorEnun::ERR_FOO;
        break;
      case 1:
        out = ErrorEnun::ERR_BAR;
        break;
    }

    return out;
  }
};
template <>
struct MinSize<WithErrorSyntax_ErrorAsEnum_Result> {
  operator size_t() {
    size_t sizes[] = {
        0,
        MinSize<
            ::fidl::test::protocols::WithErrorSyntax_ErrorAsEnum_Response>(),
        MinSize<::fidl::test::protocols::ErrorEnun>()};
    return 1 + *std::max_element(sizes, sizes + 2 + 1);
  }
};
template <>
struct Allocate<WithErrorSyntax_ErrorAsEnum_Result> {
  static_assert(2 > 0, "xunion must have at least one member");

  WithErrorSyntax_ErrorAsEnum_Result operator()(FuzzInput* src, size_t* size) {
    ZX_ASSERT(*size >= MinSize<WithErrorSyntax_ErrorAsEnum_Result>());

    uint8_t selector;
    ZX_ASSERT(src->CopyBytes(&selector, 1));
    (*size)++;

    WithErrorSyntax_ErrorAsEnum_Result out;
    switch (selector % 2) {
      case 0: {
        out.set_response(
            Allocate<::fidl::test::protocols::
                         WithErrorSyntax_ErrorAsEnum_Response>{}(src, size));
        break;
      }
      case 1: {
        out.set_err(Allocate<::fidl::test::protocols::ErrorEnun>{}(src, size));
        break;
      }
    }

    return out;
  }
};

}  // namespace fuzzing
