{{/*
// Copyright 2019 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:Dispatcher:WireMessagingHeader" }}
{{- IfdefFuchsia }}
{{- EnsureNamespace "" }}
template<>
struct {{ .WireServerDispatcher }} final {
  {{ .WireServerDispatcher.Self }}() = delete;
  static ::fidl::DispatchResult TryDispatch({{ .WireServer }}* impl, ::fidl::IncomingMessage& msg,
                                            internal::MessageStorageViewBase* storage_view,
                                            ::fidl::Transaction* txn);
  static void Dispatch({{ .WireServer }}* impl, ::fidl::IncomingMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
{{- EndifFuchsia }}
{{- end }}



{{- define "Protocol:Dispatcher:WireMessagingSource" }}
{{- IfdefFuchsia -}}
{{ EnsureNamespace "" }}

constexpr ::fidl::internal::MethodEntry {{ .WireServerDispatcher.NoLeading }}::entries_[] = {
  {{- range .ClientMethods }}
    { {{ .OrdinalName }},
      [](void* interface, ::fidl::IncomingMessage&& msg,
        internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
        {{- if eq .Transport.Name "Driver" }}
        {{/* |arena| needs to be declared before |decoded| so that |decoded| is destructed first.
             This is for the case where handles used in |decoded| are stored in |arena|. */}}
        fdf::Arena arena(::fidl::internal::TakeDriverArenaFromStorage(storage_view));
        {{- end }}
        {{- if .RequestArgs }}
        ::fidl::unstable::DecodedMessage<{{ .WireTransactionalRequest }}> decoded{std::move(msg)};
        if (unlikely(!decoded.ok())) {
          return ::fidl::Status{decoded};
        }
        auto* primary = &decoded.PrimaryObject()->body;
        {{- else }}
        {{ .WireRequest }} empty_request;
        auto* primary = &empty_request;
        {{- end }}
        {{ .WireCompleter }}::Sync completer(txn);
        {{- if eq .Transport.Name "Driver" }}
        reinterpret_cast<{{ $.WireServer }}*>(interface)->{{ .Name }}(
            primary, arena, completer);
        {{- else }}
        reinterpret_cast<{{ $.WireServer }}*>(interface)->{{ .Name }}(
            primary, completer);
          {{- end }}
        return ::fidl::Status::Ok();
      },
    },
  {{- end }}
};

const ::fidl::internal::MethodEntry* {{ .WireServerDispatcher.NoLeading }}::entries_end_ =
    &entries_[{{- len .ClientMethods -}}];

::fidl::DispatchResult {{ .WireServerDispatcher.NoLeading }}::TryDispatch(
    {{ .WireServer }}* impl, ::fidl::IncomingMessage& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  return ::fidl::internal::TryDispatch(
    impl, msg, storage_view, txn, entries_, entries_end_);
}

{{ EnsureNamespace "" }}
void {{ .WireServerDispatcher.NoLeading }}::Dispatch(
    {{- .WireServer }}* impl, ::fidl::IncomingMessage&& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_);
}

{{- EnsureNamespace "" }}
void {{ .WireServer.NoLeading }}::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  {{ .WireServerDispatcher }}::Dispatch(this, std::move(msg), storage_view, txn);
}
{{- EndifFuchsia -}}

{{- end }}



{{- define "Protocol:Dispatcher:NaturalMessagingHeader" }}
{{- IfdefFuchsia }}
{{- EnsureNamespace "" }}
template<>
struct {{ .NaturalServerDispatcher }} final {
  {{ .NaturalServerDispatcher.Self }}() = delete;
  static void Dispatch({{ .NaturalServer }}* impl, ::fidl::IncomingMessage&& msg,
                       internal::MessageStorageViewBase* storage_view,
                       ::fidl::Transaction* txn);

 private:
  static const ::fidl::internal::MethodEntry entries_[];
  static const ::fidl::internal::MethodEntry* entries_end_;
};
{{- EndifFuchsia }}
{{- end }}



{{- define "Protocol:Dispatcher:NaturalMessagingSource" }}
{{- IfdefFuchsia -}}
{{ EnsureNamespace "" }}

constexpr ::fidl::internal::MethodEntry {{ .NaturalServerDispatcher.NoLeading }}::entries_[] = {
  {{- range .ClientMethods }}
    { {{ .OrdinalName }},
      [](void* interface, ::fidl::IncomingMessage&& msg,
        internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
        ::fitx::result decoded = ::fidl::internal::DecodeTransactionalMessage
            {{- if .HasRequestPayload }}<{{ .RequestPayload }}>{{ end }}(std::move(msg));
        if (decoded.is_error()) {
          return decoded.error_value();
        }
        {{ .NaturalRequest }} request
        {{- if .HasRequestPayload }}
            = {{ .NaturalRequestConverter }}::FromDomainObject(std::move(decoded.value()))
        {{- end }};
        {{ .NaturalCompleter }}::Sync completer(txn);
        static_cast<{{ $.NaturalServer }}*>(interface)->{{ .Name }}(
            request, completer);
        return ::fidl::Status::Ok();
      },
    },
  {{- end }}
};

const ::fidl::internal::MethodEntry* {{ .NaturalServerDispatcher.NoLeading }}::entries_end_ =
    &entries_[{{- len .ClientMethods -}}];

{{ EnsureNamespace "" }}
void {{ .NaturalServerDispatcher.NoLeading }}::Dispatch(
    {{- .NaturalServer }}* impl, ::fidl::IncomingMessage&& msg,
    internal::MessageStorageViewBase* storage_view, ::fidl::Transaction* txn) {
  ::fidl::internal::Dispatch(impl, msg, storage_view, txn, entries_, entries_end_);
}

{{- EnsureNamespace "" }}
void {{ .NaturalServer.NoLeading }}::dispatch_message(
    ::fidl::IncomingMessage&& msg, ::fidl::Transaction* txn,
    ::fidl::internal::MessageStorageViewBase* storage_view) {
  {{ .NaturalServerDispatcher }}::Dispatch(this, std::move(msg), storage_view, txn);
}
{{- EndifFuchsia -}}

{{- end }}
