// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

#ifndef CTF_BUILD_SCRIPTS_TESTDATA_FIDL_H_
#define CTF_BUILD_SCRIPTS_TESTDATA_FIDL_H_

#include <fuchsia/diagnostics/cpp/fidl.h>

#include <zx/cpp/fidl.h>

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

//
// Domain objects declarations (i.e. "natural types" in unified bindings).
//
namespace fuchsia {
namespace diagnostics {
namespace stream {
#ifdef __Fuchsia__

/// A component with records for the Diagnostics system to retrieve.
///
/// To record diagnostics, a component allocates a VMO and begins writing
/// records into the buffer, incrementing a header value after each write to
/// inform readers how much of the buffer has been filled.
///
/// If any retrievers are connected, the `Source` sends them `OnBufferInit`
/// events for each diagnostic buffer created.
///
/// When the buffer fills, the `Source` sends `OnBufferDone` to the retrievers,
/// and will wait for all notified retrievers to reply with `RetireBuffer` when
/// they have finished reading from the buffer.
///
/// When all readers of the buffer have finished, the `Source` may recycle the
/// buffer by zeroing it and sending `OnBufferInit` again to connected
/// retrievers.
///
/// Once a `Source` has sent `OnBufferDone` to a retriever, it is up to the
/// `Source` to handle new records that are generated while the retriever drains
/// the buffer. Double buffering is recommended to prevent excessive blocking,
/// but this protocol does not mandate a specific approach to handling records
/// generated while buffers are full.
class Source;
using SourceHandle = ::fidl::InterfaceHandle<Source>;
#endif  // __Fuchsia__

class Value;

class Argument;

class Record;

#ifdef __Fuchsia__

namespace _internal {
__LOCAL extern "C" const fidl_type_t fuchsia_diagnostics_stream_SourceRetireBufferRequestTable;

}  // namespace _internal
class Source_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage RetireBuffer(::fidl::Encoder* _encoder, uint64_t* buffer) {
    switch (_encoder->wire_format()) {
      case ::fidl::internal::WireFormatVersion::kV1:
        _encoder->Alloc(24 - sizeof(fidl_message_header_t));
        break;
      case ::fidl::internal::WireFormatVersion::kV2:
        _encoder->Alloc(24 - sizeof(fidl_message_header_t));
        break;
    }

    if (_encoder->wire_format() == ::fidl::internal::WireFormatVersion::kV1) {
      ::fidl::Encode(_encoder, buffer, 16);

    } else {
      ::fidl::Encode(_encoder, buffer, 16);
    }

    return _encoder->GetMessage();
  }
};
namespace _internal {
__LOCAL extern "C" const fidl_type_t fuchsia_diagnostics_stream_SourceOnBufferInitEventTable;

__LOCAL extern "C" const fidl_type_t fuchsia_diagnostics_stream_SourceOnBufferDoneEventTable;

}  // namespace _internal
class Source_ResponseEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage OnBufferInit(::fidl::Encoder* _encoder, ::zx::vmo* latest) {
    switch (_encoder->wire_format()) {
      case ::fidl::internal::WireFormatVersion::kV1:
        _encoder->Alloc(24 - sizeof(fidl_message_header_t));
        break;
      case ::fidl::internal::WireFormatVersion::kV2:
        _encoder->Alloc(24 - sizeof(fidl_message_header_t));
        break;
    }

    if (_encoder->wire_format() == ::fidl::internal::WireFormatVersion::kV1) {
      ::fidl::Encode(_encoder, latest, 16,
                     ::fidl::HandleInformation{
                         .object_type = ZX_OBJ_TYPE_VMO,
                         .rights = 0x80000000,
                     });

    } else {
      ::fidl::Encode(_encoder, latest, 16,
                     ::fidl::HandleInformation{
                         .object_type = ZX_OBJ_TYPE_VMO,
                         .rights = 0x80000000,
                     });
    }

    return _encoder->GetMessage();
  }
  static ::fidl::HLCPPOutgoingMessage OnBufferDone(::fidl::Encoder* _encoder, uint64_t* buffer) {
    switch (_encoder->wire_format()) {
      case ::fidl::internal::WireFormatVersion::kV1:
        _encoder->Alloc(24 - sizeof(fidl_message_header_t));
        break;
      case ::fidl::internal::WireFormatVersion::kV2:
        _encoder->Alloc(24 - sizeof(fidl_message_header_t));
        break;
    }

    if (_encoder->wire_format() == ::fidl::internal::WireFormatVersion::kV1) {
      ::fidl::Encode(_encoder, buffer, 16);

    } else {
      ::fidl::Encode(_encoder, buffer, 16);
    }

    return _encoder->GetMessage();
  }
};
#endif  // __Fuchsia__

/// An argument value which can be one of several types.
class Value final {
 public:
  static const fidl_type_t* FidlType;

  Value();
  ~Value();

  Value(Value&&);
  Value& operator=(Value&&);

  static Value WithSignedInt(int64_t&&);
  static Value WithUnsignedInt(uint64_t&&);
  static Value WithFloating(double&&);
  static Value WithText(::std::string&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,
    Empty = kUnknown,  // DEPRECATED: use kUnknown instead.

    kSignedInt = 1,    // 0x1
    kUnsignedInt = 2,  // 0x2
    kFloating = 3,     // 0x3
    kText = 4,         // 0x4
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<Value> New() { return ::std::make_unique<Value>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              std::optional<::fidl::HandleInformation> maybe_handle_info = std::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Value* value, size_t offset);
  zx_status_t Clone(Value* result) const;

  bool has_invalid_tag() const { return tag_ == Invalid; }

  bool is_signed_int() const {
    return tag_ == ::fuchsia::diagnostics::stream::Value::Tag::kSignedInt;
  }

  /// A signed integral argument.
  int64_t& signed_int() {
    EnsureStorageInitialized(::fuchsia::diagnostics::stream::Value::Tag::kSignedInt);
    return signed_int_;
  }

  /// A signed integral argument.
  const int64_t& signed_int() const {
    ZX_ASSERT(is_signed_int());
    return signed_int_;
  }
  Value& set_signed_int(int64_t value);

  bool is_unsigned_int() const {
    return tag_ == ::fuchsia::diagnostics::stream::Value::Tag::kUnsignedInt;
  }

  /// An unsigned integral argument.
  uint64_t& unsigned_int() {
    EnsureStorageInitialized(::fuchsia::diagnostics::stream::Value::Tag::kUnsignedInt);
    return unsigned_int_;
  }

  /// An unsigned integral argument.
  const uint64_t& unsigned_int() const {
    ZX_ASSERT(is_unsigned_int());
    return unsigned_int_;
  }
  Value& set_unsigned_int(uint64_t value);

  bool is_floating() const { return tag_ == ::fuchsia::diagnostics::stream::Value::Tag::kFloating; }

  /// A double-precision floating-point argument.
  double& floating() {
    EnsureStorageInitialized(::fuchsia::diagnostics::stream::Value::Tag::kFloating);
    return floating_;
  }

  /// A double-precision floating-point argument.
  const double& floating() const {
    ZX_ASSERT(is_floating());
    return floating_;
  }
  Value& set_floating(double value);

  bool is_text() const { return tag_ == ::fuchsia::diagnostics::stream::Value::Tag::kText; }

  /// A UTF8 text argument.
  ::std::string& text() {
    EnsureStorageInitialized(::fuchsia::diagnostics::stream::Value::Tag::kText);
    return text_;
  }

  /// A UTF8 text argument.
  const ::std::string& text() const {
    ZX_ASSERT(is_text());
    return text_;
  }
  Value& set_text(::std::string value);
  Value& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::fuchsia::diagnostics::stream::Value::Tag Which() const {
    switch (tag_) {
      case ::fuchsia::diagnostics::stream::Value::Tag::Invalid:
      case ::fuchsia::diagnostics::stream::Value::Tag::kSignedInt:
      case ::fuchsia::diagnostics::stream::Value::Tag::kUnsignedInt:
      case ::fuchsia::diagnostics::stream::Value::Tag::kFloating:
      case ::fuchsia::diagnostics::stream::Value::Tag::kText:
        return ::fuchsia::diagnostics::stream::Value::Tag(tag_);
      default:
        return ::fuchsia::diagnostics::stream::Value::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal()
  // only when you need access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const { return tag_; }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::fuchsia::diagnostics::stream::Value::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::fuchsia::diagnostics::stream::Value>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ =
      static_cast<fidl_xunion_tag_t>(::fuchsia::diagnostics::stream::Value::Tag::Invalid);
  union {
    int64_t signed_int_;
    uint64_t unsigned_int_;
    double floating_;
    ::std::string text_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::fuchsia::diagnostics::stream::Value& value,
                         ::fuchsia::diagnostics::stream::Value* result) {
  return value.Clone(result);
}

using ValuePtr = ::std::unique_ptr<Value>;

/// A named key-value pair in the diagnostic record.
class Argument final {
 public:
  static const fidl_type_t* FidlType;

  /// The name of the argument.
  ::std::string name{};

  /// The value of the argument.
  ::fuchsia::diagnostics::stream::Value value{};

  static inline ::std::unique_ptr<Argument> New() { return ::std::make_unique<Argument>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              std::optional<::fidl::HandleInformation> maybe_handle_info = std::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Argument* value, size_t _offset);
  zx_status_t Clone(Argument* result) const;
};

inline zx_status_t Clone(const ::fuchsia::diagnostics::stream::Argument& _value,
                         ::fuchsia::diagnostics::stream::Argument* _result) {
  return _value.Clone(_result);
}

using ArgumentPtr = ::std::unique_ptr<Argument>;

/// A record in the diagnostic stream.
class Record final {
 public:
  static const fidl_type_t* FidlType;

  /// The monotonic time at which the record was generated.
  int64_t timestamp{};

  /// Severity of the record.
  ::fuchsia::diagnostics::Severity severity{};

  /// The key-value pairs which make up this record.
  ::std::vector<::fuchsia::diagnostics::stream::Argument> arguments{};

  static inline ::std::unique_ptr<Record> New() { return ::std::make_unique<Record>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              std::optional<::fidl::HandleInformation> maybe_handle_info = std::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Record* value, size_t _offset);
  zx_status_t Clone(Record* result) const;
};

inline zx_status_t Clone(const ::fuchsia::diagnostics::stream::Record& _value,
                         ::fuchsia::diagnostics::stream::Record* _result) {
  return _value.Clone(_result);
}

using RecordPtr = ::std::unique_ptr<Record>;

/// The maximum string length which we can encode into the tracing format.
constexpr uint32_t MAX_TEXT_ARG_LENGTH = 32768u;

/// A small(ish) limit on the length of argument names is used because argument
/// names are expected to be used repeatedly, many times.
constexpr uint32_t MAX_ARG_NAME_LENGTH = 256u;

/// Maximum number of arguments that can be encoded per record, as specified by
/// the tracing format:
///
/// https://fuchsia.dev/fuchsia-src/development/tracing/trace-format#arguments
constexpr uint32_t MAX_ARGS = 15u;

}  // namespace stream
}  // namespace diagnostics
}  // namespace fuchsia
namespace fidl {
template <>
struct IsFidlXUnion<::fuchsia::diagnostics::stream::Value> : public std::true_type {};

template <>
struct CodingTraits<::fuchsia::diagnostics::stream::Value>
    : public EncodableCodingTraits<::fuchsia::diagnostics::stream::Value, 24, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::fuchsia::diagnostics::stream::Value>> {
  static constexpr size_t inline_size_v1_no_ee = 24;
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder,
                     std::unique_ptr<::fuchsia::diagnostics::stream::Value>* value, size_t offset,
                     std::optional<::fidl::HandleInformation> maybe_handle_info) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder,
                     std::unique_ptr<::fuchsia::diagnostics::stream::Value>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::fuchsia::diagnostics::stream::Value);

    ::fuchsia::diagnostics::stream::Value::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::fuchsia::diagnostics::stream::Value& value,
                         ::fuchsia::diagnostics::stream::Value* result) {
  return ::fuchsia::diagnostics::stream::Clone(value, result);
}

template <>
struct Equality<::fuchsia::diagnostics::stream::Value> {
  bool operator()(const ::fuchsia::diagnostics::stream::Value& _lhs,
                  const ::fuchsia::diagnostics::stream::Value& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::fuchsia::diagnostics::stream::Value::Tag::Invalid):
        return true;
      case ::fuchsia::diagnostics::stream::Value::Tag::kSignedInt:
        return ::fidl::Equals(_lhs.signed_int_, _rhs.signed_int_);
      case ::fuchsia::diagnostics::stream::Value::Tag::kUnsignedInt:
        return ::fidl::Equals(_lhs.unsigned_int_, _rhs.unsigned_int_);
      case ::fuchsia::diagnostics::stream::Value::Tag::kFloating:
        return ::fidl::Equals(_lhs.floating_, _rhs.floating_);
      case ::fuchsia::diagnostics::stream::Value::Tag::kText:
        return ::fidl::Equals(_lhs.text_, _rhs.text_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::fuchsia::diagnostics::stream::Argument>
    : public EncodableCodingTraits<::fuchsia::diagnostics::stream::Argument, 40, 32> {};

template <>
struct HasPadding<::fuchsia::diagnostics::stream::Argument> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fuchsia::diagnostics::stream::Argument>
    : public internal::BoolConstant<
          !HasPadding<::fuchsia::diagnostics::stream::Argument>::value &&
          IsMemcpyCompatible<::fuchsia::diagnostics::stream::Value>::value &&
          IsMemcpyCompatible<::std::string>::value> {};

inline zx_status_t Clone(const ::fuchsia::diagnostics::stream::Argument& value,
                         ::fuchsia::diagnostics::stream::Argument* result) {
  return ::fuchsia::diagnostics::stream::Clone(value, result);
}

template <>
struct Equality<::fuchsia::diagnostics::stream::Argument> {
  bool operator()(const ::fuchsia::diagnostics::stream::Argument& _lhs,
                  const ::fuchsia::diagnostics::stream::Argument& _rhs) const {
    if (!::fidl::Equals(_lhs.name, _rhs.name)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.value, _rhs.value)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::fuchsia::diagnostics::stream::Record>
    : public EncodableCodingTraits<::fuchsia::diagnostics::stream::Record, 32, 32> {};

template <>
struct HasPadding<::fuchsia::diagnostics::stream::Record> : public std::true_type {};

template <>
struct IsMemcpyCompatible<::fuchsia::diagnostics::stream::Record>
    : public internal::BoolConstant<
          !HasPadding<::fuchsia::diagnostics::stream::Record>::value &&
          IsMemcpyCompatible<::fuchsia::diagnostics::Severity>::value &&
          IsMemcpyCompatible<::std::vector<::fuchsia::diagnostics::stream::Argument>>::value &&
          IsMemcpyCompatible<int64_t>::value> {};

inline zx_status_t Clone(const ::fuchsia::diagnostics::stream::Record& value,
                         ::fuchsia::diagnostics::stream::Record* result) {
  return ::fuchsia::diagnostics::stream::Clone(value, result);
}

template <>
struct Equality<::fuchsia::diagnostics::stream::Record> {
  bool operator()(const ::fuchsia::diagnostics::stream::Record& _lhs,
                  const ::fuchsia::diagnostics::stream::Record& _rhs) const {
    if (!::fidl::Equals(_lhs.timestamp, _rhs.timestamp)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.severity, _rhs.severity)) {
      return false;
    }
    if (!::fidl::Equals(_lhs.arguments, _rhs.arguments)) {
      return false;
    }
    return true;
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace fuchsia {
namespace diagnostics {
namespace stream {
#ifdef __Fuchsia__

/// A component with records for the Diagnostics system to retrieve.
///
/// To record diagnostics, a component allocates a VMO and begins writing
/// records into the buffer, incrementing a header value after each write to
/// inform readers how much of the buffer has been filled.
///
/// If any retrievers are connected, the `Source` sends them `OnBufferInit`
/// events for each diagnostic buffer created.
///
/// When the buffer fills, the `Source` sends `OnBufferDone` to the retrievers,
/// and will wait for all notified retrievers to reply with `RetireBuffer` when
/// they have finished reading from the buffer.
///
/// When all readers of the buffer have finished, the `Source` may recycle the
/// buffer by zeroing it and sending `OnBufferInit` again to connected
/// retrievers.
///
/// Once a `Source` has sent `OnBufferDone` to a retriever, it is up to the
/// `Source` to handle new records that are generated while the retriever drains
/// the buffer. Double buffering is recommended to prevent excessive blocking,
/// but this protocol does not mandate a specific approach to handling records
/// generated while buffers are full.
using SourcePtr = ::fidl::InterfacePtr<Source>;
class Source_Proxy;
class Source_Stub;
class Source_EventSender;
class Source_Sync;
using SourceSyncPtr = ::fidl::SynchronousInterfacePtr<Source>;
class Source_SyncProxy;

namespace internal {
constexpr uint64_t kSource_OnBufferInit_Ordinal = 0x6212abc1fa0f659flu;
constexpr uint64_t kSource_OnBufferDone_Ordinal = 0xfdedc56bd3e1e3lu;
constexpr uint64_t kSource_RetireBuffer_Ordinal = 0x17d1e2a7c5706d74lu;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

/// A component with records for the Diagnostics system to retrieve.
///
/// To record diagnostics, a component allocates a VMO and begins writing
/// records into the buffer, incrementing a header value after each write to
/// inform readers how much of the buffer has been filled.
///
/// If any retrievers are connected, the `Source` sends them `OnBufferInit`
/// events for each diagnostic buffer created.
///
/// When the buffer fills, the `Source` sends `OnBufferDone` to the retrievers,
/// and will wait for all notified retrievers to reply with `RetireBuffer` when
/// they have finished reading from the buffer.
///
/// When all readers of the buffer have finished, the `Source` may recycle the
/// buffer by zeroing it and sending `OnBufferInit` again to connected
/// retrievers.
///
/// Once a `Source` has sent `OnBufferDone` to a retriever, it is up to the
/// `Source` to handle new records that are generated while the retriever drains
/// the buffer. Double buffering is recommended to prevent excessive blocking,
/// but this protocol does not mandate a specific approach to handling records
/// generated while buffers are full.
class Source {
 public:
  using Proxy_ = ::fuchsia::diagnostics::stream::Source_Proxy;
  using Stub_ = ::fuchsia::diagnostics::stream::Source_Stub;
  using EventSender_ = ::fuchsia::diagnostics::stream::Source_EventSender;
  using Sync_ = ::fuchsia::diagnostics::stream::Source_Sync;
  static const char Name_[];
  virtual ~Source();
  using OnBufferInitCallback = fit::function<void(::zx::vmo)>;
  using OnBufferDoneCallback = fit::function<void(uint64_t)>;

  /// Notifies the `Source` that the retriever is done reading from the buffer.
  /// If the `Source` wishes it should zero the buffer's contents and recycle it
  /// for future records. Buffers must be re-sent via `OnBufferInit` after
  /// they're zeroed.
  virtual void RetireBuffer(uint64_t buffer) = 0;
};

class Source_RequestDecoder {
 public:
  Source_RequestDecoder() = default;
  virtual ~Source_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void RetireBuffer(uint64_t buffer) = 0;
};

class Source_ResponseDecoder {
 public:
  Source_ResponseDecoder() = default;
  virtual ~Source_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
  virtual void OnBufferInit(::zx::vmo latest) = 0;
  virtual void OnBufferDone(uint64_t buffer) = 0;
};

class Source_EventSender {
 public:
  virtual ~Source_EventSender();
  virtual void OnBufferInit(::zx::vmo latest) = 0;
  virtual void OnBufferDone(uint64_t buffer) = 0;
};

class Source_Sync {
 public:
  using Proxy_ = ::fuchsia::diagnostics::stream::Source_SyncProxy;
  virtual ~Source_Sync();
  virtual zx_status_t RetireBuffer(uint64_t buffer) = 0;
};

class Source_Proxy final : public ::fidl::internal::Proxy, public Source {
 public:
  explicit Source_Proxy(::fidl::internal::ProxyController* controller);
  ~Source_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  OnBufferInitCallback OnBufferInit;
  OnBufferDoneCallback OnBufferDone;
  // cts-coverage-fidl-name:fuchsia.diagnostics.stream/Source.RetireBuffer
  void RetireBuffer(uint64_t buffer) override;

 private:
  Source_Proxy(const ::fuchsia::diagnostics::stream::Source_Proxy&) = delete;
  Source_Proxy& operator=(const ::fuchsia::diagnostics::stream::Source_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class Source_Stub final : public ::fidl::internal::Stub,
                          public ::fuchsia::diagnostics::stream::Source_EventSender {
 public:
  typedef class ::fuchsia::diagnostics::stream::Source Source_clazz;
  explicit Source_Stub(::fuchsia::diagnostics::stream::Source_Stub::Source_clazz* impl);
  ~Source_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;
  void OnBufferInit(::zx::vmo latest) override;
  void OnBufferDone(uint64_t buffer) override;

 private:
  ::fuchsia::diagnostics::stream::Source_Stub::Source_clazz* impl_;
};

class Source_SyncProxy : public ::fuchsia::diagnostics::stream::Source_Sync {
 public:
  explicit Source_SyncProxy(::zx::channel channel);
  ~Source_SyncProxy() override;
  // cts-coverage-fidl-name:fuchsia.diagnostics.stream/Source.RetireBuffer
  zx_status_t RetireBuffer(uint64_t buffer) override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Source>;
};
#endif  // __Fuchsia__

}  // namespace stream
}  // namespace diagnostics
}  // namespace fuchsia

#endif  // CTF_BUILD_SCRIPTS_TESTDATA_FIDL_H_
