func (flb *FieldBuilder) IsExtension() bool {
	return flb.localExtendee != nil || flb.foreignExtendee != nil
}
IsExtension returns true if this is an extension field.
package builder
import (
	"fmt"
	"strings"
	"unicode"
	"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 FieldBuilder struct {
	baseBuilder
	number int32
	msgType   *MessageBuilder
	fieldType *FieldType
	Options        *dpb.FieldOptions
	Label          dpb.FieldDescriptorProto_Label
	Proto3Optional bool
	Default        string
	JsonName       string
	foreignExtendee *desc.MessageDescriptor
	localExtendee   *MessageBuilder
}
func NewField(name string, typ *FieldType) *FieldBuilder {
	flb := &FieldBuilder{
		baseBuilder: baseBuilderWithName(name),
		fieldType:   typ,
	}
	return flb
}
func NewMapField(name string, keyTyp, valTyp *FieldType) *FieldBuilder {
	switch keyTyp.fieldType {
	case dpb.FieldDescriptorProto_TYPE_BOOL,
		dpb.FieldDescriptorProto_TYPE_STRING,
		dpb.FieldDescriptorProto_TYPE_INT32, dpb.FieldDescriptorProto_TYPE_INT64,
		dpb.FieldDescriptorProto_TYPE_SINT32, dpb.FieldDescriptorProto_TYPE_SINT64,
		dpb.FieldDescriptorProto_TYPE_UINT32, dpb.FieldDescriptorProto_TYPE_UINT64,
		dpb.FieldDescriptorProto_TYPE_FIXED32, dpb.FieldDescriptorProto_TYPE_FIXED64,
		dpb.FieldDescriptorProto_TYPE_SFIXED32, dpb.FieldDescriptorProto_TYPE_SFIXED64:
	default:
		panic(fmt.Sprintf("Map types cannot have keys of type %v", keyTyp.fieldType))
	}
	if valTyp.fieldType == dpb.FieldDescriptorProto_TYPE_GROUP {
		panic(fmt.Sprintf("Map types cannot have values of type %v", valTyp.fieldType))
	}
	entryMsg := NewMessage(entryTypeName(name))
	keyFlb := NewField("key", keyTyp)
	keyFlb.number = 1
	valFlb := NewField("value", valTyp)
	valFlb.number = 2
	entryMsg.AddField(keyFlb)
	entryMsg.AddField(valFlb)
	entryMsg.Options = &dpb.MessageOptions{MapEntry: proto.Bool(true)}
	flb := NewField(name, FieldTypeMessage(entryMsg)).
		SetLabel(dpb.FieldDescriptorProto_LABEL_REPEATED)
	flb.msgType = entryMsg
	entryMsg.setParent(flb)
	return flb
}
func NewGroupField(mb *MessageBuilder) *FieldBuilder {
	if !unicode.IsUpper(rune(mb.name[0])) {
		panic(fmt.Sprintf("group name %s must start with a capital letter", mb.name))
	}
	Unlink(mb)
	ft := &FieldType{
		fieldType:    dpb.FieldDescriptorProto_TYPE_GROUP,
		localMsgType: mb,
	}
	fieldName := strings.ToLower(mb.GetName())
	flb := NewField(fieldName, ft)
	flb.msgType = mb
	mb.setParent(flb)
	return flb
}
func NewExtension(name string, tag int32, typ *FieldType, extendee *MessageBuilder) *FieldBuilder {
	if extendee == nil {
		panic("extendee cannot be nil")
	}
	flb := NewField(name, typ).SetNumber(tag)
	flb.localExtendee = extendee
	return flb
}
func NewExtensionImported(name string, tag int32, typ *FieldType, extendee *desc.MessageDescriptor) *FieldBuilder {
	if extendee == nil {
		panic("extendee cannot be nil")
	}
	flb := NewField(name, typ).SetNumber(tag)
	flb.foreignExtendee = extendee
	return flb
}
func FromField(fld *desc.FieldDescriptor) (*FieldBuilder, error) {
	if fb, err := FromFile(fld.GetFile()); err != nil {
		return nil, err
	} else if flb, ok := fb.findFullyQualifiedElement(fld.GetFullyQualifiedName()).(*FieldBuilder); ok {
		return flb, nil
	} else {
		return nil, fmt.Errorf("could not find field %s after converting file %q to builder", fld.GetFullyQualifiedName(), fld.GetFile().GetName())
	}
}
func fromField(fld *desc.FieldDescriptor) (*FieldBuilder, error) {
	ft := fieldTypeFromDescriptor(fld)
	flb := NewField(fld.GetName(), ft)
	flb.Options = fld.GetFieldOptions()
	flb.Label = fld.GetLabel()
	flb.Proto3Optional = fld.IsProto3Optional()
	flb.Default = fld.AsFieldDescriptorProto().GetDefaultValue()
	flb.JsonName = fld.GetJSONName()
	setComments(&flb.comments, fld.GetSourceInfo())
	if fld.IsExtension() {
		flb.foreignExtendee = fld.GetOwner()
	}
	if err := flb.TrySetNumber(fld.GetNumber()); err != nil {
		return nil, err
	}
	return flb, nil
}
func (flb *FieldBuilder) SetName(newName string) *FieldBuilder {
	if err := flb.TrySetName(newName); err != nil {
		panic(err)
	}
	return flb
}
func (flb *FieldBuilder) TrySetName(newName string) error {
	var oldMsgName string
	if flb.msgType != nil {
		if flb.fieldType.fieldType == dpb.FieldDescriptorProto_TYPE_GROUP {
			return fmt.Errorf("cannot change name of group field %s; change name of group instead", GetFullyQualifiedName(flb))
		} else {
			oldMsgName = flb.msgType.name
			msgName := entryTypeName(newName)
			if err := flb.msgType.trySetNameInternal(msgName); err != nil {
				return err
			}
		}
	}
	if err := flb.baseBuilder.setName(flb, newName); err != nil {
		if flb.msgType != nil && flb.fieldType.fieldType != dpb.FieldDescriptorProto_TYPE_GROUP {
			flb.msgType.setNameInternal(oldMsgName)
		}
		return err
	}
	return nil
}
func (flb *FieldBuilder) trySetNameInternal(newName string) error {
	return flb.baseBuilder.setName(flb, newName)
}
func (flb *FieldBuilder) setNameInternal(newName string) {
	if err := flb.trySetNameInternal(newName); err != nil {
		panic(err)
	}
}
func (flb *FieldBuilder) SetComments(c Comments) *FieldBuilder {
	flb.comments = c
	return flb
}
func (flb *FieldBuilder) setParent(newParent Builder) {
	flb.baseBuilder.setParent(newParent)
}
func (flb *FieldBuilder) GetChildren() []Builder {
	if flb.msgType != nil {
		return []Builder{flb.msgType}
	}
	return nil
}
func (flb *FieldBuilder) findChild(name string) Builder {
	if flb.msgType != nil && flb.msgType.name == name {
		return flb.msgType
	}
	return nil
}
func (flb *FieldBuilder) removeChild(b Builder) {
	if mb, ok := b.(*MessageBuilder); ok && mb == flb.msgType {
		flb.msgType = nil
		if p, ok := flb.parent.(*MessageBuilder); ok {
			delete(p.symbols, mb.GetName())
		}
	}
}
func (flb *FieldBuilder) renamedChild(b Builder, oldName string) error {
	if flb.msgType != nil {
		var oldFieldName string
		if flb.fieldType.fieldType == dpb.FieldDescriptorProto_TYPE_GROUP {
			if !unicode.IsUpper(rune(b.GetName()[0])) {
				return fmt.Errorf("group name %s must start with capital letter", b.GetName())
			}
			oldFieldName = flb.name
			fieldName := strings.ToLower(b.GetName())
			if err := flb.trySetNameInternal(fieldName); err != nil {
				return err
			}
		}
		if p, ok := flb.parent.(*MessageBuilder); ok {
			if err := p.addSymbol(b); err != nil {
				if flb.fieldType.fieldType == dpb.FieldDescriptorProto_TYPE_GROUP {
					flb.setNameInternal(oldFieldName)
				}
				return err
			}
		}
	}
	return nil
}
func (flb *FieldBuilder) GetNumber() int32 {
	return flb.number
}
func (flb *FieldBuilder) SetNumber(tag int32) *FieldBuilder {
	if err := flb.TrySetNumber(tag); err != nil {
		panic(err)
	}
	return flb
}
func (flb *FieldBuilder) TrySetNumber(tag int32) error {
	if tag == flb.number {
		return nil  
	}
	if tag < 0 {
		return fmt.Errorf("cannot set tag number for field %s to negative value %d", GetFullyQualifiedName(flb), tag)
	}
	if tag == 0 && flb.IsExtension() {
		return fmt.Errorf("cannot set tag number for extension %s; only regular fields can be auto-assigned", GetFullyQualifiedName(flb))
	}
	if tag >= internal.SpecialReservedStart && tag <= internal.SpecialReservedEnd {
		return fmt.Errorf("tag for field %s cannot be in special reserved range %d-%d", GetFullyQualifiedName(flb), internal.SpecialReservedStart, internal.SpecialReservedEnd)
	}
	if tag > internal.MaxTag {
		return fmt.Errorf("tag for field %s cannot be above max %d", GetFullyQualifiedName(flb), internal.MaxTag)
	}
	oldTag := flb.number
	flb.number = tag
	if flb.IsExtension() {
		return nil
	}
	switch p := flb.parent.(type) {
	case *OneOfBuilder:
		m := p.parent()
		if m != nil {
			if err := m.addTag(flb); err != nil {
				flb.number = oldTag
				return err
			}
			delete(m.fieldTags, oldTag)
		}
	case *MessageBuilder:
		if err := p.addTag(flb); err != nil {
			flb.number = oldTag
			return err
		}
		delete(p.fieldTags, oldTag)
	}
	return nil
}
func (flb *FieldBuilder) SetOptions(options *dpb.FieldOptions) *FieldBuilder {
	flb.Options = options
	return flb
}
func (flb *FieldBuilder) SetLabel(lbl dpb.FieldDescriptorProto_Label) *FieldBuilder {
	flb.Label = lbl
	return flb
}
func (flb *FieldBuilder) SetProto3Optional(p3o bool) *FieldBuilder {
	flb.Proto3Optional = p3o
	return flb
}
func (flb *FieldBuilder) SetRepeated() *FieldBuilder {
	return flb.SetLabel(dpb.FieldDescriptorProto_LABEL_REPEATED)
}
func (flb *FieldBuilder) SetRequired() *FieldBuilder {
	return flb.SetLabel(dpb.FieldDescriptorProto_LABEL_REQUIRED)
}
func (flb *FieldBuilder) SetOptional() *FieldBuilder {
	return flb.SetLabel(dpb.FieldDescriptorProto_LABEL_OPTIONAL)
}
func (flb *FieldBuilder) IsRepeated() bool {
	return flb.Label == dpb.FieldDescriptorProto_LABEL_REPEATED
}
func (flb *FieldBuilder) IsRequired() bool {
	return flb.Label == dpb.FieldDescriptorProto_LABEL_REQUIRED
}
func (flb *FieldBuilder) IsOptional() bool {
	return flb.Label == dpb.FieldDescriptorProto_LABEL_OPTIONAL
}
func (flb *FieldBuilder) IsMap() bool {
	return flb.IsRepeated() &&
		flb.msgType != nil &&
		flb.fieldType.fieldType != dpb.FieldDescriptorProto_TYPE_GROUP &&
		flb.msgType.Options != nil &&
		flb.msgType.Options.GetMapEntry()
}
func (flb *FieldBuilder) GetType() *FieldType {
	return flb.fieldType
}
func (flb *FieldBuilder) SetType(ft *FieldType) *FieldBuilder {
	flb.fieldType = ft
	if flb.msgType != nil && flb.msgType != ft.localMsgType {
		Unlink(flb.msgType)
	}
	return flb
}
func (flb *FieldBuilder) SetDefaultValue(defValue string) *FieldBuilder {
	flb.Default = defValue
	return flb
}
func (flb *FieldBuilder) SetJsonName(jsonName string) *FieldBuilder {
	flb.JsonName = jsonName
	return flb
}