// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.33.0
// 	protoc        v5.28.0--rc1
// 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
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Records []*Output_Record `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"`
}

func (x *Output) Reset() {
	*x = Output{}
	if protoimpl.UnsafeEnabled {
		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 protoimpl.UnsafeEnabled && 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
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Strings []string `protobuf:"bytes,1,rep,name=strings,proto3" json:"strings,omitempty"`
}

func (x *RepeatedString) Reset() {
	*x = RepeatedString{}
	if protoimpl.UnsafeEnabled {
		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 protoimpl.UnsafeEnabled && 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
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Fields []*Output_Record_Field `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty"`
}

func (x *Output_Record) Reset() {
	*x = Output_Record{}
	if protoimpl.UnsafeEnabled {
		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 protoimpl.UnsafeEnabled && 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
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	// Types that are assignable 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"`
}

func (x *Output_Record_Field) Reset() {
	*x = Output_Record_Field{}
	if protoimpl.UnsafeEnabled {
		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 protoimpl.UnsafeEnabled && 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 (m *Output_Record_Field) GetValue() isOutput_Record_Field_Value {
	if m != nil {
		return m.Value
	}
	return nil
}

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

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

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

func (x *Output_Record_Field) GetList() *RepeatedString {
	if x, ok := x.GetValue().(*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 = []interface{}{
	(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
	}
	if !protoimpl.UnsafeEnabled {
		file_api_proto_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Output); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_api_proto_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*RepeatedString); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_api_proto_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Output_Record); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
		file_api_proto_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*Output_Record_Field); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	file_api_proto_api_proto_msgTypes[3].OneofWrappers = []interface{}{
		(*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
}
