{{/*
// 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 "Method:Request:WireMessagingHeader" }}
{{- EnsureNamespace "" }}
{{- if .Request.IsResource }}
{{- IfdefFuchsia -}}
{{- end }}

template<>
struct {{ .WireRequest }} final {{- if .HasRequestPayload }} : public {{ .RequestPayload }}{{ end }} {
{{- range .RequestAnonymousChildren }}
  using {{ .ScopedName }} = {{ .FlattenedName }};
{{- end }}

  {{ if (and .RequestFlattened .HasRequestPayload) }}
  explicit {{ .WireRequest.Self }}({{ .RequestPayload }} base) : {{ .RequestPayload }}(std::move(base)) {}
  {{- end }}

  {{- if .RequestArgs }}
  explicit {{ .WireRequest.Self }}({{ RenderParams .RequestArgs }}) : {{ .RequestPayload }}
  {{- if .RequestFlattened -}}
  {{- "{ " }}{{ RenderForwardStructParams .RequestArgs }}}
  {{- else -}}
  ({{ RenderForwardParams .RequestArgs }})
  {{- end -}}{}
  {{- end }}
  {{ .WireRequest.Self }}() = default;

    {{- if and .HasResponse .ResponseArgs }}
  using ResponseType = {{ .WireResponse }};
    {{- end }}
};

{{ if .HasRequestPayload }}
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<{{ .WireRequest }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public WireStructCodingTraitsBase<{{ .WireRequest }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t inline_size = {{ .Request.TypeShapeV2.InlineSize }};

  static void Encode(
    internal::WireEncoder* encoder, {{ .WireRequest }}* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl::internal::WireCodingTraits<{{ .RequestPayload }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(
      encoder, value, position, recursion_depth);
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl::internal::WireCodingTraits<{{ .RequestPayload }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
      decoder, position, recursion_depth);
  }
};
{{- end }}

template<>
struct {{ .WireTransactionalRequest }} final {
  FIDL_ALIGNDECL
  fidl_message_header_t header;
  {{ if .RequestArgs }}
  {{ .WireRequest }} body;
  explicit {{ .WireTransactionalRequest.Self }}({{ RenderParams .RequestArgs }})
  : body({{ .WireRequest }}({{ RenderForwardParams .RequestArgs }})) {
    _InitHeader();
  }
  {{- end }}
  {{ .WireTransactionalRequest.Self }}() {
    _InitHeader();
  }

    {{- if and .HasResponse .ResponseArgs }}
  using ResponseType = {{ .WireTransactionalResponse }};
    {{- end }}

  {{- if .Request.IsResource }}
  void _CloseHandles() {
    {{- if .RequestArgs }}
    body._CloseHandles();
    {{- end }}
  }
  {{- end }}

 private:
  void _InitHeader();
};

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<{{ .WireTransactionalRequest }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
  : public WireStructCodingTraitsBase<{{ .WireTransactionalRequest }}, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t inline_size = {{ .Request.TypeShapeV2.InlineSize }} + sizeof(fidl_message_header_t);

  static void Encode(internal::WireEncoder* encoder, {{ .WireTransactionalRequest }}* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<fidl_message_header_t>() = value->header;
    {{- if .HasRequestPayload }}
    WireCodingTraits<{{ .WireRequest }}, WireCodingConstraintEmpty, IsRecursive>::Encode(
        encoder, &value->body, position + sizeof(fidl_message_header_t), recursion_depth);
    {{- end }}
  }
  static void Decode(
    internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    {{- if .HasRequestPayload }}
    WireCodingTraits<{{ .WireRequest }}, WireCodingConstraintEmpty, IsRecursive>::Decode(
        decoder, position + sizeof(fidl_message_header_t), recursion_depth);
    {{- end }}
  }
};
{{- if .Request.IsResource }}
{{- EndifFuchsia -}}
{{- end }}
{{- end }}




{{- define "Method:Request:WireMessagingSource" }}
  {{- EnsureNamespace "" }}

{{- if .Request.IsResource }}
{{- IfdefFuchsia -}}
{{- end }}
  void {{ .WireTransactionalRequest }}::_InitHeader() {
    ::fidl::InitTxnHeader(&header, 0, {{ .OrdinalName }}, {{ .DynamicFlagsName }});
  }

{{- if .Request.IsResource }}
{{- EndifFuchsia -}}
{{- end }}
{{- end }}



{{- define "Method:Request:NaturalMessagingHeader" }}
{{- IfdefFuchsia -}}
{{- EnsureNamespace "" }}

template <>
class {{ .NaturalRequest }} final
    {{- if .RequestMessageBase }} : public {{ .RequestMessageBase }} {{ end }} {
 public:
  {{- if .HasRequestPayload }}
    using {{ .RequestPayload }}::{{ .RequestPayload.Self }};
    {{ .NaturalRequest.Self }}({{ .RequestPayload }} v) : {{ .RequestPayload }}(std::move(v)) {}
  {{- end }}
};

template <>
struct {{ .RequestMessageTraits }} final {
 public:
  static constexpr bool kHasPayload = {{ .HasRequestPayload }};
  {{- if .HasRequestPayload }}
    using Payload = {{ .RequestPayload }};
  {{- end }}
};


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



{{- define "Method:Request:NaturalMessagingSource" }}

{{- end }}


{{- define "Method:Request:Traits:TypeConversionsHeader" }}
template <>
struct WireNaturalConversionTraits<{{ .WireRequest }}, {{ .NaturalRequest }}> {
  static {{ .NaturalRequest }} ToNatural({{ .WireRequest }} src);
  static {{ .WireRequest }} ToWire(fidl::AnyArena& arena, {{ .NaturalRequest }} src);
};

template <>
struct NaturalTypeForWireType<{{ .WireRequest }}> {
    using type = {{ .NaturalRequest }};
};
template <>
struct WireTypeForNaturalType<{{ .NaturalRequest }}> {
    using type = {{ .WireRequest }};
};
{{- end }}

{{- define "Method:Request:Traits:TypeConversionsSource" }}
{{ .NaturalRequest }}  WireNaturalConversionTraits<{{ .WireRequest }}, {{ .NaturalRequest }}>::ToNatural({{ .WireRequest }} src) {
  {{- if .HasRequestPayload }}
  return {{ .NaturalRequest }}(
    WireNaturalConversionTraits<{{ .RequestPayload.Wire }}, {{ .RequestMessageBase }}>::ToNatural(std::move(src)));
  {{- else }}
  return {{ .NaturalRequest }}();
  {{- end }}
}
{{ .WireRequest }}  WireNaturalConversionTraits<{{ .WireRequest }}, {{ .NaturalRequest }}>::ToWire(fidl::AnyArena& arena, {{ .NaturalRequest }} src) {
  {{- if .HasRequestPayload }}
  return {{ .WireRequest }}(
    WireNaturalConversionTraits<{{ .RequestPayload.Wire }}, {{ .RequestMessageBase }}>::ToWire(arena, std::move(src)));
  {{- else }}
  return {{ .WireRequest }}();
  {{- end }}
}
{{- end }}
