// 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"

	"google.golang.org/proto/internal/pragma"
	"google.golang.org/proto/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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { 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 := nameBuilderPool.Get().(*nameBuilder)
		defer nameBuilderPool.Put(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)          { formatList(s, r, p) }
func (p *methods) ProtoInternal(pragma.DoNotImplement) {}
