vendor/google.golang.org/protobuf/reflect/protoreflect/source.go
changeset 256 6d9efbef00a9
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
       
     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 //	.message_type[6].nested_type[15].field[3]
       
    91 func (p SourcePath) String() string {
       
    92 	b := p.appendFileDescriptorProto(nil)
       
    93 	for _, i := range p {
       
    94 		b = append(b, '.')
       
    95 		b = strconv.AppendInt(b, int64(i), 10)
       
    96 	}
       
    97 	return string(b)
       
    98 }
       
    99 
       
   100 type appendFunc func(*SourcePath, []byte) []byte
       
   101 
       
   102 func (p *SourcePath) appendSingularField(b []byte, name string, f appendFunc) []byte {
       
   103 	if len(*p) == 0 {
       
   104 		return b
       
   105 	}
       
   106 	b = append(b, '.')
       
   107 	b = append(b, name...)
       
   108 	*p = (*p)[1:]
       
   109 	if f != nil {
       
   110 		b = f(p, b)
       
   111 	}
       
   112 	return b
       
   113 }
       
   114 
       
   115 func (p *SourcePath) appendRepeatedField(b []byte, name string, f appendFunc) []byte {
       
   116 	b = p.appendSingularField(b, name, nil)
       
   117 	if len(*p) == 0 || (*p)[0] < 0 {
       
   118 		return b
       
   119 	}
       
   120 	b = append(b, '[')
       
   121 	b = strconv.AppendUint(b, uint64((*p)[0]), 10)
       
   122 	b = append(b, ']')
       
   123 	*p = (*p)[1:]
       
   124 	if f != nil {
       
   125 		b = f(p, b)
       
   126 	}
       
   127 	return b
       
   128 }