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

// fidl_experiment = output_index_json

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

#include "lib/fidl/cpp/internal/implementation.h"

//
// Domain objects definitions
//
namespace test {
namespace protocollayoutssamelibrary {

extern "C" const fidl_type_t test_protocollayoutssamelibrary_TablePayloadTable;
const fidl_type_t* TablePayload::FidlType = &test_protocollayoutssamelibrary_TablePayloadTable;

TablePayload::TablePayload() {}

TablePayload::TablePayload(TablePayload&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

TablePayload::~TablePayload() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

TablePayload& TablePayload::operator=(TablePayload&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool TablePayload::IsEmpty() const {
  return field_presence_.IsEmpty();
}
TablePayload& TablePayload::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void TablePayload::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void TablePayload::Decode(::fidl::Decoder* _decoder, TablePayload* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t TablePayload::Clone(TablePayload* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_UnionPayloadTable;
const fidl_type_t* UnionPayload::FidlType = &test_protocollayoutssamelibrary_UnionPayloadTable;

UnionPayload::UnionPayload() {}

UnionPayload::~UnionPayload() {
  Destroy();
}

UnionPayload::UnionPayload(UnionPayload&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::UnionPayload::Tag::Invalid):
      break;
  }
}

UnionPayload& UnionPayload::operator=(UnionPayload&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::UnionPayload::Tag::Invalid):
        break;
    }
  }
  return *this;
}

UnionPayload UnionPayload::WithB(bool&& val) {
  UnionPayload result;
  result.set_b(std::move(val));
  return result;
}


void UnionPayload::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void UnionPayload::Decode(::fidl::Decoder* _decoder, UnionPayload* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::UnionPayload::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t UnionPayload::Clone(UnionPayload* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::UnionPayload::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:return ZX_OK;
  }
}

UnionPayload& UnionPayload::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::UnionPayload::Tag::kB);
  b_ = std::move(value);
  return *this;
}

void UnionPayload::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::UnionPayload::Tag::Invalid);
}

void UnionPayload::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::UnionPayload::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::UnionPayload::Tag::kB:
        new (&b_) bool();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
const fidl_type_t* ComposedProtocolOneWayAnonComposedRequest::FidlType = &test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;

ComposedProtocolOneWayAnonComposedRequest::ComposedProtocolOneWayAnonComposedRequest() {}

ComposedProtocolOneWayAnonComposedRequest::ComposedProtocolOneWayAnonComposedRequest(ComposedProtocolOneWayAnonComposedRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

ComposedProtocolOneWayAnonComposedRequest::~ComposedProtocolOneWayAnonComposedRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

ComposedProtocolOneWayAnonComposedRequest& ComposedProtocolOneWayAnonComposedRequest::operator=(ComposedProtocolOneWayAnonComposedRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool ComposedProtocolOneWayAnonComposedRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
ComposedProtocolOneWayAnonComposedRequest& ComposedProtocolOneWayAnonComposedRequest::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void ComposedProtocolOneWayAnonComposedRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void ComposedProtocolOneWayAnonComposedRequest::Decode(::fidl::Decoder* _decoder, ComposedProtocolOneWayAnonComposedRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t ComposedProtocolOneWayAnonComposedRequest::Clone(ComposedProtocolOneWayAnonComposedRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
const fidl_type_t* ComposedProtocolTwoWayAnonComposedRequest::FidlType = &test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;

ComposedProtocolTwoWayAnonComposedRequest::ComposedProtocolTwoWayAnonComposedRequest() {}

ComposedProtocolTwoWayAnonComposedRequest::~ComposedProtocolTwoWayAnonComposedRequest() {
  Destroy();
}

ComposedProtocolTwoWayAnonComposedRequest::ComposedProtocolTwoWayAnonComposedRequest(ComposedProtocolTwoWayAnonComposedRequest&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::Invalid):
      break;
  }
}

ComposedProtocolTwoWayAnonComposedRequest& ComposedProtocolTwoWayAnonComposedRequest::operator=(ComposedProtocolTwoWayAnonComposedRequest&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest::WithB(bool&& val) {
  ComposedProtocolTwoWayAnonComposedRequest result;
  result.set_b(std::move(val));
  return result;
}


void ComposedProtocolTwoWayAnonComposedRequest::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ComposedProtocolTwoWayAnonComposedRequest::Decode(::fidl::Decoder* _decoder, ComposedProtocolTwoWayAnonComposedRequest* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t ComposedProtocolTwoWayAnonComposedRequest::Clone(ComposedProtocolTwoWayAnonComposedRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:return ZX_OK;
  }
}

ComposedProtocolTwoWayAnonComposedRequest& ComposedProtocolTwoWayAnonComposedRequest::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB);
  b_ = std::move(value);
  return *this;
}

void ComposedProtocolTwoWayAnonComposedRequest::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::Invalid);
}

void ComposedProtocolTwoWayAnonComposedRequest::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest::Tag::kB:
        new (&b_) bool();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
const fidl_type_t* ComposedProtocolTwoWayAnonComposedResponse::FidlType = &test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;

ComposedProtocolTwoWayAnonComposedResponse::ComposedProtocolTwoWayAnonComposedResponse() {}

ComposedProtocolTwoWayAnonComposedResponse::ComposedProtocolTwoWayAnonComposedResponse(ComposedProtocolTwoWayAnonComposedResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

ComposedProtocolTwoWayAnonComposedResponse::~ComposedProtocolTwoWayAnonComposedResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

ComposedProtocolTwoWayAnonComposedResponse& ComposedProtocolTwoWayAnonComposedResponse::operator=(ComposedProtocolTwoWayAnonComposedResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool ComposedProtocolTwoWayAnonComposedResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
ComposedProtocolTwoWayAnonComposedResponse& ComposedProtocolTwoWayAnonComposedResponse::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void ComposedProtocolTwoWayAnonComposedResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void ComposedProtocolTwoWayAnonComposedResponse::Decode(::fidl::Decoder* _decoder, ComposedProtocolTwoWayAnonComposedResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t ComposedProtocolTwoWayAnonComposedResponse::Clone(ComposedProtocolTwoWayAnonComposedResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
const fidl_type_t* ComposedProtocolTwoWayAnonComposedWithErrorRequest::FidlType = &test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;

ComposedProtocolTwoWayAnonComposedWithErrorRequest::ComposedProtocolTwoWayAnonComposedWithErrorRequest() {}

ComposedProtocolTwoWayAnonComposedWithErrorRequest::ComposedProtocolTwoWayAnonComposedWithErrorRequest(ComposedProtocolTwoWayAnonComposedWithErrorRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

ComposedProtocolTwoWayAnonComposedWithErrorRequest::~ComposedProtocolTwoWayAnonComposedWithErrorRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

ComposedProtocolTwoWayAnonComposedWithErrorRequest& ComposedProtocolTwoWayAnonComposedWithErrorRequest::operator=(ComposedProtocolTwoWayAnonComposedWithErrorRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool ComposedProtocolTwoWayAnonComposedWithErrorRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
ComposedProtocolTwoWayAnonComposedWithErrorRequest& ComposedProtocolTwoWayAnonComposedWithErrorRequest::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void ComposedProtocolTwoWayAnonComposedWithErrorRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void ComposedProtocolTwoWayAnonComposedWithErrorRequest::Decode(::fidl::Decoder* _decoder, ComposedProtocolTwoWayAnonComposedWithErrorRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t ComposedProtocolTwoWayAnonComposedWithErrorRequest::Clone(ComposedProtocolTwoWayAnonComposedWithErrorRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResponseTable;
const fidl_type_t* ComposedProtocol_TwoWayAnonComposedWithError_Response::FidlType = &test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResponseTable;

ComposedProtocol_TwoWayAnonComposedWithError_Response::ComposedProtocol_TwoWayAnonComposedWithError_Response() {}

ComposedProtocol_TwoWayAnonComposedWithError_Response::~ComposedProtocol_TwoWayAnonComposedWithError_Response() {
  Destroy();
}

ComposedProtocol_TwoWayAnonComposedWithError_Response::ComposedProtocol_TwoWayAnonComposedWithError_Response(ComposedProtocol_TwoWayAnonComposedWithError_Response&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::Invalid):
      break;
  }
}

ComposedProtocol_TwoWayAnonComposedWithError_Response& ComposedProtocol_TwoWayAnonComposedWithError_Response::operator=(ComposedProtocol_TwoWayAnonComposedWithError_Response&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ComposedProtocol_TwoWayAnonComposedWithError_Response ComposedProtocol_TwoWayAnonComposedWithError_Response::WithB(bool&& val) {
  ComposedProtocol_TwoWayAnonComposedWithError_Response result;
  result.set_b(std::move(val));
  return result;
}


void ComposedProtocol_TwoWayAnonComposedWithError_Response::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ComposedProtocol_TwoWayAnonComposedWithError_Response::Decode(::fidl::Decoder* _decoder, ComposedProtocol_TwoWayAnonComposedWithError_Response* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t ComposedProtocol_TwoWayAnonComposedWithError_Response::Clone(ComposedProtocol_TwoWayAnonComposedWithError_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:return ZX_OK;
  }
}

ComposedProtocol_TwoWayAnonComposedWithError_Response& ComposedProtocol_TwoWayAnonComposedWithError_Response::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB);
  b_ = std::move(value);
  return *this;
}

void ComposedProtocol_TwoWayAnonComposedWithError_Response::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::Invalid);
}

void ComposedProtocol_TwoWayAnonComposedWithError_Response::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response::Tag::kB:
        new (&b_) bool();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
const fidl_type_t* ComposedProtocol_TwoWayAnonComposedWithError_Result::FidlType = &test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;

ComposedProtocol_TwoWayAnonComposedWithError_Result::ComposedProtocol_TwoWayAnonComposedWithError_Result() {}

ComposedProtocol_TwoWayAnonComposedWithError_Result::~ComposedProtocol_TwoWayAnonComposedWithError_Result() {
  Destroy();
}

ComposedProtocol_TwoWayAnonComposedWithError_Result::ComposedProtocol_TwoWayAnonComposedWithError_Result(ComposedProtocol_TwoWayAnonComposedWithError_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse:
      new (&response_) ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::Invalid):
      break;
  }
}

ComposedProtocol_TwoWayAnonComposedWithError_Result& ComposedProtocol_TwoWayAnonComposedWithError_Result::operator=(ComposedProtocol_TwoWayAnonComposedWithError_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ComposedProtocol_TwoWayAnonComposedWithError_Result ComposedProtocol_TwoWayAnonComposedWithError_Result::WithResponse(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response&& val) {
  ComposedProtocol_TwoWayAnonComposedWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
ComposedProtocol_TwoWayAnonComposedWithError_Result ComposedProtocol_TwoWayAnonComposedWithError_Result::WithErr(uint32_t&& val) {
  ComposedProtocol_TwoWayAnonComposedWithError_Result result;
  result.set_err(std::move(val));
  return result;
}


void ComposedProtocol_TwoWayAnonComposedWithError_Result::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &err_,
        encoder->Alloc(::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ComposedProtocol_TwoWayAnonComposedWithError_Result::Decode(::fidl::Decoder* _decoder, ComposedProtocol_TwoWayAnonComposedWithError_Result* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t ComposedProtocol_TwoWayAnonComposedWithError_Result::Clone(ComposedProtocol_TwoWayAnonComposedWithError_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse:
      new (&result->response_) ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

ComposedProtocol_TwoWayAnonComposedWithError_Result& ComposedProtocol_TwoWayAnonComposedWithError_Result::set_response(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

ComposedProtocol_TwoWayAnonComposedWithError_Result& ComposedProtocol_TwoWayAnonComposedWithError_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void ComposedProtocol_TwoWayAnonComposedWithError_Result::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::Invalid);
}

void ComposedProtocol_TwoWayAnonComposedWithError_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Response();
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;
const fidl_type_t* ComposedProtocolOnAnonComposedRequest::FidlType = &test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;

ComposedProtocolOnAnonComposedRequest::ComposedProtocolOnAnonComposedRequest() {}

ComposedProtocolOnAnonComposedRequest::~ComposedProtocolOnAnonComposedRequest() {
  Destroy();
}

ComposedProtocolOnAnonComposedRequest::ComposedProtocolOnAnonComposedRequest(ComposedProtocolOnAnonComposedRequest&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::Invalid):
      break;
  }
}

ComposedProtocolOnAnonComposedRequest& ComposedProtocolOnAnonComposedRequest::operator=(ComposedProtocolOnAnonComposedRequest&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ComposedProtocolOnAnonComposedRequest ComposedProtocolOnAnonComposedRequest::WithB(bool&& val) {
  ComposedProtocolOnAnonComposedRequest result;
  result.set_b(std::move(val));
  return result;
}


void ComposedProtocolOnAnonComposedRequest::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ComposedProtocolOnAnonComposedRequest::Decode(::fidl::Decoder* _decoder, ComposedProtocolOnAnonComposedRequest* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t ComposedProtocolOnAnonComposedRequest::Clone(ComposedProtocolOnAnonComposedRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:return ZX_OK;
  }
}

ComposedProtocolOnAnonComposedRequest& ComposedProtocolOnAnonComposedRequest::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB);
  b_ = std::move(value);
  return *this;
}

void ComposedProtocolOnAnonComposedRequest::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::Invalid);
}

void ComposedProtocolOnAnonComposedRequest::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest::Tag::kB:
        new (&b_) bool();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
const fidl_type_t* ComposedProtocol_TwoWayNamedComposedWithError_Result::FidlType = &test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;

ComposedProtocol_TwoWayNamedComposedWithError_Result::ComposedProtocol_TwoWayNamedComposedWithError_Result() {}

ComposedProtocol_TwoWayNamedComposedWithError_Result::~ComposedProtocol_TwoWayNamedComposedWithError_Result() {
  Destroy();
}

ComposedProtocol_TwoWayNamedComposedWithError_Result::ComposedProtocol_TwoWayNamedComposedWithError_Result(ComposedProtocol_TwoWayNamedComposedWithError_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse:
      new (&response_) ::test::protocollayoutssamelibrary::UnionPayload();
      response_ = std::move(other.response_);
      break;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::Invalid):
      break;
  }
}

ComposedProtocol_TwoWayNamedComposedWithError_Result& ComposedProtocol_TwoWayNamedComposedWithError_Result::operator=(ComposedProtocol_TwoWayNamedComposedWithError_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::UnionPayload();
        response_ = std::move(other.response_);
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

ComposedProtocol_TwoWayNamedComposedWithError_Result ComposedProtocol_TwoWayNamedComposedWithError_Result::WithResponse(::test::protocollayoutssamelibrary::UnionPayload&& val) {
  ComposedProtocol_TwoWayNamedComposedWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
ComposedProtocol_TwoWayNamedComposedWithError_Result ComposedProtocol_TwoWayNamedComposedWithError_Result::WithErr(uint32_t&& val) {
  ComposedProtocol_TwoWayNamedComposedWithError_Result result;
  result.set_err(std::move(val));
  return result;
}


void ComposedProtocol_TwoWayNamedComposedWithError_Result::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::UnionPayload>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::UnionPayload, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &err_,
        encoder->Alloc(::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void ComposedProtocol_TwoWayNamedComposedWithError_Result::Decode(::fidl::Decoder* _decoder, ComposedProtocol_TwoWayNamedComposedWithError_Result* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::protocollayoutssamelibrary::UnionPayload();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t ComposedProtocol_TwoWayNamedComposedWithError_Result::Clone(ComposedProtocol_TwoWayNamedComposedWithError_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse:
      new (&result->response_) ::test::protocollayoutssamelibrary::UnionPayload();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

ComposedProtocol_TwoWayNamedComposedWithError_Result& ComposedProtocol_TwoWayNamedComposedWithError_Result::set_response(::test::protocollayoutssamelibrary::UnionPayload value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

ComposedProtocol_TwoWayNamedComposedWithError_Result& ComposedProtocol_TwoWayNamedComposedWithError_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void ComposedProtocol_TwoWayNamedComposedWithError_Result::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::Invalid);
}

void ComposedProtocol_TwoWayNamedComposedWithError_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::UnionPayload();
        break;
      case ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable;
const fidl_type_t* MainProtocol_TwoWayLocalWithError_Result::FidlType = &test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable;

MainProtocol_TwoWayLocalWithError_Result::MainProtocol_TwoWayLocalWithError_Result() {}

MainProtocol_TwoWayLocalWithError_Result::~MainProtocol_TwoWayLocalWithError_Result() {
  Destroy();
}

MainProtocol_TwoWayLocalWithError_Result::MainProtocol_TwoWayLocalWithError_Result(MainProtocol_TwoWayLocalWithError_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse:
      new (&response_) ::test::protocollayoutssamelibrary::UnionPayload();
      response_ = std::move(other.response_);
      break;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid):
      break;
  }
}

MainProtocol_TwoWayLocalWithError_Result& MainProtocol_TwoWayLocalWithError_Result::operator=(MainProtocol_TwoWayLocalWithError_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::UnionPayload();
        response_ = std::move(other.response_);
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

MainProtocol_TwoWayLocalWithError_Result MainProtocol_TwoWayLocalWithError_Result::WithResponse(::test::protocollayoutssamelibrary::UnionPayload&& val) {
  MainProtocol_TwoWayLocalWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
MainProtocol_TwoWayLocalWithError_Result MainProtocol_TwoWayLocalWithError_Result::WithErr(uint32_t&& val) {
  MainProtocol_TwoWayLocalWithError_Result result;
  result.set_err(std::move(val));
  return result;
}


void MainProtocol_TwoWayLocalWithError_Result::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::UnionPayload>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::UnionPayload, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &err_,
        encoder->Alloc(::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void MainProtocol_TwoWayLocalWithError_Result::Decode(::fidl::Decoder* _decoder, MainProtocol_TwoWayLocalWithError_Result* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::protocollayoutssamelibrary::UnionPayload();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t MainProtocol_TwoWayLocalWithError_Result::Clone(MainProtocol_TwoWayLocalWithError_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse:
      new (&result->response_) ::test::protocollayoutssamelibrary::UnionPayload();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

MainProtocol_TwoWayLocalWithError_Result& MainProtocol_TwoWayLocalWithError_Result::set_response(::test::protocollayoutssamelibrary::UnionPayload value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

MainProtocol_TwoWayLocalWithError_Result& MainProtocol_TwoWayLocalWithError_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void MainProtocol_TwoWayLocalWithError_Result::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid);
}

void MainProtocol_TwoWayLocalWithError_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::UnionPayload();
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolOneWayAnonRequestTable;
const fidl_type_t* MainProtocolOneWayAnonRequest::FidlType = &test_protocollayoutssamelibrary_MainProtocolOneWayAnonRequestTable;

MainProtocolOneWayAnonRequest::MainProtocolOneWayAnonRequest() {}

MainProtocolOneWayAnonRequest::MainProtocolOneWayAnonRequest(MainProtocolOneWayAnonRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

MainProtocolOneWayAnonRequest::~MainProtocolOneWayAnonRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

MainProtocolOneWayAnonRequest& MainProtocolOneWayAnonRequest::operator=(MainProtocolOneWayAnonRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool MainProtocolOneWayAnonRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
MainProtocolOneWayAnonRequest& MainProtocolOneWayAnonRequest::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void MainProtocolOneWayAnonRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void MainProtocolOneWayAnonRequest::Decode(::fidl::Decoder* _decoder, MainProtocolOneWayAnonRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t MainProtocolOneWayAnonRequest::Clone(MainProtocolOneWayAnonRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolTwoWayAnonRequestTable;
const fidl_type_t* MainProtocolTwoWayAnonRequest::FidlType = &test_protocollayoutssamelibrary_MainProtocolTwoWayAnonRequestTable;

MainProtocolTwoWayAnonRequest::MainProtocolTwoWayAnonRequest() {}

MainProtocolTwoWayAnonRequest::~MainProtocolTwoWayAnonRequest() {
  Destroy();
}

MainProtocolTwoWayAnonRequest::MainProtocolTwoWayAnonRequest(MainProtocolTwoWayAnonRequest&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

MainProtocolTwoWayAnonRequest& MainProtocolTwoWayAnonRequest::operator=(MainProtocolTwoWayAnonRequest&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_= std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest::WithB(bool&& val) {
  MainProtocolTwoWayAnonRequest result;
  result.set_b(std::move(val));
  return result;
}


void MainProtocolTwoWayAnonRequest::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void MainProtocolTwoWayAnonRequest::Decode(::fidl::Decoder* _decoder, MainProtocolTwoWayAnonRequest* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
  break;
    }
  }

}

zx_status_t MainProtocolTwoWayAnonRequest::Clone(MainProtocolTwoWayAnonRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

MainProtocolTwoWayAnonRequest& MainProtocolTwoWayAnonRequest::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB);
  b_ = std::move(value);
  return *this;
}
MainProtocolTwoWayAnonRequest& MainProtocolTwoWayAnonRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void MainProtocolTwoWayAnonRequest::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB:
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid);
}

void MainProtocolTwoWayAnonRequest::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest::Tag::kB:
        new (&b_) bool();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable;
const fidl_type_t* MainProtocolTwoWayAnonResponse::FidlType = &test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable;

MainProtocolTwoWayAnonResponse::MainProtocolTwoWayAnonResponse() {}

MainProtocolTwoWayAnonResponse::MainProtocolTwoWayAnonResponse(MainProtocolTwoWayAnonResponse&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

MainProtocolTwoWayAnonResponse::~MainProtocolTwoWayAnonResponse() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

MainProtocolTwoWayAnonResponse& MainProtocolTwoWayAnonResponse::operator=(MainProtocolTwoWayAnonResponse&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool MainProtocolTwoWayAnonResponse::IsEmpty() const {
  return field_presence_.IsEmpty();
}
MainProtocolTwoWayAnonResponse& MainProtocolTwoWayAnonResponse::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void MainProtocolTwoWayAnonResponse::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void MainProtocolTwoWayAnonResponse::Decode(::fidl::Decoder* _decoder, MainProtocolTwoWayAnonResponse* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t MainProtocolTwoWayAnonResponse::Clone(MainProtocolTwoWayAnonResponse* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolTwoWayAnonWithErrorRequestTable;
const fidl_type_t* MainProtocolTwoWayAnonWithErrorRequest::FidlType = &test_protocollayoutssamelibrary_MainProtocolTwoWayAnonWithErrorRequestTable;

MainProtocolTwoWayAnonWithErrorRequest::MainProtocolTwoWayAnonWithErrorRequest() {}

MainProtocolTwoWayAnonWithErrorRequest::MainProtocolTwoWayAnonWithErrorRequest(MainProtocolTwoWayAnonWithErrorRequest&& other) {
  field_presence_ = other.field_presence_;
  if (field_presence_.IsSet<0>()) {
    Construct(&a_value_.value, std::move(other.a_value_.value));
  }
}

MainProtocolTwoWayAnonWithErrorRequest::~MainProtocolTwoWayAnonWithErrorRequest() {
  if (field_presence_.IsSet<0>()) {
    Destruct(&a_value_.value);
  }
}

MainProtocolTwoWayAnonWithErrorRequest& MainProtocolTwoWayAnonWithErrorRequest::operator=(MainProtocolTwoWayAnonWithErrorRequest&& other) {
  if (other.field_presence_.IsSet<0>()) {
    if (field_presence_.IsSet<0>()) {
      a_value_.value = std::move(other.a_value_.value);
    } else {
      field_presence_.Set<0>();
      Construct(&a_value_.value, std::move(other.a_value_.value));
    }
  } else if (field_presence_.IsSet<0>()) {
    field_presence_.Clear<0>();
    Destruct(&a_value_.value);
  }
  return *this;
}

bool MainProtocolTwoWayAnonWithErrorRequest::IsEmpty() const {
  return field_presence_.IsEmpty();
}
MainProtocolTwoWayAnonWithErrorRequest& MainProtocolTwoWayAnonWithErrorRequest::set_a(uint16_t _value) {
  if (!field_presence_.IsSet<0>()) {
    field_presence_.Set<0>();
    Construct(&a_value_.value, std::move(_value));
  } else {
    a_value_.value = std::move(_value);
  }
  return *this;
}

void MainProtocolTwoWayAnonWithErrorRequest::Encode(::fidl::Encoder* _encoder, size_t _offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  size_t max_ordinal = MaxOrdinal();
  ::fidl::EncodeVectorPointer(_encoder, max_ordinal, _offset);
  if (max_ordinal == 0) return;
  [[maybe_unused]] size_t base = _encoder->Alloc(max_ordinal * sizeof(fidl_envelope_t));
  if (field_presence_.IsSet<0>()) {
    const size_t length_before = _encoder->CurrentLength();
    const size_t handles_before = _encoder->CurrentHandleCount();

    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);

    if (::fidl::EncodingInlineSize<uint16_t>(_encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
      ::fidl::Encode(_encoder, &a_value_.value, envelope_base);

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
    } else {
      ::fidl::Encode(
        _encoder,
        &a_value_.value,
        _encoder->Alloc(::fidl::EncodingInlineSize<uint16_t, ::fidl::Encoder>(_encoder)));

      fidl_envelope_t* envelope = _encoder->GetPtr<fidl_envelope_t>(envelope_base);
      envelope->num_bytes = static_cast<uint32_t>(_encoder->CurrentLength() - length_before);
      envelope->num_handles = static_cast<uint16_t>(_encoder->CurrentHandleCount() - handles_before);
      envelope->flags = 0;
    }
  }
}

void MainProtocolTwoWayAnonWithErrorRequest::Decode(::fidl::Decoder* _decoder, MainProtocolTwoWayAnonWithErrorRequest* _value, size_t _offset) {
  fidl_vector_t* encoded = _decoder->GetPtr<fidl_vector_t>(_offset);
  [[maybe_unused]] size_t base;
  [[maybe_unused]] size_t count;
  if (!encoded->data) {
    goto clear_all;
  }

  base = _decoder->GetOffset(encoded->data);
  count = encoded->count;
  if (count >= 1) {
    size_t envelope_base = base + (1 - 1) * sizeof(fidl_envelope_t);
    fidl_envelope_t* envelope = _decoder->GetPtr<fidl_envelope_t>(envelope_base);
    if (*reinterpret_cast<const void* const*>(envelope) != nullptr) {
      ::fidl::Decode(_decoder, _value->mutable_a(),
        _decoder->EnvelopeValueOffset(envelope));
    } else {
      _value->clear_a();
    }
  } else {
    goto done_1;
  }

  

  return;

  // Clear unset values.
clear_all:
done_1:
  _value->clear_a();
  return;
}

zx_status_t MainProtocolTwoWayAnonWithErrorRequest::Clone(MainProtocolTwoWayAnonWithErrorRequest* result) const {
  if (field_presence_.IsSet<0>()) {
    zx_status_t _status = ::fidl::Clone(a_value_.value, result->mutable_a());
    if (_status != ZX_OK)
      return _status;
  } else {
    result->clear_a();
  }
  return ZX_OK;
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResponseTable;
const fidl_type_t* MainProtocol_TwoWayAnonWithError_Response::FidlType = &test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResponseTable;

MainProtocol_TwoWayAnonWithError_Response::MainProtocol_TwoWayAnonWithError_Response() {}

MainProtocol_TwoWayAnonWithError_Response::~MainProtocol_TwoWayAnonWithError_Response() {
  Destroy();
}

MainProtocol_TwoWayAnonWithError_Response::MainProtocol_TwoWayAnonWithError_Response(MainProtocol_TwoWayAnonWithError_Response&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

MainProtocol_TwoWayAnonWithError_Response& MainProtocol_TwoWayAnonWithError_Response::operator=(MainProtocol_TwoWayAnonWithError_Response&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_= std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

MainProtocol_TwoWayAnonWithError_Response MainProtocol_TwoWayAnonWithError_Response::WithB(bool&& val) {
  MainProtocol_TwoWayAnonWithError_Response result;
  result.set_b(std::move(val));
  return result;
}


void MainProtocol_TwoWayAnonWithError_Response::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void MainProtocol_TwoWayAnonWithError_Response::Decode(::fidl::Decoder* _decoder, MainProtocol_TwoWayAnonWithError_Response* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
  break;
    }
  }

}

zx_status_t MainProtocol_TwoWayAnonWithError_Response::Clone(MainProtocol_TwoWayAnonWithError_Response* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

MainProtocol_TwoWayAnonWithError_Response& MainProtocol_TwoWayAnonWithError_Response::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB);
  b_ = std::move(value);
  return *this;
}
MainProtocol_TwoWayAnonWithError_Response& MainProtocol_TwoWayAnonWithError_Response::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void MainProtocol_TwoWayAnonWithError_Response::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid);
}

void MainProtocol_TwoWayAnonWithError_Response::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response::Tag::kB:
        new (&b_) bool();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable;
const fidl_type_t* MainProtocol_TwoWayAnonWithError_Result::FidlType = &test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable;

MainProtocol_TwoWayAnonWithError_Result::MainProtocol_TwoWayAnonWithError_Result() {}

MainProtocol_TwoWayAnonWithError_Result::~MainProtocol_TwoWayAnonWithError_Result() {
  Destroy();
}

MainProtocol_TwoWayAnonWithError_Result::MainProtocol_TwoWayAnonWithError_Result(MainProtocol_TwoWayAnonWithError_Result&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse:
      new (&response_) ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response();
      response_ = std::move(other.response_);
      break;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr:
      err_ = std::move(other.err_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid):
      break;
  }
}

MainProtocol_TwoWayAnonWithError_Result& MainProtocol_TwoWayAnonWithError_Result::operator=(MainProtocol_TwoWayAnonWithError_Result&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response();
        response_ = std::move(other.response_);
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr:
        err_ = std::move(other.err_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid):
        break;
    }
  }
  return *this;
}

MainProtocol_TwoWayAnonWithError_Result MainProtocol_TwoWayAnonWithError_Result::WithResponse(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response&& val) {
  MainProtocol_TwoWayAnonWithError_Result result;
  result.set_response(std::move(val));
  return result;
}
MainProtocol_TwoWayAnonWithError_Result MainProtocol_TwoWayAnonWithError_Result::WithErr(uint32_t&& val) {
  MainProtocol_TwoWayAnonWithError_Result result;
  result.set_err(std::move(val));
  return result;
}


void MainProtocol_TwoWayAnonWithError_Result::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse: {
      if (::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &response_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &response_,
        encoder->Alloc(::fidl::EncodingInlineSize<::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr: {
      if (::fidl::EncodingInlineSize<uint32_t>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &err_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &err_,
        encoder->Alloc(::fidl::EncodingInlineSize<uint32_t, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    default:
      break;
  }
}

void MainProtocol_TwoWayAnonWithError_Result::Decode(::fidl::Decoder* _decoder, MainProtocol_TwoWayAnonWithError_Result* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse: {
      value->response_.~decltype(value->response_)();
      new (&value->response_) ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response();
      ::fidl::Decode(_decoder, &value->response_, value_offset);
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr: {
      ::fidl::Decode(_decoder, &value->err_, value_offset);
      break;
    }
    default: {
  break;
    }
  }

}

zx_status_t MainProtocol_TwoWayAnonWithError_Result::Clone(MainProtocol_TwoWayAnonWithError_Result* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse:
      new (&result->response_) ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response();
      return ::fidl::Clone(response_, &result->response_);
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr:
      return ::fidl::Clone(err_, &result->err_);
    default:return ZX_OK;
  }
}

MainProtocol_TwoWayAnonWithError_Result& MainProtocol_TwoWayAnonWithError_Result::set_response(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse);
  response_ = std::move(value);
  return *this;
}

MainProtocol_TwoWayAnonWithError_Result& MainProtocol_TwoWayAnonWithError_Result::set_err(uint32_t value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr);
  err_ = std::move(value);
  return *this;
}

void MainProtocol_TwoWayAnonWithError_Result::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse:
      response_.~decltype(response_)();
      break;
    case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr:
      break;
  
    default:
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid);
}

void MainProtocol_TwoWayAnonWithError_Result::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kResponse:
        new (&response_) ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Response();
        break;
      case ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result::Tag::kErr:
        new (&err_) uint32_t();
        break;
      default:
        break;
    }
  }
}


extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable;
const fidl_type_t* MainProtocolOnAnonRequest::FidlType = &test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable;

MainProtocolOnAnonRequest::MainProtocolOnAnonRequest() {}

MainProtocolOnAnonRequest::~MainProtocolOnAnonRequest() {
  Destroy();
}

MainProtocolOnAnonRequest::MainProtocolOnAnonRequest(MainProtocolOnAnonRequest&& other) : tag_(other.tag_) {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB:
      b_ = std::move(other.b_);
      break;
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid):
      break;
    default:
      new (&unknown_data_) decltype(unknown_data_);
      unknown_data_ = std::move(other.unknown_data_);
      break;
  }
}

MainProtocolOnAnonRequest& MainProtocolOnAnonRequest::operator=(MainProtocolOnAnonRequest&& other) {
  if (this != &other) {
    Destroy();
    tag_ = other.tag_;
    switch (tag_) {
      case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB:
        b_ = std::move(other.b_);
        break;
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid):
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        unknown_data_= std::move(other.unknown_data_);
        break;
    }
  }
  return *this;
}

MainProtocolOnAnonRequest MainProtocolOnAnonRequest::WithB(bool&& val) {
  MainProtocolOnAnonRequest result;
  result.set_b(std::move(val));
  return result;
}


void MainProtocolOnAnonRequest::Encode(::fidl::Encoder* encoder, size_t offset,
                         cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
  const size_t length_before = encoder->CurrentLength();
  const size_t handles_before = encoder->CurrentHandleCount();

  switch (Which()) {
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB: {
      if (::fidl::EncodingInlineSize<bool>(encoder) <= FIDL_ENVELOPE_INLINING_SIZE_THRESHOLD) {
        ::fidl::Encode(encoder, &b_, offset + offsetof(fidl_union_t, envelope));

        fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
        xunion->tag = tag_;
        xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
        xunion->envelope.flags = FIDL_ENVELOPE_FLAGS_INLINING_MASK;
        break;
      }

      ::fidl::Encode(
        encoder,
        &b_,
        encoder->Alloc(::fidl::EncodingInlineSize<bool, ::fidl::Encoder>(encoder)));

      fidl_union_t* xunion = encoder->GetPtr<fidl_union_t>(offset);
      xunion->tag = tag_;
      xunion->envelope.num_bytes = static_cast<uint32_t>(encoder->CurrentLength() - length_before);
      xunion->envelope.num_handles = static_cast<uint16_t>(encoder->CurrentHandleCount() - handles_before);
      xunion->envelope.flags = 0;
      break;
    }
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kUnknown: {
      ::fidl::EncodeUnknownBytes(encoder, &unknown_data_, offset + offsetof(fidl_union_t, envelope));
      *encoder->GetPtr<uint64_t>(offset) = tag_;
      break;
    }
    default:
      break;
  }
}

void MainProtocolOnAnonRequest::Decode(::fidl::Decoder* _decoder, MainProtocolOnAnonRequest* value, size_t offset) {
  fidl_union_t* xunion = _decoder->GetPtr<fidl_union_t>(offset);

  if (xunion->envelope.num_bytes == 0 &&
      xunion->envelope.num_handles == 0 &&
      xunion->envelope.flags == 0) {
    value->EnsureStorageInitialized(static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid));
    return;
  }

  value->EnsureStorageInitialized(xunion->tag);


  size_t value_offset = _decoder->EnvelopeValueOffset(&xunion->envelope);

  switch (value->tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB: {
      ::fidl::Decode(_decoder, &value->b_, value_offset);
      break;
    }
    default: {
  auto unknown_info = _decoder->EnvelopeUnknownDataInfo(&xunion->envelope);
      value->unknown_data_.resize(unknown_info.num_bytes);
      ::fidl::DecodeUnknownBytesContents(_decoder, &value->unknown_data_, unknown_info.value_offset);
  break;
    }
  }

}

zx_status_t MainProtocolOnAnonRequest::Clone(MainProtocolOnAnonRequest* result) const {
  result->Destroy();
  result->tag_ = tag_;
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid:
      return ZX_OK;
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB:
      return ::fidl::Clone(b_, &result->b_);
    default:
      new (&result->unknown_data_) decltype(unknown_data_);
      return ::fidl::Clone(unknown_data_, &result->unknown_data_);
    return ZX_OK;
  }
}

MainProtocolOnAnonRequest& MainProtocolOnAnonRequest::set_b(bool value) {
  EnsureStorageInitialized(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB);
  b_ = std::move(value);
  return *this;
}
MainProtocolOnAnonRequest& MainProtocolOnAnonRequest::SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes) {
  EnsureStorageInitialized(ordinal);
  unknown_data_ = std::move(bytes);
  return *this;
}

void MainProtocolOnAnonRequest::Destroy() {
  switch (tag_) {
    case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB:
      break;
  
    case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid):
      break;
    default:
      unknown_data_.~decltype(unknown_data_)();
      break;
  
  }
  tag_ = static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid);
}

void MainProtocolOnAnonRequest::EnsureStorageInitialized(::fidl_xunion_tag_t tag) {
  if (tag_ != tag) {
    Destroy();
    tag_ = tag;
    switch (tag_) {
      case static_cast<fidl_xunion_tag_t>(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::Invalid):
        break;
      case ::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest::Tag::kB:
        new (&b_) bool();
        break;
      default:
        new (&unknown_data_) decltype(unknown_data_);
        break;
    }
  }
}

//
// Proxies and stubs definitions
//

#ifdef __Fuchsia__

  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_TablePayloadTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_UnionPayloadTable;
  
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
  
  

}  // namespace _internal

ComposedProtocol::~ComposedProtocol() = default;

const fidl_type_t* ::test::protocollayoutssamelibrary::ComposedProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayAnonComposed_Ordinal:
      *out_is_known = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayNamedComposed_Ordinal:
      *out_is_known = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    default:
      return nullptr;
  }
}

const fidl_type_t* ComposedProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnAnonComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnNamedComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
        ;
    default:
      return nullptr;
  }
}

ComposedProtocol_EventSender::~ComposedProtocol_EventSender() = default;

ComposedProtocol_Sync::~ComposedProtocol_Sync() = default;

ComposedProtocol_Proxy::ComposedProtocol_Proxy(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

ComposedProtocol_Proxy::~ComposedProtocol_Proxy() = default;

zx_status_t ComposedProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnAnonComposed_Ordinal: {
      if (!OnAnonComposed) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnAnonComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnNamedComposed_Ordinal: {
      if (!OnNamedComposed) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnNamedComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::UnionPayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}


void ComposedProtocol_Proxy::OneWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayAnonComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::OneWayAnonComposed(&_encoder, &ComposedProtocolOneWayAnonComposedRequest), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ComposedProtocol_TwoWayAnonComposed_ResponseHandler(ComposedProtocol::TwoWayAnonComposedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ComposedProtocol::TwoWayAnonComposed\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable);
}

}  // namespace
void ComposedProtocol_Proxy::TwoWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, TwoWayAnonComposedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayAnonComposed(&_encoder, &ComposedProtocolTwoWayAnonComposedRequest), ComposedProtocol_TwoWayAnonComposed_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ComposedProtocol_TwoWayAnonComposedWithError_ResponseHandler(ComposedProtocol::TwoWayAnonComposedWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ComposedProtocol::TwoWayAnonComposedWithError\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable);
}

}  // namespace
void ComposedProtocol_Proxy::TwoWayAnonComposedWithError(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, TwoWayAnonComposedWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayAnonComposedWithError(&_encoder, &ComposedProtocolTwoWayAnonComposedWithErrorRequest), ComposedProtocol_TwoWayAnonComposedWithError_ResponseHandler(std::move(callback)));
}
void ComposedProtocol_Proxy::OneWayNamedComposed(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayNamedComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::OneWayNamedComposed(&_encoder, &TablePayload), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ComposedProtocol_TwoWayNamedComposed_ResponseHandler(ComposedProtocol::TwoWayNamedComposedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ComposedProtocol::TwoWayNamedComposed\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable);
}

}  // namespace
void ComposedProtocol_Proxy::TwoWayNamedComposed(::test::protocollayoutssamelibrary::UnionPayload UnionPayload, TwoWayNamedComposedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayNamedComposed(&_encoder, &UnionPayload), ComposedProtocol_TwoWayNamedComposed_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
ComposedProtocol_TwoWayNamedComposedWithError_ResponseHandler(ComposedProtocol::TwoWayNamedComposedWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for ComposedProtocol::TwoWayNamedComposedWithError\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable);
}

}  // namespace
void ComposedProtocol_Proxy::TwoWayNamedComposedWithError(::test::protocollayoutssamelibrary::TablePayload TablePayload, TwoWayNamedComposedWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayNamedComposedWithError(&_encoder, &TablePayload), ComposedProtocol_TwoWayNamedComposedWithError_ResponseHandler(std::move(callback)));
}

ComposedProtocol_Stub::ComposedProtocol_Stub(::test::protocollayoutssamelibrary::ComposedProtocol_Stub::ComposedProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

ComposedProtocol_Stub::~ComposedProtocol_Stub() = default;

namespace {

class ComposedProtocol_TwoWayAnonComposed_Responder final {
 public:
  ComposedProtocol_TwoWayAnonComposed_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse ComposedProtocolTwoWayAnonComposedResponse) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_ResponseEncoder::TwoWayAnonComposed(&_encoder, &ComposedProtocolTwoWayAnonComposedResponse));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class ComposedProtocol_TwoWayAnonComposedWithError_Responder final {
 public:
  ComposedProtocol_TwoWayAnonComposedWithError_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result ComposedProtocol_TwoWayAnonComposedWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_ResponseEncoder::TwoWayAnonComposedWithError(&_encoder, &ComposedProtocol_TwoWayAnonComposedWithError_Result));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class ComposedProtocol_TwoWayNamedComposed_Responder final {
 public:
  ComposedProtocol_TwoWayNamedComposed_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_ResponseEncoder::TwoWayNamedComposed(&_encoder, &TablePayload));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class ComposedProtocol_TwoWayNamedComposedWithError_Responder final {
 public:
  ComposedProtocol_TwoWayNamedComposedWithError_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result ComposedProtocol_TwoWayNamedComposedWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_ResponseEncoder::TwoWayNamedComposedWithError(&_encoder, &ComposedProtocol_TwoWayNamedComposedWithError_Result));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

}  // namespace

zx_status_t ComposedProtocol_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocollayoutssamelibrary::ComposedProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (!message.has_only_header()) {
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
      return status;
    }
  }

  if (response.needs_response() != needs_response) {
    if (needs_response) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message needing a response with no txid");
    } else {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid");
    }
    return ZX_ERR_INVALID_ARGS;
  }

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayAnonComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayAnonComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolOneWayAnonComposedRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnonComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest>(&decoder, 0 + sizeof(fidl_message_header_t)), ComposedProtocol_TwoWayAnonComposed_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnonComposedWithError(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedWithErrorRequest>(&decoder, 0 + sizeof(fidl_message_header_t)), ComposedProtocol_TwoWayAnonComposedWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayNamedComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayNamedComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayNamedComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::UnionPayload>(&decoder, 0 + sizeof(fidl_message_header_t)), ComposedProtocol_TwoWayNamedComposed_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayNamedComposedWithError(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)), ComposedProtocol_TwoWayNamedComposedWithError_Responder(std::move(response)));
      break;
    }
    default: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}
void ComposedProtocol_Stub::OnAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest ComposedProtocolOnAnonComposedRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnAnonComposed_DynamicFlags);
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;sender_()->Send(resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_ResponseEncoder::OnAnonComposed(&_encoder, &ComposedProtocolOnAnonComposedRequest));
}
void ComposedProtocol_Stub::OnNamedComposed(::test::protocollayoutssamelibrary::UnionPayload UnionPayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OnNamedComposed_DynamicFlags);
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;sender_()->Send(resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_ResponseEncoder::OnNamedComposed(&_encoder, &UnionPayload));
}

ComposedProtocol_SyncProxy::ComposedProtocol_SyncProxy(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

ComposedProtocol_SyncProxy::~ComposedProtocol_SyncProxy() = default;

zx_status_t ComposedProtocol_SyncProxy::OneWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayAnonComposed_DynamicFlags);
    const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
  return proxy_.Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::OneWayAnonComposed(&_encoder, &ComposedProtocolOneWayAnonComposedRequest));
}

zx_status_t ComposedProtocol_SyncProxy::TwoWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse* out_ComposedProtocolTwoWayAnonComposedResponse) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposed_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayAnonComposed(&_encoder, &ComposedProtocolTwoWayAnonComposedRequest), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocolTwoWayAnonComposedResponse = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t ComposedProtocol_SyncProxy::TwoWayAnonComposedWithError(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result* out_ComposedProtocol_TwoWayAnonComposedWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayAnonComposedWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayAnonComposedWithError(&_encoder, &ComposedProtocolTwoWayAnonComposedWithErrorRequest), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocol_TwoWayAnonComposedWithError_Result = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t ComposedProtocol_SyncProxy::OneWayNamedComposed(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_OneWayNamedComposed_DynamicFlags);
    const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  return proxy_.Send(req_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::OneWayNamedComposed(&_encoder, &TablePayload));
}

zx_status_t ComposedProtocol_SyncProxy::TwoWayNamedComposed(::test::protocollayoutssamelibrary::UnionPayload UnionPayload, ::test::protocollayoutssamelibrary::TablePayload* out_TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposed_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayNamedComposed(&_encoder, &UnionPayload), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_TablePayload = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t ComposedProtocol_SyncProxy::TwoWayNamedComposedWithError(::test::protocollayoutssamelibrary::TablePayload TablePayload, ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result* out_ComposedProtocol_TwoWayNamedComposedWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kComposedProtocol_TwoWayNamedComposedWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::ComposedProtocol_RequestEncoder::TwoWayNamedComposedWithError(&_encoder, &TablePayload), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocol_TwoWayNamedComposedWithError_Result = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__


#ifdef __Fuchsia__

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  namespace _internal {
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable;
  
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolOneWayAnonRequestTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolTwoWayAnonRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolTwoWayAnonWithErrorRequestTable;
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable;
  
  
__LOCAL extern "C" const fidl_type_t test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable;

}  // namespace _internal

MainProtocol::~MainProtocol() = default;

const fidl_type_t* ::test::protocollayoutssamelibrary::MainProtocol_RequestDecoder::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnonComposed_Ordinal:
      *out_is_known = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayNamedComposed_Ordinal:
      *out_is_known = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayLocal_Ordinal:
      *out_is_known = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnon_Ordinal:
      *out_is_known = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOneWayAnonRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_Ordinal:
      *out_is_known = true;
      *out_needs_response = true;
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonWithErrorRequestTable;
        ;
    default:
      return nullptr;
  }
}

const fidl_type_t* MainProtocol_ResponseDecoder::GetType(uint64_t ordinal) {
  switch (ordinal) {
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnonComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnNamedComposed_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnLocal_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable;
        ;
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnon_Ordinal:
      return &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable;
        ;
    default:
      return nullptr;
  }
}

MainProtocol_EventSender::~MainProtocol_EventSender() = default;

MainProtocol_Sync::~MainProtocol_Sync() = default;

MainProtocol_Proxy::MainProtocol_Proxy(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

MainProtocol_Proxy::~MainProtocol_Proxy() = default;

zx_status_t MainProtocol_Proxy::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnonComposed_Ordinal: {
      if (!OnAnonComposed) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnAnonComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnNamedComposed_Ordinal: {
      if (!OnNamedComposed) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnNamedComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::UnionPayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnLocal_Ordinal: {
      if (!OnLocal) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnLocal(::fidl::DecodeAs<::test::protocollayoutssamelibrary::UnionPayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnon_Ordinal: {
      if (!OnAnon) {
        status = ZX_OK;
        break;
      }
      const char* error_msg = nullptr;
      status = message.Decode(&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable, error_msg);
        break;
      }
      ::fidl::Decoder decoder(std::move(message));
      OnAnon(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    default: {
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}


void MainProtocol_Proxy::OneWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnonComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayAnonComposed(&_encoder, &ComposedProtocolOneWayAnonComposedRequest), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayAnonComposed_ResponseHandler(MainProtocol::TwoWayAnonComposedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayAnonComposed\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, TwoWayAnonComposedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnonComposed(&_encoder, &ComposedProtocolTwoWayAnonComposedRequest), MainProtocol_TwoWayAnonComposed_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayAnonComposedWithError_ResponseHandler(MainProtocol::TwoWayAnonComposedWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayAnonComposedWithError\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayAnonComposedWithError(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, TwoWayAnonComposedWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnonComposedWithError(&_encoder, &ComposedProtocolTwoWayAnonComposedWithErrorRequest), MainProtocol_TwoWayAnonComposedWithError_ResponseHandler(std::move(callback)));
}
void MainProtocol_Proxy::OneWayNamedComposed(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayNamedComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayNamedComposed(&_encoder, &TablePayload), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayNamedComposed_ResponseHandler(MainProtocol::TwoWayNamedComposedCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayNamedComposed\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayNamedComposed(::test::protocollayoutssamelibrary::UnionPayload UnionPayload, TwoWayNamedComposedCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayNamedComposed(&_encoder, &UnionPayload), MainProtocol_TwoWayNamedComposed_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayNamedComposedWithError_ResponseHandler(MainProtocol::TwoWayNamedComposedWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayNamedComposedWithError\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayNamedComposedWithError(::test::protocollayoutssamelibrary::TablePayload TablePayload, TwoWayNamedComposedWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayNamedComposedWithError(&_encoder, &TablePayload), MainProtocol_TwoWayNamedComposedWithError_ResponseHandler(std::move(callback)));
}
void MainProtocol_Proxy::OneWayLocal(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayLocal_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayLocal_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayLocal(&_encoder, &TablePayload), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayLocal_ResponseHandler(MainProtocol::TwoWayLocalCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayLocal\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayLocal(::test::protocollayoutssamelibrary::UnionPayload UnionPayload, TwoWayLocalCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayLocal(&_encoder, &UnionPayload), MainProtocol_TwoWayLocal_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayLocalWithError_ResponseHandler(MainProtocol::TwoWayLocalWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayLocalWithError\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayLocalWithError(::test::protocollayoutssamelibrary::TablePayload TablePayload, TwoWayLocalWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayLocalWithError(&_encoder, &TablePayload), MainProtocol_TwoWayLocalWithError_ResponseHandler(std::move(callback)));
}
void MainProtocol_Proxy::OneWayAnon(::test::protocollayoutssamelibrary::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnon_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnon_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOneWayAnonRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayAnon(&_encoder, &MainProtocolOneWayAnonRequest), nullptr);
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayAnon_ResponseHandler(MainProtocol::TwoWayAnonCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayAnon\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonResponse>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayAnon(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest, TwoWayAnonCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnon(&_encoder, &MainProtocolTwoWayAnonRequest), MainProtocol_TwoWayAnon_ResponseHandler(std::move(callback)));
}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
MainProtocol_TwoWayAnonWithError_ResponseHandler(MainProtocol::TwoWayAnonWithErrorCallback&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for MainProtocol::TwoWayAnonWithError\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
        ::fidl::Decoder decoder(std::move(message));
        callback_(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result>(&decoder, 0 + sizeof(fidl_message_header_t)));
        return ZX_OK;
      }, &::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable);
}

}  // namespace
void MainProtocol_Proxy::TwoWayAnonWithError(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest, TwoWayAnonWithErrorCallback callback) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonWithErrorRequestTable;
  controller_->Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnonWithError(&_encoder, &MainProtocolTwoWayAnonWithErrorRequest), MainProtocol_TwoWayAnonWithError_ResponseHandler(std::move(callback)));
}

MainProtocol_Stub::MainProtocol_Stub(::test::protocollayoutssamelibrary::MainProtocol_Stub::MainProtocol_clazz* impl) : impl_(impl) {
  (void)impl_;
}

MainProtocol_Stub::~MainProtocol_Stub() = default;

namespace {

class MainProtocol_TwoWayAnonComposed_Responder final {
 public:
  MainProtocol_TwoWayAnonComposed_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse ComposedProtocolTwoWayAnonComposedResponse) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayAnonComposed(&_encoder, &ComposedProtocolTwoWayAnonComposedResponse));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayAnonComposedWithError_Responder final {
 public:
  MainProtocol_TwoWayAnonComposedWithError_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result ComposedProtocol_TwoWayAnonComposedWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayAnonComposedWithError(&_encoder, &ComposedProtocol_TwoWayAnonComposedWithError_Result));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayNamedComposed_Responder final {
 public:
  MainProtocol_TwoWayNamedComposed_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayNamedComposed(&_encoder, &TablePayload));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayNamedComposedWithError_Responder final {
 public:
  MainProtocol_TwoWayNamedComposedWithError_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result ComposedProtocol_TwoWayNamedComposedWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayNamedComposedWithError(&_encoder, &ComposedProtocol_TwoWayNamedComposedWithError_Result));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayLocal_Responder final {
 public:
  MainProtocol_TwoWayLocal_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayLocal(&_encoder, &TablePayload));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayLocalWithError_Responder final {
 public:
  MainProtocol_TwoWayLocalWithError_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result MainProtocol_TwoWayLocalWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayLocalWithError(&_encoder, &MainProtocol_TwoWayLocalWithError_Result));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayAnon_Responder final {
 public:
  MainProtocol_TwoWayAnon_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonResponse MainProtocolTwoWayAnonResponse) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayAnon(&_encoder, &MainProtocolTwoWayAnonResponse));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

class MainProtocol_TwoWayAnonWithError_Responder final {
 public:
  MainProtocol_TwoWayAnonWithError_Responder(::fidl::internal::PendingResponse response)
      : response_(std::move(response)) {}

  void operator()(::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result MainProtocol_TwoWayAnonWithError_Result) {
    ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
    const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable;
    response_.Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::TwoWayAnonWithError(&_encoder, &MainProtocol_TwoWayAnonWithError_Result));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};

}  // namespace

zx_status_t MainProtocol_Stub::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = ::test::protocollayoutssamelibrary::MainProtocol_RequestDecoder::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (!message.has_only_header()) {
    if (request_type == nullptr) {
      return ZX_ERR_NOT_SUPPORTED;
    }
    const char* error_msg = nullptr;
    zx_status_t status = message.Decode(request_type, &error_msg);
    if (status != ZX_OK) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, error_msg);
      return status;
    }
  }

  if (response.needs_response() != needs_response) {
    if (needs_response) {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message needing a response with no txid");
    } else {
      FIDL_REPORT_DECODING_ERROR(message, request_type, "Message not needing a response with a txid");
    }
    return ZX_ERR_INVALID_ARGS;
  }

  uint64_t ordinal = message.ordinal();
  switch (ordinal) {
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnonComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayAnonComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolOneWayAnonComposedRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnonComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayAnonComposed_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnonComposedWithError(::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedWithErrorRequest>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayAnonComposedWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayNamedComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayNamedComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayNamedComposed(::fidl::DecodeAs<::test::protocollayoutssamelibrary::UnionPayload>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayNamedComposed_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayNamedComposedWithError(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayNamedComposedWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayLocal_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayLocal(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayLocal(::fidl::DecodeAs<::test::protocollayoutssamelibrary::UnionPayload>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayLocal_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayLocalWithError(::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayLocalWithError_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnon_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->OneWayAnon(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocolOneWayAnonRequest>(&decoder, 0 + sizeof(fidl_message_header_t)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnon(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayAnon_Responder(std::move(response)));
      break;
    }
    case ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_Ordinal:
    {
      ::fidl::Decoder decoder(std::move(message));
      impl_->TwoWayAnonWithError(::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonWithErrorRequest>(&decoder, 0 + sizeof(fidl_message_header_t)), MainProtocol_TwoWayAnonWithError_Responder(std::move(response)));
      break;
    }
    default: {
      // Unknown ordinals are handled at the beginning of dispatching, so this
      // should be unreachable.
      ZX_PANIC("Unreachable: unknown ordinals handled earlier.");
    }
  }
  return ZX_OK;
}
void MainProtocol_Stub::OnAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolOnAnonComposedRequest ComposedProtocolOnAnonComposedRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnonComposed_DynamicFlags);
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOnAnonComposedRequestTable;sender_()->Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::OnAnonComposed(&_encoder, &ComposedProtocolOnAnonComposedRequest));
}
void MainProtocol_Stub::OnNamedComposed(::test::protocollayoutssamelibrary::UnionPayload UnionPayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OnNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnNamedComposed_DynamicFlags);
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;sender_()->Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::OnNamedComposed(&_encoder, &UnionPayload));
}
void MainProtocol_Stub::OnLocal(::test::protocollayoutssamelibrary::UnionPayload UnionPayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OnLocal_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnLocal_DynamicFlags);
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;sender_()->Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::OnLocal(&_encoder, &UnionPayload));
}
void MainProtocol_Stub::OnAnon(::test::protocollayoutssamelibrary::MainProtocolOnAnonRequest MainProtocolOnAnonRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnon_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OnAnon_DynamicFlags);
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOnAnonRequestTable;sender_()->Send(resp_type, ::test::protocollayoutssamelibrary::MainProtocol_ResponseEncoder::OnAnon(&_encoder, &MainProtocolOnAnonRequest));
}

MainProtocol_SyncProxy::MainProtocol_SyncProxy(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

MainProtocol_SyncProxy::~MainProtocol_SyncProxy() = default;

zx_status_t MainProtocol_SyncProxy::OneWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolOneWayAnonComposedRequest ComposedProtocolOneWayAnonComposedRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnonComposed_DynamicFlags);
    const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolOneWayAnonComposedRequestTable;
  return proxy_.Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayAnonComposed(&_encoder, &ComposedProtocolOneWayAnonComposedRequest));
}

zx_status_t MainProtocol_SyncProxy::TwoWayAnonComposed(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedRequest ComposedProtocolTwoWayAnonComposedRequest, ::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse* out_ComposedProtocolTwoWayAnonComposedResponse) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposed_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedRequestTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnonComposed(&_encoder, &ComposedProtocolTwoWayAnonComposedRequest), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocolTwoWayAnonComposedResponse = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayAnonComposedWithError(::test::protocollayoutssamelibrary::ComposedProtocolTwoWayAnonComposedWithErrorRequest ComposedProtocolTwoWayAnonComposedWithErrorRequest, ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result* out_ComposedProtocol_TwoWayAnonComposedWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonComposedWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocolTwoWayAnonComposedWithErrorRequestTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayAnonComposedWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnonComposedWithError(&_encoder, &ComposedProtocolTwoWayAnonComposedWithErrorRequest), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocol_TwoWayAnonComposedWithError_Result = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayAnonComposedWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::OneWayNamedComposed(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayNamedComposed_DynamicFlags);
    const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  return proxy_.Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayNamedComposed(&_encoder, &TablePayload));
}

zx_status_t MainProtocol_SyncProxy::TwoWayNamedComposed(::test::protocollayoutssamelibrary::UnionPayload UnionPayload, ::test::protocollayoutssamelibrary::TablePayload* out_TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposed_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayNamedComposed(&_encoder, &UnionPayload), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_TablePayload = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayNamedComposedWithError(::test::protocollayoutssamelibrary::TablePayload TablePayload, ::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result* out_ComposedProtocol_TwoWayNamedComposedWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayNamedComposedWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_ComposedProtocol_TwoWayNamedComposedWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayNamedComposedWithError(&_encoder, &TablePayload), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_ComposedProtocol_TwoWayNamedComposedWithError_Result = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::ComposedProtocol_TwoWayNamedComposedWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::OneWayLocal(::test::protocollayoutssamelibrary::TablePayload TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayLocal_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayLocal_DynamicFlags);
    const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  return proxy_.Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayLocal(&_encoder, &TablePayload));
}

zx_status_t MainProtocol_SyncProxy::TwoWayLocal(::test::protocollayoutssamelibrary::UnionPayload UnionPayload, ::test::protocollayoutssamelibrary::TablePayload* out_TablePayload) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocal_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_UnionPayloadTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayLocal(&_encoder, &UnionPayload), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_TablePayload = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::TablePayload>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayLocalWithError(::test::protocollayoutssamelibrary::TablePayload TablePayload, ::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result* out_MainProtocol_TwoWayLocalWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayLocalWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_TablePayloadTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayLocalWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayLocalWithError(&_encoder, &TablePayload), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_MainProtocol_TwoWayLocalWithError_Result = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocol_TwoWayLocalWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::OneWayAnon(::test::protocollayoutssamelibrary::MainProtocolOneWayAnonRequest MainProtocolOneWayAnonRequest) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnon_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_OneWayAnon_DynamicFlags);
    const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolOneWayAnonRequestTable;
  return proxy_.Send(req_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::OneWayAnon(&_encoder, &MainProtocolOneWayAnonRequest));
}

zx_status_t MainProtocol_SyncProxy::TwoWayAnon(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonRequest MainProtocolTwoWayAnonRequest, ::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonResponse* out_MainProtocolTwoWayAnonResponse) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnon_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonRequestTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonResponseTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnon(&_encoder, &MainProtocolTwoWayAnonRequest), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_MainProtocolTwoWayAnonResponse = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonResponse>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

zx_status_t MainProtocol_SyncProxy::TwoWayAnonWithError(::test::protocollayoutssamelibrary::MainProtocolTwoWayAnonWithErrorRequest MainProtocolTwoWayAnonWithErrorRequest, ::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result* out_MainProtocol_TwoWayAnonWithError_Result) {
  ::fidl::MessageEncoder _encoder(::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_Ordinal, ::test::protocollayoutssamelibrary::internal::kMainProtocol_TwoWayAnonWithError_DynamicFlags);
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocolTwoWayAnonWithErrorRequestTable;
  const fidl_type_t* resp_type =&::test::protocollayoutssamelibrary::_internal::test_protocollayoutssamelibrary_MainProtocol_TwoWayAnonWithError_ResultTable;
  zx_status_t status_ = proxy_.Call(req_type, resp_type, ::test::protocollayoutssamelibrary::MainProtocol_RequestEncoder::TwoWayAnonWithError(&_encoder, &MainProtocolTwoWayAnonWithErrorRequest), &response_);
  if (status_ != ZX_OK)
    return status_;
  ::fidl::Decoder decoder_(std::move(response_));
  *out_MainProtocol_TwoWayAnonWithError_Result = ::fidl::DecodeAs<::test::protocollayoutssamelibrary::MainProtocol_TwoWayAnonWithError_Result>(&decoder_, 0 + sizeof(fidl_message_header_t));
  return ZX_OK;
}

#endif  // __Fuchsia__

}  // namespace protocollayoutssamelibrary
}  // namespace test

