...

Source file src/google.golang.org/protobuf/internal/impl/legacy_file.go

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

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

View as plain text