// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.33.0
// 	protoc        v6.32.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
	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
}
