blob: 0b99428855fe9499b9bb4dc57e49c5bebfb2d624 [file] [log] [blame]
khenaidoo5fc5cea2021-08-11 17:39:16 -04001// 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
5package protoreflect
6
7import (
8 "strconv"
9)
10
11// SourceLocations is a list of source locations.
12type 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.
36type 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.
68type SourcePath []int32
69
70// Equal reports whether p1 equals p2.
71func (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:
Joey Armstrongba3d9d12024-01-15 14:22:11 -050090//
khenaidoo5fc5cea2021-08-11 17:39:16 -040091// .message_type[6].nested_type[15].field[3]
92func (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
101type appendFunc func(*SourcePath, []byte) []byte
102
103func (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
116func (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}