// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/ads/googleads/v3/errors/ad_group_ad_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 ad group ad errors.
type AdGroupAdErrorEnum_AdGroupAdError int32

const (
	// Enum unspecified.
	AdGroupAdErrorEnum_UNSPECIFIED AdGroupAdErrorEnum_AdGroupAdError = 0
	// The received error code is not known in this version.
	AdGroupAdErrorEnum_UNKNOWN AdGroupAdErrorEnum_AdGroupAdError = 1
	// No link found between the adgroup ad and the label.
	AdGroupAdErrorEnum_AD_GROUP_AD_LABEL_DOES_NOT_EXIST AdGroupAdErrorEnum_AdGroupAdError = 2
	// The label has already been attached to the adgroup ad.
	AdGroupAdErrorEnum_AD_GROUP_AD_LABEL_ALREADY_EXISTS AdGroupAdErrorEnum_AdGroupAdError = 3
	// The specified ad was not found in the adgroup
	AdGroupAdErrorEnum_AD_NOT_UNDER_ADGROUP AdGroupAdErrorEnum_AdGroupAdError = 4
	// Removed ads may not be modified
	AdGroupAdErrorEnum_CANNOT_OPERATE_ON_REMOVED_ADGROUPAD AdGroupAdErrorEnum_AdGroupAdError = 5
	// An ad of this type is deprecated and cannot be created. Only deletions
	// are permitted.
	AdGroupAdErrorEnum_CANNOT_CREATE_DEPRECATED_ADS AdGroupAdErrorEnum_AdGroupAdError = 6
	// Text ads are deprecated and cannot be created. Use expanded text ads
	// instead.
	AdGroupAdErrorEnum_CANNOT_CREATE_TEXT_ADS AdGroupAdErrorEnum_AdGroupAdError = 7
	// A required field was not specified or is an empty string.
	AdGroupAdErrorEnum_EMPTY_FIELD AdGroupAdErrorEnum_AdGroupAdError = 8
	// An ad may only be modified once per call
	AdGroupAdErrorEnum_RESOURCE_REFERENCED_IN_MULTIPLE_OPS AdGroupAdErrorEnum_AdGroupAdError = 9
)

var AdGroupAdErrorEnum_AdGroupAdError_name = map[int32]string{
	0: "UNSPECIFIED",
	1: "UNKNOWN",
	2: "AD_GROUP_AD_LABEL_DOES_NOT_EXIST",
	3: "AD_GROUP_AD_LABEL_ALREADY_EXISTS",
	4: "AD_NOT_UNDER_ADGROUP",
	5: "CANNOT_OPERATE_ON_REMOVED_ADGROUPAD",
	6: "CANNOT_CREATE_DEPRECATED_ADS",
	7: "CANNOT_CREATE_TEXT_ADS",
	8: "EMPTY_FIELD",
	9: "RESOURCE_REFERENCED_IN_MULTIPLE_OPS",
}

var AdGroupAdErrorEnum_AdGroupAdError_value = map[string]int32{
	"UNSPECIFIED":                         0,
	"UNKNOWN":                             1,
	"AD_GROUP_AD_LABEL_DOES_NOT_EXIST":    2,
	"AD_GROUP_AD_LABEL_ALREADY_EXISTS":    3,
	"AD_NOT_UNDER_ADGROUP":                4,
	"CANNOT_OPERATE_ON_REMOVED_ADGROUPAD": 5,
	"CANNOT_CREATE_DEPRECATED_ADS":        6,
	"CANNOT_CREATE_TEXT_ADS":              7,
	"EMPTY_FIELD":                         8,
	"RESOURCE_REFERENCED_IN_MULTIPLE_OPS": 9,
}

func (x AdGroupAdErrorEnum_AdGroupAdError) String() string {
	return proto.EnumName(AdGroupAdErrorEnum_AdGroupAdError_name, int32(x))
}

func (AdGroupAdErrorEnum_AdGroupAdError) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_77c412918395d9af, []int{0, 0}
}

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

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

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

var xxx_messageInfo_AdGroupAdErrorEnum proto.InternalMessageInfo

func init() {
	proto.RegisterEnum("google.ads.googleads.v3.errors.AdGroupAdErrorEnum_AdGroupAdError", AdGroupAdErrorEnum_AdGroupAdError_name, AdGroupAdErrorEnum_AdGroupAdError_value)
	proto.RegisterType((*AdGroupAdErrorEnum)(nil), "google.ads.googleads.v3.errors.AdGroupAdErrorEnum")
}

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

var fileDescriptor_77c412918395d9af = []byte{
	// 447 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0x41, 0x6b, 0xd4, 0x40,
	0x14, 0xc7, 0x6d, 0xaa, 0xad, 0x4e, 0x41, 0x43, 0x14, 0x91, 0x52, 0x4a, 0x59, 0x05, 0x6f, 0xc9,
	0x21, 0xe0, 0x21, 0x9e, 0xde, 0x66, 0xde, 0x2e, 0xc1, 0xec, 0x64, 0x98, 0x24, 0x6b, 0x2b, 0x0b,
	0x43, 0x74, 0x96, 0xb0, 0xd0, 0x66, 0x96, 0xcc, 0xb6, 0x1f, 0xc8, 0xa3, 0x77, 0xbf, 0x84, 0xf8,
	0x49, 0x3c, 0xf8, 0x19, 0x64, 0x32, 0xdd, 0x85, 0x05, 0xf5, 0x34, 0x7f, 0xde, 0xfb, 0xfd, 0xdf,
	0x9b, 0x99, 0xf7, 0xc8, 0xbb, 0x56, 0xeb, 0xf6, 0x7a, 0x19, 0x35, 0xca, 0x44, 0x4e, 0x5a, 0x75,
	0x17, 0x47, 0xcb, 0xbe, 0xd7, 0xbd, 0x89, 0x1a, 0x25, 0xdb, 0x5e, 0xdf, 0xae, 0x65, 0xa3, 0xe4,
	0x10, 0x0a, 0xd7, 0xbd, 0xde, 0xe8, 0xe0, 0xdc, 0xc1, 0x61, 0xa3, 0x4c, 0xb8, 0xf3, 0x85, 0x77,
	0x71, 0xe8, 0x7c, 0xa7, 0x67, 0xdb, 0xba, 0xeb, 0x55, 0xd4, 0x74, 0x9d, 0xde, 0x34, 0x9b, 0x95,
	0xee, 0x8c, 0x73, 0x8f, 0x7e, 0x7a, 0x24, 0x00, 0x35, 0xb5, 0x85, 0x41, 0xa1, 0x75, 0x60, 0x77,
	0x7b, 0x33, 0xfa, 0xee, 0x91, 0xa7, 0xfb, 0xe1, 0xe0, 0x19, 0x39, 0xa9, 0x59, 0xc9, 0x31, 0xcd,
	0x26, 0x19, 0x52, 0xff, 0x41, 0x70, 0x42, 0x8e, 0x6b, 0xf6, 0x81, 0x15, 0x1f, 0x99, 0x7f, 0x10,
	0xbc, 0x21, 0x17, 0x40, 0xe5, 0x54, 0x14, 0x35, 0x97, 0x40, 0x65, 0x0e, 0x63, 0xcc, 0x25, 0x2d,
	0xb0, 0x94, 0xac, 0xa8, 0x24, 0x5e, 0x66, 0x65, 0xe5, 0x7b, 0x7f, 0xa7, 0x20, 0x17, 0x08, 0xf4,
	0xca, 0x41, 0xa5, 0x7f, 0x18, 0xbc, 0x22, 0x2f, 0x80, 0x0e, 0xbe, 0x9a, 0x51, 0x14, 0x12, 0xe8,
	0xe0, 0xf0, 0x1f, 0x06, 0x6f, 0xc9, 0xeb, 0x14, 0x98, 0xcd, 0x14, 0x1c, 0x05, 0x54, 0x28, 0x0b,
	0x26, 0x05, 0xce, 0x8a, 0x39, 0xd2, 0x2d, 0x06, 0xd4, 0x7f, 0x14, 0x5c, 0x90, 0xb3, 0x7b, 0x30,
	0x15, 0x68, 0x39, 0x8a, 0x5c, 0x60, 0x0a, 0xd5, 0xc0, 0x95, 0xfe, 0x51, 0x70, 0x4a, 0x5e, 0xee,
	0x13, 0x15, 0x5e, 0x56, 0x43, 0xee, 0xd8, 0x3e, 0x15, 0x67, 0xbc, 0xba, 0x92, 0x93, 0x0c, 0x73,
	0xea, 0x3f, 0xb6, 0x7d, 0x05, 0x96, 0x45, 0x2d, 0x52, 0x94, 0x02, 0x27, 0x28, 0x90, 0xa5, 0x48,
	0x65, 0xc6, 0xe4, 0xac, 0xce, 0xab, 0x8c, 0xe7, 0x28, 0x0b, 0x5e, 0xfa, 0x4f, 0xc6, 0xbf, 0x0f,
	0xc8, 0xe8, 0x8b, 0xbe, 0x09, 0xff, 0x3f, 0x93, 0xf1, 0xf3, 0xfd, 0xbf, 0xe5, 0x76, 0x14, 0xfc,
	0xe0, 0x13, 0xbd, 0xb7, 0xb5, 0xfa, 0xba, 0xe9, 0xda, 0x50, 0xf7, 0x6d, 0xd4, 0x2e, 0xbb, 0x61,
	0x50, 0xdb, 0x95, 0x58, 0xaf, 0xcc, 0xbf, 0x36, 0xe4, 0xbd, 0x3b, 0xbe, 0x7a, 0x87, 0x53, 0x80,
	0x6f, 0xde, 0xf9, 0xd4, 0x15, 0x03, 0x65, 0x42, 0x27, 0xad, 0x9a, 0xc7, 0xe1, 0xd0, 0xd2, 0xfc,
	0xd8, 0x02, 0x0b, 0x50, 0x66, 0xb1, 0x03, 0x16, 0xf3, 0x78, 0xe1, 0x80, 0x5f, 0xde, 0xc8, 0x45,
	0x93, 0x04, 0x94, 0x49, 0x92, 0x1d, 0x92, 0x24, 0xf3, 0x38, 0x49, 0x1c, 0xf4, 0xf9, 0x68, 0xb8,
	0x5d, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff, 0x3b, 0x5e, 0xd4, 0x6a, 0xbe, 0x02, 0x00, 0x00,
}
