mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-03-10 16:14:39 +00:00
This removes yet another set of dependencies of v2 on v1. The only remaining dependency are in the _test.go files, primarily for proto.Equal. Changes made: * cmd/protoc-gen-go no longer generates any functionality that depends on the v1 package, and instead only depends on v2. * internal/fileinit.FileBuilder.MessageOutputTypes is switched from protoreflect.MessageType to protoimpl.MessageType since the implementation must be fully inialized before registration occurs. * The test for internal/legacy/file_test.go is switched to a legacy_test package to avoid a cyclic dependency. This requires Load{Enum,Message,File}Desc to be exported. Change-Id: I43e2fe64cff4eea204258ce11e791aca5eb6e569 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/169298 Reviewed-by: Damien Neil <dneil@google.com>
81 lines
2.5 KiB
Go
81 lines
2.5 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.
|
|
|
|
package legacy
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"io/ioutil"
|
|
"sync"
|
|
|
|
"github.com/golang/protobuf/v2/proto"
|
|
pref "github.com/golang/protobuf/v2/reflect/protoreflect"
|
|
descriptorpb "github.com/golang/protobuf/v2/types/descriptor"
|
|
)
|
|
|
|
// Every enum and message type generated by protoc-gen-go since commit 2fc053c5
|
|
// on February 25th, 2016 has had a method to get the raw descriptor.
|
|
// Types that were not generated by protoc-gen-go or were generated prior
|
|
// to that version are not supported.
|
|
//
|
|
// The []byte returned is the encoded form of a FileDescriptorProto message
|
|
// compressed using GZIP. The []int is the path from the top-level file
|
|
// to the specific message or enum declaration.
|
|
type (
|
|
enumV1 interface {
|
|
EnumDescriptor() ([]byte, []int)
|
|
}
|
|
messageV1 interface {
|
|
Descriptor() ([]byte, []int)
|
|
}
|
|
)
|
|
|
|
var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto
|
|
|
|
// LoadFileDesc unmarshals b as a compressed FileDescriptorProto message.
|
|
//
|
|
// This assumes that b is immutable and that b does not refer to part of a
|
|
// concatenated series of GZIP files (which would require shenanigans that
|
|
// rely on the concatenation properties of both protobufs and GZIP).
|
|
// File descriptors generated by protoc-gen-go do not rely on that property.
|
|
//
|
|
// This is exported for testing purposes.
|
|
func LoadFileDesc(b []byte) *descriptorpb.FileDescriptorProto {
|
|
// Fast-path: check whether we already have a cached file descriptor.
|
|
if fd, ok := fileDescCache.Load(&b[0]); ok {
|
|
return fd.(*descriptorpb.FileDescriptorProto)
|
|
}
|
|
|
|
// Slow-path: decompress and unmarshal the file descriptor proto.
|
|
fd := new(descriptorpb.FileDescriptorProto)
|
|
zr, err := gzip.NewReader(bytes.NewReader(b))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
b, err = ioutil.ReadAll(zr)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
err = proto.UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, fd)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if fd, ok := fileDescCache.LoadOrStore(&b[0], fd); ok {
|
|
return fd.(*descriptorpb.FileDescriptorProto)
|
|
}
|
|
return fd
|
|
}
|
|
|
|
// parentFileDescriptor returns the parent protoreflect.FileDescriptor for the
|
|
// provide descriptor. It returns nil if there is no parent.
|
|
func parentFileDescriptor(d pref.Descriptor) pref.FileDescriptor {
|
|
for ok := true; ok; d, ok = d.Parent() {
|
|
if fd, _ := d.(pref.FileDescriptor); fd != nil {
|
|
return fd
|
|
}
|
|
}
|
|
return nil
|
|
}
|