// Code generated by protoc-gen-go. DO NOT EDIT.
// source: project_mgmt/project.proto

package project_mgmt

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	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

// Defines ACLs for a project's builders.
type BuildbucketAcls struct {
	// A list of LUCI Auth Service groups that can view a project's builds.
	BuildbucketReaders   []string `protobuf:"bytes,1,rep,name=buildbucket_readers,json=buildbucketReaders,proto3" json:"buildbucket_readers,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_BuildbucketAcls proto.InternalMessageInfo

func (m *BuildbucketAcls) GetBuildbucketReaders() []string {
	if m != nil {
		return m.BuildbucketReaders
	}
	return nil
}

// Defines the metadata for a project, which ultimately controls how this
// project is managed throughout the infrastructure.
type Project struct {
	// Defines the git-repo path for the project.
	Repo string `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
	// Defines the path that stores all of the project configuration.
	// Relative to the git-repo
	ConfigPath string `protobuf:"bytes,2,opt,name=config_path,json=configPath,proto3" json:"config_path,omitempty"`
	// Defines the path the repo is checked out to in the source tree, i.e. the
	// "path" attribute in the manifest.
	RepoCheckoutPath string `protobuf:"bytes,3,opt,name=repo_checkout_path,json=repoCheckoutPath,proto3" json:"repo_checkout_path,omitempty"`
	// Defines ACLs for a project's builders.
	BuildbucketAcls      *BuildbucketAcls `protobuf:"bytes,4,opt,name=buildbucket_acls,json=buildbucketAcls,proto3" json:"buildbucket_acls,omitempty"`
	XXX_NoUnkeyedLiteral struct{}         `json:"-"`
	XXX_unrecognized     []byte           `json:"-"`
	XXX_sizecache        int32            `json:"-"`
}

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

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

var xxx_messageInfo_Project proto.InternalMessageInfo

func (m *Project) GetRepo() string {
	if m != nil {
		return m.Repo
	}
	return ""
}

func (m *Project) GetConfigPath() string {
	if m != nil {
		return m.ConfigPath
	}
	return ""
}

func (m *Project) GetRepoCheckoutPath() string {
	if m != nil {
		return m.RepoCheckoutPath
	}
	return ""
}

func (m *Project) GetBuildbucketAcls() *BuildbucketAcls {
	if m != nil {
		return m.BuildbucketAcls
	}
	return nil
}

type ProjectList struct {
	Value                []*Project `protobuf:"bytes,1,rep,name=value,proto3" json:"value,omitempty"`
	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
	XXX_unrecognized     []byte     `json:"-"`
	XXX_sizecache        int32      `json:"-"`
}

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

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

var xxx_messageInfo_ProjectList proto.InternalMessageInfo

func (m *ProjectList) GetValue() []*Project {
	if m != nil {
		return m.Value
	}
	return nil
}

func init() {
	proto.RegisterType((*BuildbucketAcls)(nil), "project_mgmt.BuildbucketAcls")
	proto.RegisterType((*Project)(nil), "project_mgmt.Project")
	proto.RegisterType((*ProjectList)(nil), "project_mgmt.ProjectList")
}

func init() { proto.RegisterFile("project_mgmt/project.proto", fileDescriptor_18d734e2ff24bda5) }

var fileDescriptor_18d734e2ff24bda5 = []byte{
	// 271 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x90, 0xcf, 0x4b, 0xc3, 0x30,
	0x14, 0xc7, 0xa9, 0x9b, 0xca, 0x5e, 0x85, 0x8d, 0x88, 0x50, 0x04, 0x71, 0xf4, 0x54, 0x50, 0x1a,
	0x98, 0x20, 0xe2, 0xcd, 0x7a, 0xf1, 0xe0, 0x61, 0xf4, 0xe8, 0xa5, 0xa4, 0x59, 0xd6, 0xc6, 0xb5,
	0x7b, 0x25, 0x3f, 0xfc, 0xd3, 0xfc, 0xfb, 0x64, 0x49, 0xc5, 0xcc, 0x5b, 0xde, 0xf7, 0xf3, 0xe1,
	0xf1, 0xbe, 0x81, 0xeb, 0x41, 0xe1, 0xa7, 0xe0, 0xa6, 0xea, 0x9b, 0xde, 0xd0, 0x71, 0xc8, 0x07,
	0x85, 0x06, 0xc9, 0x45, 0xc8, 0xd2, 0x02, 0xe6, 0x85, 0x95, 0xdd, 0xa6, 0xb6, 0x7c, 0x27, 0xcc,
	0x0b, 0xef, 0x34, 0xa1, 0x70, 0x59, 0xff, 0x45, 0x95, 0x12, 0x6c, 0x23, 0x94, 0x4e, 0xa2, 0xe5,
	0x24, 0x9b, 0x95, 0x24, 0x40, 0xa5, 0x27, 0xe9, 0x77, 0x04, 0xe7, 0x6b, 0xbf, 0x94, 0x10, 0x98,
	0x2a, 0x31, 0x60, 0x12, 0x2d, 0xa3, 0x6c, 0x56, 0xba, 0x37, 0xb9, 0x85, 0x98, 0xe3, 0x7e, 0x2b,
	0x9b, 0x6a, 0x60, 0xa6, 0x4d, 0x4e, 0x1c, 0x02, 0x1f, 0xad, 0x99, 0x69, 0xc9, 0x3d, 0x90, 0x83,
	0x58, 0xf1, 0x56, 0xf0, 0x1d, 0x5a, 0xe3, 0xbd, 0x89, 0xf3, 0x16, 0x07, 0xf2, 0x3a, 0x02, 0x67,
	0xbf, 0xc1, 0x22, 0xbc, 0x8f, 0xf1, 0x4e, 0x27, 0xd3, 0x65, 0x94, 0xc5, 0xab, 0x9b, 0x3c, 0xec,
	0x96, 0xff, 0x2b, 0x56, 0xce, 0xeb, 0xe3, 0x20, 0x7d, 0x86, 0x78, 0xbc, 0xfb, 0x5d, 0x6a, 0x43,
	0xee, 0xe0, 0xf4, 0x8b, 0x75, 0x56, 0xb8, 0xaa, 0xf1, 0xea, 0xea, 0x78, 0xdb, 0x68, 0x96, 0xde,
	0x29, 0x9e, 0x3e, 0x1e, 0x1b, 0xcc, 0x79, 0xab, 0xb0, 0x97, 0xb6, 0xcf, 0x51, 0x35, 0xf4, 0x77,
	0x40, 0x4d, 0xe5, 0x7e, 0xab, 0x18, 0x75, 0x1f, 0x4e, 0x1b, 0xa4, 0xe1, 0xa2, 0xfa, 0xcc, 0xc5,
	0x0f, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x15, 0x28, 0x6f, 0x50, 0xa5, 0x01, 0x00, 0x00,
}
