@@ -307,6 +307,61 @@ func (s *symbol) GetSymbolInformation() protocol.SymbolInformation {
307307 }
308308}
309309
310+ // Rename returns the [protocol.WorkspaceEdit] for renaming the symbol.
311+ func (s * symbol ) Rename (newName string ) (* protocol.WorkspaceEdit , error ) {
312+ var edits protocol.WorkspaceEdit
313+ switch s .kind .(type ) {
314+ case * referenceable :
315+ changes , err := renameChangesForReferenceableSymbol (s , newName )
316+ if err != nil {
317+ return nil , err
318+ }
319+ edits .Changes = changes
320+ case * static :
321+ edits .Changes = map [protocol.DocumentURI ][]protocol.TextEdit {
322+ s .file .uri : {{
323+ Range : reportSpanToProtocolRange (s .span ),
324+ NewText : newName ,
325+ }},
326+ }
327+ case * reference :
328+ // For references, we attempt to rename the definition symbol, if resolved. This would
329+ // include this reference symbol.
330+ if s .def != nil {
331+ changes , err := renameChangesForReferenceableSymbol (s .def , newName )
332+ if err != nil {
333+ return nil , err
334+ }
335+ edits .Changes = changes
336+ }
337+ }
338+ // All other symbol types (options, imports, built-ins, and tags) cannot be renamed.
339+ return & edits , nil
340+ }
341+
342+ // renameChangesForReferenceableSymbol is a helper for getting all rename changes for the
343+ // given referenceable symbol.
344+ func renameChangesForReferenceableSymbol (s * symbol , newName string ) (map [protocol.DocumentURI ][]protocol.TextEdit , error ) {
345+ // At minimum, we would rename the symbol itself.
346+ changes := map [protocol.DocumentURI ][]protocol.TextEdit {
347+ s .file .uri : {{
348+ Range : reportSpanToProtocolRange (s .span ),
349+ NewText : newName ,
350+ }},
351+ }
352+ if def , ok := s .def .kind .(* referenceable ); ok {
353+ for _ , reference := range def .references {
354+ changes [reference .file .uri ] = append (changes [reference .file .uri ], protocol.TextEdit {
355+ Range : reportSpanToProtocolRange (reference .span ),
356+ NewText : newName ,
357+ })
358+ }
359+ } else {
360+ return nil , fmt .Errorf ("attempting to rename a non-referenceble symbol as a referenceable symbol: %v" , s )
361+ }
362+ return changes , nil
363+ }
364+
310365func protowireTypeForPredeclared (name predeclared.Name ) protowire.Type {
311366 switch name {
312367 case predeclared .Bool , predeclared .Int32 , predeclared .Int64 , predeclared .UInt32 ,
0 commit comments