// Code generated by protoc-gen-go4grpc; DO NOT EDIT
// source: api.proto

/*
Package apipb is a generated protocol buffer package.

It is generated from these files:
	api.proto

It has these top-level messages:
	HasAncestorRequest
	HasAncestorResponse
*/
package apipb

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

import (
	context "context"
	grpc "grpc.go4.org"
)

// 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.ProtoPackageIsVersion2 // please upgrade the proto package

type HasAncestorRequest struct {
	Commit   string `protobuf:"bytes,1,opt,name=commit" json:"commit,omitempty"`
	Ancestor string `protobuf:"bytes,2,opt,name=ancestor" json:"ancestor,omitempty"`
}

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

func (m *HasAncestorRequest) GetCommit() string {
	if m != nil {
		return m.Commit
	}
	return ""
}

func (m *HasAncestorRequest) GetAncestor() string {
	if m != nil {
		return m.Ancestor
	}
	return ""
}

type HasAncestorResponse struct {
	// has_ancestor is whether ancestor appears in commit's history.
	HasAncestor bool `protobuf:"varint,1,opt,name=has_ancestor,json=hasAncestor" json:"has_ancestor,omitempty"`
	// unknown_commit is true if the provided commit was unknown.
	UnknownCommit bool `protobuf:"varint,2,opt,name=unknown_commit,json=unknownCommit" json:"unknown_commit,omitempty"`
}

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

func (m *HasAncestorResponse) GetHasAncestor() bool {
	if m != nil {
		return m.HasAncestor
	}
	return false
}

func (m *HasAncestorResponse) GetUnknownCommit() bool {
	if m != nil {
		return m.UnknownCommit
	}
	return false
}

func init() {
	proto.RegisterType((*HasAncestorRequest)(nil), "apipb.HasAncestorRequest")
	proto.RegisterType((*HasAncestorResponse)(nil), "apipb.HasAncestorResponse")
}

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

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

// Client API for MaintnerService service

type MaintnerServiceClient interface {
	// HasAncestor reports whether one commit contains another commit
	// in its git history.
	HasAncestor(ctx context.Context, in *HasAncestorRequest, opts ...grpc.CallOption) (*HasAncestorResponse, error)
}

type maintnerServiceClient struct {
	cc *grpc.ClientConn
}

func NewMaintnerServiceClient(cc *grpc.ClientConn) MaintnerServiceClient {
	return &maintnerServiceClient{cc}
}

func (c *maintnerServiceClient) HasAncestor(ctx context.Context, in *HasAncestorRequest, opts ...grpc.CallOption) (*HasAncestorResponse, error) {
	out := new(HasAncestorResponse)
	err := grpc.Invoke(ctx, "/apipb.MaintnerService/HasAncestor", in, out, c.cc, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// Server API for MaintnerService service

type MaintnerServiceServer interface {
	// HasAncestor reports whether one commit contains another commit
	// in its git history.
	HasAncestor(context.Context, *HasAncestorRequest) (*HasAncestorResponse, error)
}

func RegisterMaintnerServiceServer(s *grpc.Server, srv MaintnerServiceServer) {
	s.RegisterService(&_MaintnerService_serviceDesc, srv)
}

func _MaintnerService_HasAncestor_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HasAncestorRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(MaintnerServiceServer).HasAncestor(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/apipb.MaintnerService/HasAncestor",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(MaintnerServiceServer).HasAncestor(ctx, req.(*HasAncestorRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _MaintnerService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "apipb.MaintnerService",
	HandlerType: (*MaintnerServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "HasAncestor",
			Handler:    _MaintnerService_HasAncestor_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "api.proto",
}

func init() { proto.RegisterFile("api.proto", fileDescriptor0) }

var fileDescriptor0 = []byte{
	// 194 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x2c, 0xc8, 0xd4,
	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4d, 0x2c, 0xc8, 0x2c, 0x48, 0x52, 0xf2, 0xe0, 0x12,
	0xf2, 0x48, 0x2c, 0x76, 0xcc, 0x4b, 0x4e, 0x2d, 0x2e, 0xc9, 0x2f, 0x0a, 0x4a, 0x2d, 0x2c, 0x4d,
	0x2d, 0x2e, 0x11, 0x12, 0xe3, 0x62, 0x4b, 0xce, 0xcf, 0xcd, 0xcd, 0x2c, 0x91, 0x60, 0x54, 0x60,
	0xd4, 0xe0, 0x0c, 0x82, 0xf2, 0x84, 0xa4, 0xb8, 0x38, 0x12, 0xa1, 0x4a, 0x25, 0x98, 0xc0, 0x32,
	0x70, 0xbe, 0x52, 0x3c, 0x97, 0x30, 0x8a, 0x49, 0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x42, 0x8a,
	0x5c, 0x3c, 0x19, 0x89, 0xc5, 0xf1, 0x70, 0x6d, 0x20, 0x03, 0x39, 0x82, 0xb8, 0x33, 0x10, 0x4a,
	0x85, 0x54, 0xb9, 0xf8, 0x4a, 0xf3, 0xb2, 0xf3, 0xf2, 0xcb, 0xf3, 0xe2, 0xa1, 0xb6, 0x32, 0x81,
	0x15, 0xf1, 0x42, 0x45, 0x9d, 0xc1, 0x82, 0x46, 0xe1, 0x5c, 0xfc, 0xbe, 0x89, 0x99, 0x79, 0x25,
	0x79, 0xa9, 0x45, 0xc1, 0xa9, 0x45, 0x65, 0x99, 0xc9, 0xa9, 0x42, 0x2e, 0x5c, 0xdc, 0x48, 0x76,
	0x0a, 0x49, 0xea, 0x81, 0x3d, 0xa5, 0x87, 0xe9, 0x23, 0x29, 0x29, 0x6c, 0x52, 0x10, 0x27, 0x26,
	0xb1, 0x81, 0x43, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x74, 0x5e, 0xcf, 0x54, 0x1e, 0x01,
	0x00, 0x00,
}
