{{/*
// 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.
*/}}

{{- define "Protocol:Interface:WireMessagingHeader" }}
{{- range .TwoWayMethods }}
  {{- if eq .Transport.Name "Driver" }}
  {{- template "Method:CompleterBase:driver/WireMessagingHeader" . }}
  {{- else }}
  {{- template "Method:CompleterBase:WireMessagingHeader" . }}
  {{- end }}
{{- end }}

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |{{ .ClientEnd }}|
// and |{{ .ServerEnd }}|).
template<>
class {{ .WireServer }} : public ::fidl::internal::IncomingMessageDispatcher
{{- if .HandlesOneWayUnknownInteractions -}}
, public {{ .UnknownMethodHandler }}
{{- end }} {
  public:
  {{ .WireServer.Self }}() = default;
  virtual ~{{ .WireServer.Self }}() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = {{ . }};

  using Handler = fidl::ProtocolHandler<{{ . }}>;

{{ "" }}
  {{- range .Methods }}
    {{- if .HasRequest }}
    using {{ .WireCompleterAlias.Self }} = {{ .WireCompleter }};
    {{- if .HasRequestPayload }}
      using {{ .WireRequestViewAlias.Self }} = {{ .RequestPayload }}*;
    {{- end }}

  {{ .Docs }}
  virtual void {{ .Name }}(
    {{- if .HasRequestPayload }}
      {{ .RequestPayload }}* request,
    {{- end }}
    {{- if eq .Transport.Name "Driver" }}
       fdf::Arena& arena,
    {{- end }}
    {{ .WireCompleterArg }}& completer)
    {{- if .Transitional -}}
      { completer.Close(ZX_ERR_NOT_SUPPORTED); }
    {{- else -}}
      = 0;
    {{- end }}
{{ "" }}
    {{- end }}
  {{- end }}

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler({{ .Dispatcher }}* dispatcher) {
    return [impl=this, dispatcher=dispatcher]({{ .ServerEnd }} request) {
        (void) {{ .BindServer }}(dispatcher, std::move(request), impl);
    };
  }

  private:
  {{- /* Note that this implementation is snake_case to avoid name conflicts. */}}
  void dispatch_message(
    ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) final;
};
{{- end }}



{{- define "Protocol:Interface:NaturalMessagingHeader" }}
{{- range .ClientMethods }}
  {{- template "Method:Request:NaturalMessagingHeader" . }}
{{- end }}

{{- range .TwoWayMethods }}
  {{- if eq .Transport.Name "Driver" }}
  {{- template "Method:CompleterBase:driver/NaturalMessagingHeader" . }}
  {{- else }}
  {{- template "Method:CompleterBase:NaturalMessagingHeader" . }}
  {{- end }}
{{- end }}

template<>
class {{ .NaturalServer }} : public ::fidl::internal::IncomingMessageDispatcher
{{- if .HandlesOneWayUnknownInteractions -}}
, public {{ .UnknownMethodHandler }}
{{- end }} {
  public:
  {{ .NaturalServer.Self }}() = default;
  virtual ~{{ .NaturalServer.Self }}() = default;

  // The FIDL protocol type that is implemented by this server.
  using _EnclosingProtocol = {{ .Wire }};

  using Handler = fidl::ProtocolHandler<{{ .Wire }}>;

{{ "" }}
  {{- range .ClientMethods }}
    {{- if .HasRequestPayload }}
      using {{ .NaturalRequestAlias.Self }} = {{ .NaturalRequest }};
    {{- end }}
  using {{ .NaturalCompleterAlias.Self }} = {{ .NaturalCompleter }};

  {{ .Docs }}
  virtual void {{ .Name }}(
      {{- if .HasRequestPayload }}
        {{- .NaturalRequestAlias.Self }}& request,
      {{- end }}
      {{ .NaturalCompleterArg }}& completer
  )
    {{- if .Transitional -}}
      { completer.Close(ZX_ERR_NOT_SUPPORTED); }
    {{- else -}}
      = 0;
    {{- end }}
{{ "" }}
  {{- end }}

  // |bind_handler| returns a handler that binds incoming connections to this
  // server implementation.
  //
  // The returned handler borrows the server instance.
  // The server must outlive the provided |dispatcher|. Only after
  // the dispatcher is shutdown will it be safe to destroy the servers.
  // The server should not be moved.
  Handler bind_handler({{ .Dispatcher }}* dispatcher) {
    return [impl=this, dispatcher=dispatcher]({{ .ServerEnd }} request) {
        (void) {{ .BindServer }}(dispatcher, std::move(request), impl);
    };
  }

  private:
  {{- /* Note that this implementation is snake_case to avoid name conflicts. */}}
  void dispatch_message(
    ::fidl::IncomingHeaderAndMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) final;
};
{{- end }}



{{- define "Protocol:Interface:NaturalMessagingSource" }}
{{- range .ClientMethods }}
  {{- template "Method:Request:NaturalMessagingSource" . }}
{{- end }}

{{- range .TwoWayMethods }}
  {{- if eq .Transport.Name "Driver" }}
  {{- template "Method:CompleterBase:driver/NaturalMessagingSource" . }}
  {{- else }}
  {{- template "Method:CompleterBase:NaturalMessagingSource" . }}
  {{- end }}
{{- end }}
{{- end }}
