// Code generated by protoc-gen-go. DO NOT EDIT.
// source: testplans/common.proto

package testplans

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

type ProtoBytes struct {
	SerializedProto      []byte   `protobuf:"bytes,1,opt,name=serialized_proto,json=serializedProto,proto3" json:"serialized_proto,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_ProtoBytes proto.InternalMessageInfo

func (m *ProtoBytes) GetSerializedProto() []byte {
	if m != nil {
		return m.SerializedProto
	}
	return nil
}

type FilePattern struct {
	// Bash pattern for matching a file in the chromiumos checkout.
	// This may make use of globstar (i.e. **) notation to match against many
	// subdirectories at once. The pattern will be matched against a full
	// relative path in the chromiumos checkout.
	// e.g.
	// chromite/config/** to match anything under chromite/config/
	// **/OWNERS to match any OWNERS file
	// **/*.md to match any .md file
	// src/somefile.java to match a specific file
	Pattern              string   `protobuf:"bytes,1,opt,name=pattern,proto3" json:"pattern,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

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

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

var xxx_messageInfo_FilePattern proto.InternalMessageInfo

func (m *FilePattern) GetPattern() string {
	if m != nil {
		return m.Pattern
	}
	return ""
}

func init() {
	proto.RegisterType((*ProtoBytes)(nil), "testplans.ProtoBytes")
	proto.RegisterType((*FilePattern)(nil), "testplans.FilePattern")
}

func init() { proto.RegisterFile("testplans/common.proto", fileDescriptor_a516c54fffa1af30) }

var fileDescriptor_a516c54fffa1af30 = []byte{
	// 164 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2b, 0x49, 0x2d, 0x2e,
	0x29, 0xc8, 0x49, 0xcc, 0x2b, 0xd6, 0x4f, 0xce, 0xcf, 0xcd, 0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca,
	0x2f, 0xc9, 0x17, 0xe2, 0x84, 0x8b, 0x2b, 0x99, 0x73, 0x71, 0x05, 0x80, 0xc4, 0x9c, 0x2a, 0x4b,
	0x52, 0x8b, 0x85, 0x34, 0xb9, 0x04, 0x8a, 0x53, 0x8b, 0x32, 0x13, 0x73, 0x32, 0xab, 0x52, 0x53,
	0xe2, 0xc1, 0x8a, 0x25, 0x18, 0x15, 0x18, 0x35, 0x78, 0x82, 0xf8, 0x11, 0xe2, 0x60, 0xf5, 0x4a,
	0xea, 0x5c, 0xdc, 0x6e, 0x99, 0x39, 0xa9, 0x01, 0x89, 0x25, 0x25, 0xa9, 0x45, 0x79, 0x42, 0x12,
	0x5c, 0xec, 0x05, 0x10, 0x26, 0x58, 0x03, 0x67, 0x10, 0x8c, 0xeb, 0x64, 0x1a, 0x65, 0x9c, 0x9e,
	0xaf, 0x97, 0x9c, 0x51, 0x94, 0x9f, 0x9b, 0x59, 0x9a, 0xab, 0x97, 0x5f, 0x94, 0xae, 0x0f, 0xe3,
	0xe4, 0x17, 0xeb, 0x67, 0xe6, 0xa5, 0x15, 0x25, 0xea, 0x83, 0x6d, 0xd2, 0x4f, 0xcf, 0xd7, 0x87,
	0x3b, 0x2c, 0x89, 0x0d, 0x2c, 0x66, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x7b, 0xac, 0x82, 0xc9,
	0xc4, 0x00, 0x00, 0x00,
}
