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