source.go (3982B)
1 // Copyright 2019 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package protoreflect 6 7 import ( 8 "strconv" 9 ) 10 11 // SourceLocations is a list of source locations. 12 type SourceLocations interface { 13 // Len reports the number of source locations in the proto file. 14 Len() int 15 // Get returns the ith SourceLocation. It panics if out of bounds. 16 Get(int) SourceLocation 17 18 // ByPath returns the SourceLocation for the given path, 19 // returning the first location if multiple exist for the same path. 20 // If multiple locations exist for the same path, 21 // then SourceLocation.Next index can be used to identify the 22 // index of the next SourceLocation. 23 // If no location exists for this path, it returns the zero value. 24 ByPath(path SourcePath) SourceLocation 25 26 // ByDescriptor returns the SourceLocation for the given descriptor, 27 // returning the first location if multiple exist for the same path. 28 // If no location exists for this descriptor, it returns the zero value. 29 ByDescriptor(desc Descriptor) SourceLocation 30 31 doNotImplement 32 } 33 34 // SourceLocation describes a source location and 35 // corresponds with the google.protobuf.SourceCodeInfo.Location message. 36 type SourceLocation struct { 37 // Path is the path to the declaration from the root file descriptor. 38 // The contents of this slice must not be mutated. 39 Path SourcePath 40 41 // StartLine and StartColumn are the zero-indexed starting location 42 // in the source file for the declaration. 43 StartLine, StartColumn int 44 // EndLine and EndColumn are the zero-indexed ending location 45 // in the source file for the declaration. 46 // In the descriptor.proto, the end line may be omitted if it is identical 47 // to the start line. Here, it is always populated. 48 EndLine, EndColumn int 49 50 // LeadingDetachedComments are the leading detached comments 51 // for the declaration. The contents of this slice must not be mutated. 52 LeadingDetachedComments []string 53 // LeadingComments is the leading attached comment for the declaration. 54 LeadingComments string 55 // TrailingComments is the trailing attached comment for the declaration. 56 TrailingComments string 57 58 // Next is an index into SourceLocations for the next source location that 59 // has the same Path. It is zero if there is no next location. 60 Next int 61 } 62 63 // SourcePath identifies part of a file descriptor for a source location. 64 // The SourcePath is a sequence of either field numbers or indexes into 65 // a repeated field that form a path starting from the root file descriptor. 66 // 67 // See google.protobuf.SourceCodeInfo.Location.path. 68 type SourcePath []int32 69 70 // Equal reports whether p1 equals p2. 71 func (p1 SourcePath) Equal(p2 SourcePath) bool { 72 if len(p1) != len(p2) { 73 return false 74 } 75 for i := range p1 { 76 if p1[i] != p2[i] { 77 return false 78 } 79 } 80 return true 81 } 82 83 // String formats the path in a humanly readable manner. 84 // The output is guaranteed to be deterministic, 85 // making it suitable for use as a key into a Go map. 86 // It is not guaranteed to be stable as the exact output could change 87 // in a future version of this module. 88 // 89 // Example output: 90 // 91 // .message_type[6].nested_type[15].field[3] 92 func (p SourcePath) String() string { 93 b := p.appendFileDescriptorProto(nil) 94 for _, i := range p { 95 b = append(b, '.') 96 b = strconv.AppendInt(b, int64(i), 10) 97 } 98 return string(b) 99 } 100 101 type appendFunc func(*SourcePath, []byte) []byte 102 103 func (p *SourcePath) appendSingularField(b []byte, name string, f appendFunc) []byte { 104 if len(*p) == 0 { 105 return b 106 } 107 b = append(b, '.') 108 b = append(b, name...) 109 *p = (*p)[1:] 110 if f != nil { 111 b = f(p, b) 112 } 113 return b 114 } 115 116 func (p *SourcePath) appendRepeatedField(b []byte, name string, f appendFunc) []byte { 117 b = p.appendSingularField(b, name, nil) 118 if len(*p) == 0 || (*p)[0] < 0 { 119 return b 120 } 121 b = append(b, '[') 122 b = strconv.AppendUint(b, uint64((*p)[0]), 10) 123 b = append(b, ']') 124 *p = (*p)[1:] 125 if f != nil { 126 b = f(p, b) 127 } 128 return b 129 }