-
Notifications
You must be signed in to change notification settings - Fork 0
/
decoder.go
311 lines (268 loc) · 7.99 KB
/
decoder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package codegen
import (
"encoding"
"encoding/binary"
"errors"
"fmt"
"math"
"reflect"
"google.golang.org/protobuf/proto"
)
// decoderError is the type of error passed to panic by decoding code that encounters an error.
type decoderError struct {
err error
}
func (d decoderError) Error() string {
if d.err == nil {
return "decoder:"
}
return "decoder: " + d.err.Error()
}
func (d decoderError) Unwrap() error {
return d.err
}
// Decoder deserializes data from a byte slice data in the expected results.
type Decoder struct {
data []byte
}
// NewDecoder instantiates a new Decoder for a given byte slice.
func NewDecoder(data []byte) *Decoder {
return &Decoder{data}
}
// Empty returns true iff all bytes in d have been consumed.
func (d *Decoder) Empty() bool {
return len(d.data) == 0
}
// makeDecodeError creates and returns a decoder error.
func makeDecodeError(format string, args ...interface{}) decoderError {
return decoderError{fmt.Errorf(format, args...)}
}
// DecodeProto deserializes the value from a byte slice using proto serialization.
func (d *Decoder) DecodeProto(value proto.Message) {
if err := proto.Unmarshal(d.Bytes(), value); err != nil {
panic(makeDecodeError("error decoding to proto %T: %w", value, err))
}
}
// DecodeBinaryUnmarshaler deserializes the value from a byte slice using
// UnmarshalBinary.
func (d *Decoder) DecodeBinaryUnmarshaler(value encoding.BinaryUnmarshaler) {
if err := value.UnmarshalBinary(d.Bytes()); err != nil {
panic(makeDecodeError("error decoding BinaryUnmarshaler %T: %w", value, err))
}
}
// Read reads and returns n bytes from the decoder and advances the decode past
// the read bytes.
func (d *Decoder) Read(n int) []byte {
if len := len(d.data); len < n {
panic(makeDecodeError("unable to read #bytes: %d", n))
}
b := d.data[:n]
d.data = d.data[n:]
return b
}
// Uint8 decodes a value of type uint8.
func (d *Decoder) Uint8() uint8 {
return d.Read(1)[0]
}
// Byte decodes a value of type byte.
func (d *Decoder) Byte() byte {
return d.Uint8()
}
// Int8 decodes a value of type int8.
func (d *Decoder) Int8() int8 {
return int8(d.Uint8())
}
// Uint16 decodes a value of type uint16.
func (d *Decoder) Uint16() uint16 {
return binary.LittleEndian.Uint16(d.Read(2))
}
// Int16 decodes a value of type int16.
func (d *Decoder) Int16() int16 {
return int16(d.Uint16())
}
// Uint32 decodes a value of type uint32.
func (d *Decoder) Uint32() uint32 {
return binary.LittleEndian.Uint32(d.Read(4))
}
// Int32 decodes a value of type int32.
func (d *Decoder) Int32() int32 {
return int32(d.Uint32())
}
// Rune decodes a value of type rune.
func (d *Decoder) Rune() rune {
return d.Int32()
}
// Uint64 decodes a value of type uint64.
func (d *Decoder) Uint64() uint64 {
return binary.LittleEndian.Uint64(d.Read(8))
}
// Int64 decodes a value of type int64.
func (d *Decoder) Int64() int64 {
return int64(d.Uint64())
}
// Uint decodes a value of type uint.
// Uint values are encoded as 64 bits.
func (d *Decoder) Uint() uint {
return uint(d.Uint64())
}
// Int decodes a value of type int.
// Int values are encoded as 64 bits.
func (d *Decoder) Int() int {
return int(d.Int64())
}
// Bool decodes a value of type bool.
func (d *Decoder) Bool() bool {
if b := d.Uint8(); b == 0 {
return false
} else if b == 1 {
return true
} else {
panic(makeDecodeError("unable to decode bool; expected {0, 1} got %v", b))
}
}
// Float32 decodes a value of type float32.
func (d *Decoder) Float32() float32 {
return math.Float32frombits(d.Uint32())
}
// Float64 decodes a value of type float64.
func (d *Decoder) Float64() float64 {
return math.Float64frombits(d.Uint64())
}
// Complex64 decodes a value of type complex64.
func (d *Decoder) Complex64() complex64 {
return complex(d.Float32(), d.Float32())
}
// Complex128 decodes a value of type complex128.
func (d *Decoder) Complex128() complex128 {
return complex(d.Float64(), d.Float64())
}
// String decodes a value of type string.
func (d *Decoder) String() string {
return string(d.Bytes())
}
// Bytes decodes a value of type []byte.
func (d *Decoder) Bytes() []byte {
n := d.Int32()
// n == -1 means a nil slice.
if n == -1 {
return nil
}
if n < 0 {
panic(makeDecodeError("unable to decode bytes; expected length >= 0 got %d", n))
}
return d.Read(int(n))
}
// Len attempts to decode an int32.
//
// Panics if the result is negative (except -1).
//
// NOTE that this method should be called only in the generated code, to avoid
// generating repetitive code that decodes the length of a non-basic type (e.g., slice, map).
func (d *Decoder) Len() int {
n := int(d.Int32())
if n < -1 {
panic(makeDecodeError("length can't be smaller than -1"))
}
return n
}
// Error decodes an error. We construct an instance of a special error value
// that provides Is and Unwrap support.
func (d *Decoder) Error() error {
// Decode the list of errors produced by Encoder.Error().
var list []error
for {
tag := d.Uint8()
if tag == endOfErrors {
break
} else if tag == serializedErrorVal {
val := d.Interface()
if e, ok := val.(error); ok {
list = append(list, e)
continue
}
panic(fmt.Sprintf("received type %T which is not an error", val))
} else if tag == serializedErrorPtr {
val := d.Interface()
if e, ok := pointee(val).(error); ok {
list = append(list, e)
continue
}
panic(fmt.Sprintf("received type %T which is not a pointer to error", val))
} else if tag == emulatedError {
msg := d.String()
f := d.String()
list = append(list, decodedError{msg, f})
} else {
panic(fmt.Sprintf("invalid error list tag %d", tag))
}
}
if len(list) == 1 {
return list[0] // Preserve original error instead of wrapping it via Join
}
return errors.Join(list...)
}
// Interface decodes a value encoded by Encoder.Interface.
// Panics if the encoded value does not belong to a type registered
// using RegisterSerializable.
func (d *Decoder) Interface() any {
key := d.String()
typesMu.Lock()
defer typesMu.Unlock()
t, ok := types[key]
if !ok {
panic(fmt.Sprintf("received value for non-registered type %q", key))
}
// Allocate space for the value.
var ptr reflect.Value
if t.Kind() == reflect.Pointer {
ptr = reflect.New(t.Elem())
} else {
ptr = reflect.New(t)
}
am, ok := ptr.Interface().(AutoMarshal)
if !ok {
panic(fmt.Sprintf("received value for non-serializable type %v", t))
}
am.WeaverUnmarshal(d)
result := ptr
if t.Kind() != reflect.Pointer {
result = ptr.Elem()
}
return result.Interface()
}
// decodedError is an error used for non-serializable decoded errors.
// It supports Error() by returning the Error() string precomputed at
// the send. It partially supports Is() by comparing the string
// representation of the value.
type decodedError struct {
msg string // Error() result
fmt string // Result of fmtError
}
var _ error = decodedError{}
// Error implements error.Error.
func (e decodedError) Error() string { return e.msg }
// Is returns true if the representation of this error is the same as the
// representation of the target error. Note that this is not the same
// as the normal specification of errors.Is, but is the best we can do.
func (e decodedError) Is(target error) bool {
return e.fmt == fmtError(target)
}
// fmtError serializes an error value including its type info using fmt.Sprintf.
func fmtError(v error) string {
// Include package and type info explicitly since %#v uses a shortened path.
t := reflect.TypeOf(v)
return fmt.Sprintf("(%s:%#v)", t.PkgPath(), v)
}