github.com/Big-big-orange/protoreflect@v0.0.0-20240408141420-285cedfdf6a4/desc/builder/message.go (about)

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