mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-04 02:38:50 +00:00
d888139e7b
The internal/fileinit package is split apart into two packages: * internal/filedesc constructs descriptors from the raw proto. It is very similar to the previous internal/fileinit package. * internal/filetype wraps descriptors with Go type information Overview: * The internal/fileinit package will be deleted in a future CL. It is kept around since the v1 repo currently depends on it. * The internal/prototype package is deleted. All former usages of it are now using internal/filedesc instead. Most significantly, the reflect/protodesc package was almost entirely re-written. * The internal/impl package drops support for messages that do not have a Descriptor method (pre-2016). This removes a significant amount of technical debt. filedesc.Builder to parse raw descriptors. * The internal/encoding/defval package now handles enum values by name. Change-Id: I3957bcc8588a70470fd6c7de1122216b80615ab7 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/182360 Reviewed-by: Damien Neil <dneil@google.com>
125 lines
3.0 KiB
Go
125 lines
3.0 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build !purego,!appengine
|
|
|
|
package filedesc
|
|
|
|
import (
|
|
"sync"
|
|
"unsafe"
|
|
|
|
pref "google.golang.org/protobuf/reflect/protoreflect"
|
|
)
|
|
|
|
var nameBuilderPool = sync.Pool{
|
|
New: func() interface{} { return new(nameBuilder) },
|
|
}
|
|
|
|
func getNameBuilder() *nameBuilder {
|
|
return nameBuilderPool.Get().(*nameBuilder)
|
|
}
|
|
func putNameBuilder(b *nameBuilder) {
|
|
nameBuilderPool.Put(b)
|
|
}
|
|
|
|
type nameBuilder struct {
|
|
sb stringBuilder
|
|
}
|
|
|
|
// MakeFullName converts b to a protoreflect.FullName,
|
|
// where b must start with a leading dot.
|
|
func (nb *nameBuilder) MakeFullName(b []byte) pref.FullName {
|
|
if len(b) == 0 || b[0] != '.' {
|
|
panic("name reference must be fully qualified")
|
|
}
|
|
return pref.FullName(nb.MakeString(b[1:]))
|
|
}
|
|
|
|
// AppendFullName is equivalent to protoreflect.FullName.Append,
|
|
// but optimized for large batches where each name has a shared lifetime.
|
|
func (nb *nameBuilder) AppendFullName(prefix pref.FullName, name []byte) pref.FullName {
|
|
n := len(prefix) + len(".") + len(name)
|
|
if len(prefix) == 0 {
|
|
n -= len(".")
|
|
}
|
|
nb.grow(n)
|
|
nb.sb.WriteString(string(prefix))
|
|
nb.sb.WriteByte('.')
|
|
nb.sb.Write(name)
|
|
return pref.FullName(nb.last(n))
|
|
}
|
|
|
|
// MakeString is equivalent to string(b), but optimized for large batches
|
|
// with a shared lifetime.
|
|
func (nb *nameBuilder) MakeString(b []byte) string {
|
|
nb.grow(len(b))
|
|
nb.sb.Write(b)
|
|
return nb.last(len(b))
|
|
}
|
|
|
|
func (nb *nameBuilder) last(n int) string {
|
|
s := nb.sb.String()
|
|
return s[len(s)-n:]
|
|
}
|
|
|
|
func (nb *nameBuilder) grow(n int) {
|
|
const batchSize = 1 << 16
|
|
if nb.sb.Cap()-nb.sb.Len() < n {
|
|
nb.sb.Reset()
|
|
nb.sb.Grow(batchSize)
|
|
}
|
|
}
|
|
|
|
// stringsBuilder is a simplified copy of the strings.Builder from Go1.12:
|
|
// * removed the shallow copy check
|
|
// * removed methods that we do not use (e.g. WriteRune)
|
|
//
|
|
// A forked version is used:
|
|
// * to enable Go1.9 support, but strings.Builder was added in Go1.10
|
|
// * for the Cap method, which was missing until Go1.12
|
|
//
|
|
// TODO: Remove this when Go1.12 is the minimally supported toolchain version.
|
|
type stringBuilder struct {
|
|
buf []byte
|
|
}
|
|
|
|
func (b *stringBuilder) String() string {
|
|
return *(*string)(unsafe.Pointer(&b.buf))
|
|
}
|
|
func (b *stringBuilder) Len() int {
|
|
return len(b.buf)
|
|
}
|
|
func (b *stringBuilder) Cap() int {
|
|
return cap(b.buf)
|
|
}
|
|
func (b *stringBuilder) Reset() {
|
|
b.buf = nil
|
|
}
|
|
func (b *stringBuilder) grow(n int) {
|
|
buf := make([]byte, len(b.buf), 2*cap(b.buf)+n)
|
|
copy(buf, b.buf)
|
|
b.buf = buf
|
|
}
|
|
func (b *stringBuilder) Grow(n int) {
|
|
if n < 0 {
|
|
panic("stringBuilder.Grow: negative count")
|
|
}
|
|
if cap(b.buf)-len(b.buf) < n {
|
|
b.grow(n)
|
|
}
|
|
}
|
|
func (b *stringBuilder) Write(p []byte) (int, error) {
|
|
b.buf = append(b.buf, p...)
|
|
return len(p), nil
|
|
}
|
|
func (b *stringBuilder) WriteByte(c byte) error {
|
|
b.buf = append(b.buf, c)
|
|
return nil
|
|
}
|
|
func (b *stringBuilder) WriteString(s string) (int, error) {
|
|
b.buf = append(b.buf, s...)
|
|
return len(s), nil
|
|
}
|