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

package enums

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

// Possible placeholder types for a feed mapping.
type FeedMappingCriterionTypeEnum_FeedMappingCriterionType int32

const (
	// Not specified.
	FeedMappingCriterionTypeEnum_UNSPECIFIED FeedMappingCriterionTypeEnum_FeedMappingCriterionType = 0
	// Used for return value only. Represents value unknown in this version.
	FeedMappingCriterionTypeEnum_UNKNOWN FeedMappingCriterionTypeEnum_FeedMappingCriterionType = 1
	// Allows campaign targeting at locations within a location feed.
	FeedMappingCriterionTypeEnum_LOCATION_EXTENSION_TARGETING FeedMappingCriterionTypeEnum_FeedMappingCriterionType = 4
	// Allows url targeting for your dynamic search ads within a page feed.
	FeedMappingCriterionTypeEnum_DSA_PAGE_FEED FeedMappingCriterionTypeEnum_FeedMappingCriterionType = 3
)

var FeedMappingCriterionTypeEnum_FeedMappingCriterionType_name = map[int32]string{
	0: "UNSPECIFIED",
	1: "UNKNOWN",
	4: "LOCATION_EXTENSION_TARGETING",
	3: "DSA_PAGE_FEED",
}

var FeedMappingCriterionTypeEnum_FeedMappingCriterionType_value = map[string]int32{
	"UNSPECIFIED":                  0,
	"UNKNOWN":                      1,
	"LOCATION_EXTENSION_TARGETING": 4,
	"DSA_PAGE_FEED":                3,
}

func (x FeedMappingCriterionTypeEnum_FeedMappingCriterionType) String() string {
	return proto.EnumName(FeedMappingCriterionTypeEnum_FeedMappingCriterionType_name, int32(x))
}

func (FeedMappingCriterionTypeEnum_FeedMappingCriterionType) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_14f0d190ef2adb0a, []int{0, 0}
}

// Container for enum describing possible criterion types for a feed mapping.
type FeedMappingCriterionTypeEnum struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_FeedMappingCriterionTypeEnum proto.InternalMessageInfo

func init() {
	proto.RegisterEnum("google.ads.googleads.v3.enums.FeedMappingCriterionTypeEnum_FeedMappingCriterionType", FeedMappingCriterionTypeEnum_FeedMappingCriterionType_name, FeedMappingCriterionTypeEnum_FeedMappingCriterionType_value)
	proto.RegisterType((*FeedMappingCriterionTypeEnum)(nil), "google.ads.googleads.v3.enums.FeedMappingCriterionTypeEnum")
}

func init() {
	proto.RegisterFile("google/ads/googleads/v3/enums/feed_mapping_criterion_type.proto", fileDescriptor_14f0d190ef2adb0a)
}

var fileDescriptor_14f0d190ef2adb0a = []byte{
	// 343 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x50, 0x41, 0x6a, 0xeb, 0x30,
	0x14, 0xfc, 0x4e, 0x3e, 0xff, 0x83, 0x42, 0xa9, 0xeb, 0x55, 0x29, 0x09, 0x34, 0x39, 0x80, 0xbc,
	0xf0, 0x4e, 0x5d, 0x14, 0x25, 0x51, 0x8c, 0x69, 0xeb, 0x98, 0xc6, 0x49, 0x4b, 0x31, 0x18, 0x37,
	0x52, 0x85, 0x21, 0x96, 0x84, 0xe5, 0x04, 0x72, 0x88, 0x5e, 0xa2, 0xcb, 0x1e, 0xa5, 0x47, 0xe9,
	0xb2, 0x27, 0x28, 0xb6, 0xea, 0xec, 0xd2, 0x8d, 0x18, 0x34, 0x6f, 0xe6, 0xbd, 0x19, 0x70, 0xcd,
	0xa5, 0xe4, 0x1b, 0xe6, 0x66, 0x54, 0xbb, 0x06, 0xd6, 0x68, 0xe7, 0xb9, 0x4c, 0x6c, 0x0b, 0xed,
	0xbe, 0x30, 0x46, 0xd3, 0x22, 0x53, 0x2a, 0x17, 0x3c, 0x5d, 0x97, 0x79, 0xc5, 0xca, 0x5c, 0x8a,
	0xb4, 0xda, 0x2b, 0x06, 0x55, 0x29, 0x2b, 0xe9, 0x0c, 0x8c, 0x0a, 0x66, 0x54, 0xc3, 0x83, 0x01,
	0xdc, 0x79, 0xb0, 0x31, 0xb8, 0xe8, 0xb7, 0xfe, 0x2a, 0x77, 0x33, 0x21, 0x64, 0x95, 0x55, 0xb9,
	0x14, 0xda, 0x88, 0x47, 0xaf, 0x16, 0xe8, 0xcf, 0x18, 0xa3, 0x77, 0x66, 0xc3, 0xa4, 0x5d, 0x10,
	0xef, 0x15, 0x23, 0x62, 0x5b, 0x8c, 0x0a, 0x70, 0x7e, 0x8c, 0x77, 0x4e, 0x41, 0x6f, 0x19, 0x2e,
	0x22, 0x32, 0x09, 0x66, 0x01, 0x99, 0xda, 0x7f, 0x9c, 0x1e, 0xf8, 0xbf, 0x0c, 0x6f, 0xc2, 0xf9,
	0x43, 0x68, 0x5b, 0xce, 0x25, 0xe8, 0xdf, 0xce, 0x27, 0x38, 0x0e, 0xe6, 0x61, 0x4a, 0x1e, 0x63,
	0x12, 0x2e, 0x6a, 0x14, 0xe3, 0x7b, 0x9f, 0xc4, 0x41, 0xe8, 0xdb, 0x7f, 0x9d, 0x33, 0x70, 0x32,
	0x5d, 0xe0, 0x34, 0xc2, 0x3e, 0x49, 0x67, 0x84, 0x4c, 0xed, 0xee, 0xf8, 0xcb, 0x02, 0xc3, 0xb5,
	0x2c, 0xe0, 0xaf, 0x99, 0xc6, 0x83, 0x63, 0x27, 0x45, 0x75, 0xa8, 0xc8, 0x7a, 0x1a, 0xff, 0xe8,
	0xb9, 0xdc, 0x64, 0x82, 0x43, 0x59, 0x72, 0x97, 0x33, 0xd1, 0x44, 0x6e, 0x4b, 0x56, 0xb9, 0x3e,
	0xd2, 0xf9, 0x55, 0xf3, 0xbe, 0x75, 0xba, 0x3e, 0xc6, 0xef, 0x9d, 0x81, 0x6f, 0xac, 0x30, 0xd5,
	0xd0, 0xc0, 0x1a, 0xad, 0x3c, 0x58, 0xd7, 0xa3, 0x3f, 0x5a, 0x3e, 0xc1, 0x54, 0x27, 0x07, 0x3e,
	0x59, 0x79, 0x49, 0xc3, 0x7f, 0x76, 0x86, 0xe6, 0x13, 0x21, 0x4c, 0x35, 0x42, 0x87, 0x09, 0x84,
	0x56, 0x1e, 0x42, 0xcd, 0xcc, 0xf3, 0xbf, 0xe6, 0x30, 0xef, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xbd,
	0x6d, 0x23, 0x1a, 0x0b, 0x02, 0x00, 0x00,
}
