// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/ads/googleads/v2/errors/ad_sharing_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 sharing errors.
type AdSharingErrorEnum_AdSharingError int32

const (
	// Enum unspecified.
	AdSharingErrorEnum_UNSPECIFIED AdSharingErrorEnum_AdSharingError = 0
	// The received error code is not known in this version.
	AdSharingErrorEnum_UNKNOWN AdSharingErrorEnum_AdSharingError = 1
	// Error resulting in attempting to add an Ad to an AdGroup that already
	// contains the Ad.
	AdSharingErrorEnum_AD_GROUP_ALREADY_CONTAINS_AD AdSharingErrorEnum_AdSharingError = 2
	// Ad is not compatible with the AdGroup it is being shared with.
	AdSharingErrorEnum_INCOMPATIBLE_AD_UNDER_AD_GROUP AdSharingErrorEnum_AdSharingError = 3
	// Cannot add AdGroupAd on inactive Ad.
	AdSharingErrorEnum_CANNOT_SHARE_INACTIVE_AD AdSharingErrorEnum_AdSharingError = 4
)

var AdSharingErrorEnum_AdSharingError_name = map[int32]string{
	0: "UNSPECIFIED",
	1: "UNKNOWN",
	2: "AD_GROUP_ALREADY_CONTAINS_AD",
	3: "INCOMPATIBLE_AD_UNDER_AD_GROUP",
	4: "CANNOT_SHARE_INACTIVE_AD",
}

var AdSharingErrorEnum_AdSharingError_value = map[string]int32{
	"UNSPECIFIED":                    0,
	"UNKNOWN":                        1,
	"AD_GROUP_ALREADY_CONTAINS_AD":   2,
	"INCOMPATIBLE_AD_UNDER_AD_GROUP": 3,
	"CANNOT_SHARE_INACTIVE_AD":       4,
}

func (x AdSharingErrorEnum_AdSharingError) String() string {
	return proto.EnumName(AdSharingErrorEnum_AdSharingError_name, int32(x))
}

func (AdSharingErrorEnum_AdSharingError) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_d4e9dd35f63014b1, []int{0, 0}
}

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

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

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

var xxx_messageInfo_AdSharingErrorEnum proto.InternalMessageInfo

func init() {
	proto.RegisterEnum("google.ads.googleads.v2.errors.AdSharingErrorEnum_AdSharingError", AdSharingErrorEnum_AdSharingError_name, AdSharingErrorEnum_AdSharingError_value)
	proto.RegisterType((*AdSharingErrorEnum)(nil), "google.ads.googleads.v2.errors.AdSharingErrorEnum")
}

func init() {
	proto.RegisterFile("google/ads/googleads/v2/errors/ad_sharing_error.proto", fileDescriptor_d4e9dd35f63014b1)
}

var fileDescriptor_d4e9dd35f63014b1 = []byte{
	// 360 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x90, 0xdf, 0x4a, 0xe3, 0x40,
	0x14, 0x87, 0x37, 0xe9, 0xb2, 0x0b, 0x53, 0xd8, 0x0d, 0xd9, 0x9b, 0x65, 0x29, 0x65, 0xc9, 0x03,
	0x4c, 0x20, 0xe2, 0xcd, 0x78, 0x75, 0x9a, 0x8c, 0x35, 0x58, 0x27, 0x21, 0xff, 0x44, 0x09, 0x0c,
	0xd1, 0x94, 0x18, 0x68, 0x33, 0x25, 0x53, 0xfb, 0x20, 0x3e, 0x82, 0x77, 0xfa, 0x28, 0x3e, 0x8a,
	0x17, 0x3e, 0x83, 0x24, 0x63, 0x0a, 0xbd, 0xd0, 0xab, 0xf9, 0x71, 0xf8, 0xbe, 0x33, 0xe7, 0x1c,
	0x74, 0x5c, 0x09, 0x51, 0xad, 0x96, 0x76, 0x51, 0x4a, 0x5b, 0xc5, 0x2e, 0xed, 0x1c, 0x7b, 0xd9,
	0xb6, 0xa2, 0x95, 0x76, 0x51, 0x72, 0x79, 0x57, 0xb4, 0x75, 0x53, 0xf1, 0xbe, 0x82, 0x37, 0xad,
	0xd8, 0x0a, 0x73, 0xaa, 0x58, 0x5c, 0x94, 0x12, 0xef, 0x35, 0xbc, 0x73, 0xb0, 0xd2, 0xfe, 0x4d,
	0x86, 0xb6, 0x9b, 0xda, 0x2e, 0x9a, 0x46, 0x6c, 0x8b, 0x6d, 0x2d, 0x1a, 0xa9, 0x6c, 0xeb, 0x49,
	0x43, 0x26, 0x94, 0xb1, 0xea, 0x4b, 0x3b, 0x83, 0x36, 0xf7, 0x6b, 0xeb, 0x41, 0x43, 0xbf, 0x0e,
	0xcb, 0xe6, 0x6f, 0x34, 0x4e, 0x59, 0x1c, 0x52, 0xd7, 0x3f, 0xf5, 0xa9, 0x67, 0x7c, 0x33, 0xc7,
	0xe8, 0x67, 0xca, 0xce, 0x59, 0x70, 0xc9, 0x0c, 0xcd, 0xfc, 0x8f, 0x26, 0xe0, 0xf1, 0x79, 0x14,
	0xa4, 0x21, 0x87, 0x45, 0x44, 0xc1, 0xbb, 0xe2, 0x6e, 0xc0, 0x12, 0xf0, 0x59, 0xcc, 0xc1, 0x33,
	0x74, 0xd3, 0x42, 0x53, 0x9f, 0xb9, 0xc1, 0x45, 0x08, 0x89, 0x3f, 0x5b, 0x50, 0x0e, 0x1e, 0x4f,
	0x99, 0x47, 0x23, 0x3e, 0x78, 0xc6, 0xc8, 0x9c, 0xa0, 0xbf, 0x2e, 0x30, 0x16, 0x24, 0x3c, 0x3e,
	0x83, 0x88, 0x72, 0x9f, 0x81, 0x9b, 0xf8, 0x59, 0x07, 0x1b, 0xdf, 0x67, 0x6f, 0x1a, 0xb2, 0x6e,
	0xc5, 0x1a, 0x7f, 0xbd, 0xf0, 0xec, 0xcf, 0xe1, 0xe0, 0x61, 0xb7, 0x67, 0xa8, 0x5d, 0x7b, 0x1f,
	0x5a, 0x25, 0x56, 0x45, 0x53, 0x61, 0xd1, 0x56, 0x76, 0xb5, 0x6c, 0xfa, 0x2b, 0x0c, 0xe7, 0xde,
	0xd4, 0xf2, 0xb3, 0xeb, 0x9f, 0xa8, 0xe7, 0x51, 0x1f, 0xcd, 0x01, 0x9e, 0xf5, 0xe9, 0x5c, 0x35,
	0x83, 0x52, 0x62, 0x15, 0xbb, 0x94, 0x39, 0xb8, 0xff, 0x52, 0xbe, 0x0c, 0x40, 0x0e, 0xa5, 0xcc,
	0xf7, 0x40, 0x9e, 0x39, 0xb9, 0x02, 0x5e, 0x75, 0x4b, 0x55, 0x09, 0x81, 0x52, 0x12, 0xb2, 0x47,
	0x08, 0xc9, 0x1c, 0x42, 0x14, 0x74, 0xf3, 0xa3, 0x9f, 0xee, 0xe8, 0x3d, 0x00, 0x00, 0xff, 0xff,
	0x56, 0x02, 0xa1, 0xc0, 0x1a, 0x02, 0x00, 0x00,
}
