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