vendor/google.golang.org/protobuf/internal/impl/legacy_export.go
changeset 256 6d9efbef00a9
child 260 445e01aede7e
equal deleted inserted replaced
255:4f153a23adab 256:6d9efbef00a9
       
     1 // Copyright 2019 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 	"encoding/binary"
       
     9 	"encoding/json"
       
    10 	"hash/crc32"
       
    11 	"math"
       
    12 	"reflect"
       
    13 
       
    14 	"google.golang.org/protobuf/internal/errors"
       
    15 	pref "google.golang.org/protobuf/reflect/protoreflect"
       
    16 	piface "google.golang.org/protobuf/runtime/protoiface"
       
    17 )
       
    18 
       
    19 // These functions exist to support exported APIs in generated protobufs.
       
    20 // While these are deprecated, they cannot be removed for compatibility reasons.
       
    21 
       
    22 // LegacyEnumName returns the name of enums used in legacy code.
       
    23 func (Export) LegacyEnumName(ed pref.EnumDescriptor) string {
       
    24 	return legacyEnumName(ed)
       
    25 }
       
    26 
       
    27 // LegacyMessageTypeOf returns the protoreflect.MessageType for m,
       
    28 // with name used as the message name if necessary.
       
    29 func (Export) LegacyMessageTypeOf(m piface.MessageV1, name pref.FullName) pref.MessageType {
       
    30 	if mv := (Export{}).protoMessageV2Of(m); mv != nil {
       
    31 		return mv.ProtoReflect().Type()
       
    32 	}
       
    33 	return legacyLoadMessageType(reflect.TypeOf(m), name)
       
    34 }
       
    35 
       
    36 // UnmarshalJSONEnum unmarshals an enum from a JSON-encoded input.
       
    37 // The input can either be a string representing the enum value by name,
       
    38 // or a number representing the enum number itself.
       
    39 func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumber, error) {
       
    40 	if b[0] == '"' {
       
    41 		var name pref.Name
       
    42 		if err := json.Unmarshal(b, &name); err != nil {
       
    43 			return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
       
    44 		}
       
    45 		ev := ed.Values().ByName(name)
       
    46 		if ev == nil {
       
    47 			return 0, errors.New("invalid value for enum %v: %s", ed.FullName(), name)
       
    48 		}
       
    49 		return ev.Number(), nil
       
    50 	} else {
       
    51 		var num pref.EnumNumber
       
    52 		if err := json.Unmarshal(b, &num); err != nil {
       
    53 			return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b)
       
    54 		}
       
    55 		return num, nil
       
    56 	}
       
    57 }
       
    58 
       
    59 // CompressGZIP compresses the input as a GZIP-encoded file.
       
    60 // The current implementation does no compression.
       
    61 func (Export) CompressGZIP(in []byte) (out []byte) {
       
    62 	// RFC 1952, section 2.3.1.
       
    63 	var gzipHeader = [10]byte{0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}
       
    64 
       
    65 	// RFC 1951, section 3.2.4.
       
    66 	var blockHeader [5]byte
       
    67 	const maxBlockSize = math.MaxUint16
       
    68 	numBlocks := 1 + len(in)/maxBlockSize
       
    69 
       
    70 	// RFC 1952, section 2.3.1.
       
    71 	var gzipFooter [8]byte
       
    72 	binary.LittleEndian.PutUint32(gzipFooter[0:4], crc32.ChecksumIEEE(in))
       
    73 	binary.LittleEndian.PutUint32(gzipFooter[4:8], uint32(len(in)))
       
    74 
       
    75 	// Encode the input without compression using raw DEFLATE blocks.
       
    76 	out = make([]byte, 0, len(gzipHeader)+len(blockHeader)*numBlocks+len(in)+len(gzipFooter))
       
    77 	out = append(out, gzipHeader[:]...)
       
    78 	for blockHeader[0] == 0 {
       
    79 		blockSize := maxBlockSize
       
    80 		if blockSize > len(in) {
       
    81 			blockHeader[0] = 0x01 // final bit per RFC 1951, section 3.2.3.
       
    82 			blockSize = len(in)
       
    83 		}
       
    84 		binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize)^0x0000)
       
    85 		binary.LittleEndian.PutUint16(blockHeader[3:5], uint16(blockSize)^0xffff)
       
    86 		out = append(out, blockHeader[:]...)
       
    87 		out = append(out, in[:blockSize]...)
       
    88 		in = in[blockSize:]
       
    89 	}
       
    90 	out = append(out, gzipFooter[:]...)
       
    91 	return out
       
    92 }