1*1c12ee1eSDan Willemsen// Copyright 2018 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 impl 6*1c12ee1eSDan Willemsen 7*1c12ee1eSDan Willemsenimport ( 8*1c12ee1eSDan Willemsen "bytes" 9*1c12ee1eSDan Willemsen "compress/gzip" 10*1c12ee1eSDan Willemsen "io/ioutil" 11*1c12ee1eSDan Willemsen "sync" 12*1c12ee1eSDan Willemsen 13*1c12ee1eSDan Willemsen "google.golang.org/protobuf/internal/filedesc" 14*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoreflect" 15*1c12ee1eSDan Willemsen "google.golang.org/protobuf/reflect/protoregistry" 16*1c12ee1eSDan Willemsen) 17*1c12ee1eSDan Willemsen 18*1c12ee1eSDan Willemsen// Every enum and message type generated by protoc-gen-go since commit 2fc053c5 19*1c12ee1eSDan Willemsen// on February 25th, 2016 has had a method to get the raw descriptor. 20*1c12ee1eSDan Willemsen// Types that were not generated by protoc-gen-go or were generated prior 21*1c12ee1eSDan Willemsen// to that version are not supported. 22*1c12ee1eSDan Willemsen// 23*1c12ee1eSDan Willemsen// The []byte returned is the encoded form of a FileDescriptorProto message 24*1c12ee1eSDan Willemsen// compressed using GZIP. The []int is the path from the top-level file 25*1c12ee1eSDan Willemsen// to the specific message or enum declaration. 26*1c12ee1eSDan Willemsentype ( 27*1c12ee1eSDan Willemsen enumV1 interface { 28*1c12ee1eSDan Willemsen EnumDescriptor() ([]byte, []int) 29*1c12ee1eSDan Willemsen } 30*1c12ee1eSDan Willemsen messageV1 interface { 31*1c12ee1eSDan Willemsen Descriptor() ([]byte, []int) 32*1c12ee1eSDan Willemsen } 33*1c12ee1eSDan Willemsen) 34*1c12ee1eSDan Willemsen 35*1c12ee1eSDan Willemsenvar legacyFileDescCache sync.Map // map[*byte]protoreflect.FileDescriptor 36*1c12ee1eSDan Willemsen 37*1c12ee1eSDan Willemsen// legacyLoadFileDesc unmarshals b as a compressed FileDescriptorProto message. 38*1c12ee1eSDan Willemsen// 39*1c12ee1eSDan Willemsen// This assumes that b is immutable and that b does not refer to part of a 40*1c12ee1eSDan Willemsen// concatenated series of GZIP files (which would require shenanigans that 41*1c12ee1eSDan Willemsen// rely on the concatenation properties of both protobufs and GZIP). 42*1c12ee1eSDan Willemsen// File descriptors generated by protoc-gen-go do not rely on that property. 43*1c12ee1eSDan Willemsenfunc legacyLoadFileDesc(b []byte) protoreflect.FileDescriptor { 44*1c12ee1eSDan Willemsen // Fast-path: check whether we already have a cached file descriptor. 45*1c12ee1eSDan Willemsen if fd, ok := legacyFileDescCache.Load(&b[0]); ok { 46*1c12ee1eSDan Willemsen return fd.(protoreflect.FileDescriptor) 47*1c12ee1eSDan Willemsen } 48*1c12ee1eSDan Willemsen 49*1c12ee1eSDan Willemsen // Slow-path: decompress and unmarshal the file descriptor proto. 50*1c12ee1eSDan Willemsen zr, err := gzip.NewReader(bytes.NewReader(b)) 51*1c12ee1eSDan Willemsen if err != nil { 52*1c12ee1eSDan Willemsen panic(err) 53*1c12ee1eSDan Willemsen } 54*1c12ee1eSDan Willemsen b2, err := ioutil.ReadAll(zr) 55*1c12ee1eSDan Willemsen if err != nil { 56*1c12ee1eSDan Willemsen panic(err) 57*1c12ee1eSDan Willemsen } 58*1c12ee1eSDan Willemsen 59*1c12ee1eSDan Willemsen fd := filedesc.Builder{ 60*1c12ee1eSDan Willemsen RawDescriptor: b2, 61*1c12ee1eSDan Willemsen FileRegistry: resolverOnly{protoregistry.GlobalFiles}, // do not register back to global registry 62*1c12ee1eSDan Willemsen }.Build().File 63*1c12ee1eSDan Willemsen if fd, ok := legacyFileDescCache.LoadOrStore(&b[0], fd); ok { 64*1c12ee1eSDan Willemsen return fd.(protoreflect.FileDescriptor) 65*1c12ee1eSDan Willemsen } 66*1c12ee1eSDan Willemsen return fd 67*1c12ee1eSDan Willemsen} 68*1c12ee1eSDan Willemsen 69*1c12ee1eSDan Willemsentype resolverOnly struct { 70*1c12ee1eSDan Willemsen reg *protoregistry.Files 71*1c12ee1eSDan Willemsen} 72*1c12ee1eSDan Willemsen 73*1c12ee1eSDan Willemsenfunc (r resolverOnly) FindFileByPath(path string) (protoreflect.FileDescriptor, error) { 74*1c12ee1eSDan Willemsen return r.reg.FindFileByPath(path) 75*1c12ee1eSDan Willemsen} 76*1c12ee1eSDan Willemsenfunc (r resolverOnly) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) { 77*1c12ee1eSDan Willemsen return r.reg.FindDescriptorByName(name) 78*1c12ee1eSDan Willemsen} 79*1c12ee1eSDan Willemsenfunc (resolverOnly) RegisterFile(protoreflect.FileDescriptor) error { 80*1c12ee1eSDan Willemsen return nil 81*1c12ee1eSDan Willemsen} 82