// Copyright 2018 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.

// Code generated by generate-types. DO NOT EDIT.

package prototype

import (
	"fmt"
	"sync"

	"github.com/golang/protobuf/v2/internal/pragma"
	"github.com/golang/protobuf/v2/internal/typefmt"
	"github.com/golang/protobuf/v2/reflect/protoreflect"
)

type messagesMeta struct {
	once     sync.Once
	typs     []Message
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Message
}
type messages messagesMeta

func (p *messagesMeta) lazyInit(parent protoreflect.Descriptor, ts []Message) *messages {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]messageMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.messageMeta != nil {
				panic("already initialized")
			}
			t.messageMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*messages)(p)
}
func (p *messages) Len() int                                 { return len(p.typs) }
func (p *messages) Get(i int) protoreflect.MessageDescriptor { return messageDesc{&p.typs[i]} }
func (p *messages) ByName(s protoreflect.Name) protoreflect.MessageDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Message, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return messageDesc{t}
}
func (p *messages) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *messages) ProtoInternal(pragma.DoNotImplement) {}

type fieldsMeta struct {
	once     sync.Once
	typs     []Field
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Field
	jsonOnce sync.Once
	byJSON   map[string]*Field
	numOnce  sync.Once
	byNum    map[protoreflect.FieldNumber]*Field
}
type fields fieldsMeta

func (p *fieldsMeta) lazyInit(parent protoreflect.Descriptor, ts []Field) *fields {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]fieldMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.fieldMeta != nil {
				panic("already initialized")
			}
			t.fieldMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*fields)(p)
}
func (p *fields) Len() int                               { return len(p.typs) }
func (p *fields) Get(i int) protoreflect.FieldDescriptor { return fieldDesc{&p.typs[i]} }
func (p *fields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Field, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return fieldDesc{t}
}
func (p *fields) ByJSONName(s string) protoreflect.FieldDescriptor {
	p.jsonOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byJSON = make(map[string]*Field, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				s := fieldDesc{t}.JSONName()
				if _, ok := p.byJSON[s]; !ok {
					p.byJSON[s] = t
				}
			}
		}
	})
	t := p.byJSON[s]
	if t == nil {
		return nil
	}
	return fieldDesc{t}
}
func (p *fields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor {
	p.numOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byNum = make(map[protoreflect.FieldNumber]*Field, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				if _, ok := p.byNum[t.Number]; !ok {
					p.byNum[t.Number] = t
				}
			}
		}
	})
	t := p.byNum[n]
	if t == nil {
		return nil
	}
	return fieldDesc{t}
}
func (p *fields) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *fields) ProtoInternal(pragma.DoNotImplement) {}

type oneofsMeta struct {
	once     sync.Once
	typs     []Oneof
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Oneof
}
type oneofs oneofsMeta

func (p *oneofsMeta) lazyInit(parent protoreflect.Descriptor, ts []Oneof) *oneofs {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]oneofMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.oneofMeta != nil {
				panic("already initialized")
			}
			t.oneofMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*oneofs)(p)
}
func (p *oneofs) Len() int                               { return len(p.typs) }
func (p *oneofs) Get(i int) protoreflect.OneofDescriptor { return oneofDesc{&p.typs[i]} }
func (p *oneofs) ByName(s protoreflect.Name) protoreflect.OneofDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Oneof, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return oneofDesc{t}
}
func (p *oneofs) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *oneofs) ProtoInternal(pragma.DoNotImplement) {}

type extensionsMeta struct {
	once     sync.Once
	typs     []Extension
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Extension
}
type extensions extensionsMeta

func (p *extensionsMeta) lazyInit(parent protoreflect.Descriptor, ts []Extension) *extensions {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]extensionMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.extensionMeta != nil {
				panic("already initialized")
			}
			t.extensionMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*extensions)(p)
}
func (p *extensions) Len() int                                   { return len(p.typs) }
func (p *extensions) Get(i int) protoreflect.ExtensionDescriptor { return extensionDesc{&p.typs[i]} }
func (p *extensions) ByName(s protoreflect.Name) protoreflect.ExtensionDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Extension, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return extensionDesc{t}
}
func (p *extensions) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *extensions) ProtoInternal(pragma.DoNotImplement) {}

type enumsMeta struct {
	once     sync.Once
	typs     []Enum
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Enum
}
type enums enumsMeta

func (p *enumsMeta) lazyInit(parent protoreflect.Descriptor, ts []Enum) *enums {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]enumMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.enumMeta != nil {
				panic("already initialized")
			}
			t.enumMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*enums)(p)
}
func (p *enums) Len() int                              { return len(p.typs) }
func (p *enums) Get(i int) protoreflect.EnumDescriptor { return enumDesc{&p.typs[i]} }
func (p *enums) ByName(s protoreflect.Name) protoreflect.EnumDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Enum, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return enumDesc{t}
}
func (p *enums) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *enums) ProtoInternal(pragma.DoNotImplement) {}

type enumValuesMeta struct {
	once     sync.Once
	typs     []EnumValue
	nameOnce sync.Once
	byName   map[protoreflect.Name]*EnumValue
	numOnce  sync.Once
	byNum    map[protoreflect.EnumNumber]*EnumValue
}
type enumValues enumValuesMeta

func (p *enumValuesMeta) lazyInit(parent protoreflect.Descriptor, ts []EnumValue) *enumValues {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]enumValueMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.enumValueMeta != nil {
				panic("already initialized")
			}
			t.enumValueMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, true)
		}
		p.typs = ts
	})
	return (*enumValues)(p)
}
func (p *enumValues) Len() int                                   { return len(p.typs) }
func (p *enumValues) Get(i int) protoreflect.EnumValueDescriptor { return enumValueDesc{&p.typs[i]} }
func (p *enumValues) ByName(s protoreflect.Name) protoreflect.EnumValueDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*EnumValue, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return enumValueDesc{t}
}
func (p *enumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor {
	p.numOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byNum = make(map[protoreflect.EnumNumber]*EnumValue, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				if _, ok := p.byNum[t.Number]; !ok {
					p.byNum[t.Number] = t
				}
			}
		}
	})
	t := p.byNum[n]
	if t == nil {
		return nil
	}
	return enumValueDesc{t}
}
func (p *enumValues) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *enumValues) ProtoInternal(pragma.DoNotImplement) {}

type servicesMeta struct {
	once     sync.Once
	typs     []Service
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Service
}
type services servicesMeta

func (p *servicesMeta) lazyInit(parent protoreflect.Descriptor, ts []Service) *services {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]serviceMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.serviceMeta != nil {
				panic("already initialized")
			}
			t.serviceMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*services)(p)
}
func (p *services) Len() int                                 { return len(p.typs) }
func (p *services) Get(i int) protoreflect.ServiceDescriptor { return serviceDesc{&p.typs[i]} }
func (p *services) ByName(s protoreflect.Name) protoreflect.ServiceDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Service, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return serviceDesc{t}
}
func (p *services) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *services) ProtoInternal(pragma.DoNotImplement) {}

type methodsMeta struct {
	once     sync.Once
	typs     []Method
	nameOnce sync.Once
	byName   map[protoreflect.Name]*Method
}
type methods methodsMeta

func (p *methodsMeta) lazyInit(parent protoreflect.Descriptor, ts []Method) *methods {
	p.once.Do(func() {
		nb := getNameBuilder()
		defer putNameBuilder(nb)
		metas := make([]methodMeta, len(ts))
		for i := range ts {
			t := &ts[i]
			if t.methodMeta != nil {
				panic("already initialized")
			}
			t.methodMeta = &metas[i]
			t.inheritedMeta.init(nb, parent, i, t.Name, false)
		}
		p.typs = ts
	})
	return (*methods)(p)
}
func (p *methods) Len() int                                { return len(p.typs) }
func (p *methods) Get(i int) protoreflect.MethodDescriptor { return methodDesc{&p.typs[i]} }
func (p *methods) ByName(s protoreflect.Name) protoreflect.MethodDescriptor {
	p.nameOnce.Do(func() {
		if len(p.typs) > 0 {
			p.byName = make(map[protoreflect.Name]*Method, len(p.typs))
			for i := range p.typs {
				t := &p.typs[i]
				p.byName[t.Name] = t
			}
		}
	})
	t := p.byName[s]
	if t == nil {
		return nil
	}
	return methodDesc{t}
}
func (p *methods) Format(s fmt.State, r rune)          { typefmt.FormatList(s, r, p) }
func (p *methods) ProtoInternal(pragma.DoNotImplement) {}
