// 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 {
	// TODO(crbug/1081828): drop when no longer used.  Use sysroot instead.
	// The board whose dependency graph this is.
	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"`
	// The sysroot whose dependency graph is being created.  If no sysroot is
	// being used, may be unspecified.
	Sysroot              *Sysroot `protobuf:"bytes,3,opt,name=sysroot,proto3" json:"sysroot,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
}

func (m *DepGraph) GetSysroot() *Sysroot {
	if m != nil {
		return m.Sysroot
	}
	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 {
	// The sysroot whose dependency graph is being created.  If no sysroot is
	// being used, may be unspecified.
	Sysroot *Sysroot `protobuf:"bytes,4,opt,name=sysroot,proto3" json:"sysroot,omitempty"`
	// TODO(crbug/1081828): drop when no longer used.
	// DEPRECATED: Use sysroot instead.
	// The board whose dependency graph is being created.  If both sysroot and
	// build_target are given, sysroot is used.
	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) GetSysroot() *Sysroot {
	if m != nil {
		return m.Sysroot
	}
	return nil
}

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
}

// Message for getting a list of a board's package dependencies.
type ListRequest struct {
	// The sysroot for the board whose packages dependencies are being calculated.
	Sysroot *Sysroot `protobuf:"bytes,1,opt,name=sysroot,proto3" json:"sysroot,omitempty"`
	// The chroot to use to execute the endpoint.
	Chroot *chromiumos.Chroot `protobuf:"bytes,2,opt,name=chroot,proto3" json:"chroot,omitempty"`
	// List of paths to consider when retrieving the board's package dependencies.
	// If empty / None returns all package dependencies.
	SrcPaths []*SourcePath `protobuf:"bytes,3,rep,name=src_paths,json=srcPaths,proto3" json:"src_paths,omitempty"`
	// List of packages for which to get dependencies. If none are specified the
	// standard list of packages is used.
	Packages             []*chromiumos.PackageInfo `protobuf:"bytes,4,rep,name=packages,proto3" json:"packages,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                  `json:"-"`
	XXX_unrecognized     []byte                    `json:"-"`
	XXX_sizecache        int32                     `json:"-"`
}

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

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

var xxx_messageInfo_ListRequest proto.InternalMessageInfo

func (m *ListRequest) GetSysroot() *Sysroot {
	if m != nil {
		return m.Sysroot
	}
	return nil
}

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

func (m *ListRequest) GetSrcPaths() []*SourcePath {
	if m != nil {
		return m.SrcPaths
	}
	return nil
}

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

// Response for getting a list of package dependencies.
type ListResponse struct {
	PackageDeps          []*chromiumos.PackageInfo `protobuf:"bytes,1,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 *ListResponse) Reset()         { *m = ListResponse{} }
func (m *ListResponse) String() string { return proto.CompactTextString(m) }
func (*ListResponse) ProtoMessage()    {}
func (*ListResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_7a5308b238ddba97, []int{8}
}

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

var xxx_messageInfo_ListResponse proto.InternalMessageInfo

func (m *ListResponse) GetPackageDeps() []*chromiumos.PackageInfo {
	if m != nil {
		return m.PackageDeps
	}
	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")
	proto.RegisterType((*ListRequest)(nil), "chromite.api.ListRequest")
	proto.RegisterType((*ListResponse)(nil), "chromite.api.ListResponse")
}

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

var fileDescriptor_7a5308b238ddba97 = []byte{
	// 623 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xdf, 0x6e, 0xd3, 0x3e,
	0x18, 0x95, 0xdb, 0xfe, 0xf6, 0xeb, 0xbe, 0x94, 0x89, 0x19, 0x8d, 0x66, 0x61, 0x82, 0x2a, 0x17,
	0x30, 0x21, 0x48, 0xa4, 0x56, 0x20, 0x34, 0x09, 0x21, 0x8d, 0x8a, 0xf2, 0xef, 0xa2, 0xca, 0x76,
	0xc5, 0x4d, 0x94, 0x26, 0x6e, 0x1a, 0x75, 0x8d, 0x4d, 0xec, 0x4e, 0xda, 0x6b, 0xf0, 0x34, 0x5c,
	0x23, 0x9e, 0x81, 0x67, 0xe0, 0x06, 0x9e, 0x01, 0xc5, 0x49, 0xea, 0x64, 0xeb, 0x3f, 0xc4, 0x5d,
	0x9c, 0x73, 0xce, 0x67, 0x9f, 0xcf, 0xc7, 0x36, 0xdc, 0xf3, 0x27, 0x09, 0x9d, 0x45, 0x82, 0xd8,
	0x1e, 0x8b, 0xec, 0x80, 0xb0, 0x30, 0xf1, 0xd8, 0xc4, 0x62, 0x09, 0x15, 0x14, 0xb7, 0x0a, 0xd0,
	0xf2, 0x58, 0x64, 0x1c, 0x55, 0xa8, 0xa3, 0x79, 0x74, 0x11, 0xb8, 0x1e, 0x8b, 0x32, 0xae, 0x61,
	0x54, 0x50, 0x7e, 0xc5, 0x13, 0x4a, 0x45, 0x8e, 0xb5, 0x33, 0x6c, 0x3e, 0xa3, 0xdc, 0xf6, 0xe9,
	0x6c, 0x46, 0xe3, 0x0c, 0x30, 0xbf, 0x22, 0x68, 0xf6, 0x09, 0x1b, 0xa4, 0x73, 0xe2, 0x13, 0x68,
	0x65, 0x45, 0x85, 0x97, 0x84, 0x44, 0xe8, 0xa8, 0x83, 0x8e, 0xb5, 0x6e, 0xdb, 0x52, 0x62, 0xeb,
	0x34, 0xc5, 0xcf, 0x25, 0xec, 0x68, 0x23, 0x35, 0xc0, 0xaf, 0xa0, 0xc5, 0x3c, 0x7f, 0xea, 0x85,
	0xc4, 0x0d, 0x08, 0xe3, 0x7a, 0xad, 0x53, 0x3f, 0xd6, 0xba, 0x47, 0x56, 0xd9, 0x80, 0x35, 0xcc,
	0x18, 0x7d, 0xc2, 0xde, 0xc5, 0x63, 0xea, 0x68, 0x6c, 0x31, 0xe6, 0xd8, 0x86, 0xff, 0xf3, 0x35,
	0xeb, 0x75, 0x39, 0xef, 0x41, 0x55, 0x7b, 0x96, 0x81, 0x4e, 0xc1, 0x32, 0x7f, 0x22, 0xd8, 0xab,
	0x16, 0x4c, 0x0d, 0x14, 0x8b, 0x88, 0xe2, 0x31, 0x5d, 0x66, 0x20, 0x57, 0x54, 0xe6, 0x97, 0xda,
	0xb7, 0x70, 0x27, 0x20, 0x8c, 0xc4, 0x01, 0x89, 0xfd, 0x2b, 0x37, 0x47, 0x0a, 0x1f, 0x2b, 0x4b,
	0x60, 0xa5, 0xc9, 0x7f, 0x73, 0x3c, 0x84, 0x76, 0xa9, 0x12, 0xa7, 0xf3, 0xc4, 0x27, 0x2e, 0xf3,
	0xc4, 0x84, 0xeb, 0x75, 0x59, 0x4d, 0xbf, 0xe6, 0x4c, 0x32, 0x86, 0x9e, 0x98, 0x38, 0x07, 0x4a,
	0xa8, 0xfe, 0x72, 0xb3, 0x03, 0xa0, 0x86, 0x18, 0x43, 0x23, 0xad, 0x26, 0xdd, 0xed, 0x3a, 0xf2,
	0xdb, 0xfc, 0x8d, 0xe0, 0xfe, 0x80, 0x08, 0xb9, 0x3d, 0xfd, 0x45, 0x0d, 0xb9, 0xad, 0x0e, 0xf9,
	0x3c, 0x27, 0x5c, 0x94, 0x1b, 0xdc, 0xd8, 0xa6, 0xc1, 0xff, 0x14, 0x87, 0xc7, 0xb0, 0x93, 0xd2,
	0xa8, 0xd0, 0x6b, 0x52, 0x85, 0xcb, 0xaa, 0xd7, 0x12, 0x71, 0x72, 0x06, 0xee, 0x41, 0x73, 0xd1,
	0xee, 0xfa, 0xfa, 0x76, 0x2f, 0x88, 0xe6, 0x17, 0x04, 0x0f, 0x56, 0x1a, 0xe6, 0x8c, 0xc6, 0x9c,
	0xe0, 0x1e, 0xec, 0x06, 0x84, 0xb9, 0xf2, 0x40, 0xe5, 0xab, 0xbf, 0x5b, 0xf5, 0x5c, 0x44, 0xdf,
	0x69, 0x06, 0xea, 0x10, 0xdc, 0xe2, 0xc1, 0xd4, 0x55, 0xc2, 0xda, 0x5a, 0xa1, 0xc6, 0x83, 0x69,
	0x31, 0x30, 0xdf, 0x80, 0x3e, 0x20, 0xe2, 0x9c, 0xd2, 0x0b, 0x7f, 0xe2, 0x45, 0xb1, 0xdc, 0xbc,
	0xa2, 0xfd, 0xaa, 0x23, 0x68, 0x53, 0x47, 0xcc, 0x0f, 0x70, 0xb8, 0xa4, 0x4e, 0xee, 0xca, 0x82,
	0xff, 0xb2, 0x30, 0xa1, 0x0d, 0x61, 0xca, 0x68, 0xe6, 0x0f, 0x04, 0xda, 0xc7, 0x88, 0x8b, 0x25,
	0x39, 0x40, 0x5b, 0xe5, 0xe0, 0x6f, 0xf6, 0xf2, 0x19, 0xec, 0xf2, 0xc4, 0xdf, 0x32, 0xed, 0x4d,
	0x9e, 0xf8, 0xd2, 0x5b, 0x25, 0x02, 0x8d, 0x6d, 0x23, 0xf0, 0x1e, 0x5a, 0x99, 0xaf, 0xbc, 0x31,
	0x27, 0xd7, 0xae, 0x20, 0xb4, 0xbe, 0x50, 0xf9, 0xf6, 0xe9, 0x7e, 0xaf, 0xc1, 0xbe, 0x8a, 0xd1,
	0x19, 0x49, 0x2e, 0x23, 0x9f, 0xe0, 0x4b, 0x68, 0xaf, 0xc8, 0x18, 0x7e, 0x52, 0x75, 0xb5, 0xfe,
	0xec, 0x19, 0x4f, 0xb7, 0x64, 0xe7, 0x4e, 0x02, 0xd8, 0xbf, 0xb1, 0xff, 0xf8, 0xe1, 0x8d, 0x1a,
	0x4b, 0x83, 0x66, 0x3c, 0xda, 0xc8, 0xcb, 0x67, 0x79, 0x09, 0x8d, 0xb4, 0x7f, 0xf8, 0xb0, 0x2a,
	0x28, 0x65, 0xc5, 0x30, 0x96, 0x41, 0x99, 0xdc, 0xc0, 0xdf, 0x7e, 0x19, 0x7b, 0x00, 0xea, 0xc6,
	0xba, 0x8d, 0x4e, 0x5f, 0x7c, 0x7a, 0x1e, 0xd2, 0x45, 0xc3, 0x2d, 0x9a, 0x84, 0x76, 0xe9, 0xe5,
	0x89, 0xe2, 0x71, 0xe2, 0xd9, 0xf2, 0xe1, 0xb1, 0x43, 0x6a, 0x97, 0xdf, 0xab, 0xd1, 0x8e, 0xfc,
	0xdd, 0xfb, 0x13, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xb0, 0x79, 0x99, 0x0f, 0x07, 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)
	// Get the list of package dependencies.
	List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, 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
}

func (c *dependencyServiceClient) List(ctx context.Context, in *ListRequest, opts ...grpc.CallOption) (*ListResponse, error) {
	out := new(ListResponse)
	err := c.cc.Invoke(ctx, "/chromite.api.DependencyService/List", 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)
	// Get the list of package dependencies.
	List(context.Context, *ListRequest) (*ListResponse, 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 (*UnimplementedDependencyServiceServer) List(ctx context.Context, req *ListRequest) (*ListResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method List 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)
}

func _DependencyService_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(ListRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(DependencyServiceServer).List(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/chromite.api.DependencyService/List",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(DependencyServiceServer).List(ctx, req.(*ListRequest))
	}
	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,
		},
		{
			MethodName: "List",
			Handler:    _DependencyService_List_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "chromite/api/depgraph.proto",
}
