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

{{- define "ProtocolForwardDeclaration/ProxiesAndStubs" }}
{{ EnsureNamespace . }}
{{- IfdefFuchsia -}}
{{- .Docs }}
using {{ .Name }}Ptr = ::fidl::InterfacePtr<{{ .Name }}>;
class {{ .Proxy.Name }};
class {{ .Stub.Name }};
class {{ .EventSender.Name }};
class {{ .SyncInterface.Name }};
using {{ .Name }}SyncPtr = ::fidl::SynchronousInterfacePtr<{{ .Name }}>;
class {{ .SyncProxy.Name }};

{{ range .Methods }}
{{- EnsureNamespace .OrdinalName }}
constexpr uint64_t {{ .OrdinalName.Name }} = {{ .Ordinal | printf "%#x" }}lu;
{{- EnsureNamespace .DynamicFlagsName }}
constexpr ::fidl::MessageDynamicFlags {{ .DynamicFlagsName.Name }} = {{ .DynamicFlags }};
{{- end }}

{{- EndifFuchsia -}}
{{- end }}

{{- define "Params" -}}
  {{- range $index, $param := . -}}
    {{- if $index }}, {{ end -}}{{ $param.Type }} {{ $param.Name }}
  {{- end -}}
{{ end }}

{{- define "OutParams" -}}
  {{- range $index, $param := . -}}
    {{- if $index }}, {{ end -}}{{ $param.Type }}* out_{{ $param.Name }}
  {{- end -}}
{{ end }}

{{- define "ParamTypes" -}}
  {{- range $index, $param := . -}}
    {{- if $index }}, {{ end -}}{{ $param.Type }}
  {{- end -}}
{{ end }}

{{- define "RequestMethodSignature" -}}
  {{- if .HasResponse -}}
{{ .Name }}({{ template "Params" .RequestArgs }}{{ if .RequestArgs }}, {{ end }}{{ .CallbackType }} callback)
  {{- else -}}
{{ .Name }}({{ template "Params" .RequestArgs }})
  {{- end -}}
{{ end -}}

{{- define "EventMethodSignature" -}}
{{ .Name }}({{ template "Params" .ResponseArgs }})
{{- end -}}

{{- define "SyncRequestMethodSignature" -}}
  {{- if .ResponseArgs -}}
{{ .Name }}({{ template "Params" .RequestArgs }}{{ if .RequestArgs }}, {{ end }}{{ template "OutParams" .ResponseArgs }})
  {{- else -}}
{{ .Name }}({{ template "Params" .RequestArgs }})
  {{- end -}}
{{ end -}}

{{- define "ProtocolDeclaration/ProxiesAndStubs" }}
{{- IfdefFuchsia -}}

{{- .Docs }}
class {{ .Name }} {
 public:
  using Proxy_ = {{ .Proxy }};
  using Stub_ = {{ .Stub }};
  using EventSender_ = {{ .EventSender }};
  using Sync_ = {{ .SyncInterface }};
  {{- if .DiscoverableName }}
  static const char Name_[];
  {{- end }}
  virtual ~{{ .Name }}();

  {{- range .Methods }}
    {{- if .HasResponse }}
  using {{ .CallbackType }} =
      fit::function<void({{ template "ParamTypes" .ResponseArgs }})>;
    {{- end }}
    {{- if .HasRequest }}
      {{ .Docs }}
  virtual void {{ template "RequestMethodSignature" . }} = 0;
    {{- end }}
  {{- end }}

  {{ if .HandlesOneWayUnknownInteractions -}}
 protected:
  // Allow the stub to access the handle_unknown_method method.
  friend class {{ .Stub.Name }};

  {{ if .HandlesTwoWayUnknownInteractions -}}
  virtual void handle_unknown_method(uint64_t ordinal, bool method_has_response) = 0;
  {{ else -}}
  virtual void handle_unknown_method(uint64_t ordinal) = 0;
  {{- end }}
  {{- end }}
};

class {{ .RequestDecoder.Name }} {
 public:
  {{ .RequestDecoder.Name }}() = default;
  virtual ~{{ .RequestDecoder.Name }}() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response, bool* is_known);

  {{- range .Methods }}
    {{- if .HasRequest }}
  virtual void {{ .Name }}({{ template "Params" .RequestArgs }}) = 0;
    {{- end }}
  {{- end }}
};

class {{ .ResponseDecoder.Name }} {
 public:
  {{ .ResponseDecoder.Name }}() = default;
  virtual ~{{ .ResponseDecoder.Name }}() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);

  {{- range .Methods }}
    {{- if .HasResponse }}
  virtual void {{ .Name }}({{ template "Params" .ResponseArgs }}) = 0;
    {{- end }}
  {{- end }}
};

class {{ .EventSender.Name }} {
 public:
  virtual ~{{ .EventSender.Name }}();

  {{- range .Methods }}
    {{- if not .HasRequest }}
      {{- if .HasResponse }}
  virtual void {{ template "EventMethodSignature" . }} = 0;
      {{- end }}
    {{- end }}
  {{- end }}
};

class {{ .SyncInterface.Name }} {
 public:
  using Proxy_ = {{ .SyncProxy }};
  virtual ~{{ .SyncInterface.Name }}();

  {{- range .Methods }}
    {{- if .HasRequest }}
  virtual zx_status_t {{ template "SyncRequestMethodSignature" . }} = 0;
    {{- end }}
  {{- end }}
};

class {{ .Proxy.Name }} final : public ::fidl::internal::Proxy, public {{ .Name }} {
 public:
  explicit {{ .Proxy.Name }}(::fidl::internal::ProxyController* controller);
  ~{{ .Proxy.Name }}() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;

  {{- range .Methods }}
    {{- if .HasRequest }}
  {{ .CtsMethodAnnotation }}
  void {{ template "RequestMethodSignature" . }} override;
    {{- else if .HasResponse }}
  {{ .CallbackType }} {{ .Name }};
    {{- end }}
  {{- end }}

  {{ if .HandlesOneWayUnknownInteractions -}}
  fit::function<void(uint64_t)> handle_unknown_event;

 protected:
  {{ if .HandlesTwoWayUnknownInteractions -}}
  void handle_unknown_method(uint64_t ordinal, bool method_has_response) override {
    // This method is only provided to satisfy the base interface. It's
    // protected and should never be called by generated code on the client
    // side, so it should never be called.
    ZX_PANIC("Unreachable: {{ .Proxy.Name }}::handle_unknown_method should not be callable");
  }
  {{ else -}}
  void handle_unknown_method(uint64_t ordinal) override {
    // This method is only provided to satisfy the base interface. It's
    // protected and should never be called by generated code on the client
    // side, so it should never be called.
    ZX_PANIC("Unreachable: {{ .Proxy.Name }}::handle_unknown_method should not be callable");
  }
  {{- end }}
  {{- end }}


 private:
  {{ .Proxy.Name }}(const {{ .Proxy }}&) = delete;
  {{ .Proxy.Name }}& operator=(const {{ .Proxy }}&) = delete;

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

class {{ .Stub.Name }} final : public ::fidl::internal::Stub, public {{ .EventSender }} {
 public:
  typedef class {{ . }} {{ .InterfaceAliasForStub.Self }};
  explicit {{ .Stub.Name }}({{ .InterfaceAliasForStub }}* impl);
  ~{{ .Stub.Name }}() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

  {{- range .Methods }}
    {{- if not .HasRequest }}
      {{- if .HasResponse }}
  void {{ template "EventMethodSignature" . }} override;
      {{- end }}
    {{- end }}
  {{- end }}

 private:
  {{ .InterfaceAliasForStub }}* impl_;
};

class {{ .SyncProxy.Name }} : public {{ .SyncInterface }} {
 public:
  explicit {{ .SyncProxy.Name }}(::zx::channel channel);
  ~{{ .SyncProxy.Name }}() override;

  {{- range .Methods }}
    {{- if .HasRequest }}
  {{ .CtsMethodAnnotation }}
  zx_status_t {{ template "SyncRequestMethodSignature" . }} override;
    {{- end }}
  {{- end }}

  private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<{{ .Name }}>;
};

{{- EndifFuchsia -}}
{{- end }}

{{- define "ProtocolDefinition" }}
{{- IfdefFuchsia -}}

{{- range .Methods }}
  {{ EnsureCodingTableDecl .Request.HlCodingTable }}
  {{ EnsureCodingTableDecl .Response.HlCodingTable }}
{{- end }}

{{ EnsureNamespace . }}
{{ .Name }}::~{{ .Name }}() = default;

{{- if .DiscoverableName }}
const char {{ .Name }}::Name_[] = {{ .DiscoverableName }};
{{- end }}

const fidl_type_t* {{ .RequestDecoder }}::GetType(uint64_t ordinal, bool* out_needs_response, bool* out_is_known) {
  *out_needs_response = false;
  *out_is_known = false;
  switch (ordinal) {
    {{- range .Methods }}
      {{- if .HasRequest }}
    case {{ .OrdinalName }}:
      *out_is_known = true;
        {{- if .HasResponse }}
      *out_needs_response = true;
        {{- end }}
        {{- if .HasRequestPayload }}
      return &{{ .Request.HlCodingTable }};
        {{ else }}
      return nullptr;
        {{ end -}};
      {{- end }}
    {{- end }}
    default:
      return nullptr;
  }
}

const fidl_type_t* {{ .ResponseDecoder.Name }}::GetType(uint64_t ordinal) {
  switch (ordinal) {
    {{- range .Methods }}
      {{- if .HasResponse }}
    case {{ .OrdinalName }}:
        {{- if .HasResponsePayload }}
      return &{{ .Response.HlCodingTable }};
        {{ else }}
      return nullptr;
        {{ end -}};
      {{- end }}
    {{- end }}
    default:
      return nullptr;
  }
}

{{ .EventSender.Name }}::~{{ .EventSender.Name }}() = default;

{{ .SyncInterface.Name }}::~{{ .SyncInterface.Name }}() = default;

{{ .Proxy.Name }}::{{ .Proxy.Name }}(::fidl::internal::ProxyController* controller)
    : controller_(controller) {
  (void)controller_;
}

{{ .Proxy.Name }}::~{{ .Proxy.Name }}() = default;

zx_status_t {{ .Proxy.Name }}::Dispatch_(::fidl::HLCPPIncomingMessage message) {
  zx_status_t status = ZX_OK;
  switch (message.ordinal()) {
    {{- range .Methods }}
      {{- if not .HasRequest }}
        {{- if .HasResponse }}
    case {{ .OrdinalName }}: {
      if (!{{ .Name }}) {
        status = ZX_OK;
        break;
      }
      {{- if .HasResponsePayload }}
      const char* error_msg = nullptr;
      status = message.Decode(&{{ .Response.HlCodingTable }}, &error_msg);
      if (status != ZX_OK) {
        FIDL_REPORT_DECODING_ERROR(message, &{{ .Response.HlCodingTable }}, error_msg);
        break;
      }
        {{- if .ResponseArgs }}
      ::fidl::Decoder decoder(std::move(message));
        {{- end }}
      {{- end }}
      {{ .Name }}(
        {{- range $index, $param := .ResponseArgs -}}
          {{- if $index }}, {{ end }}::fidl::DecodeAs<{{ .Type }}>(&decoder, {{ .OffsetV2 }} + sizeof(fidl_message_header_t))
        {{- end -}}
      );
      break;
    }
        {{- end }}
      {{- end }}
    {{- end }}
    default: {
      {{- if .HandlesOneWayUnknownInteractions }}
      auto txid = message.txid();
      auto is_flexible = message.is_flexible();
      auto ordinal = message.ordinal();
      // To satisfy RFC-0138, move the message so it is destructed before
      // calling the unknown event handler.
      { auto message_ = std::move(message); }
      if (txid == 0 && is_flexible) {
        handle_unknown_event(ordinal);
        break;
      }
      {{- end }}
      status = ZX_ERR_NOT_SUPPORTED;
      break;
    }
  }
  return status;
}

{{ range .Methods }}
  {{- if .HasRequest }}
    {{- if .HasResponse }}
namespace {

::std::unique_ptr<::fidl::internal::SingleUseMessageHandler>
{{- /* Note: fidl::internal::SingleUseMessageHandler assumes that the lambda captures a single */}}
{{- /* fit::function. When changing CallbackType, make sure to update SingleUseMessageHandler. */}}
{{ .ResponseHandlerType }}({{ $.Name }}::{{ .CallbackType }}&& callback) {
  ZX_DEBUG_ASSERT_MSG(callback,
                      "Callback must not be empty for {{ $.Name }}::{{ .Name }}\n");
  return ::std::make_unique<::fidl::internal::SingleUseMessageHandler>(
      [callback_ = std::move(callback)](::fidl::HLCPPIncomingMessage&& message) {
      {{- if .ResponseArgs }}
        ::fidl::Decoder decoder(std::move(message));
      {{- end }}
        callback_(
      {{- range $index, $param := .ResponseArgs -}}
        {{- if $index }}, {{ end }}::fidl::DecodeAs<{{ .Type }}>(&decoder, {{ .OffsetV2 }} + sizeof(fidl_message_header_t))
      {{- end -}}
        );
        return ZX_OK;
      }, {{ if .HasResponsePayload }}&{{ .Response.HlCodingTable }}{{ else }}nullptr{{ end }});
}

}  // namespace
{{- end }}
void {{ $.Proxy.Name }}::{{ template "RequestMethodSignature" . }} {
  ::fidl::MessageEncoder _encoder({{ .OrdinalName }}, {{ .DynamicFlagsName }});
  const fidl_type_t* req_type =
    {{- if .HasRequestPayload -}}
      &{{ .Request.HlCodingTable }};
    {{- else -}}
      nullptr;
    {{- end }}
  controller_->Send(req_type, {{ $.RequestEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .RequestArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  )
  {{- if .HasResponse -}}
    , {{ .ResponseHandlerType }}(std::move(callback))
  {{- else -}}
    , nullptr
  {{- end -}}
  );
}
  {{- end }}
{{- end }}

{{ .Stub.Name }}::{{ .Stub.Name }}({{ .InterfaceAliasForStub }}* impl) : impl_(impl) {
  (void)impl_;
}

{{ .Stub.Name }}::~{{ .Stub.Name }}() = default;

namespace {
{{- range .Methods }}
  {{- if .HasRequest }}
    {{- if .HasResponse }}

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

  void operator()({{ template "Params" .ResponseArgs }}) {
    ::fidl::MessageEncoder _encoder({{ .OrdinalName }}, {{ .DynamicFlagsName }});
    const fidl_type_t* resp_type =
    {{- if .HasResponsePayload -}}
      &{{ .Response.HlCodingTable }};
    {{- else -}}
      nullptr;
    {{- end }}
    {{- if .HasFrameworkError }}
    ZX_ASSERT_MSG(!{{ .TheResponseArg.Name }}.is_framework_err(), "Applications must not explicitly send framework_err for flexible methods.");
    {{- end }}
    response_.Send(resp_type, {{ $.ResponseEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .ResponseArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ));
  }

 private:
  ::fidl::internal::PendingResponse response_;
};
    {{- end }}
  {{- end }}
{{- end }}

}  // namespace

zx_status_t {{ .Stub.Name }}::Dispatch_(
    ::fidl::HLCPPIncomingMessage message,
    ::fidl::internal::PendingResponse response) {
  bool needs_response;
  bool is_known;
  const fidl_type_t* request_type = {{ .RequestDecoder }}::GetType(message.ordinal(), &needs_response, &is_known);

  if (!is_known) {
    {{- if .HandlesOneWayUnknownInteractions }}
    auto is_flexible = message.is_flexible();
    auto ordinal = message.ordinal();
    // To satisfy RFC-0138, move the message so it is destructed before sending
    // a reply or calling the unknown method handler.
    { auto message_ = std::move(message); }
    if (is_flexible) {
      {{- if .HandlesTwoWayUnknownInteractions }}
      if (response.needs_response()) {
        ::fidl::MessageEncoder encoder(ordinal, ::fidl::MessageDynamicFlags::kFlexibleMethod);
        const fidl_type_t* resp_type = &kFidlInternalUnknownMethodResponseTable;
        response.Send(resp_type, ::fidl::internal::EncodeUnknownMethodResponse(&encoder));
        impl_->handle_unknown_method(ordinal, true);
      } else {
        impl_->handle_unknown_method(ordinal, false);
      }
      return ZX_OK;
      {{- else }}
      if (!response.needs_response()) {
        impl_->handle_unknown_method(ordinal);
        return ZX_OK;
      }
      {{- end }}
    }
    {{- end }}
    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) {
    {{- range .Methods }}
      {{- if .HasRequest }}
    case {{ .OrdinalName }}:
    {
        {{- if .RequestArgs }}
      ::fidl::Decoder decoder(std::move(message));
        {{- end }}
      impl_->{{ .Name }}(
        {{- range $index, $param := .RequestArgs -}}
          {{- if $index }}, {{ end }}::fidl::DecodeAs<{{ .Type }}>(&decoder, {{ .OffsetV2 }} + sizeof(fidl_message_header_t))
        {{- end -}}
        {{- if .HasResponse -}}
          {{- if .RequestArgs }}, {{ end -}}{{ .ResponderType }}(std::move(response))
        {{- end -}}
      );
      break;
    }
      {{- end }}
    {{- end }}
    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;
}

{{- range .Methods }}
  {{- if not .HasRequest }}
    {{- if .HasResponse }}
void {{ $.Stub.Name }}::{{ template "EventMethodSignature" . }} {
  ::fidl::MessageEncoder _encoder({{ .OrdinalName }}, {{ .DynamicFlagsName }});
  const fidl_type_t* resp_type =
    {{- if .HasResponsePayload -}}
      &{{ .Response.HlCodingTable }};
    {{- else -}}
      nullptr;
    {{- end -}}
  sender_()->Send(resp_type, {{ $.ResponseEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .ResponseArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ));
}
    {{- end }}
  {{- end }}
{{- end }}

{{ .SyncProxy.Name }}::{{ .SyncProxy.Name }}(::zx::channel channel)
    : proxy_(::std::move(channel)) {}

{{ .SyncProxy.Name }}::~{{ .SyncProxy.Name }}() = default;

{{- range .Methods }}
  {{- if .HasRequest }}

zx_status_t {{ $.SyncProxy.Name }}::{{ template "SyncRequestMethodSignature" . }} {
  ::fidl::MessageEncoder _encoder({{ .OrdinalName }}, {{ .DynamicFlagsName }});
    {{- if .HasResponse }}
  ::fidl::IncomingMessageBuffer buffer_;
  ::fidl::HLCPPIncomingMessage response_ = buffer_.CreateEmptyIncomingMessage();
  const fidl_type_t* req_type =
  {{- if .HasRequestPayload -}}
    &{{ .Request.HlCodingTable }};
  {{- else -}}
    nullptr;
  {{- end }}
  const fidl_type_t* resp_type =
  {{- if .HasResponsePayload -}}
    &{{ .Response.HlCodingTable }};
  {{- else -}}
    nullptr;
  {{- end }}
  zx_status_t status_ = proxy_.Call(req_type, resp_type, {{ $.RequestEncoder }}::{{
  .Name }}(&_encoder {{- range $index, $param := .RequestArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ), &response_);
  if (status_ != ZX_OK)
    return status_;
      {{- if .ResponseArgs }}
  ::fidl::Decoder decoder_(std::move(response_));
        {{- range $index, $param := .ResponseArgs }}
  *out_{{ .Name }} = ::fidl::DecodeAs<{{ .Type }}>(&decoder_, {{ .OffsetV2 }} + sizeof(fidl_message_header_t));
        {{- end }}
      {{- end }}
  return ZX_OK;
    {{- else }}
    const fidl_type_t* req_type =
    {{- if .HasRequestPayload -}}
      &{{ .Request.HlCodingTable }};
    {{- else -}}
      nullptr;
    {{- end }}
  return proxy_.Send(req_type, {{ $.RequestEncoder }}::{{ .Name }}(&_encoder
  {{- range $index, $param := .RequestArgs -}}
    , &{{ $param.Name }}
  {{- end -}}
  ));
    {{- end }}
}
  {{- end }}
{{- end }}

{{- EndifFuchsia -}}
{{ end }}
