// Code generated by protoc-gen-go. DO NOT EDIT.
// source: chromite/api/build_api_test.proto

package api

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	chromiumos "go.chromium.org/chromiumos/infra/proto/go/chromiumos"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	math "math"
)

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

type NestedPath struct {
	Path                 *chromiumos.Path `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
	XXX_unrecognized     []byte           `json:"-"`
	XXX_sizecache        int32            `json:"-"`
}

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

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

var xxx_messageInfo_NestedPath proto.InternalMessageInfo

func (m *NestedPath) GetPath() *chromiumos.Path {
	if m != nil {
		return m.Path
	}
	return nil
}

// Simple input message.
type TestRequestMessage struct {
	Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	// Chroot message for parsing and automatic chroot re-execution testing.
	Chroot *chromiumos.Chroot `protobuf:"bytes,2,opt,name=chroot,proto3" json:"chroot,omitempty"`
	// Path and ResultPath messages for insertion/extraction testing.
	Path        *chromiumos.Path       `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"`
	AnotherPath *chromiumos.Path       `protobuf:"bytes,4,opt,name=another_path,json=anotherPath,proto3" json:"another_path,omitempty"`
	NestedPath  *NestedPath            `protobuf:"bytes,5,opt,name=nested_path,json=nestedPath,proto3" json:"nested_path,omitempty"`
	ResultPath  *chromiumos.ResultPath `protobuf:"bytes,6,opt,name=result_path,json=resultPath,proto3" json:"result_path,omitempty"`
	// BuildTarget messages for parsing tests.
	BuildTarget  *chromiumos.BuildTarget   `protobuf:"bytes,7,opt,name=build_target,json=buildTarget,proto3" json:"build_target,omitempty"`
	BuildTargets []*chromiumos.BuildTarget `protobuf:"bytes,8,rep,name=build_targets,json=buildTargets,proto3" json:"build_targets,omitempty"`
	// For SyncedDir syncing tests.
	SyncedDir            *chromiumos.SyncedDir   `protobuf:"bytes,9,opt,name=synced_dir,json=syncedDir,proto3" json:"synced_dir,omitempty"`
	SyncedDirs           []*chromiumos.SyncedDir `protobuf:"bytes,10,rep,name=synced_dirs,json=syncedDirs,proto3" json:"synced_dirs,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                `json:"-"`
	XXX_unrecognized     []byte                  `json:"-"`
	XXX_sizecache        int32                   `json:"-"`
}

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

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

var xxx_messageInfo_TestRequestMessage proto.InternalMessageInfo

func (m *TestRequestMessage) GetId() string {
	if m != nil {
		return m.Id
	}
	return ""
}

func (m *TestRequestMessage) GetChroot() *chromiumos.Chroot {
	if m != nil {
		return m.Chroot
	}
	return nil
}

func (m *TestRequestMessage) GetPath() *chromiumos.Path {
	if m != nil {
		return m.Path
	}
	return nil
}

func (m *TestRequestMessage) GetAnotherPath() *chromiumos.Path {
	if m != nil {
		return m.AnotherPath
	}
	return nil
}

func (m *TestRequestMessage) GetNestedPath() *NestedPath {
	if m != nil {
		return m.NestedPath
	}
	return nil
}

func (m *TestRequestMessage) GetResultPath() *chromiumos.ResultPath {
	if m != nil {
		return m.ResultPath
	}
	return nil
}

func (m *TestRequestMessage) GetBuildTarget() *chromiumos.BuildTarget {
	if m != nil {
		return m.BuildTarget
	}
	return nil
}

func (m *TestRequestMessage) GetBuildTargets() []*chromiumos.BuildTarget {
	if m != nil {
		return m.BuildTargets
	}
	return nil
}

func (m *TestRequestMessage) GetSyncedDir() *chromiumos.SyncedDir {
	if m != nil {
		return m.SyncedDir
	}
	return nil
}

func (m *TestRequestMessage) GetSyncedDirs() []*chromiumos.SyncedDir {
	if m != nil {
		return m.SyncedDirs
	}
	return nil
}

// Simple output message.
type TestResultMessage struct {
	Result string `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"`
	// Path messages for ResultPath testing.
	Artifact             *chromiumos.Path          `protobuf:"bytes,2,opt,name=artifact,proto3" json:"artifact,omitempty"`
	NestedArtifact       *NestedPath               `protobuf:"bytes,3,opt,name=nested_artifact,json=nestedArtifact,proto3" json:"nested_artifact,omitempty"`
	Artifacts            []*chromiumos.Path        `protobuf:"bytes,4,rep,name=artifacts,proto3" json:"artifacts,omitempty"`
	Events               []*chromiumos.MetricEvent `protobuf:"bytes,5,rep,name=events,proto3" json:"events,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
	XXX_unrecognized     []byte                    `json:"-"`
	XXX_sizecache        int32                     `json:"-"`
}

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

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

var xxx_messageInfo_TestResultMessage proto.InternalMessageInfo

func (m *TestResultMessage) GetResult() string {
	if m != nil {
		return m.Result
	}
	return ""
}

func (m *TestResultMessage) GetArtifact() *chromiumos.Path {
	if m != nil {
		return m.Artifact
	}
	return nil
}

func (m *TestResultMessage) GetNestedArtifact() *NestedPath {
	if m != nil {
		return m.NestedArtifact
	}
	return nil
}

func (m *TestResultMessage) GetArtifacts() []*chromiumos.Path {
	if m != nil {
		return m.Artifacts
	}
	return nil
}

func (m *TestResultMessage) GetEvents() []*chromiumos.MetricEvent {
	if m != nil {
		return m.Events
	}
	return nil
}

func init() {
	proto.RegisterType((*NestedPath)(nil), "chromite.api.NestedPath")
	proto.RegisterType((*TestRequestMessage)(nil), "chromite.api.TestRequestMessage")
	proto.RegisterType((*TestResultMessage)(nil), "chromite.api.TestResultMessage")
}

func init() { proto.RegisterFile("chromite/api/build_api_test.proto", fileDescriptor_78ca3263cf74c05a) }

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

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

// TestApiServiceClient is the client API for TestApiService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type TestApiServiceClient interface {
	// Method that has input and output messages.
	InputOutputMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error)
	// Method name override.
	RenamedMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error)
}

type testApiServiceClient struct {
	cc *grpc.ClientConn
}

func NewTestApiServiceClient(cc *grpc.ClientConn) TestApiServiceClient {
	return &testApiServiceClient{cc}
}

func (c *testApiServiceClient) InputOutputMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error) {
	out := new(TestResultMessage)
	err := c.cc.Invoke(ctx, "/chromite.api.TestApiService/InputOutputMethod", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *testApiServiceClient) RenamedMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error) {
	out := new(TestResultMessage)
	err := c.cc.Invoke(ctx, "/chromite.api.TestApiService/RenamedMethod", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// TestApiServiceServer is the server API for TestApiService service.
type TestApiServiceServer interface {
	// Method that has input and output messages.
	InputOutputMethod(context.Context, *TestRequestMessage) (*TestResultMessage, error)
	// Method name override.
	RenamedMethod(context.Context, *TestRequestMessage) (*TestResultMessage, error)
}

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

func (*UnimplementedTestApiServiceServer) InputOutputMethod(ctx context.Context, req *TestRequestMessage) (*TestResultMessage, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InputOutputMethod not implemented")
}
func (*UnimplementedTestApiServiceServer) RenamedMethod(ctx context.Context, req *TestRequestMessage) (*TestResultMessage, error) {
	return nil, status.Errorf(codes.Unimplemented, "method RenamedMethod not implemented")
}

func RegisterTestApiServiceServer(s *grpc.Server, srv TestApiServiceServer) {
	s.RegisterService(&_TestApiService_serviceDesc, srv)
}

func _TestApiService_InputOutputMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestRequestMessage)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestApiServiceServer).InputOutputMethod(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestApiService/InputOutputMethod",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestApiServiceServer).InputOutputMethod(ctx, req.(*TestRequestMessage))
	}
	return interceptor(ctx, in, info, handler)
}

func _TestApiService_RenamedMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestRequestMessage)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(TestApiServiceServer).RenamedMethod(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.TestApiService/RenamedMethod",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(TestApiServiceServer).RenamedMethod(ctx, req.(*TestRequestMessage))
	}
	return interceptor(ctx, in, info, handler)
}

var _TestApiService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.TestApiService",
	HandlerType: (*TestApiServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "InputOutputMethod",
			Handler:    _TestApiService_InputOutputMethod_Handler,
		},
		{
			MethodName: "RenamedMethod",
			Handler:    _TestApiService_RenamedMethod_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/build_api_test.proto",
}

// InsideChrootApiServiceClient is the client API for InsideChrootApiService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type InsideChrootApiServiceClient interface {
	// No override of service level inside assertion.
	InsideServiceInsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error)
	// Override service level inside assertion with outside assertion.
	InsideServiceOutsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error)
}

type insideChrootApiServiceClient struct {
	cc *grpc.ClientConn
}

func NewInsideChrootApiServiceClient(cc *grpc.ClientConn) InsideChrootApiServiceClient {
	return &insideChrootApiServiceClient{cc}
}

func (c *insideChrootApiServiceClient) InsideServiceInsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error) {
	out := new(TestResultMessage)
	err := c.cc.Invoke(ctx, "/chromite.api.InsideChrootApiService/InsideServiceInsideMethod", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *insideChrootApiServiceClient) InsideServiceOutsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error) {
	out := new(TestResultMessage)
	err := c.cc.Invoke(ctx, "/chromite.api.InsideChrootApiService/InsideServiceOutsideMethod", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// InsideChrootApiServiceServer is the server API for InsideChrootApiService service.
type InsideChrootApiServiceServer interface {
	// No override of service level inside assertion.
	InsideServiceInsideMethod(context.Context, *TestRequestMessage) (*TestResultMessage, error)
	// Override service level inside assertion with outside assertion.
	InsideServiceOutsideMethod(context.Context, *TestRequestMessage) (*TestResultMessage, error)
}

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

func (*UnimplementedInsideChrootApiServiceServer) InsideServiceInsideMethod(ctx context.Context, req *TestRequestMessage) (*TestResultMessage, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InsideServiceInsideMethod not implemented")
}
func (*UnimplementedInsideChrootApiServiceServer) InsideServiceOutsideMethod(ctx context.Context, req *TestRequestMessage) (*TestResultMessage, error) {
	return nil, status.Errorf(codes.Unimplemented, "method InsideServiceOutsideMethod not implemented")
}

func RegisterInsideChrootApiServiceServer(s *grpc.Server, srv InsideChrootApiServiceServer) {
	s.RegisterService(&_InsideChrootApiService_serviceDesc, srv)
}

func _InsideChrootApiService_InsideServiceInsideMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestRequestMessage)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(InsideChrootApiServiceServer).InsideServiceInsideMethod(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.InsideChrootApiService/InsideServiceInsideMethod",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(InsideChrootApiServiceServer).InsideServiceInsideMethod(ctx, req.(*TestRequestMessage))
	}
	return interceptor(ctx, in, info, handler)
}

func _InsideChrootApiService_InsideServiceOutsideMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestRequestMessage)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(InsideChrootApiServiceServer).InsideServiceOutsideMethod(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.InsideChrootApiService/InsideServiceOutsideMethod",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(InsideChrootApiServiceServer).InsideServiceOutsideMethod(ctx, req.(*TestRequestMessage))
	}
	return interceptor(ctx, in, info, handler)
}

var _InsideChrootApiService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.InsideChrootApiService",
	HandlerType: (*InsideChrootApiServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "InsideServiceInsideMethod",
			Handler:    _InsideChrootApiService_InsideServiceInsideMethod_Handler,
		},
		{
			MethodName: "InsideServiceOutsideMethod",
			Handler:    _InsideChrootApiService_InsideServiceOutsideMethod_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/build_api_test.proto",
}

// OutsideChrootApiServiceClient is the client API for OutsideChrootApiService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type OutsideChrootApiServiceClient interface {
	// No override of service level outside assertion.
	OutsideServiceOutsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error)
	// Override service level outside assertion with inside assertion.
	OutsideServiceInsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error)
}

type outsideChrootApiServiceClient struct {
	cc *grpc.ClientConn
}

func NewOutsideChrootApiServiceClient(cc *grpc.ClientConn) OutsideChrootApiServiceClient {
	return &outsideChrootApiServiceClient{cc}
}

func (c *outsideChrootApiServiceClient) OutsideServiceOutsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error) {
	out := new(TestResultMessage)
	err := c.cc.Invoke(ctx, "/chromite.api.OutsideChrootApiService/OutsideServiceOutsideMethod", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *outsideChrootApiServiceClient) OutsideServiceInsideMethod(ctx context.Context, in *TestRequestMessage, opts ...grpc.CallOption) (*TestResultMessage, error) {
	out := new(TestResultMessage)
	err := c.cc.Invoke(ctx, "/chromite.api.OutsideChrootApiService/OutsideServiceInsideMethod", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// OutsideChrootApiServiceServer is the server API for OutsideChrootApiService service.
type OutsideChrootApiServiceServer interface {
	// No override of service level outside assertion.
	OutsideServiceOutsideMethod(context.Context, *TestRequestMessage) (*TestResultMessage, error)
	// Override service level outside assertion with inside assertion.
	OutsideServiceInsideMethod(context.Context, *TestRequestMessage) (*TestResultMessage, error)
}

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

func (*UnimplementedOutsideChrootApiServiceServer) OutsideServiceOutsideMethod(ctx context.Context, req *TestRequestMessage) (*TestResultMessage, error) {
	return nil, status.Errorf(codes.Unimplemented, "method OutsideServiceOutsideMethod not implemented")
}
func (*UnimplementedOutsideChrootApiServiceServer) OutsideServiceInsideMethod(ctx context.Context, req *TestRequestMessage) (*TestResultMessage, error) {
	return nil, status.Errorf(codes.Unimplemented, "method OutsideServiceInsideMethod not implemented")
}

func RegisterOutsideChrootApiServiceServer(s *grpc.Server, srv OutsideChrootApiServiceServer) {
	s.RegisterService(&_OutsideChrootApiService_serviceDesc, srv)
}

func _OutsideChrootApiService_OutsideServiceOutsideMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestRequestMessage)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OutsideChrootApiServiceServer).OutsideServiceOutsideMethod(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.OutsideChrootApiService/OutsideServiceOutsideMethod",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OutsideChrootApiServiceServer).OutsideServiceOutsideMethod(ctx, req.(*TestRequestMessage))
	}
	return interceptor(ctx, in, info, handler)
}

func _OutsideChrootApiService_OutsideServiceInsideMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(TestRequestMessage)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(OutsideChrootApiServiceServer).OutsideServiceInsideMethod(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.OutsideChrootApiService/OutsideServiceInsideMethod",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(OutsideChrootApiServiceServer).OutsideServiceInsideMethod(ctx, req.(*TestRequestMessage))
	}
	return interceptor(ctx, in, info, handler)
}

var _OutsideChrootApiService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.OutsideChrootApiService",
	HandlerType: (*OutsideChrootApiServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "OutsideServiceOutsideMethod",
			Handler:    _OutsideChrootApiService_OutsideServiceOutsideMethod_Handler,
		},
		{
			MethodName: "OutsideServiceInsideMethod",
			Handler:    _OutsideChrootApiService_OutsideServiceInsideMethod_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/build_api_test.proto",
}
