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

package services

import (
	context "context"
	fmt "fmt"
	math "math"

	proto "github.com/golang/protobuf/proto"
	wrappers "github.com/golang/protobuf/ptypes/wrappers"
	resources "google.golang.org/genproto/googleapis/ads/googleads/v3/resources"
	_ "google.golang.org/genproto/googleapis/api/annotations"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
)

// 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

// Request message for [GeoTargetConstantService.GetGeoTargetConstant][google.ads.googleads.v3.services.GeoTargetConstantService.GetGeoTargetConstant].
type GetGeoTargetConstantRequest struct {
	// Required. The resource name of the geo target constant to fetch.
	ResourceName         string   `protobuf:"bytes,1,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_GetGeoTargetConstantRequest proto.InternalMessageInfo

func (m *GetGeoTargetConstantRequest) GetResourceName() string {
	if m != nil {
		return m.ResourceName
	}
	return ""
}

// Request message for
// [GeoTargetConstantService.SuggestGeoTargetConstantsRequest][].
type SuggestGeoTargetConstantsRequest struct {
	// If possible, returned geo targets are translated using this locale. If not,
	// en is used by default. This is also used as a hint for returned geo
	// targets.
	Locale *wrappers.StringValue `protobuf:"bytes,3,opt,name=locale,proto3" json:"locale,omitempty"`
	// Returned geo targets are restricted to this country code.
	CountryCode *wrappers.StringValue `protobuf:"bytes,5,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
	// Required. A selector of geo target constants.
	//
	// Types that are valid to be assigned to Query:
	//	*SuggestGeoTargetConstantsRequest_LocationNames_
	//	*SuggestGeoTargetConstantsRequest_GeoTargets_
	Query                isSuggestGeoTargetConstantsRequest_Query `protobuf_oneof:"query"`
	XXX_NoUnkeyedLiteral struct{}                                 `json:"-"`
	XXX_unrecognized     []byte                                   `json:"-"`
	XXX_sizecache        int32                                    `json:"-"`
}

func (m *SuggestGeoTargetConstantsRequest) Reset()         { *m = SuggestGeoTargetConstantsRequest{} }
func (m *SuggestGeoTargetConstantsRequest) String() string { return proto.CompactTextString(m) }
func (*SuggestGeoTargetConstantsRequest) ProtoMessage()    {}
func (*SuggestGeoTargetConstantsRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_f7e25d1f3e9af1ca, []int{1}
}

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

var xxx_messageInfo_SuggestGeoTargetConstantsRequest proto.InternalMessageInfo

func (m *SuggestGeoTargetConstantsRequest) GetLocale() *wrappers.StringValue {
	if m != nil {
		return m.Locale
	}
	return nil
}

func (m *SuggestGeoTargetConstantsRequest) GetCountryCode() *wrappers.StringValue {
	if m != nil {
		return m.CountryCode
	}
	return nil
}

type isSuggestGeoTargetConstantsRequest_Query interface {
	isSuggestGeoTargetConstantsRequest_Query()
}

type SuggestGeoTargetConstantsRequest_LocationNames_ struct {
	LocationNames *SuggestGeoTargetConstantsRequest_LocationNames `protobuf:"bytes,1,opt,name=location_names,json=locationNames,proto3,oneof"`
}

type SuggestGeoTargetConstantsRequest_GeoTargets_ struct {
	GeoTargets *SuggestGeoTargetConstantsRequest_GeoTargets `protobuf:"bytes,2,opt,name=geo_targets,json=geoTargets,proto3,oneof"`
}

func (*SuggestGeoTargetConstantsRequest_LocationNames_) isSuggestGeoTargetConstantsRequest_Query() {}

func (*SuggestGeoTargetConstantsRequest_GeoTargets_) isSuggestGeoTargetConstantsRequest_Query() {}

func (m *SuggestGeoTargetConstantsRequest) GetQuery() isSuggestGeoTargetConstantsRequest_Query {
	if m != nil {
		return m.Query
	}
	return nil
}

func (m *SuggestGeoTargetConstantsRequest) GetLocationNames() *SuggestGeoTargetConstantsRequest_LocationNames {
	if x, ok := m.GetQuery().(*SuggestGeoTargetConstantsRequest_LocationNames_); ok {
		return x.LocationNames
	}
	return nil
}

func (m *SuggestGeoTargetConstantsRequest) GetGeoTargets() *SuggestGeoTargetConstantsRequest_GeoTargets {
	if x, ok := m.GetQuery().(*SuggestGeoTargetConstantsRequest_GeoTargets_); ok {
		return x.GeoTargets
	}
	return nil
}

// XXX_OneofWrappers is for the internal use of the proto package.
func (*SuggestGeoTargetConstantsRequest) XXX_OneofWrappers() []interface{} {
	return []interface{}{
		(*SuggestGeoTargetConstantsRequest_LocationNames_)(nil),
		(*SuggestGeoTargetConstantsRequest_GeoTargets_)(nil),
	}
}

// A list of location names.
type SuggestGeoTargetConstantsRequest_LocationNames struct {
	// A list of location names.
	Names                []*wrappers.StringValue `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
	XXX_unrecognized     []byte                  `json:"-"`
	XXX_sizecache        int32                   `json:"-"`
}

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

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

var xxx_messageInfo_SuggestGeoTargetConstantsRequest_LocationNames proto.InternalMessageInfo

func (m *SuggestGeoTargetConstantsRequest_LocationNames) GetNames() []*wrappers.StringValue {
	if m != nil {
		return m.Names
	}
	return nil
}

// A list of geo target constant resource names.
type SuggestGeoTargetConstantsRequest_GeoTargets struct {
	// A list of geo target constant resource names.
	GeoTargetConstants   []*wrappers.StringValue `protobuf:"bytes,1,rep,name=geo_target_constants,json=geoTargetConstants,proto3" json:"geo_target_constants,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
	XXX_unrecognized     []byte                  `json:"-"`
	XXX_sizecache        int32                   `json:"-"`
}

func (m *SuggestGeoTargetConstantsRequest_GeoTargets) Reset() {
	*m = SuggestGeoTargetConstantsRequest_GeoTargets{}
}
func (m *SuggestGeoTargetConstantsRequest_GeoTargets) String() string {
	return proto.CompactTextString(m)
}
func (*SuggestGeoTargetConstantsRequest_GeoTargets) ProtoMessage() {}
func (*SuggestGeoTargetConstantsRequest_GeoTargets) Descriptor() ([]byte, []int) {
	return fileDescriptor_f7e25d1f3e9af1ca, []int{1, 1}
}

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

var xxx_messageInfo_SuggestGeoTargetConstantsRequest_GeoTargets proto.InternalMessageInfo

func (m *SuggestGeoTargetConstantsRequest_GeoTargets) GetGeoTargetConstants() []*wrappers.StringValue {
	if m != nil {
		return m.GeoTargetConstants
	}
	return nil
}

// Response message for [GeoTargetConstantService.SuggestGeoTargetConstants][google.ads.googleads.v3.services.GeoTargetConstantService.SuggestGeoTargetConstants]
type SuggestGeoTargetConstantsResponse struct {
	// Geo target constant suggestions.
	GeoTargetConstantSuggestions []*GeoTargetConstantSuggestion `protobuf:"bytes,1,rep,name=geo_target_constant_suggestions,json=geoTargetConstantSuggestions,proto3" json:"geo_target_constant_suggestions,omitempty"`
	XXX_NoUnkeyedLiteral         struct{}                       `json:"-"`
	XXX_unrecognized             []byte                         `json:"-"`
	XXX_sizecache                int32                          `json:"-"`
}

func (m *SuggestGeoTargetConstantsResponse) Reset()         { *m = SuggestGeoTargetConstantsResponse{} }
func (m *SuggestGeoTargetConstantsResponse) String() string { return proto.CompactTextString(m) }
func (*SuggestGeoTargetConstantsResponse) ProtoMessage()    {}
func (*SuggestGeoTargetConstantsResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_f7e25d1f3e9af1ca, []int{2}
}

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

var xxx_messageInfo_SuggestGeoTargetConstantsResponse proto.InternalMessageInfo

func (m *SuggestGeoTargetConstantsResponse) GetGeoTargetConstantSuggestions() []*GeoTargetConstantSuggestion {
	if m != nil {
		return m.GeoTargetConstantSuggestions
	}
	return nil
}

// A geo target constant suggestion.
type GeoTargetConstantSuggestion struct {
	// The language this GeoTargetConstantSuggestion is currently translated to.
	// It affects the name of geo target fields. For example, if locale=en, then
	// name=Spain. If locale=es, then name=España. The default locale will be
	// returned if no translation exists for the locale in the request.
	Locale *wrappers.StringValue `protobuf:"bytes,1,opt,name=locale,proto3" json:"locale,omitempty"`
	// Approximate user population that will be targeted, rounded to the
	// nearest 100.
	Reach *wrappers.Int64Value `protobuf:"bytes,2,opt,name=reach,proto3" json:"reach,omitempty"`
	// If the request searched by location name, this is the location name that
	// matched the geo target.
	SearchTerm *wrappers.StringValue `protobuf:"bytes,3,opt,name=search_term,json=searchTerm,proto3" json:"search_term,omitempty"`
	// The GeoTargetConstant result.
	GeoTargetConstant *resources.GeoTargetConstant `protobuf:"bytes,4,opt,name=geo_target_constant,json=geoTargetConstant,proto3" json:"geo_target_constant,omitempty"`
	// The list of parents of the geo target constant.
	GeoTargetConstantParents []*resources.GeoTargetConstant `protobuf:"bytes,5,rep,name=geo_target_constant_parents,json=geoTargetConstantParents,proto3" json:"geo_target_constant_parents,omitempty"`
	XXX_NoUnkeyedLiteral     struct{}                       `json:"-"`
	XXX_unrecognized         []byte                         `json:"-"`
	XXX_sizecache            int32                          `json:"-"`
}

func (m *GeoTargetConstantSuggestion) Reset()         { *m = GeoTargetConstantSuggestion{} }
func (m *GeoTargetConstantSuggestion) String() string { return proto.CompactTextString(m) }
func (*GeoTargetConstantSuggestion) ProtoMessage()    {}
func (*GeoTargetConstantSuggestion) Descriptor() ([]byte, []int) {
	return fileDescriptor_f7e25d1f3e9af1ca, []int{3}
}

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

var xxx_messageInfo_GeoTargetConstantSuggestion proto.InternalMessageInfo

func (m *GeoTargetConstantSuggestion) GetLocale() *wrappers.StringValue {
	if m != nil {
		return m.Locale
	}
	return nil
}

func (m *GeoTargetConstantSuggestion) GetReach() *wrappers.Int64Value {
	if m != nil {
		return m.Reach
	}
	return nil
}

func (m *GeoTargetConstantSuggestion) GetSearchTerm() *wrappers.StringValue {
	if m != nil {
		return m.SearchTerm
	}
	return nil
}

func (m *GeoTargetConstantSuggestion) GetGeoTargetConstant() *resources.GeoTargetConstant {
	if m != nil {
		return m.GeoTargetConstant
	}
	return nil
}

func (m *GeoTargetConstantSuggestion) GetGeoTargetConstantParents() []*resources.GeoTargetConstant {
	if m != nil {
		return m.GeoTargetConstantParents
	}
	return nil
}

func init() {
	proto.RegisterType((*GetGeoTargetConstantRequest)(nil), "google.ads.googleads.v3.services.GetGeoTargetConstantRequest")
	proto.RegisterType((*SuggestGeoTargetConstantsRequest)(nil), "google.ads.googleads.v3.services.SuggestGeoTargetConstantsRequest")
	proto.RegisterType((*SuggestGeoTargetConstantsRequest_LocationNames)(nil), "google.ads.googleads.v3.services.SuggestGeoTargetConstantsRequest.LocationNames")
	proto.RegisterType((*SuggestGeoTargetConstantsRequest_GeoTargets)(nil), "google.ads.googleads.v3.services.SuggestGeoTargetConstantsRequest.GeoTargets")
	proto.RegisterType((*SuggestGeoTargetConstantsResponse)(nil), "google.ads.googleads.v3.services.SuggestGeoTargetConstantsResponse")
	proto.RegisterType((*GeoTargetConstantSuggestion)(nil), "google.ads.googleads.v3.services.GeoTargetConstantSuggestion")
}

func init() {
	proto.RegisterFile("google/ads/googleads/v3/services/geo_target_constant_service.proto", fileDescriptor_f7e25d1f3e9af1ca)
}

var fileDescriptor_f7e25d1f3e9af1ca = []byte{
	// 762 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4f, 0x6f, 0xd3, 0x48,
	0x14, 0x5f, 0x27, 0x4d, 0x57, 0x3b, 0x69, 0x57, 0xda, 0xd9, 0x4a, 0xeb, 0x4d, 0x4a, 0x1b, 0x42,
	0x0f, 0xa1, 0x07, 0x5b, 0x24, 0x15, 0x07, 0x57, 0x15, 0x38, 0x39, 0xa4, 0x48, 0x50, 0x45, 0x69,
	0x95, 0x03, 0x8a, 0x14, 0x4d, 0xed, 0x57, 0xd7, 0x92, 0xe3, 0x71, 0x67, 0x9c, 0xa0, 0x0a, 0x71,
	0x41, 0xfd, 0x06, 0x7c, 0x01, 0xc4, 0xb1, 0x47, 0x3e, 0x46, 0x25, 0xc4, 0x81, 0x13, 0x9c, 0x38,
	0x70, 0xe2, 0x53, 0x20, 0xdb, 0x63, 0x27, 0x95, 0x63, 0x12, 0x5a, 0x6e, 0x2f, 0x7e, 0xbf, 0xf7,
	0xfb, 0xbd, 0xbf, 0xd3, 0xa2, 0xa6, 0x45, 0xa9, 0xe5, 0x80, 0x4a, 0x4c, 0xae, 0x46, 0x66, 0x60,
	0x8d, 0x1b, 0x2a, 0x07, 0x36, 0xb6, 0x0d, 0xe0, 0xaa, 0x05, 0x74, 0xe0, 0x13, 0x66, 0x81, 0x3f,
	0x30, 0xa8, 0xcb, 0x7d, 0xe2, 0xfa, 0x03, 0xe1, 0x54, 0x3c, 0x46, 0x7d, 0x8a, 0x2b, 0x51, 0xa0,
	0x42, 0x4c, 0xae, 0x24, 0x1c, 0xca, 0xb8, 0xa1, 0xc4, 0x1c, 0xa5, 0xdd, 0x2c, 0x15, 0x06, 0x9c,
	0x8e, 0x58, 0x86, 0x4c, 0x44, 0x5f, 0x5a, 0x8f, 0x83, 0x3d, 0x5b, 0x25, 0xae, 0x4b, 0x7d, 0xe2,
	0xdb, 0xd4, 0xe5, 0xc2, 0xfb, 0xdf, 0x94, 0xd7, 0x70, 0x6c, 0x48, 0xc2, 0x36, 0xa7, 0x1c, 0x27,
	0x36, 0x38, 0xe6, 0xe0, 0x18, 0x4e, 0xc9, 0xd8, 0xa6, 0x4c, 0x00, 0x36, 0x04, 0x20, 0xfc, 0x75,
	0x3c, 0x3a, 0x51, 0x5f, 0x30, 0xe2, 0x79, 0xc0, 0x04, 0x73, 0xb5, 0x8d, 0xca, 0x6d, 0xf0, 0xdb,
	0x40, 0x8f, 0xc2, 0xb4, 0x5a, 0x22, 0xab, 0x2e, 0x9c, 0x8d, 0x80, 0xfb, 0xb8, 0x86, 0x56, 0xe3,
	0xec, 0x07, 0x2e, 0x19, 0x82, 0x2c, 0x55, 0xa4, 0xda, 0x5f, 0xcd, 0xfc, 0x57, 0x3d, 0xd7, 0x5d,
	0x89, 0x3d, 0x07, 0x64, 0x08, 0xd5, 0xf7, 0x4b, 0xa8, 0x72, 0x38, 0xb2, 0x2c, 0xe0, 0x69, 0x36,
	0x1e, 0xd3, 0xed, 0xa0, 0x65, 0x87, 0x1a, 0xc4, 0x01, 0x39, 0x5f, 0x91, 0x6a, 0xc5, 0xfa, 0xba,
	0x68, 0xa5, 0x12, 0xa7, 0xa7, 0x1c, 0xfa, 0xcc, 0x76, 0xad, 0x1e, 0x71, 0x46, 0xd0, 0x15, 0x58,
	0xfc, 0x08, 0xad, 0x18, 0x74, 0xe4, 0xfa, 0xec, 0x7c, 0x60, 0x50, 0x13, 0xe4, 0xc2, 0x02, 0xb1,
	0x45, 0x11, 0xd1, 0xa2, 0x26, 0xe0, 0x73, 0xf4, 0x77, 0x40, 0x15, 0x74, 0x34, 0xac, 0x82, 0x87,
	0x65, 0x14, 0xeb, 0x1d, 0x65, 0xde, 0x50, 0x95, 0x79, 0x25, 0x29, 0x4f, 0x05, 0x71, 0xd0, 0x04,
	0xbe, 0xff, 0x47, 0x77, 0xd5, 0x99, 0xfe, 0x80, 0x3d, 0x54, 0x9c, 0x0c, 0x9d, 0xcb, 0xb9, 0x50,
	0xf7, 0xd9, 0x6f, 0xd0, 0x4d, 0x3c, 0x81, 0x28, 0xb2, 0x92, 0x5f, 0xa5, 0x16, 0x5a, 0xbd, 0x96,
	0x13, 0xae, 0xa3, 0x42, 0x5c, 0x74, 0x7e, 0x6e, 0xdf, 0x22, 0x68, 0xa9, 0x8f, 0xd0, 0x44, 0x00,
	0x1f, 0xa0, 0xb5, 0x19, 0x9b, 0xbb, 0x18, 0x21, 0xb6, 0x52, 0x25, 0x34, 0xff, 0x44, 0x85, 0xb3,
	0x11, 0xb0, 0xf3, 0xea, 0xa5, 0x84, 0xee, 0xfe, 0xa4, 0x52, 0xee, 0x51, 0x97, 0x03, 0xbe, 0x90,
	0xd0, 0xe6, 0xcc, 0x03, 0x8d, 0x22, 0x83, 0x3b, 0x11, 0xa9, 0xec, 0xcd, 0x6f, 0x6c, 0x4a, 0xe7,
	0x30, 0x61, 0xe9, 0xae, 0x5b, 0xd9, 0x4e, 0x5e, 0x7d, 0x9b, 0x0f, 0x6e, 0x25, 0x13, 0x30, 0xb5,
	0xdc, 0xd2, 0x2f, 0x2c, 0xf7, 0x03, 0x54, 0x60, 0x40, 0x8c, 0x53, 0xb1, 0x1a, 0xe5, 0x54, 0xd0,
	0x13, 0xd7, 0x7f, 0xb8, 0x23, 0x86, 0x13, 0x22, 0xf1, 0x1e, 0x2a, 0x72, 0x20, 0xcc, 0x38, 0x1d,
	0xf8, 0xc0, 0x86, 0x0b, 0x9d, 0x12, 0x8a, 0x02, 0x8e, 0x80, 0x0d, 0xb1, 0x89, 0xfe, 0x9d, 0xd1,
	0x4d, 0x79, 0x29, 0xa4, 0xd9, 0xc9, 0xec, 0x60, 0xf2, 0x8a, 0xa5, 0x5b, 0xd8, 0xfd, 0x27, 0xd5,
	0x38, 0xcc, 0x51, 0x79, 0xd6, 0xcc, 0x3c, 0xc2, 0x20, 0x58, 0x9d, 0x42, 0x38, 0xaf, 0x9b, 0xa9,
	0xc9, 0x29, 0xb5, 0x4e, 0xc4, 0x5a, 0xff, 0x9c, 0x47, 0x72, 0x7a, 0x44, 0xd1, 0xe8, 0xf1, 0x07,
	0x09, 0xad, 0xcd, 0x7a, 0xeb, 0xf0, 0x42, 0x5b, 0x93, 0xf9, 0x46, 0x96, 0x6e, 0x54, 0x44, 0xf5,
	0xf1, 0x17, 0xfd, 0xfa, 0xd3, 0xfa, 0xfa, 0xd3, 0xb7, 0x37, 0xb9, 0x6d, 0x5c, 0x0b, 0xfe, 0x62,
	0xbc, 0xbc, 0xe6, 0xd9, 0x4b, 0x9f, 0x90, 0xba, 0xfd, 0x0a, 0x7f, 0x94, 0xd0, 0xff, 0x99, 0xc7,
	0x83, 0x9b, 0xb7, 0x7f, 0x63, 0x4a, 0xad, 0x5b, 0x71, 0x44, 0xd7, 0x5b, 0xbd, 0x1f, 0x16, 0x76,
	0xaf, 0xba, 0x11, 0x14, 0x96, 0xae, 0x44, 0x13, 0x57, 0xac, 0x49, 0xdb, 0xa5, 0xf2, 0x95, 0x2e,
	0x4f, 0x64, 0x84, 0xe5, 0xd9, 0x5c, 0x31, 0xe8, 0xb0, 0x79, 0x91, 0x43, 0x5b, 0x06, 0x1d, 0xce,
	0x4d, 0xa9, 0x79, 0x27, 0x6b, 0x03, 0x3a, 0xc1, 0x65, 0x74, 0xa4, 0xe7, 0xfb, 0x82, 0xc2, 0xa2,
	0x0e, 0x71, 0x2d, 0x85, 0x32, 0x4b, 0xb5, 0xc0, 0x0d, 0xef, 0x46, 0x9d, 0x88, 0x66, 0xff, 0xb7,
	0xb0, 0x1b, 0x1b, 0xef, 0x72, 0xf9, 0xb6, 0xae, 0x5f, 0xe6, 0x2a, 0xed, 0x88, 0x50, 0x37, 0xb9,
	0x12, 0x99, 0x81, 0xd5, 0x6b, 0x28, 0x42, 0x98, 0x5f, 0xc5, 0x90, 0xbe, 0x6e, 0xf2, 0x7e, 0x02,
	0xe9, 0xf7, 0x1a, 0xfd, 0x18, 0xf2, 0x3d, 0xb7, 0x15, 0x7d, 0xd7, 0x34, 0xdd, 0xe4, 0x9a, 0x96,
	0x80, 0x34, 0xad, 0xd7, 0xd0, 0xb4, 0x18, 0x76, 0xbc, 0x1c, 0xe6, 0xd9, 0xf8, 0x11, 0x00, 0x00,
	0xff, 0xff, 0x84, 0x49, 0xb7, 0x69, 0xd4, 0x08, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConnInterface

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion6

// GeoTargetConstantServiceClient is the client API for GeoTargetConstantService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type GeoTargetConstantServiceClient interface {
	// Returns the requested geo target constant in full detail.
	GetGeoTargetConstant(ctx context.Context, in *GetGeoTargetConstantRequest, opts ...grpc.CallOption) (*resources.GeoTargetConstant, error)
	// Returns GeoTargetConstant suggestions by location name or by resource name.
	SuggestGeoTargetConstants(ctx context.Context, in *SuggestGeoTargetConstantsRequest, opts ...grpc.CallOption) (*SuggestGeoTargetConstantsResponse, error)
}

type geoTargetConstantServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewGeoTargetConstantServiceClient(cc grpc.ClientConnInterface) GeoTargetConstantServiceClient {
	return &geoTargetConstantServiceClient{cc}
}

func (c *geoTargetConstantServiceClient) GetGeoTargetConstant(ctx context.Context, in *GetGeoTargetConstantRequest, opts ...grpc.CallOption) (*resources.GeoTargetConstant, error) {
	out := new(resources.GeoTargetConstant)
	err := c.cc.Invoke(ctx, "/google.ads.googleads.v3.services.GeoTargetConstantService/GetGeoTargetConstant", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *geoTargetConstantServiceClient) SuggestGeoTargetConstants(ctx context.Context, in *SuggestGeoTargetConstantsRequest, opts ...grpc.CallOption) (*SuggestGeoTargetConstantsResponse, error) {
	out := new(SuggestGeoTargetConstantsResponse)
	err := c.cc.Invoke(ctx, "/google.ads.googleads.v3.services.GeoTargetConstantService/SuggestGeoTargetConstants", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// GeoTargetConstantServiceServer is the server API for GeoTargetConstantService service.
type GeoTargetConstantServiceServer interface {
	// Returns the requested geo target constant in full detail.
	GetGeoTargetConstant(context.Context, *GetGeoTargetConstantRequest) (*resources.GeoTargetConstant, error)
	// Returns GeoTargetConstant suggestions by location name or by resource name.
	SuggestGeoTargetConstants(context.Context, *SuggestGeoTargetConstantsRequest) (*SuggestGeoTargetConstantsResponse, error)
}

// UnimplementedGeoTargetConstantServiceServer can be embedded to have forward compatible implementations.
type UnimplementedGeoTargetConstantServiceServer struct {
}

func (*UnimplementedGeoTargetConstantServiceServer) GetGeoTargetConstant(ctx context.Context, req *GetGeoTargetConstantRequest) (*resources.GeoTargetConstant, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetGeoTargetConstant not implemented")
}
func (*UnimplementedGeoTargetConstantServiceServer) SuggestGeoTargetConstants(ctx context.Context, req *SuggestGeoTargetConstantsRequest) (*SuggestGeoTargetConstantsResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SuggestGeoTargetConstants not implemented")
}

func RegisterGeoTargetConstantServiceServer(s *grpc.Server, srv GeoTargetConstantServiceServer) {
	s.RegisterService(&_GeoTargetConstantService_serviceDesc, srv)
}

func _GeoTargetConstantService_GetGeoTargetConstant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetGeoTargetConstantRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GeoTargetConstantServiceServer).GetGeoTargetConstant(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.ads.googleads.v3.services.GeoTargetConstantService/GetGeoTargetConstant",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GeoTargetConstantServiceServer).GetGeoTargetConstant(ctx, req.(*GetGeoTargetConstantRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _GeoTargetConstantService_SuggestGeoTargetConstants_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(SuggestGeoTargetConstantsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(GeoTargetConstantServiceServer).SuggestGeoTargetConstants(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/google.ads.googleads.v3.services.GeoTargetConstantService/SuggestGeoTargetConstants",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(GeoTargetConstantServiceServer).SuggestGeoTargetConstants(ctx, req.(*SuggestGeoTargetConstantsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _GeoTargetConstantService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.ads.googleads.v3.services.GeoTargetConstantService",
	HandlerType: (*GeoTargetConstantServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetGeoTargetConstant",
			Handler:    _GeoTargetConstantService_GetGeoTargetConstant_Handler,
		},
		{
			MethodName: "SuggestGeoTargetConstants",
			Handler:    _GeoTargetConstantService_SuggestGeoTargetConstants_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "google/ads/googleads/v3/services/geo_target_constant_service.proto",
}
