github.com/ffalor/go-swagger@v0.0.0-20231011000038-9f25265ac351/generator/templates/schemavalidator.gotmpl (about)

     1  {{ define "primitivefieldcontextvalidator" }}
     2    {{ if .ReadOnly }}
     3      if err := validate.ReadOnly(ctx, {{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil{
     4        return err
     5      }
     6    {{ end }}
     7  {{ end }}
     8  {{ define "primitivefieldvalidator" }}
     9    {{ if .Required }}
    10      {{- if and (eq .GoType "string") (not .IsNullable) }}
    11    if err := validate.RequiredString({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsAliased }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if .IsAliased }}){{ end }}); err != nil {
    12      {{- else }}
    13    if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
    14      {{- end }}
    15      return err
    16    }
    17    {{- end }}
    18    {{ if .MinLength }}
    19      if err := validate.MinLength({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MinLength }}); err != nil {
    20      return err
    21    }
    22    {{- end }}
    23    {{ if .MaxLength }}
    24    if err := validate.MaxLength({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ToString }}, {{.MaxLength }}); err != nil {
    25      return err
    26    }
    27    {{ end }}
    28    {{ if .Pattern }}
    29    if err := validate.Pattern({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ToString }}, `{{ escapeBackticks .Pattern }}`); err != nil {
    30      return err
    31    }
    32    {{- end }}
    33    {{ if .Minimum }}
    34      {{ template "validationMinimum" . }}
    35    {{ end }}
    36    {{ if .Maximum }}
    37      {{ template "validationMaximum" . }}
    38    {{ end }}
    39    {{ if .MultipleOf }}
    40      {{ template "validationMultipleOf" . }}
    41    {{ end }}
    42    {{ if .Enum }}
    43    // value enum
    44    if err := {{.ReceiverName }}.validate{{ pascalize .Name }}{{ .Suffix }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if .IsNullable }}*{{ end }}{{.ValueExpression }}); err != nil {
    45      return err
    46    }
    47    {{- end }}
    48    {{ if and .IsCustomFormatter (not .IsStream) (not .IsBase64) }}
    49      {{ template "validationCustomformat" . }}
    50    {{- end }}
    51  {{ end }}
    52  
    53  {{ define "slicecontextvalidator" }}
    54    {{ if .ReadOnly }}
    55      if err := validate.ReadOnly(ctx, {{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil{
    56        return err
    57      }
    58    {{ end }}
    59    {{ if .Items }}
    60      {{- if and (or .Items.ReadOnly .Items.HasContextValidations) (not .Items.IsInterface) (not .Items.IsStream) }}
    61        for {{.IndexVar }} := 0; {{.IndexVar }} < len({{.ValueExpression }}); {{.IndexVar }}++ {
    62        {{- with .Items }}
    63          {{ template "propertycontextvalidator" . }}
    64        {{- end }}
    65        }
    66      {{- end }}
    67    {{- else }}
    68      {{- if or .IsAliased (ne .ValueExpression .ReceiverName) }}{{/* prevents generated code to call itself: this is reserved for aliased types */}}
    69        {{- if and .IsNullable (not .IsMapNullOverride) }}
    70      if {{ .ValueExpression }} != nil {
    71        {{- end }}
    72        if err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil {
    73          if ve, ok := err.(*errors.Validation); ok {
    74            return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
    75          } else if ce, ok := err.(*errors.CompositeError); ok {
    76            return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
    77          }
    78          return err
    79        }
    80        {{- if and .IsNullable (not .IsMapNullOverride) }}
    81      }
    82        {{- end }}
    83      {{- end }}
    84    {{- end }}
    85  {{ end }}
    86  
    87  {{define "slicevalidator" }}
    88    {{ if .Required }}
    89      if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
    90        return err
    91      }
    92    {{ end }}
    93    {{ if or .MinItems .MaxItems }}
    94      {{ .IndexVar }}{{ pascalize .Name }}Size := int64(len({{.ValueExpression }}))
    95    {{ end }}
    96    {{ if .MinItems }}
    97      if err := validate.MinItems({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .IndexVar }}{{ pascalize .Name }}Size, {{.MinItems }}); err != nil {
    98        return err
    99      }
   100    {{ end }}
   101    {{ if .MaxItems }}
   102      if err := validate.MaxItems({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .IndexVar }}{{ pascalize .Name }}Size, {{.MaxItems }}); err != nil {
   103        return err
   104      }
   105    {{ end }}
   106    {{ if .UniqueItems }}
   107      if err := validate.UniqueItems({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
   108        return err
   109      }
   110    {{ end }}
   111    {{ if .Enum }}
   112      // for slice
   113      if err := {{.ReceiverName }}.validate{{ pascalize .Name }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
   114        return err
   115      }
   116    {{ end }}
   117    {{ if .Items }}
   118      {{- if and (or .Items.Required .Items.HasValidations .Items.IsBaseType .Items.IsAliased) (not .Items.IsInterface) (not .Items.IsStream) (not .Items.SkipExternalValidation) }}
   119        for {{.IndexVar }} := 0; {{.IndexVar }} < len({{.ValueExpression }}); {{.IndexVar }}++ {
   120        {{- with .Items }}
   121          {{- if and .IsNullable (not .Required) (not .IsMapNullOverride) }}
   122            {{- if .IsInterface }}
   123            if {{ .ValueExpression }} == nil { // not required
   124            {{- else }}
   125            if swag.IsZero({{ .ValueExpression }}) { // not required
   126            {{- end }}
   127              continue
   128            }
   129          {{- end }}
   130          {{ template "propertyvalidator" . }}
   131        {{- end }}
   132        }
   133      {{- end }}
   134    {{- else }}
   135      {{- if and (or .IsAliased (ne .ValueExpression .ReceiverName) (not .SkipExternalValidation)) }}{{/* prevents generated code to call itself: this is reserved for aliased types */}}
   136        {{- if and .IsNullable (not .IsMapNullOverride) }}
   137      if {{ .ValueExpression }} != nil {
   138        {{- end }}
   139        if err := {{.ValueExpression }}.Validate(formats); err != nil {
   140          if ve, ok := err.(*errors.Validation); ok {
   141            return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   142          } else if ce, ok := err.(*errors.CompositeError); ok {
   143            return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   144          }
   145          return err
   146        }
   147        {{- if and .IsNullable (not .IsMapNullOverride) }}
   148      }
   149        {{- end }}
   150      {{- end }}
   151    {{- end }}
   152  {{ end }}
   153  {{ define "mapcontextvalidator" }}
   154    {{- if and .Required }}
   155      {{- if or .IsNullable .IsInterface }}
   156      if {{ .ReceiverName }}.{{ pascalize .Name }} == nil {
   157        return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, nil)
   158      }
   159      {{- else }}
   160      if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{ .ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   161        return err
   162      }
   163      {{- end }}
   164    {{- end }}
   165    {{ if .HasAdditionalProperties }}
   166      {{- if  .AdditionalProperties.HasContextValidations }}
   167      {{- $validatedValues := .ValueExpression }}{{ $keyVar := .AdditionalProperties.KeyVar }}
   168      for {{ .AdditionalProperties.KeyVar }} := range {{ .ValueExpression }} {
   169        {{ with .AdditionalProperties }}
   170          {{/*Don't need to add context validate directly here since we are recursing*/}}
   171          {{- if .IsPrimitive }}
   172            {{- if .IsAliased }}
   173              {{- if not .IsAnonymous }}
   174        if val, ok := {{ $validatedValues }}[{{ $keyVar }}]; ok {
   175                {{- if and .IsNullable (not .IsMapNullOverride) }}
   176          if val != nil {
   177                {{- end }}
   178            if err := val.ContextValidate(ctx, formats); err != nil {
   179                return err
   180            }
   181                {{- if and .IsNullable (not .IsMapNullOverride) }}
   182          }
   183                {{- end }}
   184        }
   185              {{- else }}{{/* validation of anonymous objects */}}
   186                {{ range .AllOf }}
   187                  {{ range .Properties }}
   188                    {{ template "propertycontextvalidator" . }}
   189                  {{ end }}
   190                {{- end }}
   191                {{ range .Properties }}
   192                  {{ template "propertycontextvalidator" . }}
   193                {{ end }}
   194              {{- end }}
   195              {{ if and .IsTuple .AdditionalItems }}
   196        // TODO: context validating additional items should go here, if you see this raise an issue{{/* TODO(fred): investigate the case to remove that comment: AdditionalItems shouldn't come in maps. Upstream validation is needed to guard against this */}}
   197        // at https://github.com/go-swagger/go-swagger/issues
   198              {{ end }}
   199            {{ else }}
   200              {{ template "primitivefieldcontextvalidator" . }}
   201            {{ end }}
   202          {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   203            {{- if and (not .IsStream) (not .IsBase64) }}{{/* TODO: IsStream and CustomFormattershould be mutually exclusive in type resolver */}}
   204        // TODO: context validating custom formatter items should go here, if you see this raise an issue
   205        // at https://github.com/go-swagger/go-swagger/issues
   206              {{/*
   207              {{ template "validationCustomformat" . }}
   208              */}}
   209            {{- end }}
   210          {{- else if .IsArray }}
   211            {{ template "slicecontextvalidator" . }}
   212          {{- else if and .IsMap (not .IsInterface) }}
   213            {{ template "mapcontextvalidator" . }}
   214          {{- else if and .IsMap .IsInterface }}
   215            {{ if .Enum }}
   216        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
   217          return err
   218        }
   219            {{- end }}
   220          {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
   221            {{- if not .IsAnonymous }}
   222        if val, ok := {{ $validatedValues }}[{{ $keyVar }}]; ok {
   223              {{- if and .IsNullable (not .IsMapNullOverride) }}
   224          if val != nil {
   225              {{- end }}
   226            if err := val.ContextValidate(ctx, formats); err != nil {
   227                return err
   228            }
   229              {{- if and .IsNullable (not .IsMapNullOverride) }}
   230          }
   231              {{- end }}
   232        }
   233            {{- else }}
   234              {{ range .AllOf }}
   235                {{ range .Properties }}
   236                  {{ template "propertycontextvalidator" . }}
   237                {{ end }}
   238              {{- end }}
   239              {{ range .Properties }}
   240                {{ template "propertycontextvalidator" . }}
   241              {{- end }}
   242            {{- end }}
   243            {{ if and .IsTuple .AdditionalItems }}
   244        // TODO: context validating additional items should go here, if you see this raise an issue
   245        // at https://github.com/go-swagger/go-swagger/issues
   246            {{ end }}
   247          {{- end }}
   248      }
   249        {{ end }}
   250      {{ end }}
   251    {{- else if .IsAliased }}
   252      {{- if and .IsMap .HasValidations }}{{/* validation of aliased maps but does not know about AdditionalProperties: e.g. it comes from a $ref */}}
   253        {{- if not .IsAnonymous }}
   254          {{- if $.IsMap }}{{/* we come from a map range */}}
   255        if val, ok := {{ .ValueExpression }}; ok {
   256          {{- end }}
   257          {{- if and .IsNullable (not .IsMapNullOverride) }}
   258            {{- if $.IsMap }}
   259          if val != nil {
   260            {{- else }}
   261          if {{ .ValueExpression }} != nil {
   262            {{- end }}
   263          {{- end }}
   264            if err := {{ if $.IsMap }}val{{ else }}{{ .ValueExpression }}{{ end }}.ContextValidate(ctx, formats); err != nil {
   265                return err
   266            }
   267          {{- if and .IsNullable (not .IsMapNullOverride) }}
   268          }
   269          {{- end }}
   270          {{- if or $.IsMap }}
   271       }
   272          {{- end }}
   273        {{- end }}
   274      {{- end }}
   275    {{- end }}
   276  {{ end }} {{/*mapcontextvalidator*/}}
   277  {{ define "mapvalidator" }}{{/* validates additionalProperties */}}
   278    {{- if and .Required }}
   279      {{- if or .IsNullable .IsInterface }}
   280      if {{ .ReceiverName }}.{{ pascalize .Name }} == nil {
   281        return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, nil)
   282      }
   283      {{- else }}
   284      if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{ .ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   285        return err
   286      }
   287      {{- end }}
   288    {{- end }}
   289    {{ if .HasAdditionalProperties }}
   290      {{- if  and .AdditionalProperties.HasValidations (not .AdditionalProperties.SkipExternalValidation) }}
   291      {{- $validatedValues := .ValueExpression }}{{ $keyVar := .AdditionalProperties.KeyVar }}
   292      for {{ .AdditionalProperties.KeyVar }} := range {{ .ValueExpression }} {
   293        {{ with .AdditionalProperties }}
   294          {{- if and (not .Required) .IsNullable }}{{/* skip when nul type is accepted */}}
   295            {{- if .IsInterface }}
   296        if {{ $validatedValues }}[{{ $keyVar }}] == nil { // not required
   297            {{- else }}
   298        if swag.IsZero({{ $validatedValues }}[{{ $keyVar }}]) { // not required
   299            {{- end }}
   300          continue
   301        }
   302          {{- else if and (.Required) (not .IsArray) }}{{/* Required slice is processed below */}}
   303        if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
   304          return err
   305        }
   306          {{- end }}
   307          {{- if and  .IsPrimitive (not .SkipExternalValidation ) }}
   308            {{- if .IsAliased }}
   309              {{- if not .IsAnonymous }}
   310        if val, ok := {{ $validatedValues }}[{{ $keyVar }}]; ok {
   311                {{- if and .IsNullable (not .IsMapNullOverride) }}
   312          if val != nil {
   313                {{- end }}
   314            if err := val.Validate(formats); err != nil {
   315                if ve, ok := err.(*errors.Validation); ok {
   316                    return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   317                } else if ce, ok := err.(*errors.CompositeError); ok {
   318                    return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   319                }
   320                return err
   321            }
   322                {{- if and .IsNullable (not .IsMapNullOverride) }}
   323          }
   324                {{- end }}
   325        }
   326              {{- else }}{{/* validation of anonymous objects */}}
   327                {{ range .AllOf }}
   328                  {{ range .Properties }}
   329                    {{ template "propertyvalidator" . }}
   330                  {{ end }}
   331                {{- end }}
   332                {{ range .Properties }}
   333                  {{ template "propertyvalidator" . }}
   334                {{ end }}
   335              {{- end }}
   336              {{ if and .IsTuple .AdditionalItems }}
   337        // TODO: validating additional items should go here, if you see this raise an issue{{/* TODO(fred): investigate the case to remove that comment: AdditionalItems shouldn't come in maps. Upstream validation is needed to guard against this */}}
   338        // at https://github.com/go-swagger/go-swagger/issues
   339              {{ end }}
   340            {{- else }}
   341              {{ template "primitivefieldvalidator" . }}
   342            {{- end }}
   343          {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   344            {{- if .Required }}
   345        if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   346          return err
   347        }
   348            {{- end }}
   349            {{- if and (not .IsStream) (not .IsBase64) (not .SkipExternalValidation) }}{{/* TODO: IsStream and CustomFormattershould be mutually exclusive in type resolver */}}
   350              {{ template "validationCustomformat" . }}
   351            {{- end }}
   352          {{- else if .IsArray }}
   353            {{ template "slicevalidator" . }}
   354          {{- else if and .IsMap (not .IsInterface) }}
   355            {{ template "mapvalidator" . }}
   356            {{ if .Enum }}
   357        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
   358          return err
   359        }
   360            {{- end }}
   361          {{- else if and .IsMap .IsInterface }}
   362            {{ if .Enum }}
   363        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}ValueEnum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ $validatedValues }}[{{ $keyVar }}]); err != nil {
   364          return err
   365        }
   366            {{- end }}
   367          {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
   368            {{- if and (not .IsAnonymous) (not .SkipExternalValidation) }}
   369      if val, ok := {{ $validatedValues }}[{{ $keyVar }}]; ok {
   370              {{- if and .IsNullable (not .IsMapNullOverride) }}
   371        if val != nil {
   372              {{- end }}
   373            if err := val.Validate(formats); err != nil {
   374                if ve, ok := err.(*errors.Validation); ok {
   375                    return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   376                } else if ce, ok := err.(*errors.CompositeError); ok {
   377                    return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   378                }
   379                return err
   380            }
   381              {{- if and .IsNullable (not .IsMapNullOverride) }}
   382        }
   383              {{- end }}
   384      }
   385            {{- else }}
   386              {{ range .AllOf }}
   387                {{ range .Properties }}
   388                  {{ template "propertyvalidator" . }}
   389                {{ end }}
   390              {{- end }}
   391              {{ range .Properties }}
   392                {{ template "propertyvalidator" . }}
   393              {{- end }}
   394            {{- end }}
   395            {{ if and .IsTuple .AdditionalItems }}
   396        // TODO: validating additional items should go here, if you see this raise an issue
   397        // at https://github.com/go-swagger/go-swagger/issues
   398            {{ end }}
   399          {{ end }}
   400      }
   401        {{- end }}
   402      {{ end }}
   403      {{ if .Enum }}
   404      // from map
   405      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Enum({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }}); err != nil {
   406        return err
   407      }
   408      {{ end }}
   409    {{- else if .IsAliased }}
   410      {{- if and .IsMap .HasValidations (not .SkipExternalValidation) }}{{/* validation of aliased maps but does not know about AdditionalProperties: e.g. it comes from a $ref */}}
   411        {{- if not .IsAnonymous }}
   412          {{- if $.IsMap }}{{/* we come from a map range */}}
   413        if val, ok := {{ .ValueExpression }}; ok {
   414          {{- end }}
   415          {{- if and .IsNullable (not .IsMapNullOverride) }}
   416            {{- if $.IsMap }}
   417          if val != nil {
   418            {{- else }}
   419          if {{ .ValueExpression }} != nil {
   420            {{- end }}
   421          {{- end }}
   422            if err := {{ if $.IsMap }}val{{ else }}{{ .ValueExpression }}{{ end }}.Validate(formats); err != nil {
   423                return err
   424            }
   425          {{- if and .IsNullable (not .IsMapNullOverride) }}
   426          }
   427          {{- end }}
   428          {{- if or $.IsMap }}
   429       }
   430          {{- end }}
   431        {{- end }}
   432      {{- end }}
   433    {{- end }}
   434  {{ end }}
   435  
   436  {{define "objectcontextvalidator" }}
   437    {{/* Debug
   438    // .Name: {{ .Name }}
   439    // .IsAliased: {{ .IsAliased }}
   440    // .IsAnonymous: {{ .IsAnonymous }}
   441    // .IsNullable: {{ .IsNullable }}
   442    // .Required: {{ .Required }}
   443    // .ReadOnly: {{ .ReadOnly }}
   444    // .HasContextValidations {{ .HasContextValidations }}
   445    // .IsBaseType: {{ .IsBaseType }}
   446    // .ValueExpression: {{ .ValueExpression }}
   447    // .ReceiverName: {{ .ReceiverName }}
   448    */}}
   449    {{- if not .IsAnonymous }}
   450      {{- if or .IsAliased (ne .ValueExpression .ReceiverName) }}{{/* prevents generated code to call itself: case of aliased types */}}
   451        {{- if and .IsNullable (not .IsMapNullOverride) }}
   452        if {{ .ValueExpression }} != nil {
   453        {{- end }}
   454        {{ if not .Required }}
   455                {{- if .IsInterface }}
   456        if {{ .ValueExpression }} == nil { // not required
   457                {{- else }}
   458        if swag.IsZero({{ .ValueExpression }}) { // not required
   459                {{- end }}
   460          return nil
   461        }
   462        {{ end }}
   463        if err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil {
   464          if ve, ok := err.(*errors.Validation); ok {
   465            return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   466          } else if ce, ok := err.(*errors.CompositeError); ok {
   467            return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   468          }
   469          return err
   470        }
   471        {{- if and .IsNullable (not .IsMapNullOverride) }}
   472      }
   473        {{- end }}
   474      {{- end }}
   475    {{- else }}
   476      {{ range .AllOf }}
   477        {{ range .Properties }}
   478          {{ template "propertycontextvalidator" . }}
   479        {{ end }}
   480      {{ end }}
   481      {{ range .Properties }}
   482        {{ template "propertycontextvalidator" . }}
   483      {{ end }}
   484    {{- end }}
   485    {{- if and .IsTuple .AdditionalItems }}
   486      // TODO: context validating additional items should go here, if you see this raise an issue
   487      // at https://github.com/go-swagger/go-swagger/issues
   488    {{- end }}
   489  {{ end }}
   490  {{ define "minmaxProperties" }}
   491    {{- if and (or .IsMap (and .IsAdditionalProperties .HasAdditionalProperties)) (or .MinProperties .MaxProperties) }}
   492      {{- if and (not .IsAdditionalProperties) (not .IsInterface) (eq (len .Properties) 0) }}{{/* map only */}}
   493      nprops := len({{ if and (not .IsAliased) .HasAdditionalProperties }}{{ .ReceiverName }}{{ else }}{{ .ValueExpression }}{{ end }})
   494      {{- else }}{{/* object with properties */}}
   495        {{- if and .IsNullable .MinProperties }}
   496          {{- if gt0 .MinProperties }}
   497  
   498      // short circuits minProperties > 0
   499      if {{ .ReceiverName }} == nil {
   500        return errors.TooFewProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MinProperties }})
   501      }
   502          {{- end }}
   503        {{- end }}
   504  
   505      props := make(map[string]json.RawMessage, {{ len .Properties }}{{ if .HasAdditionalProperties }}+ 10{{ end }})
   506      j, err := swag.WriteJSON({{ .ReceiverName }})
   507      if err != nil {
   508        return err
   509      }
   510  
   511      if err = swag.ReadJSON(j, &props) ; err != nil {
   512        return err
   513      }
   514  
   515      nprops := len(props)
   516      {{- end }}
   517      {{ if .MinProperties }}
   518      // minProperties: {{ .MinProperties }}
   519      if nprops < {{ .MinProperties }} {
   520        return errors.TooFewProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MinProperties }})
   521      }
   522      {{- end }}
   523      {{ if .MaxProperties }}
   524      // maxProperties: {{ .MaxProperties }}
   525      if nprops > {{ .MaxProperties }} {
   526        return errors.TooManyProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MaxProperties }})
   527      }
   528      {{- end }}
   529    {{- end }}
   530  {{- end }}
   531  {{define "objectvalidator" }}{{/* // DEBUG
   532    // .Name: {{ .Name }}
   533    // .IsAliased: {{ .IsAliased }}
   534    // .IsAnonymous: {{ .IsAnonymous }}
   535    // .IsNullable: {{ .IsNullable }}
   536    // .Required: {{ .Required }}
   537    // .ReadOnly: {{ .ReadOnly }}
   538    // .HasValidations {{ .HasValidations }}
   539    // .HasContextValidations {{ .HasContextValidations }}
   540    // .IsBaseType: {{ .IsBaseType }}
   541    // .ValueExpression: {{ .ValueExpression }}
   542    // .ReceiverName: {{ .ReceiverName }}
   543    // .IsAdditionalProperties: {{ .IsAdditionalProperties }}
   544    // .IsInterface: {{ .IsInterface }}
   545    // .IsMap: {{ .IsMap }}
   546    // .IsArray: {{ .IsArray }}
   547    // .IsMapNullOverride: {{ .IsMapNullOverride }}
   548    */}}
   549    {{- if not .IsAnonymous }}
   550      {{- if and .Required (or .IsNullable .IsBaseType .IsMap) }}
   551        if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
   552          return err
   553        }
   554        {{- if and (not .Required) .IsBaseType }}
   555        if {{ .ValueExpression }} == nil {
   556          return nil
   557        }
   558        {{- end }}
   559      {{ end }}
   560      {{- if and (or .IsAliased (ne .ValueExpression .ReceiverName)) (not .SkipExternalValidation) }}{{/* prevents generated code to call itself: case of aliased types */}}
   561        {{- if or (and (or .IsNullable) (not .IsMapNullOverride)) .IsMap .IsArray }}
   562        if {{ .ValueExpression }} != nil {
   563        {{- end }}
   564        if err := {{.ValueExpression }}.Validate(formats); err != nil {
   565          if ve, ok := err.(*errors.Validation); ok {
   566            return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   567          } else if ce, ok := err.(*errors.CompositeError); ok {
   568            return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   569          }
   570          return err
   571        }
   572        {{- if or (and (or .IsNullable) (not .IsMapNullOverride)) .IsMap .IsArray }}
   573      }
   574        {{- end }}
   575      {{- end }}
   576    {{- else }}
   577      {{ template "minmaxProperties" .}}
   578      {{ range .AllOf }}
   579        {{ range .Properties }}
   580          {{ template "propertyvalidator" . }}
   581        {{ end }}
   582      {{ end }}
   583      {{ range .Properties }}
   584        {{ template "propertyvalidator" . }}
   585      {{ end }}
   586    {{- end }}
   587    {{- if and .IsTuple .AdditionalItems }}
   588      // TODO: validating additional items should go here, if you see this raise an issue
   589      // at https://github.com/go-swagger/go-swagger/issues
   590    {{- end }}
   591  {{ end }}
   592  
   593  {{define "propertycontextvalidator"}}
   594    {{- if .IsPrimitive }}
   595      {{- if .IsAliased }}
   596        {{ template "objectcontextvalidator" . }}
   597      {{- else }}
   598        {{ template "primitivefieldcontextvalidator" . }}
   599      {{- end }}
   600      {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   601      // TODO: context validating primitive with custom formatter should go here, if you see this raise an issue
   602      // at https://github.com/go-swagger/go-swagger/issues
   603      {{- if .ReadOnly }}
   604  
   605    if err := validate.ReadOnly{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   606      return err
   607    }
   608      {{- end }}
   609      {{- if and (not .IsStream) (not .IsBase64) }}
   610    // TODO: context validating properties with custom formatter should go here, if you see this raise an issue
   611    // at https://github.com/go-swagger/go-swagger/issues
   612      {{/*{{ template "validationCustomformat" . }}*/}}
   613      {{- end }}
   614    {{- else if .IsArray }}
   615      {{ template "slicecontextvalidator" . }}
   616    {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}{{/* except for interface, the renderinf for aliased maps is performed by objectvalidator */}}
   617      {{ template "mapcontextvalidator" . }}
   618    {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
   619      {{ template "objectcontextvalidator" . }}
   620    {{- end }}
   621  
   622  {{end}}
   623  
   624  {{define "propertyvalidator" }}
   625    {{- if .IsPrimitive }}
   626      {{- if .IsAliased }}
   627        {{- if and .Required (not .IsAnonymous) }}
   628    if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   629      return err
   630    }
   631        {{- end }}
   632        {{ template "objectvalidator" . }}
   633      {{- else }}
   634        {{ template "primitivefieldvalidator" . }}
   635      {{- end }}
   636    {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   637      {{- if .Required }}
   638    if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   639      return err
   640    }
   641      {{- end }}
   642      {{- if and (not .IsStream) (not .IsBase64) }}
   643        {{ template "validationCustomformat" . }}
   644      {{- end }}
   645     {{- else if .IsArray }}
   646      {{ template "slicevalidator" . }}
   647    {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}
   648      {{ template "minmaxProperties" . }}
   649      {{ template "mapvalidator" . }}
   650    {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
   651      {{- if and .IsAdditionalProperties .Required (not .IsAliased) }}
   652        {{- if or .IsNullable .IsInterface }}
   653        if {{ .ValueExpression }} == nil {
   654          return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
   655        }
   656        {{- else }}
   657        if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   658          return err
   659        }
   660        {{- end }}
   661      {{- end }}
   662      {{ template "objectvalidator" . }}
   663    {{- else if and .IsExternal .Required }}
   664      {{- if or .IsNullable .IsInterface }}
   665        if {{ .ValueExpression }} == nil {
   666          return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
   667        }
   668      {{- else }}
   669        if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   670          return err
   671        }
   672      {{- end }}
   673    {{- end }}
   674  {{ end }}
   675  
   676  {{define "fieldcontextvalidator" }}
   677    {{- if .IsPrimitive }}
   678      {{ template "primitivefieldcontextvalidator" . }}
   679    {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   680      {{- if and (not .IsStream) (not .IsBase64) }}
   681        // TODO: context validating properties with custom formatter should go here, if you see this raise an issue
   682        // at https://github.com/go-swagger/go-swagger/issues
   683        {{/*
   684        {{ template "validationCustomformat" . }}
   685        */}}
   686      {{- end }}
   687    {{- else if .IsArray }}
   688      {{ template "slicecontextvalidator" . }}
   689    {{- else if .IsMap }}
   690      {{ template "mapcontextvalidator" . }}
   691    {{- end }}
   692  
   693  {{ end }}
   694  
   695  {{ define "fieldvalidator"}}
   696    {{- if .IsPrimitive }}
   697      {{ template "primitivefieldvalidator" . }}
   698    {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   699      {{- if .Required }}
   700    if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ if not (or .IsAnonymous .IsNullable) }}{{ .GoType }}({{ end }}{{.ValueExpression }}{{ if not (or .IsAnonymous .IsNullable) }}){{ end }}); err != nil {
   701      return err
   702    }
   703      {{- end }}
   704      {{- if and (not .IsStream) (not .IsBase64) }}
   705        {{ template "validationCustomformat" . }}
   706      {{- end }}
   707    {{- else if .IsArray }}
   708      {{ template "slicevalidator" . }}
   709    {{- else if .IsMap }}
   710      {{ template "mapvalidator" . }}
   711    {{- end }}
   712  {{ end }}
   713  
   714  {{define "schemacontextvalidator" }}
   715  // ContextValidate validate this {{ humanize .Name }} based on the context it is used
   716  func ({{.ReceiverName }} {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ if .Discriminates }}{{ camelize .Name }}{{ else if .IsExported }}{{ pascalize .Name }}{{ else }}{{ .Name }}{{ end }}) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
   717    var res []error
   718    {{ range .AllOf }}
   719      {{- if not .Properties }}
   720        // validation for a type composition with {{ .GoType }}
   721      {{- end }}
   722      {{- if and (or .IsInterface .IsAnonymous .IsBaseType) (or .HasContextValidations) }}
   723        {{ template "fieldcontextvalidator" . }}
   724        {{ range .Properties }}
   725          {{ if and (ne $.DiscriminatorField .Name) (or .HasContextValidations) }}
   726            if err := {{.ReceiverName }}.contextValidate{{ pascalize .Name }}(ctx, formats); err != nil {
   727              res = append(res, err)
   728            }
   729          {{- end }}
   730        {{- end }}
   731        {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   732          {{ template "mapcontextvalidator" . }}
   733        {{- end }}
   734        {{ if and .IsTuple .AdditionalItems }}
   735        // TODO: context validating additional items should go here, if you see this raise an issue
   736        // at https://github.com/go-swagger/go-swagger/issues
   737        {{/*
   738        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Items(formats); err != nil {
   739          res = append(res, err)
   740        }
   741        */}}
   742        {{ end }}
   743      {{- else if (or .HasContextValidations) }}
   744        if err := {{ .ReceiverName }}.{{ pascalize (dropPackage .GoType) }}.ContextValidate(ctx, formats); err != nil {
   745          res = append(res, err)
   746        }
   747      {{- end }}
   748    {{- end }} {{/*end AllOf*/}}
   749    {{ template "fieldcontextvalidator" . }}
   750    {{ range .Properties }}
   751      {{ if .HasContextValidations }} {{/* complex obj always has cv*/}}
   752        if err := {{.ReceiverName }}.contextValidate{{ pascalize .Name }}(ctx, formats); err != nil {
   753          res = append(res, err)
   754        }
   755      {{ end }}
   756    {{ end }}
   757    {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   758      {{ template "mapcontextvalidator" . }}
   759    {{- end }}
   760    if len(res) > 0 {
   761      return errors.CompositeValidationError(res...)
   762    }
   763    return nil
   764  }
   765  
   766  
   767    {{ range .Properties }}
   768      {{ if .HasContextValidations }}
   769  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) contextValidate{{ pascalize .Name }}(ctx context.Context, formats strfmt.Registry) error {
   770         {{template "propertycontextvalidator" . }}
   771    return nil
   772  }
   773      {{ end }}
   774    {{ end }} {{/*Properties*/}}
   775    {{ range .AllOf }}
   776      {{ range .Properties }}
   777        {{ if .HasContextValidations }}
   778  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) contextValidate{{ pascalize .Name }}(ctx context.Context, formats strfmt.Registry) error {
   779         {{template "propertycontextvalidator" . }}
   780    return nil
   781  }
   782        {{ end }}
   783      {{ end }}
   784    {{ end }} {{/*AllOf*/}}
   785  {{end}} {{/*schemacontextvalidator*/}}
   786  
   787  {{define "schemavalidator" }}
   788    {{ if .Enum }}
   789      {{ if (eq .SwaggerType "string") }}
   790        {{ $gotype := .GoType }}
   791  const (
   792        {{ range .Enum }}
   793        {{- $variant := print $gotype (pascalize (cleanupEnumVariant .)) }}
   794    // {{ $variant }} captures enum value {{ printf "%q" . }}
   795  	{{ $variant }} {{ $gotype }} = {{ printf "%q" . }}
   796        {{ end }}
   797  )
   798      {{ end }}
   799  
   800  // for schema
   801  var {{ camelize .Name }}Enum []interface{}
   802  func init() {
   803    var res []{{ template "dereffedSchemaType" . }}
   804    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   805      panic(err)
   806    }
   807    for _, v := range res {
   808      {{ camelize .Name }}Enum = append({{ camelize .Name }}Enum, v)
   809    }
   810  }
   811  
   812  func ({{ .ReceiverName }} {{ if not .IsPrimitive }}*{{ end }}{{ if .IsExported }}{{ pascalize .Name }}{{ else }}{{ .Name }}{{ end }}) validate{{ pascalize .Name }}Enum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" . }}) error {
   813    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}Enum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   814      return err
   815    }
   816    return nil
   817  }
   818    {{ end }}
   819    {{ if .ItemsEnum }}
   820  var {{ camelize .Name }}ItemsEnum []interface{}
   821  
   822  func init() {
   823    var res []{{ template "dereffedSchemaType" .Items }}
   824    if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil {
   825      panic(err)
   826    }
   827    for _, v := range res {
   828      {{ camelize .Name }}ItemsEnum = append({{ camelize .Name }}ItemsEnum, v)
   829    }
   830  }
   831  
   832  func ({{ .ReceiverName }} *{{ if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{  $.Name }}{{ end }}) validate{{ pascalize .Name }}ItemsEnum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" .Items }}) error {
   833    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   834      return err
   835    }
   836    return nil
   837  }
   838    {{ end }}
   839    {{ with .AdditionalProperties }}
   840      {{ if .Enum }}
   841  // for additional props
   842  var {{ camelize .Name }}ValueEnum []interface{}
   843  
   844  func init() {
   845    var res []{{ template "dereffedSchemaType" . }}
   846    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   847      panic(err)
   848    }
   849    for _, v := range res {
   850      {{ camelize .Name }}ValueEnum = append({{ camelize .Name }}ValueEnum, v)
   851    }
   852  }
   853  
   854  func ({{ .ReceiverName }} *{{ if .IsExported }}{{ pascalize .Name }}{{ else }}{{ .Name }}{{ end }}) validate{{ pascalize .Name }}ValueEnum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" . }}) error {
   855    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}ValueEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   856      return err
   857    }
   858    return nil
   859  }
   860      {{- end }}
   861    {{ end }}
   862  // Validate validates this {{ humanize .Name }}
   863  func ({{.ReceiverName }} {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ if .Discriminates }}{{ camelize .Name }}{{ else if .IsExported }}{{ pascalize .Name }}{{ else }}{{ .Name }}{{ end }}) Validate(formats strfmt.Registry) error {
   864    var res []error
   865    {{ template "minmaxProperties" .}}
   866    {{ range .AllOf }}
   867      {{- if not .Properties }}
   868        // validation for a type composition with {{ .GoType }}
   869      {{- end }}
   870      {{- if and (or .IsInterface .IsAnonymous .IsBaseType) (or .Required .HasValidations) }}
   871        {{ template "fieldvalidator" . }}
   872  
   873        {{ range .Properties }}
   874          {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
   875            if err := {{.ReceiverName }}.validate{{ pascalize .Name }}(formats); err != nil {
   876              res = append(res, err)
   877            }
   878          {{- end }}
   879        {{- end }}
   880        {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   881          {{ template "mapvalidator" . }}
   882        {{- end }}
   883        {{ if and .IsTuple .AdditionalItems }}
   884        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Items(formats); err != nil {
   885          res = append(res, err)
   886        }
   887        {{ end }}
   888      {{- else if (or .Required .HasValidations) }}
   889        if err := {{ .ReceiverName }}.{{ pascalize (dropPackage .GoType) }}.Validate(formats); err != nil {
   890          res = append(res, err)
   891        }
   892      {{- end }}
   893    {{- end }}
   894    {{ template "fieldvalidator" . }}
   895    {{ range .Properties }}
   896      {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
   897        if err := {{.ReceiverName }}.validate{{ pascalize .Name }}(formats); err != nil {
   898          res = append(res, err)
   899        }
   900      {{ end }}
   901    {{ end }}
   902    {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   903      {{ template "mapvalidator" . }}
   904    {{- end }}
   905    {{ if and .IsTuple .AdditionalItems }}{{/* validates additionalItems in a tuple */}}
   906      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Items(formats); err != nil {
   907        res = append(res, err)
   908      }
   909    {{ end }}
   910    {{ if and .Enum (not .IsPrimitive) (not .IsMap) }}
   911      // value enum
   912      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Enum("", "body", {{ .ReceiverName }}); err != nil {
   913        res = append(res, err)
   914      }
   915    {{ end }}
   916  
   917    if len(res) > 0 {
   918      return errors.CompositeValidationError(res...)
   919    }
   920    return nil
   921  }
   922  
   923    {{ range .Properties }}
   924      {{ if or .Required .HasValidations }}
   925        {{ if .Enum }}
   926  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
   927  
   928  func init() {
   929    var res []{{ template "dereffedSchemaType" . }}
   930    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   931      panic(err)
   932    }
   933    for _, v := range res {
   934      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
   935    }
   936  }
   937  
   938          {{ if (eq .SwaggerType "string") }}
   939            {{ $gotype := .GoType }}
   940            {{ $propname := .Name }}
   941  const (
   942            {{ range .Enum }}
   943            {{- $variant := print (pascalize $.Name) (pascalize $propname) (pascalize (cleanupEnumVariant .)) }}
   944    // {{ $variant }} captures enum value {{ printf "%q" . }}
   945  	{{ $variant }} {{ $gotype }} = {{ printf "%q" . }}
   946            {{ end }}
   947  )
   948          {{ end }}
   949  
   950  // prop value enum
   951  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}Enum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" . }}) error {
   952    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   953      return err
   954    }
   955    return nil
   956  }
   957        {{ end }}
   958        {{ if .ItemsEnum }}
   959  var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []interface{}
   960  func init() {
   961    var res []{{ template "dereffedSchemaType" .Items }}
   962    if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil {
   963      panic(err)
   964    }
   965    for _, v := range res {
   966      {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, v)
   967    }
   968  }
   969  
   970  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}ItemsEnum(path, location string, value {{ if or .Items.IsTuple .Items.IsComplexObject .Items.IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" .Items }}) error {
   971    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   972      return err
   973    }
   974    return nil
   975  }
   976        {{ end }}
   977        {{ if .AdditionalItems }}
   978          {{ if .AdditionalItems.Enum }}
   979  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
   980  
   981  func init() {
   982    var res []{{ template "dereffedSchemaType" .AdditionalItems }}
   983    if err := json.Unmarshal([]byte(`{{ json .AdditionalItems.Enum }}`), &res); err != nil {
   984      panic(err)
   985    }
   986    for _, v := range res {
   987      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
   988    }
   989  }
   990  
   991  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}Enum(path, location string, value {{ if or .AdditionalItems.IsTuple .AdditionalItems.IsComplexObject .AdditionalItems.IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" .AdditionalItems }}) error {
   992    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   993      return err
   994    }
   995    return nil
   996  }
   997          {{ end }}
   998        {{ end }}
   999        {{ with .AdditionalProperties }}
  1000          {{ if .Enum }}
  1001  // additional properties value enum
  1002  var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []interface{}
  1003  
  1004  func init() {
  1005    var res []{{ template "dereffedSchemaType" . }}
  1006    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
  1007      panic(err)
  1008    }
  1009    for _, v := range res {
  1010      {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, v)
  1011    }
  1012  }
  1013  
  1014  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}ValueEnum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" . }}) error {
  1015    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1016      return err
  1017    }
  1018    return nil
  1019  }
  1020          {{ end }}
  1021        {{ end }}
  1022  
  1023        {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
  1024  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}(formats strfmt.Registry) error {
  1025          {{- if not .Required }}
  1026            {{- if .IsInterface }}
  1027    if .ValueExpression == nil { // not required
  1028            {{- else }}
  1029    if swag.IsZero({{ .ValueExpression }}) { // not required
  1030            {{- end }}
  1031      return nil
  1032    }
  1033          {{- end }}
  1034          {{- if and $.IsTuple .IsMap .Required }}
  1035            {{- if .IsInterface }}
  1036    if {{ .ValueExpression }} == nil {
  1037      return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
  1038    }
  1039            {{- else }}
  1040    if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}(
  1041              {{- if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }},
  1042              {{- if and (eq .GoType "string") (not (or .IsAnonymous .IsNullable)) }}{{ .GoType }}({{ end }}
  1043              {{- .ValueExpression }}
  1044              {{- if and (eq .GoType "string") (not (or .IsAnonymous .IsNullable)) }}){{ end }}); err != nil {
  1045      return err
  1046    }
  1047            {{- end }}
  1048          {{- end }}
  1049          {{template "propertyvalidator" . }}
  1050  
  1051    return nil
  1052  }
  1053        {{ end }}
  1054      {{ end }}
  1055    {{ end }}
  1056    {{ range .AllOf }}
  1057      {{ range .Properties }}
  1058        {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
  1059          {{ if .Enum }}
  1060  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
  1061  
  1062  func init() {
  1063    var res []{{ template "dereffedSchemaType" . }}
  1064    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
  1065      panic(err)
  1066    }
  1067    for _, v := range res {
  1068      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
  1069    }
  1070  }
  1071  
  1072  // property enum
  1073  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}Enum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" . }}) error {
  1074    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1075      return err
  1076    }
  1077    return nil
  1078  }
  1079          {{ end }}
  1080          {{ if .ItemsEnum }}
  1081  var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []interface{}
  1082  
  1083  func init() {
  1084    var res []{{ template "dereffedSchemaType" .Items }}
  1085    if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil {
  1086      panic(err)
  1087    }
  1088    for _, v := range res {
  1089      {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, v)
  1090    }
  1091  }
  1092  
  1093  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}ItemsEnum(path, location string, value {{ if or .Items.IsTuple .Items.IsComplexObject .Items.IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" .Items }}) error {
  1094    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1095      return err
  1096    }
  1097    return nil
  1098  }
  1099          {{ end }}
  1100          {{ if .AdditionalItems }}
  1101            {{ if .AdditionalItems.Enum }}
  1102  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
  1103  
  1104  func init() {
  1105    var res []{{ template "dereffedSchemaType" .AdditionalItems }}
  1106    if err := json.Unmarshal([]byte(`{{ json .AdditionalItems.Enum }}`), &res); err != nil {
  1107      panic(err)
  1108    }
  1109    for _, v := range res {
  1110      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
  1111    }
  1112  }
  1113  
  1114  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}Enum(path, location string, value {{ if or .AdditionalItems.IsTuple .AdditionalItems.IsComplexObject .AdditionalItems.IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" .AdditionalItems }}) error {
  1115    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1116      return err
  1117    }
  1118    return nil
  1119  }
  1120            {{ end }}
  1121          {{ end }}
  1122          {{ with .AdditionalProperties }}
  1123            {{ if .Enum }}
  1124  var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []interface{}
  1125  func init() {
  1126    var res []{{ template "dereffedSchemaType" . }}
  1127    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
  1128      panic(err)
  1129    }
  1130    for _, v := range res {
  1131      {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, v)
  1132    }
  1133  }
  1134  
  1135  // additional properties value enum
  1136  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}ValueEnum(path, location string, value {{ if or .IsTuple .IsComplexObject .IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" . }}) error {
  1137    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1138      return err
  1139    }
  1140    return nil
  1141  }
  1142            {{ end }}
  1143          {{ end }}
  1144  
  1145  
  1146  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}(formats strfmt.Registry) error {
  1147          {{ if not .Required }}
  1148            {{- if .IsInterface }}
  1149    if {{ .ValueExpression }} == nil { // not required
  1150            {{- else }}
  1151    if swag.IsZero({{ .ValueExpression }}) { // not required
  1152            {{- end }}
  1153      return nil
  1154    }
  1155          {{ end }}
  1156          {{template "propertyvalidator" . }}
  1157  
  1158    return nil
  1159  }
  1160        {{ end }}
  1161      {{ end }}
  1162    {{ end }}
  1163  
  1164    {{ if .HasAdditionalItems }}
  1165      {{ if .AdditionalItems.Enum }}
  1166  var {{ camelize .Name }}ItemsEnum []interface{}
  1167  
  1168  func init() {
  1169    var res []{{ template "dereffedSchemaType" .AdditionalItems }}
  1170    if err := json.Unmarshal([]byte(`{{ json .AdditionalItems.Enum }}`), &res); err != nil {
  1171      panic(err)
  1172    }
  1173    for _, v := range res {
  1174      {{ camelize .Name }}ItemsEnum = append({{ camelize .Name }}ItemsEnum, v)
  1175    }
  1176  }
  1177  
  1178  func ({{ .ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}ItemsEnum(path, location string, value {{ if or .AdditionalItems.IsTuple .AdditionalItems.IsComplexObject .AdditionalItems.IsAdditionalProperties }}*{{ end }}{{ template "dereffedSchemaType" .AdditionalItems }}) error {
  1179    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1180      return err
  1181    }
  1182    return nil
  1183  }
  1184      {{ end }}
  1185  func ({{.ReceiverName }} *{{ pascalize .Name }}) validate{{ pascalize .Name }}Items(formats strfmt.Registry) error {
  1186      {{ if and (or .AdditionalItems.Required .AdditionalItems.HasValidations) (not .AdditionalItems.SkipExternalValidation) }}
  1187    for {{ .IndexVar }} := range {{ .ValueExpression }}.{{ pascalize .Name }}Items {
  1188        {{template "propertyvalidator" .AdditionalItems }}
  1189    }
  1190      {{ end }}
  1191    return nil
  1192  }
  1193    {{ end }}
  1194  {{ end }}