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

package services

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

	proto "github.com/golang/protobuf/proto"
	enums "google.golang.org/genproto/googleapis/ads/googleads/v3/enums"
	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 fetching the invoices of a given billing setup that were
// issued during a given month.
type ListInvoicesRequest struct {
	// Required. The ID of the customer to fetch invoices for.
	CustomerId string `protobuf:"bytes,1,opt,name=customer_id,json=customerId,proto3" json:"customer_id,omitempty"`
	// Required. The billing setup resource name of the requested invoices.
	//
	// `customers/{customer_id}/billingSetups/{billing_setup_id}`
	BillingSetup string `protobuf:"bytes,2,opt,name=billing_setup,json=billingSetup,proto3" json:"billing_setup,omitempty"`
	// Required. The issue year to retrieve invoices, in yyyy format. Only
	// invoices issued in 2019 or later can be retrieved.
	IssueYear string `protobuf:"bytes,3,opt,name=issue_year,json=issueYear,proto3" json:"issue_year,omitempty"`
	// Required. The issue month to retrieve invoices.
	IssueMonth           enums.MonthOfYearEnum_MonthOfYear `protobuf:"varint,4,opt,name=issue_month,json=issueMonth,proto3,enum=google.ads.googleads.v3.enums.MonthOfYearEnum_MonthOfYear" json:"issue_month,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                          `json:"-"`
	XXX_unrecognized     []byte                            `json:"-"`
	XXX_sizecache        int32                             `json:"-"`
}

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

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

var xxx_messageInfo_ListInvoicesRequest proto.InternalMessageInfo

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

func (m *ListInvoicesRequest) GetBillingSetup() string {
	if m != nil {
		return m.BillingSetup
	}
	return ""
}

func (m *ListInvoicesRequest) GetIssueYear() string {
	if m != nil {
		return m.IssueYear
	}
	return ""
}

func (m *ListInvoicesRequest) GetIssueMonth() enums.MonthOfYearEnum_MonthOfYear {
	if m != nil {
		return m.IssueMonth
	}
	return enums.MonthOfYearEnum_UNSPECIFIED
}

// Response message for [InvoiceService.ListInvoices][google.ads.googleads.v3.services.InvoiceService.ListInvoices].
type ListInvoicesResponse struct {
	// The list of invoices that match the billing setup and time period.
	Invoices             []*resources.Invoice `protobuf:"bytes,1,rep,name=invoices,proto3" json:"invoices,omitempty"`
	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
	XXX_unrecognized     []byte               `json:"-"`
	XXX_sizecache        int32                `json:"-"`
}

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

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

var xxx_messageInfo_ListInvoicesResponse proto.InternalMessageInfo

func (m *ListInvoicesResponse) GetInvoices() []*resources.Invoice {
	if m != nil {
		return m.Invoices
	}
	return nil
}

func init() {
	proto.RegisterType((*ListInvoicesRequest)(nil), "google.ads.googleads.v3.services.ListInvoicesRequest")
	proto.RegisterType((*ListInvoicesResponse)(nil), "google.ads.googleads.v3.services.ListInvoicesResponse")
}

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

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

// InvoiceServiceClient is the client API for InvoiceService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type InvoiceServiceClient interface {
	// Returns all invoices associated with a billing setup, for a given month.
	ListInvoices(ctx context.Context, in *ListInvoicesRequest, opts ...grpc.CallOption) (*ListInvoicesResponse, error)
}

type invoiceServiceClient struct {
	cc grpc.ClientConnInterface
}

func NewInvoiceServiceClient(cc grpc.ClientConnInterface) InvoiceServiceClient {
	return &invoiceServiceClient{cc}
}

func (c *invoiceServiceClient) ListInvoices(ctx context.Context, in *ListInvoicesRequest, opts ...grpc.CallOption) (*ListInvoicesResponse, error) {
	out := new(ListInvoicesResponse)
	err := c.cc.Invoke(ctx, "/google.ads.googleads.v3.services.InvoiceService/ListInvoices", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// InvoiceServiceServer is the server API for InvoiceService service.
type InvoiceServiceServer interface {
	// Returns all invoices associated with a billing setup, for a given month.
	ListInvoices(context.Context, *ListInvoicesRequest) (*ListInvoicesResponse, error)
}

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

func (*UnimplementedInvoiceServiceServer) ListInvoices(ctx context.Context, req *ListInvoicesRequest) (*ListInvoicesResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListInvoices not implemented")
}

func RegisterInvoiceServiceServer(s *grpc.Server, srv InvoiceServiceServer) {
	s.RegisterService(&_InvoiceService_serviceDesc, srv)
}

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

var _InvoiceService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "google.ads.googleads.v3.services.InvoiceService",
	HandlerType: (*InvoiceServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "ListInvoices",
			Handler:    _InvoiceService_ListInvoices_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "google/ads/googleads/v3/services/invoice_service.proto",
}
