// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package filedesc

import (
	

	
	
	
	
)

// fileRaw is a data struct used when initializing a file descriptor from
// a raw FileDescriptorProto.
type fileRaw struct {
	builder       Builder
	allEnums      []Enum
	allMessages   []Message
	allExtensions []Extension
	allServices   []Service
}

func ( Builder) *File {
	 := &File{fileRaw: fileRaw{builder: }}
	.initDecls(.NumEnums, .NumMessages, .NumExtensions, .NumServices)
	.unmarshalSeed(.RawDescriptor)

	// Extended message targets are eagerly resolved since registration
	// needs this information at program init time.
	for  := range .allExtensions {
		 := &.allExtensions[]
		.L1.Extendee = .resolveMessageDependency(.L1.Extendee, listExtTargets, int32())
	}

	.checkDecls()
	return 
}

// initDecls pre-allocates slices for the exact number of enums, messages
// (including map entries), extensions, and services declared in the proto file.
// This is done to avoid regrowing the slice, which would change the address
// for any previously seen declaration.
//
// The alloc methods "allocates" slices by pulling from the capacity.
func ( *File) (, , ,  int32) {
	.allEnums = make([]Enum, 0, )
	.allMessages = make([]Message, 0, )
	.allExtensions = make([]Extension, 0, )
	.allServices = make([]Service, 0, )
}

func ( *File) ( int) []Enum {
	 := len(.allEnums)
	 := .allEnums[ : +]
	.allEnums = .allEnums[:+]
	return 
}
func ( *File) ( int) []Message {
	 := len(.allMessages)
	 := .allMessages[ : +]
	.allMessages = .allMessages[:+]
	return 
}
func ( *File) ( int) []Extension {
	 := len(.allExtensions)
	 := .allExtensions[ : +]
	.allExtensions = .allExtensions[:+]
	return 
}
func ( *File) ( int) []Service {
	 := len(.allServices)
	 := .allServices[ : +]
	.allServices = .allServices[:+]
	return 
}

// checkDecls performs a sanity check that the expected number of expected
// declarations matches the number that were found in the descriptor proto.
func ( *File) () {
	switch {
	case len(.allEnums) != cap(.allEnums):
	case len(.allMessages) != cap(.allMessages):
	case len(.allExtensions) != cap(.allExtensions):
	case len(.allServices) != cap(.allServices):
	default:
		return
	}
	panic("mismatching cardinality")
}

func ( *File) ( []byte) {
	 := getBuilder()
	defer putBuilder()

	var  protoreflect.FieldNumber
	var , , ,  int
	var , , ,  int
	 := 
	for len() > 0 {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.BytesType:
			,  := protowire.ConsumeBytes()
			 = [:]
			switch  {
			case genid.FileDescriptorProto_Syntax_field_number:
				switch string() {
				case "proto2":
					.L1.Syntax = protoreflect.Proto2
				case "proto3":
					.L1.Syntax = protoreflect.Proto3
				default:
					panic("invalid syntax")
				}
			case genid.FileDescriptorProto_Name_field_number:
				.L1.Path = .MakeString()
			case genid.FileDescriptorProto_Package_field_number:
				.L1.Package = protoreflect.FullName(.MakeString())
			case genid.FileDescriptorProto_EnumType_field_number:
				if  != genid.FileDescriptorProto_EnumType_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			case genid.FileDescriptorProto_MessageType_field_number:
				if  != genid.FileDescriptorProto_MessageType_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			case genid.FileDescriptorProto_Extension_field_number:
				if  != genid.FileDescriptorProto_Extension_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			case genid.FileDescriptorProto_Service_field_number:
				if  != genid.FileDescriptorProto_Service_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			}
			 = 
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
			 = -1 // ignore known field numbers of unknown wire type
		}
	}

	// If syntax is missing, it is assumed to be proto2.
	if .L1.Syntax == 0 {
		.L1.Syntax = protoreflect.Proto2
	}

	// Must allocate all declarations before parsing each descriptor type
	// to ensure we handled all descriptors in "flattened ordering".
	if  > 0 {
		.L1.Enums.List = .allocEnums()
	}
	if  > 0 {
		.L1.Messages.List = .allocMessages()
	}
	if  > 0 {
		.L1.Extensions.List = .allocExtensions()
	}
	if  > 0 {
		.L1.Services.List = .allocServices()
	}

	if  > 0 {
		 := [:]
		for  := range .L1.Enums.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Enums.List[].unmarshalSeed(, , , , )
			 = [+:]
		}
	}
	if  > 0 {
		 := [:]
		for  := range .L1.Messages.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Messages.List[].unmarshalSeed(, , , , )
			 = [+:]
		}
	}
	if  > 0 {
		 := [:]
		for  := range .L1.Extensions.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Extensions.List[].unmarshalSeed(, , , , )
			 = [+:]
		}
	}
	if  > 0 {
		 := [:]
		for  := range .L1.Services.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Services.List[].unmarshalSeed(, , , , )
			 = [+:]
		}
	}
}

func ( *Enum) ( []byte,  *strs.Builder,  *File,  protoreflect.Descriptor,  int) {
	.L0.ParentFile = 
	.L0.Parent = 
	.L0.Index = 

	var  int
	for  := ; len() > 0; {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.BytesType:
			,  := protowire.ConsumeBytes()
			 = [:]
			switch  {
			case genid.EnumDescriptorProto_Name_field_number:
				.L0.FullName = appendFullName(, .FullName(), )
			case genid.EnumDescriptorProto_Value_field_number:
				++
			}
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
		}
	}

	// Only construct enum value descriptors for top-level enums since
	// they are needed for registration.
	if  !=  {
		return
	}
	.L1.eagerValues = true
	.L2 = new(EnumL2)
	.L2.Values.List = make([]EnumValue, )
	for  := 0; len() > 0; {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.BytesType:
			,  := protowire.ConsumeBytes()
			 = [:]
			switch  {
			case genid.EnumDescriptorProto_Value_field_number:
				.L2.Values.List[].unmarshalFull(, , , , )
				++
			}
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
		}
	}
}

func ( *Message) ( []byte,  *strs.Builder,  *File,  protoreflect.Descriptor,  int) {
	.L0.ParentFile = 
	.L0.Parent = 
	.L0.Index = 

	var  protoreflect.FieldNumber
	var , ,  int
	var , ,  int
	 := 
	for len() > 0 {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.BytesType:
			,  := protowire.ConsumeBytes()
			 = [:]
			switch  {
			case genid.DescriptorProto_Name_field_number:
				.L0.FullName = appendFullName(, .FullName(), )
			case genid.DescriptorProto_EnumType_field_number:
				if  != genid.DescriptorProto_EnumType_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			case genid.DescriptorProto_NestedType_field_number:
				if  != genid.DescriptorProto_NestedType_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			case genid.DescriptorProto_Extension_field_number:
				if  != genid.DescriptorProto_Extension_field_number {
					if  > 0 {
						panic("non-contiguous repeated field")
					}
					 = len() - len() -  - 
				}
				++
			case genid.DescriptorProto_Options_field_number:
				.unmarshalSeedOptions()
			}
			 = 
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
			 = -1 // ignore known field numbers of unknown wire type
		}
	}

	// Must allocate all declarations before parsing each descriptor type
	// to ensure we handled all descriptors in "flattened ordering".
	if  > 0 {
		.L1.Enums.List = .allocEnums()
	}
	if  > 0 {
		.L1.Messages.List = .allocMessages()
	}
	if  > 0 {
		.L1.Extensions.List = .allocExtensions()
	}

	if  > 0 {
		 := [:]
		for  := range .L1.Enums.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Enums.List[].unmarshalSeed(, , , , )
			 = [+:]
		}
	}
	if  > 0 {
		 := [:]
		for  := range .L1.Messages.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Messages.List[].(, , , , )
			 = [+:]
		}
	}
	if  > 0 {
		 := [:]
		for  := range .L1.Extensions.List {
			,  := protowire.ConsumeVarint()
			,  := protowire.ConsumeBytes([:])
			.L1.Extensions.List[].unmarshalSeed(, , , , )
			 = [+:]
		}
	}
}

func ( *Message) ( []byte) {
	for len() > 0 {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.VarintType:
			,  := protowire.ConsumeVarint()
			 = [:]
			switch  {
			case genid.MessageOptions_MapEntry_field_number:
				.L1.IsMapEntry = protowire.DecodeBool()
			case genid.MessageOptions_MessageSetWireFormat_field_number:
				.L1.IsMessageSet = protowire.DecodeBool()
			}
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
		}
	}
}

func ( *Extension) ( []byte,  *strs.Builder,  *File,  protoreflect.Descriptor,  int) {
	.L0.ParentFile = 
	.L0.Parent = 
	.L0.Index = 

	for len() > 0 {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.VarintType:
			,  := protowire.ConsumeVarint()
			 = [:]
			switch  {
			case genid.FieldDescriptorProto_Number_field_number:
				.L1.Number = protoreflect.FieldNumber()
			case genid.FieldDescriptorProto_Label_field_number:
				.L1.Cardinality = protoreflect.Cardinality()
			case genid.FieldDescriptorProto_Type_field_number:
				.L1.Kind = protoreflect.Kind()
			}
		case protowire.BytesType:
			,  := protowire.ConsumeBytes()
			 = [:]
			switch  {
			case genid.FieldDescriptorProto_Name_field_number:
				.L0.FullName = appendFullName(, .FullName(), )
			case genid.FieldDescriptorProto_Extendee_field_number:
				.L1.Extendee = PlaceholderMessage(makeFullName(, ))
			}
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
		}
	}
}

func ( *Service) ( []byte,  *strs.Builder,  *File,  protoreflect.Descriptor,  int) {
	.L0.ParentFile = 
	.L0.Parent = 
	.L0.Index = 

	for len() > 0 {
		, ,  := protowire.ConsumeTag()
		 = [:]
		switch  {
		case protowire.BytesType:
			,  := protowire.ConsumeBytes()
			 = [:]
			switch  {
			case genid.ServiceDescriptorProto_Name_field_number:
				.L0.FullName = appendFullName(, .FullName(), )
			}
		default:
			 := protowire.ConsumeFieldValue(, , )
			 = [:]
		}
	}
}

var nameBuilderPool = sync.Pool{
	New: func() interface{} { return new(strs.Builder) },
}

func () *strs.Builder {
	return nameBuilderPool.Get().(*strs.Builder)
}
func ( *strs.Builder) {
	nameBuilderPool.Put()
}

// makeFullName converts b to a protoreflect.FullName,
// where b must start with a leading dot.
func ( *strs.Builder,  []byte) protoreflect.FullName {
	if len() == 0 || [0] != '.' {
		panic("name reference must be fully qualified")
	}
	return protoreflect.FullName(.MakeString([1:]))
}

func ( *strs.Builder,  protoreflect.FullName,  []byte) protoreflect.FullName {
	return .AppendFullName(, protoreflect.Name(strs.UnsafeString()))
}