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

package resources

import (
	fmt "fmt"
	math "math"

	proto "github.com/golang/protobuf/proto"
	wrappers "github.com/golang/protobuf/ptypes/wrappers"
	_ "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

// A language.
type LanguageConstant struct {
	// The resource name of the language constant.
	// Language constant resource names have the form:
	//
	// `languageConstants/{criterion_id}`
	ResourceName string `protobuf:"bytes,1,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"`
	// The ID of the language constant.
	Id *wrappers.Int64Value `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
	// The language code, e.g. "en_US", "en_AU", "es", "fr", etc.
	Code *wrappers.StringValue `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"`
	// The full name of the language in English, e.g., "English (US)", "Spanish",
	// etc.
	Name *wrappers.StringValue `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"`
	// Whether the language is targetable.
	Targetable           *wrappers.BoolValue `protobuf:"bytes,5,opt,name=targetable,proto3" json:"targetable,omitempty"`
	XXX_NoUnkeyedLiteral struct{}            `json:"-"`
	XXX_unrecognized     []byte              `json:"-"`
	XXX_sizecache        int32               `json:"-"`
}

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

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

var xxx_messageInfo_LanguageConstant proto.InternalMessageInfo

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

func (m *LanguageConstant) GetId() *wrappers.Int64Value {
	if m != nil {
		return m.Id
	}
	return nil
}

func (m *LanguageConstant) GetCode() *wrappers.StringValue {
	if m != nil {
		return m.Code
	}
	return nil
}

func (m *LanguageConstant) GetName() *wrappers.StringValue {
	if m != nil {
		return m.Name
	}
	return nil
}

func (m *LanguageConstant) GetTargetable() *wrappers.BoolValue {
	if m != nil {
		return m.Targetable
	}
	return nil
}

func init() {
	proto.RegisterType((*LanguageConstant)(nil), "google.ads.googleads.v3.resources.LanguageConstant")
}

func init() {
	proto.RegisterFile("google/ads/googleads/v3/resources/language_constant.proto", fileDescriptor_1d50094a07423762)
}

var fileDescriptor_1d50094a07423762 = []byte{
	// 407 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xd1, 0x8a, 0xd4, 0x30,
	0x14, 0x86, 0x69, 0x76, 0x15, 0x8c, 0x0a, 0x52, 0x10, 0xea, 0xb8, 0xc8, 0xae, 0x32, 0xb0, 0x22,
	0x24, 0x62, 0x45, 0x30, 0x5e, 0x75, 0xbc, 0x58, 0x14, 0x91, 0xa5, 0x62, 0x2f, 0xa4, 0xb0, 0x64,
	0x9a, 0x18, 0x0a, 0x6d, 0x52, 0x92, 0x74, 0xbc, 0x10, 0x6f, 0x7c, 0x14, 0x2f, 0x7d, 0x14, 0x5f,
	0xc1, 0x37, 0x98, 0xa7, 0x90, 0x36, 0x69, 0x66, 0x98, 0x82, 0x7a, 0xf7, 0x37, 0xe7, 0xfb, 0xcf,
	0xf9, 0x9b, 0x13, 0xf8, 0x52, 0x28, 0x25, 0x1a, 0x8e, 0x29, 0x33, 0xd8, 0xc9, 0x41, 0x6d, 0x52,
	0xac, 0xb9, 0x51, 0xbd, 0xae, 0xb8, 0xc1, 0x0d, 0x95, 0xa2, 0xa7, 0x82, 0x5f, 0x55, 0x4a, 0x1a,
	0x4b, 0xa5, 0x45, 0x9d, 0x56, 0x56, 0xc5, 0x67, 0x8e, 0x47, 0x94, 0x19, 0x14, 0xac, 0x68, 0x93,
	0xa2, 0x60, 0x5d, 0xdc, 0x9b, 0xba, 0x77, 0x75, 0x68, 0xe8, 0xdc, 0x8b, 0x07, 0xbe, 0x34, 0x7e,
	0xad, 0xfb, 0xcf, 0xf8, 0x8b, 0xa6, 0x5d, 0xc7, 0xb5, 0xf1, 0xf5, 0x93, 0x3d, 0x2b, 0x95, 0x52,
	0x59, 0x6a, 0x6b, 0x25, 0x7d, 0xf5, 0xe1, 0x6f, 0x00, 0xef, 0xbc, 0xf3, 0xb9, 0x5e, 0xfb, 0x58,
	0xf1, 0x23, 0x78, 0x7b, 0x1a, 0x72, 0x25, 0x69, 0xcb, 0x93, 0xe8, 0x34, 0x3a, 0xbf, 0x91, 0xdf,
	0x9a, 0x0e, 0xdf, 0xd3, 0x96, 0xc7, 0x4f, 0x20, 0xa8, 0x59, 0x02, 0x4e, 0xa3, 0xf3, 0x9b, 0xcf,
	0xee, 0xfb, 0xdc, 0x68, 0x0a, 0x81, 0xde, 0x48, 0xfb, 0xe2, 0x79, 0x41, 0x9b, 0x9e, 0xe7, 0xa0,
	0x66, 0xf1, 0x53, 0x78, 0x5c, 0x29, 0xc6, 0x93, 0xa3, 0x11, 0x3f, 0x99, 0xe1, 0x1f, 0xac, 0xae,
	0xa5, 0x70, 0xfc, 0x48, 0x0e, 0x8e, 0x71, 0xf4, 0xf1, 0xff, 0x38, 0x06, 0x32, 0x26, 0x10, 0x5a,
	0xaa, 0x05, 0xb7, 0x74, 0xdd, 0xf0, 0xe4, 0xda, 0xe8, 0x5b, 0xcc, 0x7c, 0x2b, 0xa5, 0x1a, 0xe7,
	0xda, 0xa3, 0xc9, 0xc7, 0x6d, 0x96, 0xc3, 0xc7, 0xbb, 0xcb, 0xf7, 0xaa, 0xab, 0x0d, 0xaa, 0x54,
	0x8b, 0x67, 0x37, 0xb4, 0x6c, 0x0e, 0x4e, 0x0c, 0xfe, 0x3a, 0x5b, 0xef, 0xb7, 0xd5, 0x77, 0x00,
	0x97, 0x95, 0x6a, 0xd1, 0x3f, 0x17, 0xbc, 0xba, 0x7b, 0x38, 0xe2, 0x72, 0x08, 0x7c, 0x19, 0x7d,
	0x7a, 0xeb, 0xbd, 0x42, 0x0d, 0xfd, 0x91, 0xd2, 0x02, 0x0b, 0x2e, 0xc7, 0xdf, 0xc1, 0xbb, 0x94,
	0x7f, 0x79, 0x76, 0xaf, 0x82, 0xfa, 0x01, 0x8e, 0x2e, 0xb2, 0xec, 0x27, 0x38, 0xbb, 0x70, 0x2d,
	0x33, 0x66, 0x90, 0x93, 0x83, 0x2a, 0x52, 0x94, 0x4f, 0xe4, 0xaf, 0x89, 0x29, 0x33, 0x66, 0xca,
	0xc0, 0x94, 0x45, 0x5a, 0x06, 0x66, 0x0b, 0x96, 0xae, 0x40, 0x48, 0xc6, 0x0c, 0x21, 0x81, 0x22,
	0xa4, 0x48, 0x09, 0x09, 0xdc, 0xfa, 0xfa, 0x18, 0x36, 0xfd, 0x13, 0x00, 0x00, 0xff, 0xff, 0xd0,
	0xc3, 0x88, 0x06, 0x22, 0x03, 0x00, 0x00,
}
