github.com/hoveychen/protoreflect@v1.4.7-0.20221103114119-0b4b3385ec76/desc/builder/message.go (about)

     1  package builder
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	"github.com/golang/protobuf/proto"
     8  	dpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
     9  
    10  	"github.com/hoveychen/protoreflect/desc"
    11  	"github.com/hoveychen/protoreflect/desc/internal"
    12  )
    13  
    14  // MessageBuilder is a builder used to construct a desc.MessageDescriptor. A
    15  // message builder can define nested messages, enums, and extensions in addition
    16  // to defining the message's fields.
    17  //
    18  // Note that when building a descriptor from a MessageBuilder, not all protobuf
    19  // validation rules are enforced. See the package documentation for more info.
    20  //
    21  // To create a new MessageBuilder, use NewMessage.
    22  type MessageBuilder struct {
    23  	baseBuilder
    24  
    25  	Options         *dpb.MessageOptions
    26  	ExtensionRanges []*dpb.DescriptorProto_ExtensionRange
    27  	ReservedRanges  []*dpb.DescriptorProto_ReservedRange
    28  	ReservedNames   []string
    29  
    30  	fieldsAndOneOfs  []Builder
    31  	fieldTags        map[int32]*FieldBuilder
    32  	nestedMessages   []*MessageBuilder
    33  	nestedExtensions []*FieldBuilder
    34  	nestedEnums      []*EnumBuilder
    35  	symbols          map[string]Builder
    36  }
    37  
    38  // NewMessage creates a new MessageBuilder for a message with the given name.
    39  // Since the new message has no parent element, it also has no package name
    40  // (e.g. it is in the unnamed package, until it is assigned to a file builder
    41  // that defines a package name).
    42  func NewMessage(name string) *MessageBuilder {
    43  	return &MessageBuilder{
    44  		baseBuilder: baseBuilderWithName(name),
    45  		fieldTags:   map[int32]*FieldBuilder{},
    46  		symbols:     map[string]Builder{},
    47  	}
    48  }
    49  
    50  // FromMessage returns a MessageBuilder that is effectively a copy of the given
    51  // descriptor.
    52  //
    53  // Note that it is not just the given message that is copied but its entire
    54  // file. So the caller can get the parent element of the returned builder and
    55  // the result would be a builder that is effectively a copy of the message
    56  // descriptor's parent.
    57  //
    58  // This means that message builders created from descriptors do not need to be
    59  // explicitly assigned to a file in order to preserve the original message's
    60  // package name.
    61  func FromMessage(md *desc.MessageDescriptor) (*MessageBuilder, error) {
    62  	if fb, err := FromFile(md.GetFile()); err != nil {
    63  		return nil, err
    64  	} else if mb, ok := fb.findFullyQualifiedElement(md.GetFullyQualifiedName()).(*MessageBuilder); ok {
    65  		return mb, nil
    66  	} else {
    67  		return nil, fmt.Errorf("could not find message %s after converting file %q to builder", md.GetFullyQualifiedName(), md.GetFile().GetName())
    68  	}
    69  }
    70  
    71  func fromMessage(md *desc.MessageDescriptor,
    72  	localMessages map[*desc.MessageDescriptor]*MessageBuilder,
    73  	localEnums map[*desc.EnumDescriptor]*EnumBuilder) (*MessageBuilder, error) {
    74  
    75  	mb := NewMessage(md.GetName())
    76  	mb.Options = md.GetMessageOptions()
    77  	mb.ExtensionRanges = md.AsDescriptorProto().GetExtensionRange()
    78  	mb.ReservedRanges = md.AsDescriptorProto().GetReservedRange()
    79  	mb.ReservedNames = md.AsDescriptorProto().GetReservedName()
    80  	setComments(&mb.comments, md.GetSourceInfo())
    81  
    82  	localMessages[md] = mb
    83  
    84  	oneOfs := make([]*OneOfBuilder, len(md.GetOneOfs()))
    85  	for i, ood := range md.GetOneOfs() {
    86  		if oob, err := fromOneOf(ood); err != nil {
    87  			return nil, err
    88  		} else {
    89  			oneOfs[i] = oob
    90  		}
    91  	}
    92  
    93  	for _, fld := range md.GetFields() {
    94  		if fld.GetOneOf() != nil {
    95  			// add one-ofs in the order of their first constituent field
    96  			oob := oneOfs[fld.AsFieldDescriptorProto().GetOneofIndex()]
    97  			if oob != nil {
    98  				oneOfs[fld.AsFieldDescriptorProto().GetOneofIndex()] = nil
    99  				if err := mb.TryAddOneOf(oob); err != nil {
   100  					return nil, err
   101  				}
   102  			}
   103  			continue
   104  		}
   105  		if flb, err := fromField(fld); err != nil {
   106  			return nil, err
   107  		} else if err := mb.TryAddField(flb); err != nil {
   108  			return nil, err
   109  		}
   110  	}
   111  
   112  	for _, nmd := range md.GetNestedMessageTypes() {
   113  		if nmb, err := fromMessage(nmd, localMessages, localEnums); err != nil {
   114  			return nil, err
   115  		} else if err := mb.TryAddNestedMessage(nmb); err != nil {
   116  			return nil, err
   117  		}
   118  	}
   119  	for _, ed := range md.GetNestedEnumTypes() {
   120  		if eb, err := fromEnum(ed, localEnums); err != nil {
   121  			return nil, err
   122  		} else if err := mb.TryAddNestedEnum(eb); err != nil {
   123  			return nil, err
   124  		}
   125  	}
   126  	for _, exd := range md.GetNestedExtensions() {
   127  		if exb, err := fromField(exd); err != nil {
   128  			return nil, err
   129  		} else if err := mb.TryAddNestedExtension(exb); err != nil {
   130  			return nil, err
   131  		}
   132  	}
   133  
   134  	return mb, nil
   135  }
   136  
   137  // SetName changes this message's name, returning the message builder for method
   138  // chaining. If the given new name is not valid (e.g. TrySetName would have
   139  // returned an error) then this method will panic.
   140  func (mb *MessageBuilder) SetName(newName string) *MessageBuilder {
   141  	if err := mb.TrySetName(newName); err != nil {
   142  		panic(err)
   143  	}
   144  	return mb
   145  }
   146  
   147  // TrySetName changes this message's name. It will return an error if the given
   148  // new name is not a valid protobuf identifier or if the parent builder already
   149  // has an element with the given name.
   150  //
   151  // If the message is a map or group type whose parent is the corresponding map
   152  // or group field, the parent field's enclosing message is checked for elements
   153  // with a conflicting name. Despite the fact that these message types are
   154  // modeled as children of their associated field builder, in the protobuf IDL
   155  // they are actually all defined in the enclosing message's namespace.
   156  func (mb *MessageBuilder) TrySetName(newName string) error {
   157  	if p, ok := mb.parent.(*FieldBuilder); ok && p.fieldType.fieldType != dpb.FieldDescriptorProto_TYPE_GROUP {
   158  		return fmt.Errorf("cannot change name of map entry %s; change name of field instead", GetFullyQualifiedName(mb))
   159  	}
   160  	return mb.trySetNameInternal(newName)
   161  }
   162  
   163  func (mb *MessageBuilder) trySetNameInternal(newName string) error {
   164  	return mb.baseBuilder.setName(mb, newName)
   165  }
   166  
   167  func (mb *MessageBuilder) setNameInternal(newName string) {
   168  	if err := mb.trySetNameInternal(newName); err != nil {
   169  		panic(err)
   170  	}
   171  }
   172  
   173  // SetComments sets the comments associated with the message. This method
   174  // returns the message builder, for method chaining.
   175  func (mb *MessageBuilder) SetComments(c Comments) *MessageBuilder {
   176  	mb.comments = c
   177  	return mb
   178  }
   179  
   180  // GetChildren returns any builders assigned to this message builder. These will
   181  // include the message's fields and one-ofs as well as any nested messages,
   182  // extensions, and enums.
   183  func (mb *MessageBuilder) GetChildren() []Builder {
   184  	ch := append([]Builder(nil), mb.fieldsAndOneOfs...)
   185  	for _, nmb := range mb.nestedMessages {
   186  		ch = append(ch, nmb)
   187  	}
   188  	for _, exb := range mb.nestedExtensions {
   189  		ch = append(ch, exb)
   190  	}
   191  	for _, eb := range mb.nestedEnums {
   192  		ch = append(ch, eb)
   193  	}
   194  	return ch
   195  }
   196  
   197  func (mb *MessageBuilder) findChild(name string) Builder {
   198  	return mb.symbols[name]
   199  }
   200  
   201  func (mb *MessageBuilder) removeChild(b Builder) {
   202  	if p, ok := b.GetParent().(*MessageBuilder); !ok || p != mb {
   203  		return
   204  	}
   205  
   206  	switch b := b.(type) {
   207  	case *FieldBuilder:
   208  		if b.IsExtension() {
   209  			mb.nestedExtensions = deleteBuilder(b.GetName(), mb.nestedExtensions).([]*FieldBuilder)
   210  		} else {
   211  			mb.fieldsAndOneOfs = deleteBuilder(b.GetName(), mb.fieldsAndOneOfs).([]Builder)
   212  			delete(mb.fieldTags, b.GetNumber())
   213  			if b.msgType != nil {
   214  				delete(mb.symbols, b.msgType.GetName())
   215  			}
   216  		}
   217  	case *OneOfBuilder:
   218  		mb.fieldsAndOneOfs = deleteBuilder(b.GetName(), mb.fieldsAndOneOfs).([]Builder)
   219  		for _, flb := range b.choices {
   220  			delete(mb.symbols, flb.GetName())
   221  			delete(mb.fieldTags, flb.GetNumber())
   222  		}
   223  	case *MessageBuilder:
   224  		mb.nestedMessages = deleteBuilder(b.GetName(), mb.nestedMessages).([]*MessageBuilder)
   225  	case *EnumBuilder:
   226  		mb.nestedEnums = deleteBuilder(b.GetName(), mb.nestedEnums).([]*EnumBuilder)
   227  	}
   228  	delete(mb.symbols, b.GetName())
   229  	b.setParent(nil)
   230  }
   231  
   232  func (mb *MessageBuilder) renamedChild(b Builder, oldName string) error {
   233  	if p, ok := b.GetParent().(*MessageBuilder); !ok || p != mb {
   234  		return nil
   235  	}
   236  
   237  	if err := mb.addSymbol(b); err != nil {
   238  		return err
   239  	}
   240  	delete(mb.symbols, oldName)
   241  	return nil
   242  }
   243  
   244  func (mb *MessageBuilder) addSymbol(b Builder) error {
   245  	if ex, ok := mb.symbols[b.GetName()]; ok {
   246  		return fmt.Errorf("message %s already contains element (%T) named %q", GetFullyQualifiedName(mb), ex, b.GetName())
   247  	}
   248  	mb.symbols[b.GetName()] = b
   249  	return nil
   250  }
   251  
   252  func (mb *MessageBuilder) addTag(flb *FieldBuilder) error {
   253  	if flb.number == 0 {
   254  		return nil
   255  	}
   256  	if ex, ok := mb.fieldTags[flb.GetNumber()]; ok {
   257  		return fmt.Errorf("message %s already contains field with tag %d: %s", GetFullyQualifiedName(mb), flb.GetNumber(), ex.GetName())
   258  	}
   259  	mb.fieldTags[flb.GetNumber()] = flb
   260  	return nil
   261  }
   262  
   263  func (mb *MessageBuilder) registerField(flb *FieldBuilder) error {
   264  	if err := mb.addSymbol(flb); err != nil {
   265  		return err
   266  	}
   267  	if err := mb.addTag(flb); err != nil {
   268  		delete(mb.symbols, flb.GetName())
   269  		return err
   270  	}
   271  	if flb.msgType != nil {
   272  		if err := mb.addSymbol(flb.msgType); err != nil {
   273  			delete(mb.symbols, flb.GetName())
   274  			delete(mb.fieldTags, flb.GetNumber())
   275  			return err
   276  		}
   277  	}
   278  	return nil
   279  }
   280  
   281  // GetField returns the field with the given name. If no such field exists in
   282  // the message, nil is returned. The field does not have to be an immediate
   283  // child of this message but could instead be an indirect child via a one-of.
   284  func (mb *MessageBuilder) GetField(name string) *FieldBuilder {
   285  	b := mb.symbols[name]
   286  	if flb, ok := b.(*FieldBuilder); ok && !flb.IsExtension() {
   287  		return flb
   288  	} else {
   289  		return nil
   290  	}
   291  }
   292  
   293  // RemoveField removes the field with the given name. If no such field exists in
   294  // the message, this is a no-op. If the field is part of a one-of, the one-of
   295  // remains assigned to this message and the field is removed from it. This
   296  // returns the message builder, for method chaining.
   297  func (mb *MessageBuilder) RemoveField(name string) *MessageBuilder {
   298  	mb.TryRemoveField(name)
   299  	return mb
   300  }
   301  
   302  // TryRemoveField removes the field with the given name and returns false if the
   303  // message has no such field. If the field is part of a one-of, the one-of
   304  // remains assigned to this message and the field is removed from it.
   305  func (mb *MessageBuilder) TryRemoveField(name string) bool {
   306  	b := mb.symbols[name]
   307  	if flb, ok := b.(*FieldBuilder); ok && !flb.IsExtension() {
   308  		// parent could be mb, but could also be a one-of
   309  		flb.GetParent().removeChild(flb)
   310  		return true
   311  	}
   312  	return false
   313  }
   314  
   315  // AddField adds the given field to this message. If an error prevents the field
   316  // from being added, this method panics. If the given field is an extension,
   317  // this method panics. This returns the message builder, for method chaining.
   318  func (mb *MessageBuilder) AddField(flb *FieldBuilder) *MessageBuilder {
   319  	if err := mb.TryAddField(flb); err != nil {
   320  		panic(err)
   321  	}
   322  	return mb
   323  }
   324  
   325  // TryAddField adds the given field to this message, returning any error that
   326  // prevents the field from being added (such as a name collision with another
   327  // element already added to the message). An error is returned if the given
   328  // field is an extension field.
   329  func (mb *MessageBuilder) TryAddField(flb *FieldBuilder) error {
   330  	if flb.IsExtension() {
   331  		return fmt.Errorf("field %s is an extension, not a regular field", flb.GetName())
   332  	}
   333  	// If we are moving field from a one-of that belongs to this message
   334  	// directly to this message, we have to use different order of operations
   335  	// to prevent failure (otherwise, it looks like it's being added twice).
   336  	// (We do similar if moving the other direction, from message to a one-of
   337  	// that is already assigned to same message.)
   338  	needToUnlinkFirst := mb.isPresentButNotChild(flb)
   339  	if needToUnlinkFirst {
   340  		Unlink(flb)
   341  		mb.registerField(flb)
   342  	} else {
   343  		if err := mb.registerField(flb); err != nil {
   344  			return err
   345  		}
   346  		Unlink(flb)
   347  	}
   348  	flb.setParent(mb)
   349  	mb.fieldsAndOneOfs = append(mb.fieldsAndOneOfs, flb)
   350  	return nil
   351  }
   352  
   353  // GetOneOf returns the one-of with the given name. If no such one-of exists in
   354  // the message, nil is returned.
   355  func (mb *MessageBuilder) GetOneOf(name string) *OneOfBuilder {
   356  	b := mb.symbols[name]
   357  	if oob, ok := b.(*OneOfBuilder); ok {
   358  		return oob
   359  	} else {
   360  		return nil
   361  	}
   362  }
   363  
   364  // RemoveOneOf removes the one-of with the given name. If no such one-of exists
   365  // in the message, this is a no-op. This returns the message builder, for method
   366  // chaining.
   367  func (mb *MessageBuilder) RemoveOneOf(name string) *MessageBuilder {
   368  	mb.TryRemoveOneOf(name)
   369  	return mb
   370  }
   371  
   372  // TryRemoveOneOf removes the one-of with the given name and returns false if
   373  // the message has no such one-of.
   374  func (mb *MessageBuilder) TryRemoveOneOf(name string) bool {
   375  	b := mb.symbols[name]
   376  	if oob, ok := b.(*OneOfBuilder); ok {
   377  		mb.removeChild(oob)
   378  		return true
   379  	}
   380  	return false
   381  }
   382  
   383  // AddOneOf adds the given one-of to this message. If an error prevents the
   384  // one-of from being added, this method panics. This returns the message
   385  // builder, for method chaining.
   386  func (mb *MessageBuilder) AddOneOf(oob *OneOfBuilder) *MessageBuilder {
   387  	if err := mb.TryAddOneOf(oob); err != nil {
   388  		panic(err)
   389  	}
   390  	return mb
   391  }
   392  
   393  // TryAddOneOf adds the given one-of to this message, returning any error that
   394  // prevents the one-of from being added (such as a name collision with another
   395  // element already added to the message).
   396  func (mb *MessageBuilder) TryAddOneOf(oob *OneOfBuilder) error {
   397  	if err := mb.addSymbol(oob); err != nil {
   398  		return err
   399  	}
   400  	// add nested fields to symbol and tag map
   401  	for i, flb := range oob.choices {
   402  		if err := mb.registerField(flb); err != nil {
   403  			// must undo all additions we've made so far
   404  			delete(mb.symbols, oob.GetName())
   405  			for i > 1 {
   406  				i--
   407  				flb := oob.choices[i]
   408  				delete(mb.symbols, flb.GetName())
   409  				delete(mb.fieldTags, flb.GetNumber())
   410  			}
   411  			return err
   412  		}
   413  	}
   414  	Unlink(oob)
   415  	oob.setParent(mb)
   416  	mb.fieldsAndOneOfs = append(mb.fieldsAndOneOfs, oob)
   417  	return nil
   418  }
   419  
   420  // GetNestedMessage returns the nested message with the given name. If no such
   421  // message exists, nil is returned. The named message must be in this message's
   422  // scope. If the message is nested more deeply, this will return nil. This means
   423  // the message must be a direct child of this message or a child of one of this
   424  // message's fields (e.g. the group type for a group field or a map entry for a
   425  // map field).
   426  func (mb *MessageBuilder) GetNestedMessage(name string) *MessageBuilder {
   427  	b := mb.symbols[name]
   428  	if nmb, ok := b.(*MessageBuilder); ok {
   429  		return nmb
   430  	} else {
   431  		return nil
   432  	}
   433  }
   434  
   435  // RemoveNestedMessage removes the nested message with the given name. If no
   436  // such message exists, this is a no-op. This returns the message builder, for
   437  // method chaining.
   438  func (mb *MessageBuilder) RemoveNestedMessage(name string) *MessageBuilder {
   439  	mb.TryRemoveNestedMessage(name)
   440  	return mb
   441  }
   442  
   443  // TryRemoveNestedMessage removes the nested message with the given name and
   444  // returns false if this message has no nested message with that name. If the
   445  // named message is a child of a field (e.g. the group type for a group field or
   446  // the map entry for a map field), it is removed from that field and thus
   447  // removed from this message's scope.
   448  func (mb *MessageBuilder) TryRemoveNestedMessage(name string) bool {
   449  	b := mb.symbols[name]
   450  	if nmb, ok := b.(*MessageBuilder); ok {
   451  		// parent could be mb, but could also be a field (if the message
   452  		// is the field's group or map entry type)
   453  		nmb.GetParent().removeChild(nmb)
   454  		return true
   455  	}
   456  	return false
   457  }
   458  
   459  // AddNestedMessage adds the given message as a nested child of this message. If
   460  // an error prevents the message from being added, this method panics. This
   461  // returns the message builder, for method chaining.
   462  func (mb *MessageBuilder) AddNestedMessage(nmb *MessageBuilder) *MessageBuilder {
   463  	if err := mb.TryAddNestedMessage(nmb); err != nil {
   464  		panic(err)
   465  	}
   466  	return mb
   467  }
   468  
   469  // TryAddNestedMessage adds the given message as a nested child of this message,
   470  // returning any error that prevents the message from being added (such as a
   471  // name collision with another element already added to the message).
   472  func (mb *MessageBuilder) TryAddNestedMessage(nmb *MessageBuilder) error {
   473  	// If we are moving nested message from field (map entry or group type)
   474  	// directly to this message, we have to use different order of operations
   475  	// to prevent failure (otherwise, it looks like it's being added twice).
   476  	// (We don't need to do similar for the other direction, because that isn't
   477  	// possible: you can't add messages to a field, they can only be constructed
   478  	// that way using NewGroupField or NewMapField.)
   479  	needToUnlinkFirst := mb.isPresentButNotChild(nmb)
   480  	if needToUnlinkFirst {
   481  		Unlink(nmb)
   482  		mb.addSymbol(nmb)
   483  	} else {
   484  		if err := mb.addSymbol(nmb); err != nil {
   485  			return err
   486  		}
   487  		Unlink(mb)
   488  	}
   489  	nmb.setParent(mb)
   490  	mb.nestedMessages = append(mb.nestedMessages, nmb)
   491  	return nil
   492  }
   493  
   494  func (mb *MessageBuilder) isPresentButNotChild(b Builder) bool {
   495  	if p, ok := b.GetParent().(*MessageBuilder); ok && p == mb {
   496  		// it's a child
   497  		return false
   498  	}
   499  	return mb.symbols[b.GetName()] == b
   500  }
   501  
   502  // GetNestedExtension returns the nested extension with the given name. If no
   503  // such extension exists, nil is returned. The named extension must be in this
   504  // message's scope. If the extension is nested more deeply, this will return
   505  // nil. This means the extension must be a direct child of this message.
   506  func (mb *MessageBuilder) GetNestedExtension(name string) *FieldBuilder {
   507  	b := mb.symbols[name]
   508  	if exb, ok := b.(*FieldBuilder); ok && exb.IsExtension() {
   509  		return exb
   510  	} else {
   511  		return nil
   512  	}
   513  }
   514  
   515  // RemoveNestedExtension removes the nested extension with the given name. If no
   516  // such extension exists, this is a no-op. This returns the message builder, for
   517  // method chaining.
   518  func (mb *MessageBuilder) RemoveNestedExtension(name string) *MessageBuilder {
   519  	mb.TryRemoveNestedExtension(name)
   520  	return mb
   521  }
   522  
   523  // TryRemoveNestedExtension removes the nested extension with the given name and
   524  // returns false if this message has no nested extension with that name.
   525  func (mb *MessageBuilder) TryRemoveNestedExtension(name string) bool {
   526  	b := mb.symbols[name]
   527  	if exb, ok := b.(*FieldBuilder); ok && exb.IsExtension() {
   528  		mb.removeChild(exb)
   529  		return true
   530  	}
   531  	return false
   532  }
   533  
   534  // AddNestedExtension adds the given extension as a nested child of this
   535  // message. If an error prevents the extension from being added, this method
   536  // panics. This returns the message builder, for method chaining.
   537  func (mb *MessageBuilder) AddNestedExtension(exb *FieldBuilder) *MessageBuilder {
   538  	if err := mb.TryAddNestedExtension(exb); err != nil {
   539  		panic(err)
   540  	}
   541  	return mb
   542  }
   543  
   544  // TryAddNestedExtension adds the given extension as a nested child of this
   545  // message, returning any error that prevents the extension from being added
   546  // (such as a name collision with another element already added to the message).
   547  func (mb *MessageBuilder) TryAddNestedExtension(exb *FieldBuilder) error {
   548  	if !exb.IsExtension() {
   549  		return fmt.Errorf("field %s is not an extension", exb.GetName())
   550  	}
   551  	if err := mb.addSymbol(exb); err != nil {
   552  		return err
   553  	}
   554  	Unlink(exb)
   555  	exb.setParent(mb)
   556  	mb.nestedExtensions = append(mb.nestedExtensions, exb)
   557  	return nil
   558  }
   559  
   560  // GetNestedEnum returns the nested enum with the given name. If no such enum
   561  // exists, nil is returned. The named enum must be in this message's scope. If
   562  // the enum is nested more deeply, this will return nil. This means the enum
   563  // must be a direct child of this message.
   564  func (mb *MessageBuilder) GetNestedEnum(name string) *EnumBuilder {
   565  	b := mb.symbols[name]
   566  	if eb, ok := b.(*EnumBuilder); ok {
   567  		return eb
   568  	} else {
   569  		return nil
   570  	}
   571  }
   572  
   573  // RemoveNestedEnum removes the nested enum with the given name. If no such enum
   574  // exists, this is a no-op. This returns the message builder, for method
   575  // chaining.
   576  func (mb *MessageBuilder) RemoveNestedEnum(name string) *MessageBuilder {
   577  	mb.TryRemoveNestedEnum(name)
   578  	return mb
   579  }
   580  
   581  // TryRemoveNestedEnum removes the nested enum with the given name and returns
   582  // false if this message has no nested enum with that name.
   583  func (mb *MessageBuilder) TryRemoveNestedEnum(name string) bool {
   584  	b := mb.symbols[name]
   585  	if eb, ok := b.(*EnumBuilder); ok {
   586  		mb.removeChild(eb)
   587  		return true
   588  	}
   589  	return false
   590  }
   591  
   592  // AddNestedEnum adds the given enum as a nested child of this message. If an
   593  // error prevents the enum from being added, this method panics. This returns
   594  // the message builder, for method chaining.
   595  func (mb *MessageBuilder) AddNestedEnum(eb *EnumBuilder) *MessageBuilder {
   596  	if err := mb.TryAddNestedEnum(eb); err != nil {
   597  		panic(err)
   598  	}
   599  	return mb
   600  }
   601  
   602  // TryAddNestedEnum adds the given enum as a nested child of this message,
   603  // returning any error that prevents the enum from being added (such as a name
   604  // collision with another element already added to the message).
   605  func (mb *MessageBuilder) TryAddNestedEnum(eb *EnumBuilder) error {
   606  	if err := mb.addSymbol(eb); err != nil {
   607  		return err
   608  	}
   609  	Unlink(eb)
   610  	eb.setParent(mb)
   611  	mb.nestedEnums = append(mb.nestedEnums, eb)
   612  	return nil
   613  }
   614  
   615  // SetOptions sets the message options for this message and returns the message,
   616  // for method chaining.
   617  func (mb *MessageBuilder) SetOptions(options *dpb.MessageOptions) *MessageBuilder {
   618  	mb.Options = options
   619  	return mb
   620  }
   621  
   622  // AddExtensionRange adds the given extension range to this message. The range
   623  // is inclusive of both the start and end, just like defining a range in proto
   624  // IDL source. This returns the message, for method chaining.
   625  func (mb *MessageBuilder) AddExtensionRange(start, end int32) *MessageBuilder {
   626  	return mb.AddExtensionRangeWithOptions(start, end, nil)
   627  }
   628  
   629  // AddExtensionRangeWithOptions adds the given extension range to this message.
   630  // The range is inclusive of both the start and end, just like defining a range
   631  // in proto IDL source. This returns the message, for method chaining.
   632  func (mb *MessageBuilder) AddExtensionRangeWithOptions(start, end int32, options *dpb.ExtensionRangeOptions) *MessageBuilder {
   633  	er := &dpb.DescriptorProto_ExtensionRange{
   634  		Start:   proto.Int32(start),
   635  		End:     proto.Int32(end + 1),
   636  		Options: options,
   637  	}
   638  	mb.ExtensionRanges = append(mb.ExtensionRanges, er)
   639  	return mb
   640  }
   641  
   642  // SetExtensionRanges replaces all of this message's extension ranges with the
   643  // given slice of ranges. Unlike AddExtensionRange and unlike the way ranges are
   644  // defined in proto IDL source, a DescriptorProto_ExtensionRange struct treats
   645  // the end of the range as *exclusive*. So the range is inclusive of the start
   646  // but exclusive of the end. This returns the message, for method chaining.
   647  func (mb *MessageBuilder) SetExtensionRanges(ranges []*dpb.DescriptorProto_ExtensionRange) *MessageBuilder {
   648  	mb.ExtensionRanges = ranges
   649  	return mb
   650  }
   651  
   652  // AddReservedRange adds the given reserved range to this message. The range is
   653  // inclusive of both the start and end, just like defining a range in proto IDL
   654  // source. This returns the message, for method chaining.
   655  func (mb *MessageBuilder) AddReservedRange(start, end int32) *MessageBuilder {
   656  	rr := &dpb.DescriptorProto_ReservedRange{
   657  		Start: proto.Int32(start),
   658  		End:   proto.Int32(end + 1),
   659  	}
   660  	mb.ReservedRanges = append(mb.ReservedRanges, rr)
   661  	return mb
   662  }
   663  
   664  // SetReservedRanges replaces all of this message's reserved ranges with the
   665  // given slice of ranges. Unlike AddReservedRange and unlike the way ranges are
   666  // defined in proto IDL source, a DescriptorProto_ReservedRange struct treats
   667  // the end of the range as *exclusive* (so it would be the value defined in the
   668  // IDL plus one). So the range is inclusive of the start but exclusive of the
   669  // end. This returns the message, for method chaining.
   670  func (mb *MessageBuilder) SetReservedRanges(ranges []*dpb.DescriptorProto_ReservedRange) *MessageBuilder {
   671  	mb.ReservedRanges = ranges
   672  	return mb
   673  }
   674  
   675  // AddReservedName adds the given name to the list of reserved field names for
   676  // this message. This returns the message, for method chaining.
   677  func (mb *MessageBuilder) AddReservedName(name string) *MessageBuilder {
   678  	mb.ReservedNames = append(mb.ReservedNames, name)
   679  	return mb
   680  }
   681  
   682  // SetReservedNames replaces all of this message's reserved field names with the
   683  // given slice of names. This returns the message, for method chaining.
   684  func (mb *MessageBuilder) SetReservedNames(names []string) *MessageBuilder {
   685  	mb.ReservedNames = names
   686  	return mb
   687  }
   688  
   689  func (mb *MessageBuilder) buildProto(path []int32, sourceInfo *dpb.SourceCodeInfo) (*dpb.DescriptorProto, error) {
   690  	addCommentsTo(sourceInfo, path, &mb.comments)
   691  
   692  	var needTagsAssigned []*dpb.FieldDescriptorProto
   693  	nestedMessages := make([]*dpb.DescriptorProto, 0, len(mb.nestedMessages))
   694  	oneOfCount := 0
   695  	for _, b := range mb.fieldsAndOneOfs {
   696  		if _, ok := b.(*OneOfBuilder); ok {
   697  			oneOfCount++
   698  		}
   699  	}
   700  	fields := make([]*dpb.FieldDescriptorProto, 0, len(mb.fieldsAndOneOfs)-oneOfCount)
   701  	oneOfs := make([]*dpb.OneofDescriptorProto, 0, oneOfCount)
   702  	for _, b := range mb.fieldsAndOneOfs {
   703  		if flb, ok := b.(*FieldBuilder); ok {
   704  			fldpath := append(path, internal.Message_fieldsTag, int32(len(fields)))
   705  			fld, err := flb.buildProto(fldpath, sourceInfo)
   706  			if err != nil {
   707  				return nil, err
   708  			}
   709  			fields = append(fields, fld)
   710  			if flb.number == 0 {
   711  				needTagsAssigned = append(needTagsAssigned, fld)
   712  			}
   713  			if flb.msgType != nil {
   714  				nmpath := append(path, internal.Message_nestedMessagesTag, int32(len(nestedMessages)))
   715  				if entry, err := flb.msgType.buildProto(nmpath, sourceInfo); err != nil {
   716  					return nil, err
   717  				} else {
   718  					nestedMessages = append(nestedMessages, entry)
   719  				}
   720  			}
   721  		} else {
   722  			oopath := append(path, internal.Message_oneOfsTag, int32(len(oneOfs)))
   723  			oob := b.(*OneOfBuilder)
   724  			oobIndex := len(oneOfs)
   725  			ood, err := oob.buildProto(oopath, sourceInfo)
   726  			if err != nil {
   727  				return nil, err
   728  			}
   729  			oneOfs = append(oneOfs, ood)
   730  			for _, flb := range oob.choices {
   731  				path := append(path, internal.Message_fieldsTag, int32(len(fields)))
   732  				fld, err := flb.buildProto(path, sourceInfo)
   733  				if err != nil {
   734  					return nil, err
   735  				}
   736  				fld.OneofIndex = proto.Int32(int32(oobIndex))
   737  				fields = append(fields, fld)
   738  				if flb.number == 0 {
   739  					needTagsAssigned = append(needTagsAssigned, fld)
   740  				}
   741  			}
   742  		}
   743  	}
   744  
   745  	if len(needTagsAssigned) > 0 {
   746  		tags := make([]int, len(fields)-len(needTagsAssigned))
   747  		for i, fld := range fields {
   748  			tag := fld.GetNumber()
   749  			if tag != 0 {
   750  				tags[i] = int(tag)
   751  			}
   752  		}
   753  		sort.Ints(tags)
   754  		t := 1
   755  		for len(needTagsAssigned) > 0 {
   756  			for len(tags) > 0 && t == tags[0] {
   757  				t++
   758  				tags = tags[1:]
   759  			}
   760  			needTagsAssigned[0].Number = proto.Int32(int32(t))
   761  			needTagsAssigned = needTagsAssigned[1:]
   762  			t++
   763  		}
   764  	}
   765  
   766  	for _, nmb := range mb.nestedMessages {
   767  		path := append(path, internal.Message_nestedMessagesTag, int32(len(nestedMessages)))
   768  		if nmd, err := nmb.buildProto(path, sourceInfo); err != nil {
   769  			return nil, err
   770  		} else {
   771  			nestedMessages = append(nestedMessages, nmd)
   772  		}
   773  	}
   774  
   775  	nestedExtensions := make([]*dpb.FieldDescriptorProto, 0, len(mb.nestedExtensions))
   776  	for _, exb := range mb.nestedExtensions {
   777  		path := append(path, internal.Message_extensionsTag, int32(len(nestedExtensions)))
   778  		if exd, err := exb.buildProto(path, sourceInfo); err != nil {
   779  			return nil, err
   780  		} else {
   781  			nestedExtensions = append(nestedExtensions, exd)
   782  		}
   783  	}
   784  
   785  	nestedEnums := make([]*dpb.EnumDescriptorProto, 0, len(mb.nestedEnums))
   786  	for _, eb := range mb.nestedEnums {
   787  		path := append(path, internal.Message_enumsTag, int32(len(nestedEnums)))
   788  		if ed, err := eb.buildProto(path, sourceInfo); err != nil {
   789  			return nil, err
   790  		} else {
   791  			nestedEnums = append(nestedEnums, ed)
   792  		}
   793  	}
   794  
   795  	return &dpb.DescriptorProto{
   796  		Name:           proto.String(mb.name),
   797  		Options:        mb.Options,
   798  		Field:          fields,
   799  		OneofDecl:      oneOfs,
   800  		NestedType:     nestedMessages,
   801  		EnumType:       nestedEnums,
   802  		Extension:      nestedExtensions,
   803  		ExtensionRange: mb.ExtensionRanges,
   804  		ReservedName:   mb.ReservedNames,
   805  		ReservedRange:  mb.ReservedRanges,
   806  	}, nil
   807  }
   808  
   809  // Build constructs a message descriptor based on the contents of this message
   810  // builder. If there are any problems constructing the descriptor, including
   811  // resolving symbols referenced by the builder or failing to meet certain
   812  // validation rules, an error is returned.
   813  func (mb *MessageBuilder) Build() (*desc.MessageDescriptor, error) {
   814  	md, err := mb.BuildDescriptor()
   815  	if err != nil {
   816  		return nil, err
   817  	}
   818  	return md.(*desc.MessageDescriptor), nil
   819  }
   820  
   821  // BuildDescriptor constructs a message descriptor based on the contents of this
   822  // message builder. Most usages will prefer Build() instead, whose return type
   823  // is a concrete descriptor type. This method is present to satisfy the Builder
   824  // interface.
   825  func (mb *MessageBuilder) BuildDescriptor() (desc.Descriptor, error) {
   826  	return doBuild(mb, BuilderOptions{})
   827  }