256
|
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: |
260
|
90 |
// |
256
|
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 |
} |