// Code generated by protoc-gen-go. DO NOT EDIT.
// source: chromite/api/depgraph.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

// Message contains data about the portage dependency graph and the packages'
// dependency source paths.
type DepGraph struct {
	// The board whose dependency graph is being created for.
	BuildTarget *chromiumos.BuildTarget `protobuf:"bytes,1,opt,name=build_target,json=buildTarget,proto3" json:"build_target,omitempty"`
	// List of packages in the dependency graph and their infos, which include
	// dependency packages and the source paths.
	PackageDeps          []*PackageDepInfo `protobuf:"bytes,2,rep,name=package_deps,json=packageDeps,proto3" json:"package_deps,omitempty"`
	XXX_NoUnkeyedLiteral struct{}          `json:"-"`
	XXX_unrecognized     []byte            `json:"-"`
	XXX_sizecache        int32             `json:"-"`
}

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

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

var xxx_messageInfo_DepGraph proto.InternalMessageInfo

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

func (m *DepGraph) GetPackageDeps() []*PackageDepInfo {
	if m != nil {
		return m.PackageDeps
	}
	return nil
}

// Message describing a package and its dependencies.
type PackageDepInfo struct {
	// The package itself.
	PackageInfo *chromiumos.PackageInfo `protobuf:"bytes,1,opt,name=package_info,json=packageInfo,proto3" json:"package_info,omitempty"`
	// List of packages this package depends on.
	DependencyPackages []*chromiumos.PackageInfo `protobuf:"bytes,2,rep,name=dependency_packages,json=dependencyPackages,proto3" json:"dependency_packages,omitempty"`
	// List of source paths the package depends on.
	DependencySourcePaths []*SourcePath `protobuf:"bytes,3,rep,name=dependency_source_paths,json=dependencySourcePaths,proto3" json:"dependency_source_paths,omitempty"`
	XXX_NoUnkeyedLiteral  struct{}      `json:"-"`
	XXX_unrecognized      []byte        `json:"-"`
	XXX_sizecache         int32         `json:"-"`
}

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

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

var xxx_messageInfo_PackageDepInfo proto.InternalMessageInfo

func (m *PackageDepInfo) GetPackageInfo() *chromiumos.PackageInfo {
	if m != nil {
		return m.PackageInfo
	}
	return nil
}

func (m *PackageDepInfo) GetDependencyPackages() []*chromiumos.PackageInfo {
	if m != nil {
		return m.DependencyPackages
	}
	return nil
}

func (m *PackageDepInfo) GetDependencySourcePaths() []*SourcePath {
	if m != nil {
		return m.DependencySourcePaths
	}
	return nil
}

// Message describes a source path.
type SourcePath struct {
	Path                 string   `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_SourcePath proto.InternalMessageInfo

func (m *SourcePath) GetPath() string {
	if m != nil {
		return m.Path
	}
	return ""
}

// Message for creating dependency graph json map.
// Example Json:
// {"build_target":{"name":"board"},"output_file":"/tmp/depgraph.json"}
type GetBuildDependencyGraphRequest struct {
	// Required.
	// The board whose dependency graph is being created.
	BuildTarget *chromiumos.BuildTarget `protobuf:"bytes,1,opt,name=build_target,json=buildTarget,proto3" json:"build_target,omitempty"`
	// The chroot to use to execute the endpoint.
	Chroot *chromiumos.Chroot `protobuf:"bytes,2,opt,name=chroot,proto3" json:"chroot,omitempty"`
	// List of packages for which to create the dependency graph. If none are
	// specified the standard list of packages is used.
	Packages             []*chromiumos.PackageInfo `protobuf:"bytes,3,rep,name=packages,proto3" json:"packages,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
	XXX_unrecognized     []byte                    `json:"-"`
	XXX_sizecache        int32                     `json:"-"`
}

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

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

var xxx_messageInfo_GetBuildDependencyGraphRequest proto.InternalMessageInfo

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

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

func (m *GetBuildDependencyGraphRequest) GetPackages() []*chromiumos.PackageInfo {
	if m != nil {
		return m.Packages
	}
	return nil
}

// Response from creating dependency graph json map.
type GetBuildDependencyGraphResponse struct {
	DepGraph             *DepGraph `protobuf:"bytes,1,opt,name=dep_graph,json=depGraph,proto3" json:"dep_graph,omitempty"`
	SdkDepGraph          *DepGraph `protobuf:"bytes,2,opt,name=sdk_dep_graph,json=sdkDepGraph,proto3" json:"sdk_dep_graph,omitempty"`
	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
	XXX_unrecognized     []byte    `json:"-"`
	XXX_sizecache        int32     `json:"-"`
}

func (m *GetBuildDependencyGraphResponse) Reset()         { *m = GetBuildDependencyGraphResponse{} }
func (m *GetBuildDependencyGraphResponse) String() string { return proto.CompactTextString(m) }
func (*GetBuildDependencyGraphResponse) ProtoMessage()    {}
func (*GetBuildDependencyGraphResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_7a5308b238ddba97, []int{4}
}

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

var xxx_messageInfo_GetBuildDependencyGraphResponse proto.InternalMessageInfo

func (m *GetBuildDependencyGraphResponse) GetDepGraph() *DepGraph {
	if m != nil {
		return m.DepGraph
	}
	return nil
}

func (m *GetBuildDependencyGraphResponse) GetSdkDepGraph() *DepGraph {
	if m != nil {
		return m.SdkDepGraph
	}
	return nil
}

type GetToolchainPathsRequest struct {
	// The chroot to use to execute the endpoint.
	Chroot               *chromiumos.Chroot `protobuf:"bytes,1,opt,name=chroot,proto3" json:"chroot,omitempty"`
	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
	XXX_unrecognized     []byte             `json:"-"`
	XXX_sizecache        int32              `json:"-"`
}

func (m *GetToolchainPathsRequest) Reset()         { *m = GetToolchainPathsRequest{} }
func (m *GetToolchainPathsRequest) String() string { return proto.CompactTextString(m) }
func (*GetToolchainPathsRequest) ProtoMessage()    {}
func (*GetToolchainPathsRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_7a5308b238ddba97, []int{5}
}

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

var xxx_messageInfo_GetToolchainPathsRequest proto.InternalMessageInfo

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

type GetToolchainPathsResponse struct {
	// List of paths considered relevant to toolchain packages.
	Paths                []*SourcePath `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"`
	XXX_NoUnkeyedLiteral struct{}      `json:"-"`
	XXX_unrecognized     []byte        `json:"-"`
	XXX_sizecache        int32         `json:"-"`
}

func (m *GetToolchainPathsResponse) Reset()         { *m = GetToolchainPathsResponse{} }
func (m *GetToolchainPathsResponse) String() string { return proto.CompactTextString(m) }
func (*GetToolchainPathsResponse) ProtoMessage()    {}
func (*GetToolchainPathsResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_7a5308b238ddba97, []int{6}
}

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

var xxx_messageInfo_GetToolchainPathsResponse proto.InternalMessageInfo

func (m *GetToolchainPathsResponse) GetPaths() []*SourcePath {
	if m != nil {
		return m.Paths
	}
	return nil
}

func init() {
	proto.RegisterType((*DepGraph)(nil), "chromite.api.DepGraph")
	proto.RegisterType((*PackageDepInfo)(nil), "chromite.api.PackageDepInfo")
	proto.RegisterType((*SourcePath)(nil), "chromite.api.SourcePath")
	proto.RegisterType((*GetBuildDependencyGraphRequest)(nil), "chromite.api.GetBuildDependencyGraphRequest")
	proto.RegisterType((*GetBuildDependencyGraphResponse)(nil), "chromite.api.GetBuildDependencyGraphResponse")
	proto.RegisterType((*GetToolchainPathsRequest)(nil), "chromite.api.GetToolchainPathsRequest")
	proto.RegisterType((*GetToolchainPathsResponse)(nil), "chromite.api.GetToolchainPathsResponse")
}

func init() { proto.RegisterFile("chromite/api/depgraph.proto", fileDescriptor_7a5308b238ddba97) }

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

// DependencyServiceClient is the client API for DependencyService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type DependencyServiceClient interface {
	// Get the build dependency graph.
	GetBuildDependencyGraph(ctx context.Context, in *GetBuildDependencyGraphRequest, opts ...grpc.CallOption) (*GetBuildDependencyGraphResponse, error)
	// Get the list of source paths that are relevant to the toolchain
	GetToolchainPaths(ctx context.Context, in *GetToolchainPathsRequest, opts ...grpc.CallOption) (*GetToolchainPathsResponse, error)
}

type dependencyServiceClient struct {
	cc *grpc.ClientConn
}

func NewDependencyServiceClient(cc *grpc.ClientConn) DependencyServiceClient {
	return &dependencyServiceClient{cc}
}

func (c *dependencyServiceClient) GetBuildDependencyGraph(ctx context.Context, in *GetBuildDependencyGraphRequest, opts ...grpc.CallOption) (*GetBuildDependencyGraphResponse, error) {
	out := new(GetBuildDependencyGraphResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.DependencyService/GetBuildDependencyGraph", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *dependencyServiceClient) GetToolchainPaths(ctx context.Context, in *GetToolchainPathsRequest, opts ...grpc.CallOption) (*GetToolchainPathsResponse, error) {
	out := new(GetToolchainPathsResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.DependencyService/GetToolchainPaths", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

// DependencyServiceServer is the server API for DependencyService service.
type DependencyServiceServer interface {
	// Get the build dependency graph.
	GetBuildDependencyGraph(context.Context, *GetBuildDependencyGraphRequest) (*GetBuildDependencyGraphResponse, error)
	// Get the list of source paths that are relevant to the toolchain
	GetToolchainPaths(context.Context, *GetToolchainPathsRequest) (*GetToolchainPathsResponse, error)
}

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

func (*UnimplementedDependencyServiceServer) GetBuildDependencyGraph(ctx context.Context, req *GetBuildDependencyGraphRequest) (*GetBuildDependencyGraphResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetBuildDependencyGraph not implemented")
}
func (*UnimplementedDependencyServiceServer) GetToolchainPaths(ctx context.Context, req *GetToolchainPathsRequest) (*GetToolchainPathsResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetToolchainPaths not implemented")
}

func RegisterDependencyServiceServer(s *grpc.Server, srv DependencyServiceServer) {
	s.RegisterService(&_DependencyService_serviceDesc, srv)
}

func _DependencyService_GetBuildDependencyGraph_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetBuildDependencyGraphRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DependencyServiceServer).GetBuildDependencyGraph(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.DependencyService/GetBuildDependencyGraph",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DependencyServiceServer).GetBuildDependencyGraph(ctx, req.(*GetBuildDependencyGraphRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _DependencyService_GetToolchainPaths_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetToolchainPathsRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DependencyServiceServer).GetToolchainPaths(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.DependencyService/GetToolchainPaths",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DependencyServiceServer).GetToolchainPaths(ctx, req.(*GetToolchainPathsRequest))
	}
	return interceptor(ctx, in, info, handler)
}

var _DependencyService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "chromite.api.DependencyService",
	HandlerType: (*DependencyServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "GetBuildDependencyGraph",
			Handler:    _DependencyService_GetBuildDependencyGraph_Handler,
		},
		{
			MethodName: "GetToolchainPaths",
			Handler:    _DependencyService_GetToolchainPaths_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/depgraph.proto",
}
