// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.36.3
// 	protoc        v6.33.0
// source: api_proto/api.proto

package api_proto

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type Output_Record_Field_ERROR int32

const (
	Output_Record_Field_UNKNOWN           Output_Record_Field_ERROR = 0
	Output_Record_Field_MISSING           Output_Record_Field_ERROR = 1
	Output_Record_Field_MISSING_LIST_ITEM Output_Record_Field_ERROR = 2
)

// Enum value maps for Output_Record_Field_ERROR.
var (
	Output_Record_Field_ERROR_name = map[int32]string{
		0: "UNKNOWN",
		1: "MISSING",
		2: "MISSING_LIST_ITEM",
	}
	Output_Record_Field_ERROR_value = map[string]int32{
		"UNKNOWN":           0,
		"MISSING":           1,
		"MISSING_LIST_ITEM": 2,
	}
)

func (x Output_Record_Field_ERROR) Enum() *Output_Record_Field_ERROR {
	p := new(Output_Record_Field_ERROR)
	*p = x
	return p
}

func (x Output_Record_Field_ERROR) String() string {
	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}

func (Output_Record_Field_ERROR) Descriptor() protoreflect.EnumDescriptor {
	return file_api_proto_api_proto_enumTypes[0].Descriptor()
}

func (Output_Record_Field_ERROR) Type() protoreflect.EnumType {
	return &file_api_proto_api_proto_enumTypes[0]
}

func (x Output_Record_Field_ERROR) Number() protoreflect.EnumNumber {
	return protoreflect.EnumNumber(x)
}

// Deprecated: Use Output_Record_Field_ERROR.Descriptor instead.
func (Output_Record_Field_ERROR) EnumDescriptor() ([]byte, []int) {
	return file_api_proto_api_proto_rawDescGZIP(), []int{0, 0, 0, 0}
}

type Output struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Records       []*Output_Record       `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *Output) Reset() {
	*x = Output{}
	mi := &file_api_proto_api_proto_msgTypes[0]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *Output) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Output) ProtoMessage() {}

func (x *Output) ProtoReflect() protoreflect.Message {
	mi := &file_api_proto_api_proto_msgTypes[0]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Output.ProtoReflect.Descriptor instead.
func (*Output) Descriptor() ([]byte, []int) {
	return file_api_proto_api_proto_rawDescGZIP(), []int{0}
}

func (x *Output) GetRecords() []*Output_Record {
	if x != nil {
		return x.Records
	}
	return nil
}

type RepeatedString struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Strings       []string               `protobuf:"bytes,1,rep,name=strings,proto3" json:"strings,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *RepeatedString) Reset() {
	*x = RepeatedString{}
	mi := &file_api_proto_api_proto_msgTypes[1]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *RepeatedString) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*RepeatedString) ProtoMessage() {}

func (x *RepeatedString) ProtoReflect() protoreflect.Message {
	mi := &file_api_proto_api_proto_msgTypes[1]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use RepeatedString.ProtoReflect.Descriptor instead.
func (*RepeatedString) Descriptor() ([]byte, []int) {
	return file_api_proto_api_proto_rawDescGZIP(), []int{1}
}

func (x *RepeatedString) GetStrings() []string {
	if x != nil {
		return x.Strings
	}
	return nil
}

type Output_Record struct {
	state         protoimpl.MessageState `protogen:"open.v1"`
	Fields        []*Output_Record_Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"`
	unknownFields protoimpl.UnknownFields
	sizeCache     protoimpl.SizeCache
}

func (x *Output_Record) Reset() {
	*x = Output_Record{}
	mi := &file_api_proto_api_proto_msgTypes[2]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *Output_Record) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Output_Record) ProtoMessage() {}

func (x *Output_Record) ProtoReflect() protoreflect.Message {
	mi := &file_api_proto_api_proto_msgTypes[2]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Output_Record.ProtoReflect.Descriptor instead.
func (*Output_Record) Descriptor() ([]byte, []int) {
	return file_api_proto_api_proto_rawDescGZIP(), []int{0, 0}
}

func (x *Output_Record) GetFields() []*Output_Record_Field {
	if x != nil {
		return x.Fields
	}
	return nil
}

type Output_Record_Field struct {
	state protoimpl.MessageState `protogen:"open.v1"`
	// Types that are valid to be assigned to Value:
	//
	//	*Output_Record_Field_Text
	//	*Output_Record_Field_Number
	//	*Output_Record_Field_Error
	//	*Output_Record_Field_List
	Value             isOutput_Record_Field_Value `protobuf_oneof:"value"`
	QuoteWhenPrinting bool                        `protobuf:"varint,7,opt,name=quote_when_printing,json=quoteWhenPrinting,proto3" json:"quote_when_printing,omitempty"`
	unknownFields     protoimpl.UnknownFields
	sizeCache         protoimpl.SizeCache
}

func (x *Output_Record_Field) Reset() {
	*x = Output_Record_Field{}
	mi := &file_api_proto_api_proto_msgTypes[3]
	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
	ms.StoreMessageInfo(mi)
}

func (x *Output_Record_Field) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*Output_Record_Field) ProtoMessage() {}

func (x *Output_Record_Field) ProtoReflect() protoreflect.Message {
	mi := &file_api_proto_api_proto_msgTypes[3]
	if x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use Output_Record_Field.ProtoReflect.Descriptor instead.
func (*Output_Record_Field) Descriptor() ([]byte, []int) {
	return file_api_proto_api_proto_rawDescGZIP(), []int{0, 0, 0}
}

func (x *Output_Record_Field) GetValue() isOutput_Record_Field_Value {
	if x != nil {
		return x.Value
	}
	return nil
}

func (x *Output_Record_Field) GetText() string {
	if x != nil {
		if x, ok := x.Value.(*Output_Record_Field_Text); ok {
			return x.Text
		}
	}
	return ""
}

func (x *Output_Record_Field) GetNumber() int32 {
	if x != nil {
		if x, ok := x.Value.(*Output_Record_Field_Number); ok {
			return x.Number
		}
	}
	return 0
}

func (x *Output_Record_Field) GetError() Output_Record_Field_ERROR {
	if x != nil {
		if x, ok := x.Value.(*Output_Record_Field_Error); ok {
			return x.Error
		}
	}
	return Output_Record_Field_UNKNOWN
}

func (x *Output_Record_Field) GetList() *RepeatedString {
	if x != nil {
		if x, ok := x.Value.(*Output_Record_Field_List); ok {
			return x.List
		}
	}
	return nil
}

func (x *Output_Record_Field) GetQuoteWhenPrinting() bool {
	if x != nil {
		return x.QuoteWhenPrinting
	}
	return false
}

type isOutput_Record_Field_Value interface {
	isOutput_Record_Field_Value()
}

type Output_Record_Field_Text struct {
	Text string `protobuf:"bytes,1,opt,name=text,proto3,oneof"`
}

type Output_Record_Field_Number struct {
	Number int32 `protobuf:"varint,2,opt,name=number,proto3,oneof"`
}

type Output_Record_Field_Error struct {
	Error Output_Record_Field_ERROR `protobuf:"varint,3,opt,name=error,proto3,enum=devtools.buildozer.Output_Record_Field_ERROR,oneof"`
}

type Output_Record_Field_List struct {
	List *RepeatedString `protobuf:"bytes,5,opt,name=list,proto3,oneof"`
}

func (*Output_Record_Field_Text) isOutput_Record_Field_Value() {}

func (*Output_Record_Field_Number) isOutput_Record_Field_Value() {}

func (*Output_Record_Field_Error) isOutput_Record_Field_Value() {}

func (*Output_Record_Field_List) isOutput_Record_Field_Value() {}

var File_api_proto_api_proto protoreflect.FileDescriptor

var file_api_proto_api_proto_rawDesc = []byte{
	0x0a, 0x13, 0x61, 0x70, 0x69, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2e,
	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x12, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e,
	0x62, 0x75, 0x69, 0x6c, 0x64, 0x6f, 0x7a, 0x65, 0x72, 0x22, 0xbf, 0x03, 0x0a, 0x06, 0x4f, 0x75,
	0x74, 0x70, 0x75, 0x74, 0x12, 0x3b, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x18,
	0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73,
	0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6f, 0x7a, 0x65, 0x72, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75,
	0x74, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64,
	0x73, 0x1a, 0xf7, 0x02, 0x0a, 0x06, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x3f, 0x0a, 0x06,
	0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x64,
	0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6f, 0x7a, 0x65,
	0x72, 0x2e, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e,
	0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x1a, 0xab, 0x02,
	0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18,
	0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x18, 0x0a,
	0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52,
	0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x45, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72,
	0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2d, 0x2e, 0x64, 0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c,
	0x73, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6f, 0x7a, 0x65, 0x72, 0x2e, 0x4f, 0x75, 0x74, 0x70,
	0x75, 0x74, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x2e,
	0x45, 0x52, 0x52, 0x4f, 0x52, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x38,
	0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x64,
	0x65, 0x76, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x6f, 0x7a, 0x65,
	0x72, 0x2e, 0x52, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
	0x48, 0x00, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x13, 0x71, 0x75, 0x6f, 0x74,
	0x65, 0x5f, 0x77, 0x68, 0x65, 0x6e, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x18,
	0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x57, 0x68, 0x65, 0x6e,
	0x50, 0x72, 0x69, 0x6e, 0x74, 0x69, 0x6e, 0x67, 0x22, 0x38, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f,
	0x52, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b,
	0x0a, 0x07, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4d,
	0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x5f, 0x49, 0x54, 0x45, 0x4d,
	0x10, 0x02, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x2a, 0x0a, 0x0e, 0x52,
	0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a,
	0x07, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07,
	0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x42, 0x0b, 0x5a, 0x09, 0x61, 0x70, 0x69, 0x5f, 0x70,
	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_api_proto_api_proto_rawDescOnce sync.Once
	file_api_proto_api_proto_rawDescData = file_api_proto_api_proto_rawDesc
)

func file_api_proto_api_proto_rawDescGZIP() []byte {
	file_api_proto_api_proto_rawDescOnce.Do(func() {
		file_api_proto_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_api_proto_api_proto_rawDescData)
	})
	return file_api_proto_api_proto_rawDescData
}

var file_api_proto_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_api_proto_api_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_api_proto_api_proto_goTypes = []any{
	(Output_Record_Field_ERROR)(0), // 0: devtools.buildozer.Output.Record.Field.ERROR
	(*Output)(nil),                 // 1: devtools.buildozer.Output
	(*RepeatedString)(nil),         // 2: devtools.buildozer.RepeatedString
	(*Output_Record)(nil),          // 3: devtools.buildozer.Output.Record
	(*Output_Record_Field)(nil),    // 4: devtools.buildozer.Output.Record.Field
}
var file_api_proto_api_proto_depIdxs = []int32{
	3, // 0: devtools.buildozer.Output.records:type_name -> devtools.buildozer.Output.Record
	4, // 1: devtools.buildozer.Output.Record.fields:type_name -> devtools.buildozer.Output.Record.Field
	0, // 2: devtools.buildozer.Output.Record.Field.error:type_name -> devtools.buildozer.Output.Record.Field.ERROR
	2, // 3: devtools.buildozer.Output.Record.Field.list:type_name -> devtools.buildozer.RepeatedString
	4, // [4:4] is the sub-list for method output_type
	4, // [4:4] is the sub-list for method input_type
	4, // [4:4] is the sub-list for extension type_name
	4, // [4:4] is the sub-list for extension extendee
	0, // [0:4] is the sub-list for field type_name
}

func init() { file_api_proto_api_proto_init() }
func file_api_proto_api_proto_init() {
	if File_api_proto_api_proto != nil {
		return
	}
	file_api_proto_api_proto_msgTypes[3].OneofWrappers = []any{
		(*Output_Record_Field_Text)(nil),
		(*Output_Record_Field_Number)(nil),
		(*Output_Record_Field_Error)(nil),
		(*Output_Record_Field_List)(nil),
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_api_proto_api_proto_rawDesc,
			NumEnums:      1,
			NumMessages:   4,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_api_proto_api_proto_goTypes,
		DependencyIndexes: file_api_proto_api_proto_depIdxs,
		EnumInfos:         file_api_proto_api_proto_enumTypes,
		MessageInfos:      file_api_proto_api_proto_msgTypes,
	}.Build()
	File_api_proto_api_proto = out.File
	file_api_proto_api_proto_rawDesc = nil
	file_api_proto_api_proto_goTypes = nil
	file_api_proto_api_proto_depIdxs = nil
}
