// Code generated by protoc-gen-validate. DO NOT EDIT.
// source: go.chromium.org/luci/cv/internal/run/eventpb/submission.proto

package eventpb

import (
	"bytes"
	"errors"
	"fmt"
	"net"
	"net/mail"
	"net/url"
	"regexp"
	"sort"
	"strings"
	"time"
	"unicode/utf8"

	"google.golang.org/protobuf/types/known/anypb"
)

// ensure the imports are used
var (
	_ = bytes.MinRead
	_ = errors.New("")
	_ = fmt.Print
	_ = utf8.UTFMax
	_ = (*regexp.Regexp)(nil)
	_ = (*strings.Reader)(nil)
	_ = net.IPv4len
	_ = time.Duration(0)
	_ = (*url.URL)(nil)
	_ = (*mail.Address)(nil)
	_ = anypb.Any{}
	_ = sort.Sort
)

// Validate checks the field values on SubmissionCompleted with the rules
// defined in the proto definition for this message. If any rules are
// violated, the first error encountered is returned, or nil if there are no violations.
func (m *SubmissionCompleted) Validate() error {
	return m.validate(false)
}

// ValidateAll checks the field values on SubmissionCompleted with the rules
// defined in the proto definition for this message. If any rules are
// violated, the result is a list of violation errors wrapped in
// SubmissionCompletedMultiError, or nil if none found.
func (m *SubmissionCompleted) ValidateAll() error {
	return m.validate(true)
}

func (m *SubmissionCompleted) validate(all bool) error {
	if m == nil {
		return nil
	}

	var errors []error

	// no validation rules for Result

	if all {
		switch v := interface{}(m.GetQueueReleaseTimestamp()).(type) {
		case interface{ ValidateAll() error }:
			if err := v.ValidateAll(); err != nil {
				errors = append(errors, SubmissionCompletedValidationError{
					field:  "QueueReleaseTimestamp",
					reason: "embedded message failed validation",
					cause:  err,
				})
			}
		case interface{ Validate() error }:
			if err := v.Validate(); err != nil {
				errors = append(errors, SubmissionCompletedValidationError{
					field:  "QueueReleaseTimestamp",
					reason: "embedded message failed validation",
					cause:  err,
				})
			}
		}
	} else if v, ok := interface{}(m.GetQueueReleaseTimestamp()).(interface{ Validate() error }); ok {
		if err := v.Validate(); err != nil {
			return SubmissionCompletedValidationError{
				field:  "QueueReleaseTimestamp",
				reason: "embedded message failed validation",
				cause:  err,
			}
		}
	}

	switch v := m.FailureReason.(type) {
	case *SubmissionCompleted_Timeout:
		if v == nil {
			err := SubmissionCompletedValidationError{
				field:  "FailureReason",
				reason: "oneof value cannot be a typed-nil",
			}
			if !all {
				return err
			}
			errors = append(errors, err)
		}
		// no validation rules for Timeout
	case *SubmissionCompleted_ClFailures:
		if v == nil {
			err := SubmissionCompletedValidationError{
				field:  "FailureReason",
				reason: "oneof value cannot be a typed-nil",
			}
			if !all {
				return err
			}
			errors = append(errors, err)
		}

		if all {
			switch v := interface{}(m.GetClFailures()).(type) {
			case interface{ ValidateAll() error }:
				if err := v.ValidateAll(); err != nil {
					errors = append(errors, SubmissionCompletedValidationError{
						field:  "ClFailures",
						reason: "embedded message failed validation",
						cause:  err,
					})
				}
			case interface{ Validate() error }:
				if err := v.Validate(); err != nil {
					errors = append(errors, SubmissionCompletedValidationError{
						field:  "ClFailures",
						reason: "embedded message failed validation",
						cause:  err,
					})
				}
			}
		} else if v, ok := interface{}(m.GetClFailures()).(interface{ Validate() error }); ok {
			if err := v.Validate(); err != nil {
				return SubmissionCompletedValidationError{
					field:  "ClFailures",
					reason: "embedded message failed validation",
					cause:  err,
				}
			}
		}

	default:
		_ = v // ensures v is used
	}

	if len(errors) > 0 {
		return SubmissionCompletedMultiError(errors)
	}

	return nil
}

// SubmissionCompletedMultiError is an error wrapping multiple validation
// errors returned by SubmissionCompleted.ValidateAll() if the designated
// constraints aren't met.
type SubmissionCompletedMultiError []error

// Error returns a concatenation of all the error messages it wraps.
func (m SubmissionCompletedMultiError) Error() string {
	var msgs []string
	for _, err := range m {
		msgs = append(msgs, err.Error())
	}
	return strings.Join(msgs, "; ")
}

// AllErrors returns a list of validation violation errors.
func (m SubmissionCompletedMultiError) AllErrors() []error { return m }

// SubmissionCompletedValidationError is the validation error returned by
// SubmissionCompleted.Validate if the designated constraints aren't met.
type SubmissionCompletedValidationError struct {
	field  string
	reason string
	cause  error
	key    bool
}

// Field function returns field value.
func (e SubmissionCompletedValidationError) Field() string { return e.field }

// Reason function returns reason value.
func (e SubmissionCompletedValidationError) Reason() string { return e.reason }

// Cause function returns cause value.
func (e SubmissionCompletedValidationError) Cause() error { return e.cause }

// Key function returns key value.
func (e SubmissionCompletedValidationError) Key() bool { return e.key }

// ErrorName returns error name.
func (e SubmissionCompletedValidationError) ErrorName() string {
	return "SubmissionCompletedValidationError"
}

// Error satisfies the builtin error interface
func (e SubmissionCompletedValidationError) Error() string {
	cause := ""
	if e.cause != nil {
		cause = fmt.Sprintf(" | caused by: %v", e.cause)
	}

	key := ""
	if e.key {
		key = "key for "
	}

	return fmt.Sprintf(
		"invalid %sSubmissionCompleted.%s: %s%s",
		key,
		e.field,
		e.reason,
		cause)
}

var _ error = SubmissionCompletedValidationError{}

var _ interface {
	Field() string
	Reason() string
	Key() bool
	Cause() error
	ErrorName() string
} = SubmissionCompletedValidationError{}

// Validate checks the field values on SubmissionCompleted_CLSubmissionFailure
// with the rules defined in the proto definition for this message. If any
// rules are violated, the first error encountered is returned, or nil if
// there are no violations.
func (m *SubmissionCompleted_CLSubmissionFailure) Validate() error {
	return m.validate(false)
}

// ValidateAll checks the field values on
// SubmissionCompleted_CLSubmissionFailure with the rules defined in the proto
// definition for this message. If any rules are violated, the result is a
// list of violation errors wrapped in
// SubmissionCompleted_CLSubmissionFailureMultiError, or nil if none found.
func (m *SubmissionCompleted_CLSubmissionFailure) ValidateAll() error {
	return m.validate(true)
}

func (m *SubmissionCompleted_CLSubmissionFailure) validate(all bool) error {
	if m == nil {
		return nil
	}

	var errors []error

	// no validation rules for Clid

	// no validation rules for Message

	if len(errors) > 0 {
		return SubmissionCompleted_CLSubmissionFailureMultiError(errors)
	}

	return nil
}

// SubmissionCompleted_CLSubmissionFailureMultiError is an error wrapping
// multiple validation errors returned by
// SubmissionCompleted_CLSubmissionFailure.ValidateAll() if the designated
// constraints aren't met.
type SubmissionCompleted_CLSubmissionFailureMultiError []error

// Error returns a concatenation of all the error messages it wraps.
func (m SubmissionCompleted_CLSubmissionFailureMultiError) Error() string {
	var msgs []string
	for _, err := range m {
		msgs = append(msgs, err.Error())
	}
	return strings.Join(msgs, "; ")
}

// AllErrors returns a list of validation violation errors.
func (m SubmissionCompleted_CLSubmissionFailureMultiError) AllErrors() []error { return m }

// SubmissionCompleted_CLSubmissionFailureValidationError is the validation
// error returned by SubmissionCompleted_CLSubmissionFailure.Validate if the
// designated constraints aren't met.
type SubmissionCompleted_CLSubmissionFailureValidationError struct {
	field  string
	reason string
	cause  error
	key    bool
}

// Field function returns field value.
func (e SubmissionCompleted_CLSubmissionFailureValidationError) Field() string { return e.field }

// Reason function returns reason value.
func (e SubmissionCompleted_CLSubmissionFailureValidationError) Reason() string { return e.reason }

// Cause function returns cause value.
func (e SubmissionCompleted_CLSubmissionFailureValidationError) Cause() error { return e.cause }

// Key function returns key value.
func (e SubmissionCompleted_CLSubmissionFailureValidationError) Key() bool { return e.key }

// ErrorName returns error name.
func (e SubmissionCompleted_CLSubmissionFailureValidationError) ErrorName() string {
	return "SubmissionCompleted_CLSubmissionFailureValidationError"
}

// Error satisfies the builtin error interface
func (e SubmissionCompleted_CLSubmissionFailureValidationError) Error() string {
	cause := ""
	if e.cause != nil {
		cause = fmt.Sprintf(" | caused by: %v", e.cause)
	}

	key := ""
	if e.key {
		key = "key for "
	}

	return fmt.Sprintf(
		"invalid %sSubmissionCompleted_CLSubmissionFailure.%s: %s%s",
		key,
		e.field,
		e.reason,
		cause)
}

var _ error = SubmissionCompleted_CLSubmissionFailureValidationError{}

var _ interface {
	Field() string
	Reason() string
	Key() bool
	Cause() error
	ErrorName() string
} = SubmissionCompleted_CLSubmissionFailureValidationError{}

// Validate checks the field values on SubmissionCompleted_CLSubmissionFailures
// with the rules defined in the proto definition for this message. If any
// rules are violated, the first error encountered is returned, or nil if
// there are no violations.
func (m *SubmissionCompleted_CLSubmissionFailures) Validate() error {
	return m.validate(false)
}

// ValidateAll checks the field values on
// SubmissionCompleted_CLSubmissionFailures with the rules defined in the
// proto definition for this message. If any rules are violated, the result is
// a list of violation errors wrapped in
// SubmissionCompleted_CLSubmissionFailuresMultiError, or nil if none found.
func (m *SubmissionCompleted_CLSubmissionFailures) ValidateAll() error {
	return m.validate(true)
}

func (m *SubmissionCompleted_CLSubmissionFailures) validate(all bool) error {
	if m == nil {
		return nil
	}

	var errors []error

	for idx, item := range m.GetFailures() {
		_, _ = idx, item

		if all {
			switch v := interface{}(item).(type) {
			case interface{ ValidateAll() error }:
				if err := v.ValidateAll(); err != nil {
					errors = append(errors, SubmissionCompleted_CLSubmissionFailuresValidationError{
						field:  fmt.Sprintf("Failures[%v]", idx),
						reason: "embedded message failed validation",
						cause:  err,
					})
				}
			case interface{ Validate() error }:
				if err := v.Validate(); err != nil {
					errors = append(errors, SubmissionCompleted_CLSubmissionFailuresValidationError{
						field:  fmt.Sprintf("Failures[%v]", idx),
						reason: "embedded message failed validation",
						cause:  err,
					})
				}
			}
		} else if v, ok := interface{}(item).(interface{ Validate() error }); ok {
			if err := v.Validate(); err != nil {
				return SubmissionCompleted_CLSubmissionFailuresValidationError{
					field:  fmt.Sprintf("Failures[%v]", idx),
					reason: "embedded message failed validation",
					cause:  err,
				}
			}
		}

	}

	if len(errors) > 0 {
		return SubmissionCompleted_CLSubmissionFailuresMultiError(errors)
	}

	return nil
}

// SubmissionCompleted_CLSubmissionFailuresMultiError is an error wrapping
// multiple validation errors returned by
// SubmissionCompleted_CLSubmissionFailures.ValidateAll() if the designated
// constraints aren't met.
type SubmissionCompleted_CLSubmissionFailuresMultiError []error

// Error returns a concatenation of all the error messages it wraps.
func (m SubmissionCompleted_CLSubmissionFailuresMultiError) Error() string {
	var msgs []string
	for _, err := range m {
		msgs = append(msgs, err.Error())
	}
	return strings.Join(msgs, "; ")
}

// AllErrors returns a list of validation violation errors.
func (m SubmissionCompleted_CLSubmissionFailuresMultiError) AllErrors() []error { return m }

// SubmissionCompleted_CLSubmissionFailuresValidationError is the validation
// error returned by SubmissionCompleted_CLSubmissionFailures.Validate if the
// designated constraints aren't met.
type SubmissionCompleted_CLSubmissionFailuresValidationError struct {
	field  string
	reason string
	cause  error
	key    bool
}

// Field function returns field value.
func (e SubmissionCompleted_CLSubmissionFailuresValidationError) Field() string { return e.field }

// Reason function returns reason value.
func (e SubmissionCompleted_CLSubmissionFailuresValidationError) Reason() string { return e.reason }

// Cause function returns cause value.
func (e SubmissionCompleted_CLSubmissionFailuresValidationError) Cause() error { return e.cause }

// Key function returns key value.
func (e SubmissionCompleted_CLSubmissionFailuresValidationError) Key() bool { return e.key }

// ErrorName returns error name.
func (e SubmissionCompleted_CLSubmissionFailuresValidationError) ErrorName() string {
	return "SubmissionCompleted_CLSubmissionFailuresValidationError"
}

// Error satisfies the builtin error interface
func (e SubmissionCompleted_CLSubmissionFailuresValidationError) Error() string {
	cause := ""
	if e.cause != nil {
		cause = fmt.Sprintf(" | caused by: %v", e.cause)
	}

	key := ""
	if e.key {
		key = "key for "
	}

	return fmt.Sprintf(
		"invalid %sSubmissionCompleted_CLSubmissionFailures.%s: %s%s",
		key,
		e.field,
		e.reason,
		cause)
}

var _ error = SubmissionCompleted_CLSubmissionFailuresValidationError{}

var _ interface {
	Field() string
	Reason() string
	Key() bool
	Cause() error
	ErrorName() string
} = SubmissionCompleted_CLSubmissionFailuresValidationError{}
