// Code generated by protoc-gen-go. DO NOT EDIT.
// source: project_mgmt/program.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 the metadata for a program, which ultimately controls how this
// program is managed throughout the infrastructure.
//
// NEXT ID: 6
type Program struct {
	// Defines the human-readable name for the program.
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// Defines the git-repo path for the program.
	Repo string `protobuf:"bytes,2,opt,name=repo,proto3" json:"repo,omitempty"`
	// Defines the path that stores all of the program configuration.
	// Relative to the git-repo
	ConfigPath string `protobuf:"bytes,3,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,4,opt,name=repo_checkout_path,json=repoCheckoutPath,proto3" json:"repo_checkout_path,omitempty"`
	// Defines projects within this program.
	Projects             *ProjectList `protobuf:"bytes,5,opt,name=projects,proto3" json:"projects,omitempty"`
	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
	XXX_unrecognized     []byte       `json:"-"`
	XXX_sizecache        int32        `json:"-"`
}

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

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

var xxx_messageInfo_Program proto.InternalMessageInfo

func (m *Program) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

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

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

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

func (m *Program) GetProjects() *ProjectList {
	if m != nil {
		return m.Projects
	}
	return nil
}

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

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

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

var xxx_messageInfo_ProgramList proto.InternalMessageInfo

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

func init() {
	proto.RegisterType((*Program)(nil), "project_mgmt.Program")
	proto.RegisterType((*ProgramList)(nil), "project_mgmt.ProgramList")
}

func init() { proto.RegisterFile("project_mgmt/program.proto", fileDescriptor_3321a169ccc78e39) }

var fileDescriptor_3321a169ccc78e39 = []byte{
	// 248 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0x4d, 0x4b, 0xc4, 0x30,
	0x10, 0x86, 0xa9, 0xbb, 0xeb, 0xc7, 0xd4, 0x83, 0x04, 0x84, 0xba, 0x17, 0x97, 0x3d, 0x15, 0x94,
	0x04, 0x56, 0x14, 0xf1, 0xa8, 0x57, 0x0f, 0xa5, 0x47, 0x2f, 0x25, 0x86, 0x6e, 0x1a, 0x35, 0x9d,
	0x90, 0xa6, 0xfe, 0x35, 0xff, 0x9e, 0x4c, 0x52, 0xa5, 0xb0, 0xb7, 0x99, 0xf7, 0x79, 0x32, 0xbc,
	0x04, 0xd6, 0xce, 0xe3, 0x47, 0xab, 0x42, 0x63, 0xb5, 0x0d, 0xc2, 0x79, 0xd4, 0x5e, 0x5a, 0xee,
	0x3c, 0x06, 0x64, 0xe7, 0x73, 0xb6, 0x3e, 0x30, 0x69, 0x49, 0xe6, 0xf6, 0x27, 0x83, 0x93, 0x2a,
	0xbd, 0x65, 0x0c, 0x96, 0xbd, 0xb4, 0x6d, 0x91, 0x6d, 0xb2, 0xf2, 0xac, 0x8e, 0x33, 0x65, 0xbe,
	0x75, 0x58, 0x1c, 0xa5, 0x8c, 0x66, 0x76, 0x0d, 0xb9, 0xc2, 0x7e, 0x6f, 0x74, 0xe3, 0x64, 0xe8,
	0x8a, 0x45, 0x44, 0x90, 0xa2, 0x4a, 0x86, 0x8e, 0xdd, 0x02, 0x23, 0xb1, 0x51, 0x5d, 0xab, 0x3e,
	0x71, 0x0c, 0xc9, 0x5b, 0x46, 0xef, 0x82, 0xc8, 0xcb, 0x04, 0xa2, 0x7d, 0x0f, 0xa7, 0x53, 0xa7,
	0xa1, 0x58, 0x6d, 0xb2, 0x32, 0xdf, 0x5d, 0xf1, 0x79, 0x63, 0x5e, 0xa5, 0xe5, 0xd5, 0x0c, 0xa1,
	0xfe, 0x57, 0xb7, 0x4f, 0x90, 0x4f, 0xc5, 0x09, 0xb0, 0x1b, 0x58, 0x7d, 0xcb, 0xaf, 0x91, 0xda,
	0x2f, 0xca, 0x7c, 0x77, 0x79, 0x70, 0x82, 0xcc, 0x3a, 0x39, 0xcf, 0x8f, 0x6f, 0x0f, 0x1a, 0xb9,
	0xea, 0x3c, 0x5a, 0x33, 0x5a, 0x8e, 0x5e, 0x8b, 0xbf, 0x05, 0x07, 0x61, 0xfa, 0xbd, 0x97, 0x22,
	0xfe, 0x8f, 0xd0, 0x28, 0xe6, 0x87, 0xde, 0x8f, 0x63, 0x7c, 0xf7, 0x1b, 0x00, 0x00, 0xff, 0xff,
	0xe0, 0xe0, 0xe9, 0xb1, 0x7e, 0x01, 0x00, 0x00,
}
