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