@@ -761,6 +761,7 @@ def initialize descriptor, address, docs, message, enum
761761 super descriptor , address , docs
762762 @message = message
763763 @enum = enum
764+ @oneof_siblings = nil
764765 end
765766
766767 OPTION_EXTENSION_NAMES = {
@@ -968,6 +969,32 @@ def is_deprecated?
968969 option_named "deprecated"
969970 end
970971
972+ # @private
973+ # Populate the oneof_siblings array. This is nil if this field is not part
974+ # of a oneof, otherwise it's an array of fields that are members of the
975+ # oneof, with the first element being the current field.
976+ def populate_oneof_siblings! all_fields
977+ return unless oneof?
978+ @oneof_siblings = [ self ]
979+ all_fields . each do |field |
980+ @oneof_siblings << field if field != self && field . oneof? && field . oneof_index == oneof_index
981+ end
982+ end
983+
984+ # @private
985+ # Override this to add a note related to oneofs being mutually exclusive.
986+ def docs_leading_comments disable_xrefs : false , transport : nil
987+ str = super
988+ return str unless @oneof_siblings && @oneof_siblings . size > 1
989+ siblings = @oneof_siblings . map { |field | "`#{ field . name } `" } . join ", "
990+ note = "Note: The following fields are mutually exclusive: " \
991+ "#{ siblings } . If a field in that set is populated, all other " \
992+ "fields in the set will automatically be cleared. As a best " \
993+ "practice, explicitly clear any existing field first, by " \
994+ "setting it to `nil`, before populating another."
995+ str ? "#{ str . strip } \n \n #{ note } " : note
996+ end
997+
971998 # @!method name
972999 # @return [String] the unqualified name of the field.
9731000 # @!method number
0 commit comments