...

Source file src/google.golang.org/protobuf/internal/strs/strings_unsafe_go121.go

Documentation: google.golang.org/protobuf/internal/strs

     1  // Copyright 2018 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  //go:build !purego && !appengine && go1.21
     6  // +build !purego,!appengine,go1.21
     7  
     8  package strs
     9  
    10  import (
    11  	"unsafe"
    12  
    13  	"google.golang.org/protobuf/reflect/protoreflect"
    14  )
    15  
    16  // UnsafeString returns an unsafe string reference of b.
    17  // The caller must treat the input slice as immutable.
    18  //
    19  // WARNING: Use carefully. The returned result must not leak to the end user
    20  // unless the input slice is provably immutable.
    21  func UnsafeString(b []byte) string {
    22  	return unsafe.String(unsafe.SliceData(b), len(b))
    23  }
    24  
    25  // UnsafeBytes returns an unsafe bytes slice reference of s.
    26  // The caller must treat returned slice as immutable.
    27  //
    28  // WARNING: Use carefully. The returned result must not leak to the end user.
    29  func UnsafeBytes(s string) []byte {
    30  	return unsafe.Slice(unsafe.StringData(s), len(s))
    31  }
    32  
    33  // Builder builds a set of strings with shared lifetime.
    34  // This differs from strings.Builder, which is for building a single string.
    35  type Builder struct {
    36  	buf []byte
    37  }
    38  
    39  // AppendFullName is equivalent to protoreflect.FullName.Append,
    40  // but optimized for large batches where each name has a shared lifetime.
    41  func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName {
    42  	n := len(prefix) + len(".") + len(name)
    43  	if len(prefix) == 0 {
    44  		n -= len(".")
    45  	}
    46  	sb.grow(n)
    47  	sb.buf = append(sb.buf, prefix...)
    48  	sb.buf = append(sb.buf, '.')
    49  	sb.buf = append(sb.buf, name...)
    50  	return protoreflect.FullName(sb.last(n))
    51  }
    52  
    53  // MakeString is equivalent to string(b), but optimized for large batches
    54  // with a shared lifetime.
    55  func (sb *Builder) MakeString(b []byte) string {
    56  	sb.grow(len(b))
    57  	sb.buf = append(sb.buf, b...)
    58  	return sb.last(len(b))
    59  }
    60  
    61  func (sb *Builder) grow(n int) {
    62  	if cap(sb.buf)-len(sb.buf) >= n {
    63  		return
    64  	}
    65  
    66  	// Unlike strings.Builder, we do not need to copy over the contents
    67  	// of the old buffer since our builder provides no API for
    68  	// retrieving previously created strings.
    69  	sb.buf = make([]byte, 0, 2*(cap(sb.buf)+n))
    70  }
    71  
    72  func (sb *Builder) last(n int) string {
    73  	return UnsafeString(sb.buf[len(sb.buf)-n:])
    74  }
    75  

View as plain text