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

package services

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

	proto "github.com/golang/protobuf/proto"
	resources "google.golang.org/genproto/googleapis/ads/googleads/v3/resources"
	_ "google.golang.org/genproto/googleapis/api/annotations"
	status "google.golang.org/genproto/googleapis/rpc/status"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status1 "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 [FeedMappingService.GetFeedMapping][google.ads.googleads.v3.services.FeedMappingService.GetFeedMapping].
type GetFeedMappingRequest struct {
	// Required. The resource name of the feed mapping 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 *GetFeedMappingRequest) Reset()         { *m = GetFeedMappingRequest{} }
func (m *GetFeedMappingRequest) String() string { return proto.CompactTextString(m) }
func (*GetFeedMappingRequest) ProtoMessage()    {}
func (*GetFeedMappingRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_c1bab55b5a827835, []int{0}
}

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

var xxx_messageInfo_GetFeedMappingRequest proto.InternalMessageInfo

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

// Request message for [FeedMappingService.MutateFeedMappings][google.ads.googleads.v3.services.FeedMappingService.MutateFeedMappings].
type MutateFeedMappingsRequest struct {
	// Required. The ID of the customer whose feed mappings are being modified.
	CustomerId string `protobuf:"bytes,1,opt,name=customer_id,json=customerId,proto3" json:"customer_id,omitempty"`
	// Required. The list of operations to perform on individual feed mappings.
	Operations []*FeedMappingOperation `protobuf:"bytes,2,rep,name=operations,proto3" json:"operations,omitempty"`
	// If true, successful operations will be carried out and invalid
	// operations will return errors. If false, all operations will be carried
	// out in one transaction if and only if they are all valid.
	// Default is false.
	PartialFailure bool `protobuf:"varint,3,opt,name=partial_failure,json=partialFailure,proto3" json:"partial_failure,omitempty"`
	// If true, the request is validated but not executed. Only errors are
	// returned, not results.
	ValidateOnly         bool     `protobuf:"varint,4,opt,name=validate_only,json=validateOnly,proto3" json:"validate_only,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_MutateFeedMappingsRequest proto.InternalMessageInfo

func (m *MutateFeedMappingsRequest) GetCustomerId() string {
	if m != nil {
		return m.CustomerId
	}
	return ""
}

func (m *MutateFeedMappingsRequest) GetOperations() []*FeedMappingOperation {
	if m != nil {
		return m.Operations
	}
	return nil
}

func (m *MutateFeedMappingsRequest) GetPartialFailure() bool {
	if m != nil {
		return m.PartialFailure
	}
	return false
}

func (m *MutateFeedMappingsRequest) GetValidateOnly() bool {
	if m != nil {
		return m.ValidateOnly
	}
	return false
}

// A single operation (create, remove) on a feed mapping.
type FeedMappingOperation struct {
	// The mutate operation.
	//
	// Types that are valid to be assigned to Operation:
	//	*FeedMappingOperation_Create
	//	*FeedMappingOperation_Remove
	Operation            isFeedMappingOperation_Operation `protobuf_oneof:"operation"`
	XXX_NoUnkeyedLiteral struct{}                         `json:"-"`
	XXX_unrecognized     []byte                           `json:"-"`
	XXX_sizecache        int32                            `json:"-"`
}

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

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

var xxx_messageInfo_FeedMappingOperation proto.InternalMessageInfo

type isFeedMappingOperation_Operation interface {
	isFeedMappingOperation_Operation()
}

type FeedMappingOperation_Create struct {
	Create *resources.FeedMapping `protobuf:"bytes,1,opt,name=create,proto3,oneof"`
}

type FeedMappingOperation_Remove struct {
	Remove string `protobuf:"bytes,3,opt,name=remove,proto3,oneof"`
}

func (*FeedMappingOperation_Create) isFeedMappingOperation_Operation() {}

func (*FeedMappingOperation_Remove) isFeedMappingOperation_Operation() {}

func (m *FeedMappingOperation) GetOperation() isFeedMappingOperation_Operation {
	if m != nil {
		return m.Operation
	}
	return nil
}

func (m *FeedMappingOperation) GetCreate() *resources.FeedMapping {
	if x, ok := m.GetOperation().(*FeedMappingOperation_Create); ok {
		return x.Create
	}
	return nil
}

func (m *FeedMappingOperation) GetRemove() string {
	if x, ok := m.GetOperation().(*FeedMappingOperation_Remove); ok {
		return x.Remove
	}
	return ""
}

// XXX_OneofWrappers is for the internal use of the proto package.
func (*FeedMappingOperation) XXX_OneofWrappers() []interface{} {
	return []interface{}{
		(*FeedMappingOperation_Create)(nil),
		(*FeedMappingOperation_Remove)(nil),
	}
}

// Response message for a feed mapping mutate.
type MutateFeedMappingsResponse struct {
	// Errors that pertain to operation failures in the partial failure mode.
	// Returned only when partial_failure = true and all errors occur inside the
	// operations. If any errors occur outside the operations (e.g. auth errors),
	// we return an RPC level error.
	PartialFailureError *status.Status `protobuf:"bytes,3,opt,name=partial_failure_error,json=partialFailureError,proto3" json:"partial_failure_error,omitempty"`
	// All results for the mutate.
	Results              []*MutateFeedMappingResult `protobuf:"bytes,2,rep,name=results,proto3" json:"results,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                   `json:"-"`
	XXX_unrecognized     []byte                     `json:"-"`
	XXX_sizecache        int32                      `json:"-"`
}

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

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

var xxx_messageInfo_MutateFeedMappingsResponse proto.InternalMessageInfo

func (m *MutateFeedMappingsResponse) GetPartialFailureError() *status.Status {
	if m != nil {
		return m.PartialFailureError
	}
	return nil
}

func (m *MutateFeedMappingsResponse) GetResults() []*MutateFeedMappingResult {
	if m != nil {
		return m.Results
	}
	return nil
}

// The result for the feed mapping mutate.
type MutateFeedMappingResult struct {
	// Returned for successful operations.
	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 *MutateFeedMappingResult) Reset()         { *m = MutateFeedMappingResult{} }
func (m *MutateFeedMappingResult) String() string { return proto.CompactTextString(m) }
func (*MutateFeedMappingResult) ProtoMessage()    {}
func (*MutateFeedMappingResult) Descriptor() ([]byte, []int) {
	return fileDescriptor_c1bab55b5a827835, []int{4}
}

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

var xxx_messageInfo_MutateFeedMappingResult proto.InternalMessageInfo

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

func init() {
	proto.RegisterType((*GetFeedMappingRequest)(nil), "google.ads.googleads.v3.services.GetFeedMappingRequest")
	proto.RegisterType((*MutateFeedMappingsRequest)(nil), "google.ads.googleads.v3.services.MutateFeedMappingsRequest")
	proto.RegisterType((*FeedMappingOperation)(nil), "google.ads.googleads.v3.services.FeedMappingOperation")
	proto.RegisterType((*MutateFeedMappingsResponse)(nil), "google.ads.googleads.v3.services.MutateFeedMappingsResponse")
	proto.RegisterType((*MutateFeedMappingResult)(nil), "google.ads.googleads.v3.services.MutateFeedMappingResult")
}

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

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

// FeedMappingServiceClient is the client API for FeedMappingService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type FeedMappingServiceClient interface {
	// Returns the requested feed mapping in full detail.
	GetFeedMapping(ctx context.Context, in *GetFeedMappingRequest, opts ...grpc.CallOption) (*resources.FeedMapping, error)
	// Creates or removes feed mappings. Operation statuses are
	// returned.
	MutateFeedMappings(ctx context.Context, in *MutateFeedMappingsRequest, opts ...grpc.CallOption) (*MutateFeedMappingsResponse, error)
}

type feedMappingServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewFeedMappingServiceClient(cc grpc.ClientConnInterface) FeedMappingServiceClient {
	return &feedMappingServiceClient{cc}
}

func (c *feedMappingServiceClient) GetFeedMapping(ctx context.Context, in *GetFeedMappingRequest, opts ...grpc.CallOption) (*resources.FeedMapping, error) {
	out := new(resources.FeedMapping)
	err := c.cc.Invoke(ctx, "/google.ads.googleads.v3.services.FeedMappingService/GetFeedMapping", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *feedMappingServiceClient) MutateFeedMappings(ctx context.Context, in *MutateFeedMappingsRequest, opts ...grpc.CallOption) (*MutateFeedMappingsResponse, error) {
	out := new(MutateFeedMappingsResponse)
	err := c.cc.Invoke(ctx, "/google.ads.googleads.v3.services.FeedMappingService/MutateFeedMappings", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// FeedMappingServiceServer is the server API for FeedMappingService service.
type FeedMappingServiceServer interface {
	// Returns the requested feed mapping in full detail.
	GetFeedMapping(context.Context, *GetFeedMappingRequest) (*resources.FeedMapping, error)
	// Creates or removes feed mappings. Operation statuses are
	// returned.
	MutateFeedMappings(context.Context, *MutateFeedMappingsRequest) (*MutateFeedMappingsResponse, error)
}

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

func (*UnimplementedFeedMappingServiceServer) GetFeedMapping(ctx context.Context, req *GetFeedMappingRequest) (*resources.FeedMapping, error) {
	return nil, status1.Errorf(codes.Unimplemented, "method GetFeedMapping not implemented")
}
func (*UnimplementedFeedMappingServiceServer) MutateFeedMappings(ctx context.Context, req *MutateFeedMappingsRequest) (*MutateFeedMappingsResponse, error) {
	return nil, status1.Errorf(codes.Unimplemented, "method MutateFeedMappings not implemented")
}

func RegisterFeedMappingServiceServer(s *grpc.Server, srv FeedMappingServiceServer) {
	s.RegisterService(&_FeedMappingService_serviceDesc, srv)
}

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

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

var _FeedMappingService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.ads.googleads.v3.services.FeedMappingService",
	HandlerType: (*FeedMappingServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetFeedMapping",
			Handler:    _FeedMappingService_GetFeedMapping_Handler,
		},
		{
			MethodName: "MutateFeedMappings",
			Handler:    _FeedMappingService_MutateFeedMappings_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "google/ads/googleads/v3/services/feed_mapping_service.proto",
}
