{{/*
// 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 "Enum:CommonTypesHeader" }}
{{ EnsureNamespace . }}
{{ if .IsStrict }}
{{ .Docs }}
enum class {{ .Name }} : {{ .Type }} {
  {{- range .Members }}
    {{ .Docs }}
    {{ .Name }} = {{ .Value }},
  {{- end }}
};
{{ else }}
{{ .Docs }}
class {{ .Name }} final {
public:
  constexpr {{ .Name }}() : value_(0) {}
  constexpr explicit {{ .Name }}({{ .Type }} value) : value_(value) {}
  constexpr operator {{ .Type }}() const { return value_; }

  constexpr bool IsUnknown() const {
    {{ if .Members }}
    switch (value_) {
      {{ range .Members }}
      {{ if not .IsUnknown }}
    case {{ .Value }}:
      {{ end }}
      {{ end }}
      return false;
    }
    {{- end }}
    return true;
  }

  constexpr static {{ .Name }} Unknown() {
    return {{ .Name }}({{ .UnknownValueForTmpl | printf "%#x" }});
  }

  {{- range .Members }}
    {{ .Docs }}
    static const {{ $.Name }} {{ .Name }};
  {{- end }}

private:
  {{ .Type }} value_;
};

{{- range $member := .Members }}
constexpr const {{ $ }} {{ $.Name }}::{{ $member.Name }} =
  {{ $ }}({{ $member.Value }});
{{- end }}
{{ end }}

{{- if .IsCompatibleWithError }}
{{ EnsureNamespace "" }}
template <>
struct fidl::internal::DisplayError<{{ . }}> {
  static size_t Format(const {{ . }}& value, char* destination, size_t capacity);
};
{{- end }}

{{ end }}



{{- define "Enum:CommonTypesSource" }}

{{ EnsureNamespace . }}
extern "C" const fidl_type_t {{ .CodingTableType.Name }};

{{- if .IsCompatibleWithError }}
{{ EnsureNamespace "" }}
size_t fidl::internal::DisplayError<{{ . }}>::Format(
    const {{ . }}& value, char* destination, size_t capacity
) {
  const char* name = [&] () -> const char* {
    switch (static_cast<{{ .Type }}>(value)) {
      {{- range .Members }}
     case {{ .Value }}: return "{{ .EnumMember.Name }}";
      {{- end }}
     default: return nullptr;
    }
  }();
  return ::fidl::internal::FormatApplicationError(
      static_cast<{{ .Type }}>(value), name, &{{ .CodingTableType }}, destination, capacity);
}
{{- end }}

{{- end }}



{{- define "Enum:Traits:CommonTypesHeader" }}

template <>
struct IsFidlType<{{ . }}> : public std::true_type {};
template <>
struct ContainsHandle<{{ . }}> : public std::false_type {};

{{- end }}

{{- define "Enum:WireTypesHeader" }}
{{ EnsureNamespace . -}}
using {{ .Name }} = {{ .Unified }};
{{- end }}

{{- define "Enum:Traits:NaturalTypesHeader" }}
  template <>
  struct internal::NaturalCodingTraits<{{ . }}, ::fidl::internal::NaturalCodingConstraintEmpty> {
    static constexpr size_t inline_size_v2 = sizeof({{ .Type }});
    static constexpr bool is_memcpy_compatible = {{ not .Strictness }};

    static void Encode(internal::NaturalEncoder* encoder, {{ . }}* value, size_t offset, size_t recursion_depth) {
      {{- if .Strictness }}
      {{- $enumType := . }}
      switch (*value) {
        {{- range .Members }}
        case {{ $enumType }}::{{ .Unified }}:
        {{- end }}
        {{- if .Members }}
          break;
        {{- end }}
        default:
          encoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
          return;
      }
      {{- end }}
      *encoder->template GetPtr<{{ . }}>(offset) = *value;
    }
    static void Decode(internal::NaturalDecoder* decoder, {{ . }}* value, size_t offset, size_t recursion_depth) {
      *value = *decoder->template GetPtr<{{ . }}>(offset);
      {{- if .Strictness }}
      {{- $enumType := . }}
      switch (*value) {
        {{- range .Members }}
        case {{ $enumType }}::{{ .Unified }}:
        {{- end }}
        {{- if .Members }}
          break;
        {{- end }}
        default:
          decoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
          return;
      }
      {{- end }}
    }
  };

{{- end }}
