// 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 := 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)          { 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)          { 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)          { 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)          { 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)          { 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)          { 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)          { 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)          { formatList(s, r, p) }
func (p *methods) ProtoInternal(pragma.DoNotImplement) {}
