github.com/jamescostian/go-swagger@v0.30.4-0.20221130163922-68364d6b567b/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 err := {{.ValueExpression }}.ContextValidate(ctx, formats); err != nil {
   455          if ve, ok := err.(*errors.Validation); ok {
   456            return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   457          } else if ce, ok := err.(*errors.CompositeError); ok {
   458            return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   459          }
   460          return err
   461        }
   462        {{- if and .IsNullable (not .IsMapNullOverride) }}
   463      }
   464        {{- end }}
   465      {{- end }}
   466    {{- else }}
   467      {{ range .AllOf }}
   468        {{ range .Properties }}
   469          {{ template "propertycontextvalidator" . }}
   470        {{ end }}
   471      {{ end }}
   472      {{ range .Properties }}
   473        {{ template "propertycontextvalidator" . }}
   474      {{ end }}
   475    {{- end }}
   476    {{- if and .IsTuple .AdditionalItems }}
   477      // TODO: context validating additional items should go here, if you see this raise an issue
   478      // at https://github.com/go-swagger/go-swagger/issues
   479    {{- end }}
   480  {{ end }}
   481  {{ define "minmaxProperties" }}
   482    {{- if and (or .IsMap (and .IsAdditionalProperties .HasAdditionalProperties)) (or .MinProperties .MaxProperties) }}
   483      {{- if and (not .IsAdditionalProperties) (not .IsInterface) (eq (len .Properties) 0) }}{{/* map only */}}
   484      nprops := len({{ if and (not .IsAliased) .HasAdditionalProperties }}{{ .ReceiverName }}{{ else }}{{ .ValueExpression }}{{ end }})
   485      {{- else }}{{/* object with properties */}}
   486        {{- if and .IsNullable .MinProperties }}
   487          {{- if gt0 .MinProperties }}
   488  
   489      // short circuits minProperties > 0
   490      if {{ .ReceiverName }} == nil {
   491        return errors.TooFewProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MinProperties }})
   492      }
   493          {{- end }}
   494        {{- end }}
   495  
   496      props := make(map[string]json.RawMessage, {{ len .Properties }}{{ if .HasAdditionalProperties }}+ 10{{ end }})
   497      j, err := swag.WriteJSON({{ .ReceiverName }})
   498      if err != nil {
   499        return err
   500      }
   501  
   502      if err = swag.ReadJSON(j, &props) ; err != nil {
   503        return err
   504      }
   505  
   506      nprops := len(props)
   507      {{- end }}
   508      {{ if .MinProperties }}
   509      // minProperties: {{ .MinProperties }}
   510      if nprops < {{ .MinProperties }} {
   511        return errors.TooFewProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MinProperties }})
   512      }
   513      {{- end }}
   514      {{ if .MaxProperties }}
   515      // maxProperties: {{ .MaxProperties }}
   516      if nprops > {{ .MaxProperties }} {
   517        return errors.TooManyProperties({{ if .Path }}{{ .Path }}{{else}}""{{end}}, {{ printf "%q" .Location }}, {{ .MaxProperties }})
   518      }
   519      {{- end }}
   520    {{- end }}
   521  {{- end }}
   522  {{define "objectvalidator" }}{{/* // DEBUG
   523    // .Name: {{ .Name }}
   524    // .IsAliased: {{ .IsAliased }}
   525    // .IsAnonymous: {{ .IsAnonymous }}
   526    // .IsNullable: {{ .IsNullable }}
   527    // .Required: {{ .Required }}
   528    // .ReadOnly: {{ .ReadOnly }}
   529    // .HasValidations {{ .HasValidations }}
   530    // .HasContextValidations {{ .HasContextValidations }}
   531    // .IsBaseType: {{ .IsBaseType }}
   532    // .ValueExpression: {{ .ValueExpression }}
   533    // .ReceiverName: {{ .ReceiverName }}
   534    // .IsAdditionalProperties: {{ .IsAdditionalProperties }}
   535    // .IsInterface: {{ .IsInterface }}
   536    // .IsMap: {{ .IsMap }}
   537    // .IsArray: {{ .IsArray }}
   538    // .IsMapNullOverride: {{ .IsMapNullOverride }}
   539    */}}
   540    {{- if not .IsAnonymous }}
   541      {{- if and .Required (or .IsNullable .IsBaseType .IsMap) }}
   542        if err := validate.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{.ValueExpression }}); err != nil {
   543          return err
   544        }
   545        {{- if and (not .Required) .IsBaseType }}
   546        if {{ .ValueExpression }} == nil {
   547          return nil
   548        }
   549        {{- end }}
   550      {{ end }}
   551      {{- if and (or .IsAliased (ne .ValueExpression .ReceiverName)) (not .SkipExternalValidation) }}{{/* prevents generated code to call itself: case of aliased types */}}
   552        {{- if or (and (or .IsNullable) (not .IsMapNullOverride)) .IsMap .IsArray }}
   553        if {{ .ValueExpression }} != nil {
   554        {{- end }}
   555        if err := {{.ValueExpression }}.Validate(formats); err != nil {
   556          if ve, ok := err.(*errors.Validation); ok {
   557            return ve.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   558          } else if ce, ok := err.(*errors.CompositeError); ok {
   559            return ce.ValidateName({{ if .Path }}{{ .Path }}{{ else }}""{{ end }})
   560          }
   561          return err
   562        }
   563        {{- if or (and (or .IsNullable) (not .IsMapNullOverride)) .IsMap .IsArray }}
   564      }
   565        {{- end }}
   566      {{- end }}
   567    {{- else }}
   568      {{ template "minmaxProperties" .}}
   569      {{ range .AllOf }}
   570        {{ range .Properties }}
   571          {{ template "propertyvalidator" . }}
   572        {{ end }}
   573      {{ end }}
   574      {{ range .Properties }}
   575        {{ template "propertyvalidator" . }}
   576      {{ end }}
   577    {{- end }}
   578    {{- if and .IsTuple .AdditionalItems }}
   579      // TODO: validating additional items should go here, if you see this raise an issue
   580      // at https://github.com/go-swagger/go-swagger/issues
   581    {{- end }}
   582  {{ end }}
   583  
   584  {{define "propertycontextvalidator"}}
   585    {{- if .IsPrimitive }}
   586      {{- if .IsAliased }}
   587        {{ template "objectcontextvalidator" . }}
   588      {{- else }}
   589        {{ template "primitivefieldcontextvalidator" . }}
   590      {{- end }}
   591      {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   592      // TODO: context validating primitive with custom formatter should go here, if you see this raise an issue
   593      // at https://github.com/go-swagger/go-swagger/issues
   594      {{- if .ReadOnly }}
   595  
   596    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 {
   597      return err
   598    }
   599      {{- end }}
   600      {{- if and (not .IsStream) (not .IsBase64) }}
   601    // TODO: context validating properties with custom formatter should go here, if you see this raise an issue
   602    // at https://github.com/go-swagger/go-swagger/issues
   603      {{/*{{ template "validationCustomformat" . }}*/}}
   604      {{- end }}
   605    {{- else if .IsArray }}
   606      {{ template "slicecontextvalidator" . }}
   607    {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}{{/* except for interface, the renderinf for aliased maps is performed by objectvalidator */}}
   608      {{ template "mapcontextvalidator" . }}
   609    {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
   610      {{ template "objectcontextvalidator" . }}
   611    {{- end }}
   612  
   613  {{end}}
   614  
   615  {{define "propertyvalidator" }}
   616    {{- if .IsPrimitive }}
   617      {{- if .IsAliased }}
   618        {{- if and .Required (not .IsAnonymous) }}
   619    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 {
   620      return err
   621    }
   622        {{- end }}
   623        {{ template "objectvalidator" . }}
   624      {{- else }}
   625        {{ template "primitivefieldvalidator" . }}
   626      {{- end }}
   627    {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   628      {{- if .Required }}
   629    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 {
   630      return err
   631    }
   632      {{- end }}
   633      {{- if and (not .IsStream) (not .IsBase64) }}
   634        {{ template "validationCustomformat" . }}
   635      {{- end }}
   636     {{- else if .IsArray }}
   637      {{ template "slicevalidator" . }}
   638    {{- else if and .IsMap (or (not .IsAliased) (and .IsAliased .IsInterface)) }}
   639      {{ template "minmaxProperties" . }}
   640      {{ template "mapvalidator" . }}
   641    {{- else if or .IsComplexObject .IsTuple .IsAdditionalProperties .IsAliased }}
   642      {{- if and .IsAdditionalProperties .Required (not .IsAliased) }}
   643        {{- if or .IsNullable .IsInterface }}
   644        if {{ .ValueExpression }} == nil {
   645          return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
   646        }
   647        {{- else }}
   648        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 {
   649          return err
   650        }
   651        {{- end }}
   652      {{- end }}
   653      {{ template "objectvalidator" . }}
   654    {{- else if and .IsExternal .Required }}
   655      {{- if or .IsNullable .IsInterface }}
   656        if {{ .ValueExpression }} == nil {
   657          return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
   658        }
   659      {{- else }}
   660        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 {
   661          return err
   662        }
   663      {{- end }}
   664    {{- end }}
   665  {{ end }}
   666  
   667  {{define "fieldcontextvalidator" }}
   668    {{- if .IsPrimitive }}
   669      {{ template "primitivefieldcontextvalidator" . }}
   670    {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   671      {{- if and (not .IsStream) (not .IsBase64) }}
   672        // TODO: context validating properties with custom formatter should go here, if you see this raise an issue
   673        // at https://github.com/go-swagger/go-swagger/issues
   674        {{/*
   675        {{ template "validationCustomformat" . }}
   676        */}}
   677      {{- end }}
   678    {{- else if .IsArray }}
   679      {{ template "slicecontextvalidator" . }}
   680    {{- else if .IsMap }}
   681      {{ template "mapcontextvalidator" . }}
   682    {{- end }}
   683  
   684  {{ end }}
   685  
   686  {{ define "fieldvalidator"}}
   687    {{- if .IsPrimitive }}
   688      {{ template "primitivefieldvalidator" . }}
   689    {{- else if and .IsCustomFormatter (or .HasValidations .Required) }}{{/* custom format not captured as primitive */}}
   690      {{- if .Required }}
   691    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 {
   692      return err
   693    }
   694      {{- end }}
   695      {{- if and (not .IsStream) (not .IsBase64) }}
   696        {{ template "validationCustomformat" . }}
   697      {{- end }}
   698    {{- else if .IsArray }}
   699      {{ template "slicevalidator" . }}
   700    {{- else if .IsMap }}
   701      {{ template "mapvalidator" . }}
   702    {{- end }}
   703  {{ end }}
   704  
   705  {{define "schemacontextvalidator" }}
   706  // ContextValidate validate this {{ humanize .Name }} based on the context it is used
   707  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 {
   708    var res []error
   709    {{ range .AllOf }}
   710      {{- if not .Properties }}
   711        // validation for a type composition with {{ .GoType }}
   712      {{- end }}
   713      {{- if and (or .IsInterface .IsAnonymous .IsBaseType) (or .HasContextValidations) }}
   714        {{ template "fieldcontextvalidator" . }}
   715        {{ range .Properties }}
   716          {{ if and (ne $.DiscriminatorField .Name) (or .HasContextValidations) }}
   717            if err := {{.ReceiverName }}.contextValidate{{ pascalize .Name }}(ctx, formats); err != nil {
   718              res = append(res, err)
   719            }
   720          {{- end }}
   721        {{- end }}
   722        {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   723          {{ template "mapcontextvalidator" . }}
   724        {{- end }}
   725        {{ if and .IsTuple .AdditionalItems }}
   726        // TODO: context validating additional items should go here, if you see this raise an issue
   727        // at https://github.com/go-swagger/go-swagger/issues
   728        {{/*
   729        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Items(formats); err != nil {
   730          res = append(res, err)
   731        }
   732        */}}
   733        {{ end }}
   734      {{- else if (or .HasContextValidations) }}
   735        if err := {{ .ReceiverName }}.{{ pascalize (dropPackage .GoType) }}.ContextValidate(ctx, formats); err != nil {
   736          res = append(res, err)
   737        }
   738      {{- end }}
   739    {{- end }} {{/*end AllOf*/}}
   740    {{ template "fieldcontextvalidator" . }}
   741    {{ range .Properties }}
   742      {{ if .HasContextValidations }} {{/* complex obj always has cv*/}}
   743        if err := {{.ReceiverName }}.contextValidate{{ pascalize .Name }}(ctx, formats); err != nil {
   744          res = append(res, err)
   745        }
   746      {{ end }}
   747    {{ end }}
   748    {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   749      {{ template "mapcontextvalidator" . }}
   750    {{- end }}
   751    if len(res) > 0 {
   752      return errors.CompositeValidationError(res...)
   753    }
   754    return nil
   755  }
   756  
   757  
   758    {{ range .Properties }}
   759      {{ if .HasContextValidations }}
   760  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) contextValidate{{ pascalize .Name }}(ctx context.Context, formats strfmt.Registry) error {
   761         {{template "propertycontextvalidator" . }}
   762    return nil
   763  }
   764      {{ end }}
   765    {{ end }} {{/*Properties*/}}
   766    {{ range .AllOf }}
   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 }}
   775    {{ end }} {{/*AllOf*/}}
   776  {{end}} {{/*schemacontextvalidator*/}}
   777  
   778  {{define "schemavalidator" }}
   779    {{ if .Enum }}
   780      {{ if (eq .SwaggerType "string") }}
   781        {{ $gotype := .GoType }}
   782  const (
   783        {{ range .Enum }}
   784        {{- $variant := print $gotype (pascalize (cleanupEnumVariant .)) }}
   785    // {{ $variant }} captures enum value {{ printf "%q" . }}
   786  	{{ $variant }} {{ $gotype }} = {{ printf "%q" . }}
   787        {{ end }}
   788  )
   789      {{ end }}
   790  
   791  // for schema
   792  var {{ camelize .Name }}Enum []interface{}
   793  func init() {
   794    var res []{{ template "dereffedSchemaType" . }}
   795    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   796      panic(err)
   797    }
   798    for _, v := range res {
   799      {{ camelize .Name }}Enum = append({{ camelize .Name }}Enum, v)
   800    }
   801  }
   802  
   803  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 {
   804    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}Enum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   805      return err
   806    }
   807    return nil
   808  }
   809    {{ end }}
   810    {{ if .ItemsEnum }}
   811  var {{ camelize .Name }}ItemsEnum []interface{}
   812  
   813  func init() {
   814    var res []{{ template "dereffedSchemaType" .Items }}
   815    if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil {
   816      panic(err)
   817    }
   818    for _, v := range res {
   819      {{ camelize .Name }}ItemsEnum = append({{ camelize .Name }}ItemsEnum, v)
   820    }
   821  }
   822  
   823  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 {
   824    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   825      return err
   826    }
   827    return nil
   828  }
   829    {{ end }}
   830    {{ with .AdditionalProperties }}
   831      {{ if .Enum }}
   832  // for additional props
   833  var {{ camelize .Name }}ValueEnum []interface{}
   834  
   835  func init() {
   836    var res []{{ template "dereffedSchemaType" . }}
   837    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   838      panic(err)
   839    }
   840    for _, v := range res {
   841      {{ camelize .Name }}ValueEnum = append({{ camelize .Name }}ValueEnum, v)
   842    }
   843  }
   844  
   845  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 {
   846    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}ValueEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   847      return err
   848    }
   849    return nil
   850  }
   851      {{- end }}
   852    {{ end }}
   853  // Validate validates this {{ humanize .Name }}
   854  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 {
   855    var res []error
   856    {{ template "minmaxProperties" .}}
   857    {{ range .AllOf }}
   858      {{- if not .Properties }}
   859        // validation for a type composition with {{ .GoType }}
   860      {{- end }}
   861      {{- if and (or .IsInterface .IsAnonymous .IsBaseType) (or .Required .HasValidations) }}
   862        {{ template "fieldvalidator" . }}
   863  
   864        {{ range .Properties }}
   865          {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
   866            if err := {{.ReceiverName }}.validate{{ pascalize .Name }}(formats); err != nil {
   867              res = append(res, err)
   868            }
   869          {{- end }}
   870        {{- end }}
   871        {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   872          {{ template "mapvalidator" . }}
   873        {{- end }}
   874        {{ if and .IsTuple .AdditionalItems }}
   875        if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Items(formats); err != nil {
   876          res = append(res, err)
   877        }
   878        {{ end }}
   879      {{- else if (or .Required .HasValidations) }}
   880        if err := {{ .ReceiverName }}.{{ pascalize (dropPackage .GoType) }}.Validate(formats); err != nil {
   881          res = append(res, err)
   882        }
   883      {{- end }}
   884    {{- end }}
   885    {{ template "fieldvalidator" . }}
   886    {{ range .Properties }}
   887      {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
   888        if err := {{.ReceiverName }}.validate{{ pascalize .Name }}(formats); err != nil {
   889          res = append(res, err)
   890        }
   891      {{ end }}
   892    {{ end }}
   893    {{- if and .HasAdditionalProperties (not .IsMap) }}{{/* validates additionalProperties in an object which is not itself a map */}}
   894      {{ template "mapvalidator" . }}
   895    {{- end }}
   896    {{ if and .IsTuple .AdditionalItems }}{{/* validates additionalItems in a tuple */}}
   897      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Items(formats); err != nil {
   898        res = append(res, err)
   899      }
   900    {{ end }}
   901    {{ if and .Enum (not .IsPrimitive) (not .IsMap) }}
   902      // value enum
   903      if err := {{ .ReceiverName }}.validate{{ pascalize .Name }}Enum("", "body", {{ .ReceiverName }}); err != nil {
   904        res = append(res, err)
   905      }
   906    {{ end }}
   907  
   908    if len(res) > 0 {
   909      return errors.CompositeValidationError(res...)
   910    }
   911    return nil
   912  }
   913  
   914    {{ range .Properties }}
   915      {{ if or .Required .HasValidations }}
   916        {{ if .Enum }}
   917  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
   918  
   919  func init() {
   920    var res []{{ template "dereffedSchemaType" . }}
   921    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   922      panic(err)
   923    }
   924    for _, v := range res {
   925      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
   926    }
   927  }
   928  
   929          {{ if (eq .SwaggerType "string") }}
   930            {{ $gotype := .GoType }}
   931            {{ $propname := .Name }}
   932  const (
   933            {{ range .Enum }}
   934            {{- $variant := print (pascalize $.Name) (pascalize $propname) (pascalize (cleanupEnumVariant .)) }}
   935    // {{ $variant }} captures enum value {{ printf "%q" . }}
   936  	{{ $variant }} {{ $gotype }} = {{ printf "%q" . }}
   937            {{ end }}
   938  )
   939          {{ end }}
   940  
   941  // prop value enum
   942  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 {
   943    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   944      return err
   945    }
   946    return nil
   947  }
   948        {{ end }}
   949        {{ if .ItemsEnum }}
   950  var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []interface{}
   951  func init() {
   952    var res []{{ template "dereffedSchemaType" .Items }}
   953    if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil {
   954      panic(err)
   955    }
   956    for _, v := range res {
   957      {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, v)
   958    }
   959  }
   960  
   961  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 {
   962    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   963      return err
   964    }
   965    return nil
   966  }
   967        {{ end }}
   968        {{ if .AdditionalItems }}
   969          {{ if .AdditionalItems.Enum }}
   970  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
   971  
   972  func init() {
   973    var res []{{ template "dereffedSchemaType" .AdditionalItems }}
   974    if err := json.Unmarshal([]byte(`{{ json .AdditionalItems.Enum }}`), &res); err != nil {
   975      panic(err)
   976    }
   977    for _, v := range res {
   978      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
   979    }
   980  }
   981  
   982  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 {
   983    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
   984      return err
   985    }
   986    return nil
   987  }
   988          {{ end }}
   989        {{ end }}
   990        {{ with .AdditionalProperties }}
   991          {{ if .Enum }}
   992  // additional properties value enum
   993  var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []interface{}
   994  
   995  func init() {
   996    var res []{{ template "dereffedSchemaType" . }}
   997    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
   998      panic(err)
   999    }
  1000    for _, v := range res {
  1001      {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, v)
  1002    }
  1003  }
  1004  
  1005  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 {
  1006    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1007      return err
  1008    }
  1009    return nil
  1010  }
  1011          {{ end }}
  1012        {{ end }}
  1013  
  1014        {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
  1015  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}(formats strfmt.Registry) error {
  1016          {{- if not .Required }}
  1017            {{- if .IsInterface }}
  1018    if .ValueExpression == nil { // not required
  1019            {{- else }}
  1020    if swag.IsZero({{ .ValueExpression }}) { // not required
  1021            {{- end }}
  1022      return nil
  1023    }
  1024          {{- end }}
  1025          {{- if and $.IsTuple .IsMap .Required }}
  1026            {{- if .IsInterface }}
  1027    if {{ .ValueExpression }} == nil {
  1028      return errors.Required({{ if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }}, {{ .ValueExpression }})
  1029    }
  1030            {{- else }}
  1031    if err := validate.Required{{ if and (eq .GoType "string") (not .IsNullable) }}String{{ end }}(
  1032              {{- if .Path }}{{ .Path }}{{ else }}""{{ end }}, {{ printf "%q" .Location }},
  1033              {{- if and (eq .GoType "string") (not (or .IsAnonymous .IsNullable)) }}{{ .GoType }}({{ end }}
  1034              {{- .ValueExpression }}
  1035              {{- if and (eq .GoType "string") (not (or .IsAnonymous .IsNullable)) }}){{ end }}); err != nil {
  1036      return err
  1037    }
  1038            {{- end }}
  1039          {{- end }}
  1040          {{template "propertyvalidator" . }}
  1041  
  1042    return nil
  1043  }
  1044        {{ end }}
  1045      {{ end }}
  1046    {{ end }}
  1047    {{ range .AllOf }}
  1048      {{ range .Properties }}
  1049        {{ if and (ne $.DiscriminatorField .Name) (or .Required .HasValidations) }}
  1050          {{ if .Enum }}
  1051  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
  1052  
  1053  func init() {
  1054    var res []{{ template "dereffedSchemaType" . }}
  1055    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
  1056      panic(err)
  1057    }
  1058    for _, v := range res {
  1059      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
  1060    }
  1061  }
  1062  
  1063  // property enum
  1064  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 {
  1065    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1066      return err
  1067    }
  1068    return nil
  1069  }
  1070          {{ end }}
  1071          {{ if .ItemsEnum }}
  1072  var {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum []interface{}
  1073  
  1074  func init() {
  1075    var res []{{ template "dereffedSchemaType" .Items }}
  1076    if err := json.Unmarshal([]byte(`{{ json .ItemsEnum }}`), &res); err != nil {
  1077      panic(err)
  1078    }
  1079    for _, v := range res {
  1080      {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, v)
  1081    }
  1082  }
  1083  
  1084  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 {
  1085    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1086      return err
  1087    }
  1088    return nil
  1089  }
  1090          {{ end }}
  1091          {{ if .AdditionalItems }}
  1092            {{ if .AdditionalItems.Enum }}
  1093  var {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum []interface{}
  1094  
  1095  func init() {
  1096    var res []{{ template "dereffedSchemaType" .AdditionalItems }}
  1097    if err := json.Unmarshal([]byte(`{{ json .AdditionalItems.Enum }}`), &res); err != nil {
  1098      panic(err)
  1099    }
  1100    for _, v := range res {
  1101      {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum = append({{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, v)
  1102    }
  1103  }
  1104  
  1105  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 {
  1106    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}Type{{ pascalize .Name }}PropEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1107      return err
  1108    }
  1109    return nil
  1110  }
  1111            {{ end }}
  1112          {{ end }}
  1113          {{ with .AdditionalProperties }}
  1114            {{ if .Enum }}
  1115  var {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum []interface{}
  1116  func init() {
  1117    var res []{{ template "dereffedSchemaType" . }}
  1118    if err := json.Unmarshal([]byte(`{{ json .Enum }}`), &res); err != nil {
  1119      panic(err)
  1120    }
  1121    for _, v := range res {
  1122      {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum = append({{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, v)
  1123    }
  1124  }
  1125  
  1126  // additional properties value enum
  1127  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 {
  1128    if err := validate.EnumCase(path, location, value, {{ camelize $.Name }}{{ pascalize .Name }}ValueEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1129      return err
  1130    }
  1131    return nil
  1132  }
  1133            {{ end }}
  1134          {{ end }}
  1135  
  1136  
  1137  func ({{.ReceiverName }} *{{ if $.Discriminates }}{{ camelize $.Name }}{{ else if $.IsExported }}{{ pascalize $.Name }}{{ else }}{{ $.Name }}{{ end }}) validate{{ pascalize .Name }}(formats strfmt.Registry) error {
  1138          {{ if not .Required }}
  1139            {{- if .IsInterface }}
  1140    if {{ .ValueExpression }} == nil { // not required
  1141            {{- else }}
  1142    if swag.IsZero({{ .ValueExpression }}) { // not required
  1143            {{- end }}
  1144      return nil
  1145    }
  1146          {{ end }}
  1147          {{template "propertyvalidator" . }}
  1148  
  1149    return nil
  1150  }
  1151        {{ end }}
  1152      {{ end }}
  1153    {{ end }}
  1154  
  1155    {{ if .HasAdditionalItems }}
  1156      {{ if .AdditionalItems.Enum }}
  1157  var {{ camelize .Name }}ItemsEnum []interface{}
  1158  
  1159  func init() {
  1160    var res []{{ template "dereffedSchemaType" .AdditionalItems }}
  1161    if err := json.Unmarshal([]byte(`{{ json .AdditionalItems.Enum }}`), &res); err != nil {
  1162      panic(err)
  1163    }
  1164    for _, v := range res {
  1165      {{ camelize .Name }}ItemsEnum = append({{ camelize .Name }}ItemsEnum, v)
  1166    }
  1167  }
  1168  
  1169  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 {
  1170    if err := validate.EnumCase(path, location, value, {{ camelize .Name }}ItemsEnum, {{ if .IsEnumCI }}false{{ else }}true{{ end }}); err != nil {
  1171      return err
  1172    }
  1173    return nil
  1174  }
  1175      {{ end }}
  1176  func ({{.ReceiverName }} *{{ pascalize .Name }}) validate{{ pascalize .Name }}Items(formats strfmt.Registry) error {
  1177      {{ if and (or .AdditionalItems.Required .AdditionalItems.HasValidations) (not .AdditionalItems.SkipExternalValidation) }}
  1178    for {{ .IndexVar }} := range {{ .ValueExpression }}.{{ pascalize .Name }}Items {
  1179        {{template "propertyvalidator" .AdditionalItems }}
  1180    }
  1181      {{ end }}
  1182    return nil
  1183  }
  1184    {{ end }}
  1185  {{ end }}