// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/ads/googleads/v3/errors/range_error.proto

package errors

import (
	fmt "fmt"
	math "math"

	proto "github.com/golang/protobuf/proto"
	_ "google.golang.org/genproto/googleapis/api/annotations"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// Enum describing possible range errors.
type RangeErrorEnum_RangeError int32

const (
	// Enum unspecified.
	RangeErrorEnum_UNSPECIFIED RangeErrorEnum_RangeError = 0
	// The received error code is not known in this version.
	RangeErrorEnum_UNKNOWN RangeErrorEnum_RangeError = 1
	// Too low.
	RangeErrorEnum_TOO_LOW RangeErrorEnum_RangeError = 2
	// Too high.
	RangeErrorEnum_TOO_HIGH RangeErrorEnum_RangeError = 3
)

var RangeErrorEnum_RangeError_name = map[int32]string{
	0: "UNSPECIFIED",
	1: "UNKNOWN",
	2: "TOO_LOW",
	3: "TOO_HIGH",
}

var RangeErrorEnum_RangeError_value = map[string]int32{
	"UNSPECIFIED": 0,
	"UNKNOWN":     1,
	"TOO_LOW":     2,
	"TOO_HIGH":    3,
}

func (x RangeErrorEnum_RangeError) String() string {
	return proto.EnumName(RangeErrorEnum_RangeError_name, int32(x))
}

func (RangeErrorEnum_RangeError) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_2ccd0a5d18cd27d7, []int{0, 0}
}

// Container for enum describing possible range errors.
type RangeErrorEnum struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *RangeErrorEnum) Reset()         { *m = RangeErrorEnum{} }
func (m *RangeErrorEnum) String() string { return proto.CompactTextString(m) }
func (*RangeErrorEnum) ProtoMessage()    {}
func (*RangeErrorEnum) Descriptor() ([]byte, []int) {
	return fileDescriptor_2ccd0a5d18cd27d7, []int{0}
}

func (m *RangeErrorEnum) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_RangeErrorEnum.Unmarshal(m, b)
}
func (m *RangeErrorEnum) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_RangeErrorEnum.Marshal(b, m, deterministic)
}
func (m *RangeErrorEnum) XXX_Merge(src proto.Message) {
	xxx_messageInfo_RangeErrorEnum.Merge(m, src)
}
func (m *RangeErrorEnum) XXX_Size() int {
	return xxx_messageInfo_RangeErrorEnum.Size(m)
}
func (m *RangeErrorEnum) XXX_DiscardUnknown() {
	xxx_messageInfo_RangeErrorEnum.DiscardUnknown(m)
}

var xxx_messageInfo_RangeErrorEnum proto.InternalMessageInfo

func init() {
	proto.RegisterEnum("google.ads.googleads.v3.errors.RangeErrorEnum_RangeError", RangeErrorEnum_RangeError_name, RangeErrorEnum_RangeError_value)
	proto.RegisterType((*RangeErrorEnum)(nil), "google.ads.googleads.v3.errors.RangeErrorEnum")
}

func init() {
	proto.RegisterFile("google/ads/googleads/v3/errors/range_error.proto", fileDescriptor_2ccd0a5d18cd27d7)
}

var fileDescriptor_2ccd0a5d18cd27d7 = []byte{
	// 290 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xd1, 0x4a, 0xc3, 0x30,
	0x18, 0x85, 0x6d, 0x07, 0x2a, 0x99, 0xb8, 0xd2, 0x4b, 0x91, 0x5d, 0xf4, 0x01, 0x12, 0x21, 0x77,
	0xf1, 0xaa, 0x73, 0xb5, 0x2b, 0x4a, 0x5b, 0xd4, 0xb5, 0x20, 0x85, 0x11, 0x4d, 0x09, 0x85, 0x2d,
	0x29, 0x49, 0xdd, 0x03, 0x79, 0xe9, 0xa3, 0xf8, 0x28, 0x7b, 0x0a, 0x49, 0x63, 0xbb, 0x2b, 0xbd,
	0xca, 0xf9, 0xc3, 0x77, 0xce, 0x7f, 0xf8, 0xc1, 0x0d, 0x97, 0x92, 0x6f, 0x6b, 0x44, 0x99, 0x46,
	0x56, 0x1a, 0xb5, 0xc7, 0xa8, 0x56, 0x4a, 0x2a, 0x8d, 0x14, 0x15, 0xbc, 0xde, 0xf4, 0x03, 0x6c,
	0x95, 0xec, 0xa4, 0x3f, 0xb7, 0x18, 0xa4, 0x4c, 0xc3, 0xd1, 0x01, 0xf7, 0x18, 0x5a, 0xc7, 0xd5,
	0xf5, 0x90, 0xd8, 0x36, 0x88, 0x0a, 0x21, 0x3b, 0xda, 0x35, 0x52, 0x68, 0xeb, 0x0e, 0x4a, 0x70,
	0xf9, 0x64, 0x22, 0x23, 0x03, 0x47, 0xe2, 0x63, 0x17, 0x44, 0x00, 0x1c, 0x7f, 0xfc, 0x19, 0x98,
	0xae, 0xd3, 0xe7, 0x3c, 0xba, 0x4b, 0xee, 0x93, 0x68, 0xe9, 0x9d, 0xf8, 0x53, 0x70, 0xb6, 0x4e,
	0x1f, 0xd2, 0xac, 0x4c, 0x3d, 0xc7, 0x0c, 0x2f, 0x59, 0xb6, 0x79, 0xcc, 0x4a, 0xcf, 0xf5, 0x2f,
	0xc0, 0xb9, 0x19, 0x56, 0x49, 0xbc, 0xf2, 0x26, 0x8b, 0x83, 0x03, 0x82, 0x77, 0xb9, 0x83, 0xff,
	0xb7, 0x5b, 0xcc, 0x8e, 0xbb, 0x72, 0x53, 0x28, 0x77, 0x5e, 0x97, 0xbf, 0x16, 0x2e, 0xb7, 0x54,
	0x70, 0x28, 0x15, 0x47, 0xbc, 0x16, 0x7d, 0xdd, 0xe1, 0x24, 0x6d, 0xa3, 0xff, 0xba, 0xd0, 0xad,
	0x7d, 0x3e, 0xdd, 0x49, 0x1c, 0x86, 0x5f, 0xee, 0x3c, 0xb6, 0x61, 0x21, 0xd3, 0xd0, 0x4a, 0xa3,
	0x0a, 0x0c, 0xfb, 0x95, 0xfa, 0x7b, 0x00, 0xaa, 0x90, 0xe9, 0x6a, 0x04, 0xaa, 0x02, 0x57, 0x16,
	0x38, 0xb8, 0x81, 0xfd, 0x25, 0x24, 0x64, 0x9a, 0x90, 0x11, 0x21, 0xa4, 0xc0, 0x84, 0x58, 0xe8,
	0xed, 0xb4, 0x6f, 0x87, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xcb, 0xe5, 0x3f, 0xbe, 0x01,
	0x00, 0x00,
}
