func (mb *MessageBuilder) AddExtensionRange(start, end int32) *MessageBuilder {
	return mb.AddExtensionRangeWithOptions(start, end, nil)
}
AddExtensionRange adds the given extension range to this message. The range
is inclusive of both the start and end, just like defining a range in proto
IDL source. This returns the message, for method chaining.
package builder
import (
	"fmt"
	"sort"
	"github.com/golang/protobuf/proto"
	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/jhump/protoreflect/desc"
	"github.com/jhump/protoreflect/desc/internal"
)
type MessageBuilder struct {
	baseBuilder
	Options         *dpb.MessageOptions
	ExtensionRanges []*dpb.DescriptorProto_ExtensionRange
	ReservedRanges  []*dpb.DescriptorProto_ReservedRange
	ReservedNames   []string
	fieldsAndOneOfs  []Builder
	fieldTags        map[int32]*FieldBuilder
	nestedMessages   []*MessageBuilder
	nestedExtensions []*FieldBuilder
	nestedEnums      []*EnumBuilder
	symbols          map[string]Builder
}
func NewMessage(name string) *MessageBuilder {
	return &MessageBuilder{
		baseBuilder: baseBuilderWithName(name),
		fieldTags:   map[int32]*FieldBuilder{},
		symbols:     map[string]Builder{},
	}
}
func FromMessage(md *desc.MessageDescriptor) (*MessageBuilder, error) {
	if fb, err := FromFile(md.GetFile()); err != nil {
		return nil, err
	} else if mb, ok := fb.findFullyQualifiedElement(md.GetFullyQualifiedName()).(*MessageBuilder); ok {
		return mb, nil
	} else {
		return nil, fmt.Errorf("could not find message %s after converting file %q to builder", md.GetFullyQualifiedName(), md.GetFile().GetName())
	}
}
func fromMessage(md *desc.MessageDescriptor,
	localMessages map[*desc.MessageDescriptor]*MessageBuilder,
	localEnums map[*desc.EnumDescriptor]*EnumBuilder) (*MessageBuilder, error) {
	mb := NewMessage(md.GetName())
	mb.Options = md.GetMessageOptions()
	mb.ExtensionRanges = md.AsDescriptorProto().GetExtensionRange()
	mb.ReservedRanges = md.AsDescriptorProto().GetReservedRange()
	mb.ReservedNames = md.AsDescriptorProto().GetReservedName()
	setComments(&mb.comments, md.GetSourceInfo())
	localMessages[md] = mb
	oneOfs := make([]*OneOfBuilder, len(md.GetOneOfs()))
	for i, ood := range md.GetOneOfs() {
		if ood.IsSynthetic() {
			continue
		}
		if oob, err := fromOneOf(ood); err != nil {
			return nil, err
		} else {
			oneOfs[i] = oob
		}
	}
	for _, fld := range md.GetFields() {
		if fld.GetOneOf() != nil && !fld.GetOneOf().IsSynthetic() {
			oob := oneOfs[fld.AsFieldDescriptorProto().GetOneofIndex()]
			if oob != nil {
				oneOfs[fld.AsFieldDescriptorProto().GetOneofIndex()] = nil
				if err := mb.TryAddOneOf(oob); err != nil {
					return nil, err
				}
			}
			continue
		}
		if flb, err := fromField(fld); err != nil {
			return nil, err
		} else if err := mb.TryAddField(flb); err != nil {
			return nil, err
		}
	}
	for _, nmd := range md.GetNestedMessageTypes() {
		if nmb, err := fromMessage(nmd, localMessages, localEnums); err != nil {
			return nil, err
		} else if err := mb.TryAddNestedMessage(nmb); err != nil {
			return nil, err
		}
	}
	for _, ed := range md.GetNestedEnumTypes() {
		if eb, err := fromEnum(ed, localEnums); err != nil {
			return nil, err
		} else if err := mb.TryAddNestedEnum(eb); err != nil {
			return nil, err
		}
	}
	for _, exd := range md.GetNestedExtensions() {
		if exb, err := fromField(exd); err != nil {
			return nil, err
		} else if err := mb.TryAddNestedExtension(exb); err != nil {
			return nil, err
		}
	}
	return mb, nil
}
func (mb *MessageBuilder) SetName(newName string) *MessageBuilder {
	if err := mb.TrySetName(newName); err != nil {
		panic(err)
	}
	return mb
}
func (mb *MessageBuilder) TrySetName(newName string) error {
	if p, ok := mb.parent.(*FieldBuilder); ok && p.fieldType.fieldType != dpb.FieldDescriptorProto_TYPE_GROUP {
		return fmt.Errorf("cannot change name of map entry %s; change name of field instead", GetFullyQualifiedName(mb))
	}
	return mb.trySetNameInternal(newName)
}
func (mb *MessageBuilder) trySetNameInternal(newName string) error {
	return mb.baseBuilder.setName(mb, newName)
}
func (mb *MessageBuilder) setNameInternal(newName string) {
	if err := mb.trySetNameInternal(newName); err != nil {
		panic(err)
	}
}
func (mb *MessageBuilder) SetComments(c Comments) *MessageBuilder {
	mb.comments = c
	return mb
}
func (mb *MessageBuilder) GetChildren() []Builder {
	ch := append([]Builder(nil), mb.fieldsAndOneOfs...)
	for _, nmb := range mb.nestedMessages {
		ch = append(ch, nmb)
	}
	for _, exb := range mb.nestedExtensions {
		ch = append(ch, exb)
	}
	for _, eb := range mb.nestedEnums {
		ch = append(ch, eb)
	}
	return ch
}
func (mb *MessageBuilder) findChild(name string) Builder {
	return mb.symbols[name]
}
func (mb *MessageBuilder) removeChild(b Builder) {
	if p, ok := b.GetParent().(*MessageBuilder); !ok || p != mb {
		return
	}
	switch b := b.(type) {
	case *FieldBuilder:
		if b.IsExtension() {
			mb.nestedExtensions = deleteBuilder(b.GetName(), mb.nestedExtensions).([]*FieldBuilder)
		} else {
			mb.fieldsAndOneOfs = deleteBuilder(b.GetName(), mb.fieldsAndOneOfs).([]Builder)
			delete(mb.fieldTags, b.GetNumber())
			if b.msgType != nil {
				delete(mb.symbols, b.msgType.GetName())
			}
		}
	case *OneOfBuilder:
		mb.fieldsAndOneOfs = deleteBuilder(b.GetName(), mb.fieldsAndOneOfs).([]Builder)
		for _, flb := range b.choices {
			delete(mb.symbols, flb.GetName())
			delete(mb.fieldTags, flb.GetNumber())
		}
	case *MessageBuilder:
		mb.nestedMessages = deleteBuilder(b.GetName(), mb.nestedMessages).([]*MessageBuilder)
	case *EnumBuilder:
		mb.nestedEnums = deleteBuilder(b.GetName(), mb.nestedEnums).([]*EnumBuilder)
	}
	delete(mb.symbols, b.GetName())
	b.setParent(nil)
}
func (mb *MessageBuilder) renamedChild(b Builder, oldName string) error {
	if p, ok := b.GetParent().(*MessageBuilder); !ok || p != mb {
		return nil
	}
	if err := mb.addSymbol(b); err != nil {
		return err
	}
	delete(mb.symbols, oldName)
	return nil
}
func (mb *MessageBuilder) addSymbol(b Builder) error {
	if ex, ok := mb.symbols[b.GetName()]; ok {
		return fmt.Errorf("message %s already contains element (%T) named %q", GetFullyQualifiedName(mb), ex, b.GetName())
	}
	mb.symbols[b.GetName()] = b
	return nil
}
func (mb *MessageBuilder) addTag(flb *FieldBuilder) error {
	if flb.number == 0 {
		return nil
	}
	if ex, ok := mb.fieldTags[flb.GetNumber()]; ok {
		return fmt.Errorf("message %s already contains field with tag %d: %s", GetFullyQualifiedName(mb), flb.GetNumber(), ex.GetName())
	}
	mb.fieldTags[flb.GetNumber()] = flb
	return nil
}
func (mb *MessageBuilder) registerField(flb *FieldBuilder) error {
	if err := mb.addSymbol(flb); err != nil {
		return err
	}
	if err := mb.addTag(flb); err != nil {
		delete(mb.symbols, flb.GetName())
		return err
	}
	if flb.msgType != nil {
		if err := mb.addSymbol(flb.msgType); err != nil {
			delete(mb.symbols, flb.GetName())
			delete(mb.fieldTags, flb.GetNumber())
			return err
		}
	}
	return nil
}
func (mb *MessageBuilder) GetField(name string) *FieldBuilder {
	b := mb.symbols[name]
	if flb, ok := b.(*FieldBuilder); ok && !flb.IsExtension() {
		return flb
	} else {
		return nil
	}
}
func (mb *MessageBuilder) RemoveField(name string) *MessageBuilder {
	mb.TryRemoveField(name)
	return mb
}
func (mb *MessageBuilder) TryRemoveField(name string) bool {
	b := mb.symbols[name]
	if flb, ok := b.(*FieldBuilder); ok && !flb.IsExtension() {
		flb.GetParent().removeChild(flb)
		return true
	}
	return false
}
func (mb *MessageBuilder) AddField(flb *FieldBuilder) *MessageBuilder {
	if err := mb.TryAddField(flb); err != nil {
		panic(err)
	}
	return mb
}
func (mb *MessageBuilder) TryAddField(flb *FieldBuilder) error {
	if flb.IsExtension() {
		return fmt.Errorf("field %s is an extension, not a regular field", flb.GetName())
	}
	needToUnlinkFirst := mb.isPresentButNotChild(flb)
	if needToUnlinkFirst {
		Unlink(flb)
		mb.registerField(flb)
	} else {
		if err := mb.registerField(flb); err != nil {
			return err
		}
		Unlink(flb)
	}
	flb.setParent(mb)
	mb.fieldsAndOneOfs = append(mb.fieldsAndOneOfs, flb)
	return nil
}
func (mb *MessageBuilder) GetOneOf(name string) *OneOfBuilder {
	b := mb.symbols[name]
	if oob, ok := b.(*OneOfBuilder); ok {
		return oob
	} else {
		return nil
	}
}
func (mb *MessageBuilder) RemoveOneOf(name string) *MessageBuilder {
	mb.TryRemoveOneOf(name)
	return mb
}
func (mb *MessageBuilder) TryRemoveOneOf(name string) bool {
	b := mb.symbols[name]
	if oob, ok := b.(*OneOfBuilder); ok {
		mb.removeChild(oob)
		return true
	}
	return false
}
func (mb *MessageBuilder) AddOneOf(oob *OneOfBuilder) *MessageBuilder {
	if err := mb.TryAddOneOf(oob); err != nil {
		panic(err)
	}
	return mb
}
func (mb *MessageBuilder) TryAddOneOf(oob *OneOfBuilder) error {
	if err := mb.addSymbol(oob); err != nil {
		return err
	}
	for i, flb := range oob.choices {
		if err := mb.registerField(flb); err != nil {
			delete(mb.symbols, oob.GetName())
			for i > 1 {
				i--
				flb := oob.choices[i]
				delete(mb.symbols, flb.GetName())
				delete(mb.fieldTags, flb.GetNumber())
			}
			return err
		}
	}
	Unlink(oob)
	oob.setParent(mb)
	mb.fieldsAndOneOfs = append(mb.fieldsAndOneOfs, oob)
	return nil
}
func (mb *MessageBuilder) GetNestedMessage(name string) *MessageBuilder {
	b := mb.symbols[name]
	if nmb, ok := b.(*MessageBuilder); ok {
		return nmb
	} else {
		return nil
	}
}
func (mb *MessageBuilder) RemoveNestedMessage(name string) *MessageBuilder {
	mb.TryRemoveNestedMessage(name)
	return mb
}
func (mb *MessageBuilder) TryRemoveNestedMessage(name string) bool {
	b := mb.symbols[name]
	if nmb, ok := b.(*MessageBuilder); ok {
		nmb.GetParent().removeChild(nmb)
		return true
	}
	return false
}
func (mb *MessageBuilder) AddNestedMessage(nmb *MessageBuilder) *MessageBuilder {
	if err := mb.TryAddNestedMessage(nmb); err != nil {
		panic(err)
	}
	return mb
}
func (mb *MessageBuilder) TryAddNestedMessage(nmb *MessageBuilder) error {
	needToUnlinkFirst := mb.isPresentButNotChild(nmb)
	if needToUnlinkFirst {
		Unlink(nmb)
		_ = mb.addSymbol(nmb)
	} else {
		if err := mb.addSymbol(nmb); err != nil {
			return err
		}
		Unlink(nmb)
	}
	nmb.setParent(mb)
	mb.nestedMessages = append(mb.nestedMessages, nmb)
	return nil
}
func (mb *MessageBuilder) isPresentButNotChild(b Builder) bool {
	if p, ok := b.GetParent().(*MessageBuilder); ok && p == mb {
		return false
	}
	return mb.symbols[b.GetName()] == b
}
func (mb *MessageBuilder) GetNestedExtension(name string) *FieldBuilder {
	b := mb.symbols[name]
	if exb, ok := b.(*FieldBuilder); ok && exb.IsExtension() {
		return exb
	} else {
		return nil
	}
}
func (mb *MessageBuilder) RemoveNestedExtension(name string) *MessageBuilder {
	mb.TryRemoveNestedExtension(name)
	return mb
}
func (mb *MessageBuilder) TryRemoveNestedExtension(name string) bool {
	b := mb.symbols[name]
	if exb, ok := b.(*FieldBuilder); ok && exb.IsExtension() {
		mb.removeChild(exb)
		return true
	}
	return false
}
func (mb *MessageBuilder) AddNestedExtension(exb *FieldBuilder) *MessageBuilder {
	if err := mb.TryAddNestedExtension(exb); err != nil {
		panic(err)
	}
	return mb
}
func (mb *MessageBuilder) TryAddNestedExtension(exb *FieldBuilder) error {
	if !exb.IsExtension() {
		return fmt.Errorf("field %s is not an extension", exb.GetName())
	}
	if err := mb.addSymbol(exb); err != nil {
		return err
	}
	Unlink(exb)
	exb.setParent(mb)
	mb.nestedExtensions = append(mb.nestedExtensions, exb)
	return nil
}
func (mb *MessageBuilder) GetNestedEnum(name string) *EnumBuilder {
	b := mb.symbols[name]
	if eb, ok := b.(*EnumBuilder); ok {
		return eb
	} else {
		return nil
	}
}
func (mb *MessageBuilder) RemoveNestedEnum(name string) *MessageBuilder {
	mb.TryRemoveNestedEnum(name)
	return mb
}
func (mb *MessageBuilder) TryRemoveNestedEnum(name string) bool {
	b := mb.symbols[name]
	if eb, ok := b.(*EnumBuilder); ok {
		mb.removeChild(eb)
		return true
	}
	return false
}
func (mb *MessageBuilder) AddNestedEnum(eb *EnumBuilder) *MessageBuilder {
	if err := mb.TryAddNestedEnum(eb); err != nil {
		panic(err)
	}
	return mb
}
func (mb *MessageBuilder) TryAddNestedEnum(eb *EnumBuilder) error {
	if err := mb.addSymbol(eb); err != nil {
		return err
	}
	Unlink(eb)
	eb.setParent(mb)
	mb.nestedEnums = append(mb.nestedEnums, eb)
	return nil
}
func (mb *MessageBuilder) SetOptions(options *dpb.MessageOptions) *MessageBuilder {
	mb.Options = options
	return mb
}