VOL-2265 test go.mod and vendor consistency;
Update dependencies to resolve `410 Gone` errors when fetching modules

Change-Id: If0bdbc1b6d629ce819b9fa4701c016df812f92d5
diff --git a/vendor/github.com/jhump/protoreflect/desc/protoparse/source_code_info.go b/vendor/github.com/jhump/protoreflect/desc/protoparse/source_code_info.go
index d0a61c2..ff37733 100644
--- a/vendor/github.com/jhump/protoreflect/desc/protoparse/source_code_info.go
+++ b/vendor/github.com/jhump/protoreflect/desc/protoparse/source_code_info.go
@@ -2,8 +2,6 @@
 
 import (
 	"bytes"
-	"reflect"
-	"sort"
 	"strings"
 
 	"github.com/golang/protobuf/proto"
@@ -23,287 +21,267 @@
 	path := make([]int32, 0, 10)
 
 	fn := r.getFileNode(r.fd).(*fileNode)
+	sci.newLocWithoutComments(fn, nil)
+
 	if fn.syntax != nil {
 		sci.newLoc(fn.syntax, append(path, internal.File_syntaxTag))
 	}
-	if fn.pkg != nil {
-		sci.newLoc(fn.pkg, append(path, internal.File_packageTag))
-	}
-	for i, imp := range fn.imports {
-		sci.newLoc(imp, append(path, internal.File_dependencyTag, int32(i)))
-	}
 
-	// file options
-	r.generateSourceCodeInfoForOptions(&sci, fn.decls, func(n interface{}) *optionNode {
-		return n.(*fileElement).option
-	}, r.fd.Options.GetUninterpretedOption(), append(path, internal.File_optionsTag))
+	var depIndex, optIndex, msgIndex, enumIndex, extendIndex, svcIndex int32
 
-	// message types
-	for i, msg := range r.fd.GetMessageType() {
-		r.generateSourceCodeInfoForMessage(&sci, msg, append(path, internal.File_messagesTag, int32(i)))
-	}
-
-	// enum types
-	for i, enum := range r.fd.GetEnumType() {
-		r.generateSourceCodeInfoForEnum(&sci, enum, append(path, internal.File_enumsTag, int32(i)))
-	}
-
-	// extension fields
-	for i, ext := range r.fd.GetExtension() {
-		r.generateSourceCodeInfoForField(&sci, ext, append(path, internal.File_extensionsTag, int32(i)))
-	}
-
-	// services and methods
-	for i, svc := range r.fd.GetService() {
-		n := r.getServiceNode(svc).(*serviceNode)
-		svcPath := append(path, internal.File_servicesTag, int32(i))
-		sci.newLoc(n, svcPath)
-		sci.newLoc(n.name, append(svcPath, internal.Service_nameTag))
-
-		// service options
-		r.generateSourceCodeInfoForOptions(&sci, n.decls, func(n interface{}) *optionNode {
-			return n.(*serviceElement).option
-		}, svc.Options.GetUninterpretedOption(), append(svcPath, internal.Service_optionsTag))
-
-		// methods
-		for j, mtd := range svc.GetMethod() {
-			mn := r.getMethodNode(mtd).(*methodNode)
-			mtdPath := append(svcPath, internal.Service_methodsTag, int32(j))
-			sci.newLoc(mn, mtdPath)
-			sci.newLoc(mn.name, append(mtdPath, internal.Method_nameTag))
-
-			sci.newLoc(mn.input.msgType, append(mtdPath, internal.Method_inputTag))
-			if mn.input.streamKeyword != nil {
-				sci.newLoc(mn.input.streamKeyword, append(mtdPath, internal.Method_inputStreamTag))
-			}
-			sci.newLoc(mn.output.msgType, append(mtdPath, internal.Method_outputTag))
-			if mn.output.streamKeyword != nil {
-				sci.newLoc(mn.output.streamKeyword, append(mtdPath, internal.Method_outputStreamTag))
-			}
-
-			// method options
-			r.generateSourceCodeInfoForOptions(&sci, mn.options, func(n interface{}) *optionNode {
-				return n.(*optionNode)
-			}, mtd.Options.GetUninterpretedOption(), append(mtdPath, internal.Method_optionsTag))
-		}
-	}
-	return &dpb.SourceCodeInfo{Location: sci.generateLocs()}
-}
-
-func (r *parseResult) generateSourceCodeInfoForOptions(sci *sourceCodeInfo, elements interface{}, extractor func(interface{}) *optionNode, uninterp []*dpb.UninterpretedOption, path []int32) {
-	// Known options are option node elements that have a corresponding
-	// path in r.interpretedOptions. We'll do those first.
-	rv := reflect.ValueOf(elements)
-	for i := 0; i < rv.Len(); i++ {
-		on := extractor(rv.Index(i).Interface())
-		if on == nil {
-			continue
-		}
-		optPath := r.interpretedOptions[on]
-		if len(optPath) > 0 {
-			p := path
-			if optPath[0] == -1 {
-				// used by "default" and "json_name" field pseudo-options
-				// to attribute path to parent element (since those are
-				// stored directly on the descriptor, not its options)
-				p = make([]int32, len(path)-1)
-				copy(p, path)
-				optPath = optPath[1:]
-			}
-			sci.newLoc(on, append(p, optPath...))
-		}
-	}
-
-	// Now uninterpreted options
-	for i, uo := range uninterp {
-		optPath := append(path, internal.UninterpretedOptionsTag, int32(i))
-		on := r.getOptionNode(uo).(*optionNode)
-		sci.newLoc(on, optPath)
-
-		var valTag int32
+	for _, child := range fn.decls {
 		switch {
-		case uo.IdentifierValue != nil:
-			valTag = internal.Uninterpreted_identTag
-		case uo.PositiveIntValue != nil:
-			valTag = internal.Uninterpreted_posIntTag
-		case uo.NegativeIntValue != nil:
-			valTag = internal.Uninterpreted_negIntTag
-		case uo.DoubleValue != nil:
-			valTag = internal.Uninterpreted_doubleTag
-		case uo.StringValue != nil:
-			valTag = internal.Uninterpreted_stringTag
-		case uo.AggregateValue != nil:
-			valTag = internal.Uninterpreted_aggregateTag
+		case child.imp != nil:
+			sci.newLoc(child.imp, append(path, internal.File_dependencyTag, int32(depIndex)))
+			depIndex++
+		case child.pkg != nil:
+			sci.newLoc(child.pkg, append(path, internal.File_packageTag))
+		case child.option != nil:
+			r.generateSourceCodeInfoForOption(&sci, child.option, false, &optIndex, append(path, internal.File_optionsTag))
+		case child.message != nil:
+			r.generateSourceCodeInfoForMessage(&sci, child.message, nil, append(path, internal.File_messagesTag, msgIndex))
+			msgIndex++
+		case child.enum != nil:
+			r.generateSourceCodeInfoForEnum(&sci, child.enum, append(path, internal.File_enumsTag, enumIndex))
+			enumIndex++
+		case child.extend != nil:
+			r.generateSourceCodeInfoForExtensions(&sci, child.extend, &extendIndex, &msgIndex, append(path, internal.File_extensionsTag), append(dup(path), internal.File_messagesTag))
+		case child.service != nil:
+			r.generateSourceCodeInfoForService(&sci, child.service, append(path, internal.File_servicesTag, svcIndex))
+			svcIndex++
 		}
-		if valTag != 0 {
-			sci.newLoc(on.val, append(optPath, valTag))
-		}
+	}
 
-		for j, n := range uo.Name {
-			optNmPath := append(optPath, internal.Uninterpreted_nameTag, int32(j))
-			nn := r.getOptionNamePartNode(n).(*optionNamePartNode)
-			sci.newLoc(nn, optNmPath)
-			sci.newLoc(nn.text, append(optNmPath, internal.UninterpretedName_nameTag))
+	return &dpb.SourceCodeInfo{Location: sci.locs}
+}
+
+func (r *parseResult) generateSourceCodeInfoForOption(sci *sourceCodeInfo, n *optionNode, compact bool, uninterpIndex *int32, path []int32) {
+	if !compact {
+		sci.newLocWithoutComments(n, path)
+	}
+	subPath := r.interpretedOptions[n]
+	if len(subPath) > 0 {
+		p := path
+		if subPath[0] == -1 {
+			// used by "default" and "json_name" field pseudo-options
+			// to attribute path to parent element (since those are
+			// stored directly on the descriptor, not its options)
+			p = make([]int32, len(path)-1)
+			copy(p, path)
+			subPath = subPath[1:]
 		}
+		sci.newLoc(n, append(p, subPath...))
+		return
+	}
+
+	// it's an uninterpreted option
+	optPath := append(path, internal.UninterpretedOptionsTag, *uninterpIndex)
+	*uninterpIndex++
+	sci.newLoc(n, optPath)
+	var valTag int32
+	switch n.val.(type) {
+	case *compoundIdentNode:
+		valTag = internal.Uninterpreted_identTag
+	case *intLiteralNode:
+		valTag = internal.Uninterpreted_posIntTag
+	case *compoundIntNode:
+		valTag = internal.Uninterpreted_negIntTag
+	case *compoundFloatNode:
+		valTag = internal.Uninterpreted_doubleTag
+	case *compoundStringNode:
+		valTag = internal.Uninterpreted_stringTag
+	case *aggregateLiteralNode:
+		valTag = internal.Uninterpreted_aggregateTag
+	}
+	if valTag != 0 {
+		sci.newLoc(n.val, append(optPath, valTag))
+	}
+	for j, nn := range n.name.parts {
+		optNmPath := append(optPath, internal.Uninterpreted_nameTag, int32(j))
+		sci.newLoc(nn, optNmPath)
+		sci.newLoc(nn.text, append(optNmPath, internal.UninterpretedName_nameTag))
 	}
 }
 
-func (r *parseResult) generateSourceCodeInfoForMessage(sci *sourceCodeInfo, msg *dpb.DescriptorProto, path []int32) {
-	n := r.getMessageNode(msg)
+func (r *parseResult) generateSourceCodeInfoForMessage(sci *sourceCodeInfo, n msgDecl, fieldPath []int32, path []int32) {
 	sci.newLoc(n, path)
 
 	var decls []*messageElement
-	var resvdNames []*stringLiteralNode
 	switch n := n.(type) {
 	case *messageNode:
 		decls = n.decls
-		resvdNames = n.reserved
 	case *groupNode:
 		decls = n.decls
-		resvdNames = n.reserved
-	}
-	if decls == nil {
+	case *mapFieldNode:
 		// map entry so nothing else to do
 		return
 	}
 
 	sci.newLoc(n.messageName(), append(path, internal.Message_nameTag))
-
-	// message options
-	r.generateSourceCodeInfoForOptions(sci, decls, func(n interface{}) *optionNode {
-		return n.(*messageElement).option
-	}, msg.Options.GetUninterpretedOption(), append(path, internal.Message_optionsTag))
-
-	// fields
-	for i, fld := range msg.GetField() {
-		r.generateSourceCodeInfoForField(sci, fld, append(path, internal.Message_fieldsTag, int32(i)))
+	// matching protoc, which emits the corresponding field type name (for group fields)
+	// right after the source location for the group message name
+	if fieldPath != nil {
+		sci.newLoc(n.messageName(), append(fieldPath, internal.Field_typeNameTag))
 	}
 
-	// one-ofs
-	for i, ood := range msg.GetOneofDecl() {
-		oon := r.getOneOfNode(ood).(*oneOfNode)
-		ooPath := append(path, internal.Message_oneOfsTag, int32(i))
-		sci.newLoc(oon, ooPath)
-		sci.newLoc(oon.name, append(ooPath, internal.OneOf_nameTag))
-
-		// one-of options
-		r.generateSourceCodeInfoForOptions(sci, oon.decls, func(n interface{}) *optionNode {
-			return n.(*oneOfElement).option
-		}, ood.Options.GetUninterpretedOption(), append(ooPath, internal.OneOf_optionsTag))
-	}
-
-	// nested messages
-	for i, nm := range msg.GetNestedType() {
-		r.generateSourceCodeInfoForMessage(sci, nm, append(path, internal.Message_nestedMessagesTag, int32(i)))
-	}
-
-	// nested enums
-	for i, enum := range msg.GetEnumType() {
-		r.generateSourceCodeInfoForEnum(sci, enum, append(path, internal.Message_enumsTag, int32(i)))
-	}
-
-	// nested extensions
-	for i, ext := range msg.GetExtension() {
-		r.generateSourceCodeInfoForField(sci, ext, append(path, internal.Message_extensionsTag, int32(i)))
-	}
-
-	// extension ranges
-	for i, er := range msg.ExtensionRange {
-		rangePath := append(path, internal.Message_extensionRangeTag, int32(i))
-		rn := r.getExtensionRangeNode(er).(*rangeNode)
-		sci.newLoc(rn, rangePath)
-		sci.newLoc(rn.stNode, append(rangePath, internal.ExtensionRange_startTag))
-		if rn.stNode != rn.enNode {
-			sci.newLoc(rn.enNode, append(rangePath, internal.ExtensionRange_endTag))
-		}
-		// now we have to find the extension decl and options that correspond to this range :(
-		for _, d := range decls {
-			found := false
-			if d.extensionRange != nil {
-				for _, r := range d.extensionRange.ranges {
-					if rn == r {
-						found = true
-						break
-					}
+	var optIndex, fieldIndex, oneOfIndex, extendIndex, nestedMsgIndex int32
+	var nestedEnumIndex, extRangeIndex, reservedRangeIndex, reservedNameIndex int32
+	for _, child := range decls {
+		switch {
+		case child.option != nil:
+			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(path, internal.Message_optionsTag))
+		case child.field != nil:
+			r.generateSourceCodeInfoForField(sci, child.field, append(path, internal.Message_fieldsTag, fieldIndex))
+			fieldIndex++
+		case child.group != nil:
+			fldPath := append(path, internal.Message_fieldsTag, fieldIndex)
+			r.generateSourceCodeInfoForField(sci, child.group, fldPath)
+			fieldIndex++
+			r.generateSourceCodeInfoForMessage(sci, child.group, fldPath, append(dup(path), internal.Message_nestedMessagesTag, nestedMsgIndex))
+			nestedMsgIndex++
+		case child.mapField != nil:
+			r.generateSourceCodeInfoForField(sci, child.mapField, append(path, internal.Message_fieldsTag, fieldIndex))
+			fieldIndex++
+		case child.oneOf != nil:
+			r.generateSourceCodeInfoForOneOf(sci, child.oneOf, &fieldIndex, &nestedMsgIndex, append(path, internal.Message_fieldsTag), append(dup(path), internal.Message_nestedMessagesTag), append(dup(path), internal.Message_oneOfsTag, oneOfIndex))
+			oneOfIndex++
+		case child.nested != nil:
+			r.generateSourceCodeInfoForMessage(sci, child.nested, nil, append(path, internal.Message_nestedMessagesTag, nestedMsgIndex))
+			nestedMsgIndex++
+		case child.enum != nil:
+			r.generateSourceCodeInfoForEnum(sci, child.enum, append(path, internal.Message_enumsTag, nestedEnumIndex))
+			nestedEnumIndex++
+		case child.extend != nil:
+			r.generateSourceCodeInfoForExtensions(sci, child.extend, &extendIndex, &nestedMsgIndex, append(path, internal.Message_extensionsTag), append(dup(path), internal.Message_nestedMessagesTag))
+		case child.extensionRange != nil:
+			r.generateSourceCodeInfoForExtensionRanges(sci, child.extensionRange, &extRangeIndex, append(path, internal.Message_extensionRangeTag))
+		case child.reserved != nil:
+			if len(child.reserved.names) > 0 {
+				resPath := append(path, internal.Message_reservedNameTag)
+				sci.newLoc(child.reserved, resPath)
+				for _, rn := range child.reserved.names {
+					sci.newLoc(rn, append(resPath, reservedNameIndex))
+					reservedNameIndex++
 				}
 			}
-			if found {
-				r.generateSourceCodeInfoForOptions(sci, d.extensionRange.options, func(n interface{}) *optionNode {
-					return n.(*optionNode)
-				}, er.Options.GetUninterpretedOption(), append(rangePath, internal.ExtensionRange_optionsTag))
-				break
+			if len(child.reserved.ranges) > 0 {
+				resPath := append(path, internal.Message_reservedRangeTag)
+				sci.newLoc(child.reserved, resPath)
+				for _, rr := range child.reserved.ranges {
+					r.generateSourceCodeInfoForReservedRange(sci, rr, append(resPath, reservedRangeIndex))
+					reservedRangeIndex++
+				}
 			}
 		}
 	}
-
-	// reserved ranges
-	for i, rr := range msg.ReservedRange {
-		rangePath := append(path, internal.Message_reservedRangeTag, int32(i))
-		rn := r.getMessageReservedRangeNode(rr).(*rangeNode)
-		sci.newLoc(rn, rangePath)
-		sci.newLoc(rn.stNode, append(rangePath, internal.ReservedRange_startTag))
-		if rn.stNode != rn.enNode {
-			sci.newLoc(rn.enNode, append(rangePath, internal.ReservedRange_endTag))
-		}
-	}
-
-	// reserved names
-	for i, n := range resvdNames {
-		sci.newLoc(n, append(path, internal.Message_reservedNameTag, int32(i)))
-	}
 }
 
-func (r *parseResult) generateSourceCodeInfoForEnum(sci *sourceCodeInfo, enum *dpb.EnumDescriptorProto, path []int32) {
-	n := r.getEnumNode(enum).(*enumNode)
+func (r *parseResult) generateSourceCodeInfoForEnum(sci *sourceCodeInfo, n *enumNode, path []int32) {
 	sci.newLoc(n, path)
 	sci.newLoc(n.name, append(path, internal.Enum_nameTag))
 
-	// enum options
-	r.generateSourceCodeInfoForOptions(sci, n.decls, func(n interface{}) *optionNode {
-		return n.(*enumElement).option
-	}, enum.Options.GetUninterpretedOption(), append(path, internal.Enum_optionsTag))
-
-	// enum values
-	for j, ev := range enum.GetValue() {
-		evn := r.getEnumValueNode(ev).(*enumValueNode)
-		evPath := append(path, internal.Enum_valuesTag, int32(j))
-		sci.newLoc(evn, evPath)
-		sci.newLoc(evn.name, append(evPath, internal.EnumVal_nameTag))
-		sci.newLoc(evn.getNumber(), append(evPath, internal.EnumVal_numberTag))
-
-		// enum value options
-		r.generateSourceCodeInfoForOptions(sci, evn.options, func(n interface{}) *optionNode {
-			return n.(*optionNode)
-		}, ev.Options.GetUninterpretedOption(), append(evPath, internal.EnumVal_optionsTag))
-	}
-
-	// reserved ranges
-	for i, rr := range enum.GetReservedRange() {
-		rangePath := append(path, internal.Enum_reservedRangeTag, int32(i))
-		rn := r.getEnumReservedRangeNode(rr).(*rangeNode)
-		sci.newLoc(rn, rangePath)
-		sci.newLoc(rn.stNode, append(rangePath, internal.ReservedRange_startTag))
-		if rn.stNode != rn.enNode {
-			sci.newLoc(rn.enNode, append(rangePath, internal.ReservedRange_endTag))
+	var optIndex, valIndex, reservedNameIndex, reservedRangeIndex int32
+	for _, child := range n.decls {
+		switch {
+		case child.option != nil:
+			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(path, internal.Enum_optionsTag))
+		case child.value != nil:
+			r.generateSourceCodeInfoForEnumValue(sci, child.value, append(path, internal.Enum_valuesTag, valIndex))
+			valIndex++
+		case child.reserved != nil:
+			if len(child.reserved.names) > 0 {
+				resPath := append(path, internal.Enum_reservedNameTag)
+				sci.newLoc(child.reserved, resPath)
+				for _, rn := range child.reserved.names {
+					sci.newLoc(rn, append(resPath, reservedNameIndex))
+					reservedNameIndex++
+				}
+			}
+			if len(child.reserved.ranges) > 0 {
+				resPath := append(path, internal.Enum_reservedRangeTag)
+				sci.newLoc(child.reserved, resPath)
+				for _, rr := range child.reserved.ranges {
+					r.generateSourceCodeInfoForReservedRange(sci, rr, append(resPath, reservedRangeIndex))
+					reservedRangeIndex++
+				}
+			}
 		}
 	}
-
-	// reserved names
-	for i, rn := range n.reserved {
-		sci.newLoc(rn, append(path, internal.Enum_reservedNameTag, int32(i)))
-	}
 }
 
-func (r *parseResult) generateSourceCodeInfoForField(sci *sourceCodeInfo, fld *dpb.FieldDescriptorProto, path []int32) {
-	n := r.getFieldNode(fld)
+func (r *parseResult) generateSourceCodeInfoForEnumValue(sci *sourceCodeInfo, n *enumValueNode, path []int32) {
+	sci.newLoc(n, path)
+	sci.newLoc(n.name, append(path, internal.EnumVal_nameTag))
+	sci.newLoc(n.getNumber(), append(path, internal.EnumVal_numberTag))
 
+	// enum value options
+	if n.options != nil {
+		optsPath := append(path, internal.EnumVal_optionsTag)
+		sci.newLoc(n.options, optsPath)
+		var optIndex int32
+		for _, opt := range n.options.decls {
+			r.generateSourceCodeInfoForOption(sci, opt, true, &optIndex, optsPath)
+		}
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForReservedRange(sci *sourceCodeInfo, n *rangeNode, path []int32) {
+	sci.newLoc(n, path)
+	sci.newLoc(n.stNode, append(path, internal.ReservedRange_startTag))
+	if n.stNode != n.enNode {
+		sci.newLoc(n.enNode, append(path, internal.ReservedRange_endTag))
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForExtensions(sci *sourceCodeInfo, n *extendNode, extendIndex, msgIndex *int32, extendPath, msgPath []int32) {
+	sci.newLoc(n, extendPath)
+	for _, decl := range n.decls {
+		switch {
+		case decl.field != nil:
+			r.generateSourceCodeInfoForField(sci, decl.field, append(extendPath, *extendIndex))
+			*extendIndex++
+		case decl.group != nil:
+			fldPath := append(extendPath, *extendIndex)
+			r.generateSourceCodeInfoForField(sci, decl.group, fldPath)
+			*extendIndex++
+			r.generateSourceCodeInfoForMessage(sci, decl.group, fldPath, append(msgPath, *msgIndex))
+			*msgIndex++
+		}
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForOneOf(sci *sourceCodeInfo, n *oneOfNode, fieldIndex, nestedMsgIndex *int32, fieldPath, nestedMsgPath, oneOfPath []int32) {
+	sci.newLoc(n, oneOfPath)
+	sci.newLoc(n.name, append(oneOfPath, internal.OneOf_nameTag))
+
+	var optIndex int32
+	for _, child := range n.decls {
+		switch {
+		case child.option != nil:
+			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(oneOfPath, internal.OneOf_optionsTag))
+		case child.field != nil:
+			r.generateSourceCodeInfoForField(sci, child.field, append(fieldPath, *fieldIndex))
+			*fieldIndex++
+		case child.group != nil:
+			fldPath := append(fieldPath, *fieldIndex)
+			r.generateSourceCodeInfoForField(sci, child.group, fldPath)
+			*fieldIndex++
+			r.generateSourceCodeInfoForMessage(sci, child.group, fldPath, append(nestedMsgPath, *nestedMsgIndex))
+			*nestedMsgIndex++
+		}
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForField(sci *sourceCodeInfo, n fieldDecl, path []int32) {
 	isGroup := false
-	var opts []*optionNode
+	var opts *compactOptionsNode
 	var extendee *extendNode
+	var fieldType string
 	switch n := n.(type) {
 	case *fieldNode:
 		opts = n.options
 		extendee = n.extendee
+		fieldType = n.fldType.val
 	case *mapFieldNode:
 		opts = n.options
 	case *groupNode:
@@ -315,22 +293,105 @@
 		return
 	}
 
-	sci.newLoc(n, path)
-	if !isGroup {
-		sci.newLoc(n.fieldName(), append(path, internal.Field_nameTag))
+	if isGroup {
+		// comments will appear on group message
+		sci.newLocWithoutComments(n, path)
+		if extendee != nil {
+			sci.newLoc(extendee.extendee, append(path, internal.Field_extendeeTag))
+		}
+		if n.fieldLabel() != nil {
+			// no comments here either (label is first token for group, so we want
+			// to leave the comments to be associated with the group message instead)
+			sci.newLocWithoutComments(n.fieldLabel(), append(path, internal.Field_labelTag))
+		}
 		sci.newLoc(n.fieldType(), append(path, internal.Field_typeTag))
-	}
-	if n.fieldLabel() != nil {
-		sci.newLoc(n.fieldLabel(), append(path, internal.Field_labelTag))
+		// let the name comments be attributed to the group name
+		sci.newLocWithoutComments(n.fieldName(), append(path, internal.Field_nameTag))
+	} else {
+		sci.newLoc(n, path)
+		if extendee != nil {
+			sci.newLoc(extendee.extendee, append(path, internal.Field_extendeeTag))
+		}
+		if n.fieldLabel() != nil {
+			sci.newLoc(n.fieldLabel(), append(path, internal.Field_labelTag))
+		}
+		n.fieldType()
+		var tag int32
+		if _, isScalar := fieldTypes[fieldType]; isScalar {
+			tag = internal.Field_typeTag
+		} else {
+			// this is a message or an enum, so attribute type location
+			// to the type name field
+			tag = internal.Field_typeNameTag
+		}
+		sci.newLoc(n.fieldType(), append(path, tag))
+		sci.newLoc(n.fieldName(), append(path, internal.Field_nameTag))
 	}
 	sci.newLoc(n.fieldTag(), append(path, internal.Field_numberTag))
-	if extendee != nil {
-		sci.newLoc(extendee.extendee, append(path, internal.Field_extendeeTag))
-	}
 
-	r.generateSourceCodeInfoForOptions(sci, opts, func(n interface{}) *optionNode {
-		return n.(*optionNode)
-	}, fld.Options.GetUninterpretedOption(), append(path, internal.Field_optionsTag))
+	if opts != nil {
+		optsPath := append(path, internal.Field_optionsTag)
+		sci.newLoc(opts, optsPath)
+		var optIndex int32
+		for _, opt := range opts.decls {
+			r.generateSourceCodeInfoForOption(sci, opt, true, &optIndex, optsPath)
+		}
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForExtensionRanges(sci *sourceCodeInfo, n *extensionRangeNode, extRangeIndex *int32, path []int32) {
+	sci.newLoc(n, path)
+	for _, child := range n.ranges {
+		path := append(path, *extRangeIndex)
+		*extRangeIndex++
+		sci.newLoc(child, path)
+		sci.newLoc(child.stNode, append(path, internal.ExtensionRange_startTag))
+		if child.stNode != child.enNode {
+			sci.newLoc(child.enNode, append(path, internal.ExtensionRange_endTag))
+		}
+		if n.options != nil {
+			optsPath := append(path, internal.ExtensionRange_optionsTag)
+			sci.newLoc(n.options, optsPath)
+			var optIndex int32
+			for _, opt := range n.options.decls {
+				r.generateSourceCodeInfoForOption(sci, opt, true, &optIndex, optsPath)
+			}
+		}
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForService(sci *sourceCodeInfo, n *serviceNode, path []int32) {
+	sci.newLoc(n, path)
+	sci.newLoc(n.name, append(path, internal.Service_nameTag))
+	var optIndex, rpcIndex int32
+	for _, child := range n.decls {
+		switch {
+		case child.option != nil:
+			r.generateSourceCodeInfoForOption(sci, child.option, false, &optIndex, append(path, internal.Service_optionsTag))
+		case child.rpc != nil:
+			r.generateSourceCodeInfoForMethod(sci, child.rpc, append(path, internal.Service_methodsTag, rpcIndex))
+			rpcIndex++
+		}
+	}
+}
+
+func (r *parseResult) generateSourceCodeInfoForMethod(sci *sourceCodeInfo, n *methodNode, path []int32) {
+	sci.newLoc(n, path)
+	sci.newLoc(n.name, append(path, internal.Method_nameTag))
+	if n.input.streamKeyword != nil {
+		sci.newLoc(n.input.streamKeyword, append(path, internal.Method_inputStreamTag))
+	}
+	sci.newLoc(n.input.msgType, append(path, internal.Method_inputTag))
+	if n.output.streamKeyword != nil {
+		sci.newLoc(n.output.streamKeyword, append(path, internal.Method_outputStreamTag))
+	}
+	sci.newLoc(n.output.msgType, append(path, internal.Method_outputTag))
+
+	optsPath := append(path, internal.Method_optionsTag)
+	var optIndex int32
+	for _, opt := range n.options {
+		r.generateSourceCodeInfoForOption(sci, opt, false, &optIndex, optsPath)
+	}
 }
 
 type sourceCodeInfo struct {
@@ -338,6 +399,15 @@
 	commentsUsed map[*comment]struct{}
 }
 
+func (sci *sourceCodeInfo) newLocWithoutComments(n node, path []int32) {
+	dup := make([]int32, len(path))
+	copy(dup, path)
+	sci.locs = append(sci.locs, &dpb.SourceCodeInfo_Location{
+		Path: dup,
+		Span: makeSpan(n.start(), n.end()),
+	})
+}
+
 func (sci *sourceCodeInfo) newLoc(n node, path []int32) {
 	leadingComments := n.leadingComments()
 	trailingComments := n.trailingComments()
@@ -348,7 +418,10 @@
 		trailingComments = nil
 	}
 	detached := groupComments(leadingComments)
-	trail := combineComments(trailingComments)
+	var trail *string
+	if str, ok := combineComments(trailingComments); ok {
+		trail = proto.String(str)
+	}
 	var lead *string
 	if len(leadingComments) > 0 && leadingComments[len(leadingComments)-1].end.Line >= n.start().Line-1 {
 		lead = proto.String(detached[len(detached)-1])
@@ -356,34 +429,35 @@
 	}
 	dup := make([]int32, len(path))
 	copy(dup, path)
-	var span []int32
-	if n.start().Line == n.end().Line {
-		span = []int32{int32(n.start().Line) - 1, int32(n.start().Col) - 1, int32(n.end().Col) - 1}
-	} else {
-		span = []int32{int32(n.start().Line) - 1, int32(n.start().Col) - 1, int32(n.end().Line) - 1, int32(n.end().Col) - 1}
-	}
 	sci.locs = append(sci.locs, &dpb.SourceCodeInfo_Location{
 		LeadingDetachedComments: detached,
 		LeadingComments:         lead,
 		TrailingComments:        trail,
 		Path:                    dup,
-		Span:                    span,
+		Span:                    makeSpan(n.start(), n.end()),
 	})
 }
 
-func (sci *sourceCodeInfo) commentUsed(c []*comment) bool {
+func makeSpan(start, end *SourcePos) []int32 {
+	if start.Line == end.Line {
+		return []int32{int32(start.Line) - 1, int32(start.Col) - 1, int32(end.Col) - 1}
+	}
+	return []int32{int32(start.Line) - 1, int32(start.Col) - 1, int32(end.Line) - 1, int32(end.Col) - 1}
+}
+
+func (sci *sourceCodeInfo) commentUsed(c []comment) bool {
 	if len(c) == 0 {
 		return false
 	}
-	if _, ok := sci.commentsUsed[c[0]]; ok {
+	if _, ok := sci.commentsUsed[&c[0]]; ok {
 		return true
 	}
 
-	sci.commentsUsed[c[0]] = struct{}{}
+	sci.commentsUsed[&c[0]] = struct{}{}
 	return false
 }
 
-func groupComments(comments []*comment) []string {
+func groupComments(comments []comment) []string {
 	if len(comments) == 0 {
 		return nil
 	}
@@ -398,29 +472,26 @@
 		singleLineStyle = strings.HasPrefix(comments[i].text, "//")
 		if !singleLineStyle || prevSingleLine != singleLineStyle || c.start.Line > line+1 {
 			// new group!
-			groups = append(groups, *combineComments(comments[start:i]))
+			if str, ok := combineComments(comments[start:i]); ok {
+				groups = append(groups, str)
+			}
 			start = i
 		}
 		line = c.end.Line
 	}
 	// don't forget last group
-	groups = append(groups, *combineComments(comments[start:]))
-
+	if str, ok := combineComments(comments[start:]); ok {
+		groups = append(groups, str)
+	}
 	return groups
 }
 
-func combineComments(comments []*comment) *string {
+func combineComments(comments []comment) (string, bool) {
 	if len(comments) == 0 {
-		return nil
+		return "", false
 	}
-	first := true
 	var buf bytes.Buffer
 	for _, c := range comments {
-		if first {
-			first = false
-		} else {
-			buf.WriteByte('\n')
-		}
 		if c.text[:2] == "//" {
 			buf.WriteString(c.text[2:])
 		} else {
@@ -453,160 +524,9 @@
 			}
 		}
 	}
-	return proto.String(buf.String())
+	return buf.String(), true
 }
 
-func (sci *sourceCodeInfo) generateLocs() []*dpb.SourceCodeInfo_Location {
-	// generate intermediate locations: paths between root (inclusive) and the
-	// leaf locations already created, these will not have comments but will
-	// have aggregate span, than runs from min(start pos) to max(end pos) for
-	// all descendent paths.
-
-	if len(sci.locs) == 0 {
-		// nothing to generate
-		return nil
-	}
-
-	var root locTrie
-	for _, loc := range sci.locs {
-		root.add(loc.Path, loc)
-	}
-	root.fillIn()
-	locs := make([]*dpb.SourceCodeInfo_Location, 0, root.countLocs())
-	root.aggregate(&locs)
-	// finally, sort the resulting slice by location
-	sort.Slice(locs, func(i, j int) bool {
-		startI, endI := getSpanPositions(locs[i].Span)
-		startJ, endJ := getSpanPositions(locs[j].Span)
-		cmp := compareSlice(startI, startJ)
-		if cmp == 0 {
-			// if start position is the same, sort by end position _decreasing_
-			// (so enclosing locations will appear before leaves)
-			cmp = -compareSlice(endI, endJ)
-			if cmp == 0 {
-				// start and end position are the same? so break ties using path
-				cmp = compareSlice(locs[i].Path, locs[j].Path)
-			}
-		}
-		return cmp < 0
-	})
-	return locs
-}
-
-type locTrie struct {
-	children map[int32]*locTrie
-	loc      *dpb.SourceCodeInfo_Location
-}
-
-func (t *locTrie) add(path []int32, loc *dpb.SourceCodeInfo_Location) {
-	if len(path) == 0 {
-		t.loc = loc
-		return
-	}
-	child := t.children[path[0]]
-	if child == nil {
-		if t.children == nil {
-			t.children = map[int32]*locTrie{}
-		}
-		child = &locTrie{}
-		t.children[path[0]] = child
-	}
-	child.add(path[1:], loc)
-}
-
-func (t *locTrie) fillIn() {
-	var path []int32
-	var start, end []int32
-	for _, child := range t.children {
-		// recurse
-		child.fillIn()
-		if t.loc == nil {
-			// maintain min(start) and max(end) so we can
-			// populate t.loc below
-			childStart, childEnd := getSpanPositions(child.loc.Span)
-
-			if start == nil {
-				if path == nil {
-					path = child.loc.Path[:len(child.loc.Path)-1]
-				}
-				start = childStart
-				end = childEnd
-			} else {
-				if compareSlice(childStart, start) < 0 {
-					start = childStart
-				}
-				if compareSlice(childEnd, end) > 0 {
-					end = childEnd
-				}
-			}
-		}
-	}
-
-	if t.loc == nil {
-		var span []int32
-		// we don't use append below because we want a new slice
-		// that doesn't share underlying buffer with spans from
-		// any other location
-		if start[0] == end[0] {
-			span = []int32{start[0], start[1], end[1]}
-		} else {
-			span = []int32{start[0], start[1], end[0], end[1]}
-		}
-		t.loc = &dpb.SourceCodeInfo_Location{
-			Path: path,
-			Span: span,
-		}
-	}
-}
-
-func (t *locTrie) countLocs() int {
-	count := 0
-	if t.loc != nil {
-		count = 1
-	}
-	for _, ch := range t.children {
-		count += ch.countLocs()
-	}
-	return count
-}
-
-func (t *locTrie) aggregate(dest *[]*dpb.SourceCodeInfo_Location) {
-	if t.loc != nil {
-		*dest = append(*dest, t.loc)
-	}
-	for _, child := range t.children {
-		child.aggregate(dest)
-	}
-}
-
-func getSpanPositions(span []int32) (start, end []int32) {
-	start = span[:2]
-	if len(span) == 3 {
-		end = []int32{span[0], span[2]}
-	} else {
-		end = span[2:]
-	}
-	return
-}
-
-func compareSlice(a, b []int32) int {
-	end := len(a)
-	if len(b) < end {
-		end = len(b)
-	}
-	for i := 0; i < end; i++ {
-		if a[i] < b[i] {
-			return -1
-		}
-		if a[i] > b[i] {
-			return 1
-		}
-	}
-	if len(a) < len(b) {
-		return -1
-	}
-	if len(a) > len(b) {
-		return 1
-	}
-	return 0
+func dup(p []int32) []int32 {
+	return append(([]int32)(nil), p...)
 }