Home | History | Annotate | Download | only in gob
      1 // Copyright 2009 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 //go:generate go run encgen.go -output enc_helpers.go
      6 
      7 package gob
      8 
      9 import (
     10 	"encoding"
     11 	"encoding/binary"
     12 	"math"
     13 	"math/bits"
     14 	"reflect"
     15 	"sync"
     16 )
     17 
     18 const uint64Size = 8
     19 
     20 type encHelper func(state *encoderState, v reflect.Value) bool
     21 
     22 // encoderState is the global execution state of an instance of the encoder.
     23 // Field numbers are delta encoded and always increase. The field
     24 // number is initialized to -1 so 0 comes out as delta(1). A delta of
     25 // 0 terminates the structure.
     26 type encoderState struct {
     27 	enc      *Encoder
     28 	b        *encBuffer
     29 	sendZero bool                 // encoding an array element or map key/value pair; send zero values
     30 	fieldnum int                  // the last field number written.
     31 	buf      [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
     32 	next     *encoderState        // for free list
     33 }
     34 
     35 // encBuffer is an extremely simple, fast implementation of a write-only byte buffer.
     36 // It never returns a non-nil error, but Write returns an error value so it matches io.Writer.
     37 type encBuffer struct {
     38 	data    []byte
     39 	scratch [64]byte
     40 }
     41 
     42 var encBufferPool = sync.Pool{
     43 	New: func() interface{} {
     44 		e := new(encBuffer)
     45 		e.data = e.scratch[0:0]
     46 		return e
     47 	},
     48 }
     49 
     50 func (e *encBuffer) WriteByte(c byte) {
     51 	e.data = append(e.data, c)
     52 }
     53 
     54 func (e *encBuffer) Write(p []byte) (int, error) {
     55 	e.data = append(e.data, p...)
     56 	return len(p), nil
     57 }
     58 
     59 func (e *encBuffer) WriteString(s string) {
     60 	e.data = append(e.data, s...)
     61 }
     62 
     63 func (e *encBuffer) Len() int {
     64 	return len(e.data)
     65 }
     66 
     67 func (e *encBuffer) Bytes() []byte {
     68 	return e.data
     69 }
     70 
     71 func (e *encBuffer) Reset() {
     72 	if len(e.data) >= tooBig {
     73 		e.data = e.scratch[0:0]
     74 	} else {
     75 		e.data = e.data[0:0]
     76 	}
     77 }
     78 
     79 func (enc *Encoder) newEncoderState(b *encBuffer) *encoderState {
     80 	e := enc.freeList
     81 	if e == nil {
     82 		e = new(encoderState)
     83 		e.enc = enc
     84 	} else {
     85 		enc.freeList = e.next
     86 	}
     87 	e.sendZero = false
     88 	e.fieldnum = 0
     89 	e.b = b
     90 	if len(b.data) == 0 {
     91 		b.data = b.scratch[0:0]
     92 	}
     93 	return e
     94 }
     95 
     96 func (enc *Encoder) freeEncoderState(e *encoderState) {
     97 	e.next = enc.freeList
     98 	enc.freeList = e
     99 }
    100 
    101 // Unsigned integers have a two-state encoding. If the number is less
    102 // than 128 (0 through 0x7F), its value is written directly.
    103 // Otherwise the value is written in big-endian byte order preceded
    104 // by the byte length, negated.
    105 
    106 // encodeUint writes an encoded unsigned integer to state.b.
    107 func (state *encoderState) encodeUint(x uint64) {
    108 	if x <= 0x7F {
    109 		state.b.WriteByte(uint8(x))
    110 		return
    111 	}
    112 
    113 	binary.BigEndian.PutUint64(state.buf[1:], x)
    114 	bc := bits.LeadingZeros64(x) >> 3      // 8 - bytelen(x)
    115 	state.buf[bc] = uint8(bc - uint64Size) // and then we subtract 8 to get -bytelen(x)
    116 
    117 	state.b.Write(state.buf[bc : uint64Size+1])
    118 }
    119 
    120 // encodeInt writes an encoded signed integer to state.w.
    121 // The low bit of the encoding says whether to bit complement the (other bits of the)
    122 // uint to recover the int.
    123 func (state *encoderState) encodeInt(i int64) {
    124 	var x uint64
    125 	if i < 0 {
    126 		x = uint64(^i<<1) | 1
    127 	} else {
    128 		x = uint64(i << 1)
    129 	}
    130 	state.encodeUint(x)
    131 }
    132 
    133 // encOp is the signature of an encoding operator for a given type.
    134 type encOp func(i *encInstr, state *encoderState, v reflect.Value)
    135 
    136 // The 'instructions' of the encoding machine
    137 type encInstr struct {
    138 	op    encOp
    139 	field int   // field number in input
    140 	index []int // struct index
    141 	indir int   // how many pointer indirections to reach the value in the struct
    142 }
    143 
    144 // update emits a field number and updates the state to record its value for delta encoding.
    145 // If the instruction pointer is nil, it does nothing
    146 func (state *encoderState) update(instr *encInstr) {
    147 	if instr != nil {
    148 		state.encodeUint(uint64(instr.field - state.fieldnum))
    149 		state.fieldnum = instr.field
    150 	}
    151 }
    152 
    153 // Each encoder for a composite is responsible for handling any
    154 // indirections associated with the elements of the data structure.
    155 // If any pointer so reached is nil, no bytes are written. If the
    156 // data item is zero, no bytes are written. Single values - ints,
    157 // strings etc. - are indirected before calling their encoders.
    158 // Otherwise, the output (for a scalar) is the field number, as an
    159 // encoded integer, followed by the field data in its appropriate
    160 // format.
    161 
    162 // encIndirect dereferences pv indir times and returns the result.
    163 func encIndirect(pv reflect.Value, indir int) reflect.Value {
    164 	for ; indir > 0; indir-- {
    165 		if pv.IsNil() {
    166 			break
    167 		}
    168 		pv = pv.Elem()
    169 	}
    170 	return pv
    171 }
    172 
    173 // encBool encodes the bool referenced by v as an unsigned 0 or 1.
    174 func encBool(i *encInstr, state *encoderState, v reflect.Value) {
    175 	b := v.Bool()
    176 	if b || state.sendZero {
    177 		state.update(i)
    178 		if b {
    179 			state.encodeUint(1)
    180 		} else {
    181 			state.encodeUint(0)
    182 		}
    183 	}
    184 }
    185 
    186 // encInt encodes the signed integer (int int8 int16 int32 int64) referenced by v.
    187 func encInt(i *encInstr, state *encoderState, v reflect.Value) {
    188 	value := v.Int()
    189 	if value != 0 || state.sendZero {
    190 		state.update(i)
    191 		state.encodeInt(value)
    192 	}
    193 }
    194 
    195 // encUint encodes the unsigned integer (uint uint8 uint16 uint32 uint64 uintptr) referenced by v.
    196 func encUint(i *encInstr, state *encoderState, v reflect.Value) {
    197 	value := v.Uint()
    198 	if value != 0 || state.sendZero {
    199 		state.update(i)
    200 		state.encodeUint(value)
    201 	}
    202 }
    203 
    204 // floatBits returns a uint64 holding the bits of a floating-point number.
    205 // Floating-point numbers are transmitted as uint64s holding the bits
    206 // of the underlying representation. They are sent byte-reversed, with
    207 // the exponent end coming out first, so integer floating point numbers
    208 // (for example) transmit more compactly. This routine does the
    209 // swizzling.
    210 func floatBits(f float64) uint64 {
    211 	u := math.Float64bits(f)
    212 	return bits.ReverseBytes64(u)
    213 }
    214 
    215 // encFloat encodes the floating point value (float32 float64) referenced by v.
    216 func encFloat(i *encInstr, state *encoderState, v reflect.Value) {
    217 	f := v.Float()
    218 	if f != 0 || state.sendZero {
    219 		bits := floatBits(f)
    220 		state.update(i)
    221 		state.encodeUint(bits)
    222 	}
    223 }
    224 
    225 // encComplex encodes the complex value (complex64 complex128) referenced by v.
    226 // Complex numbers are just a pair of floating-point numbers, real part first.
    227 func encComplex(i *encInstr, state *encoderState, v reflect.Value) {
    228 	c := v.Complex()
    229 	if c != 0+0i || state.sendZero {
    230 		rpart := floatBits(real(c))
    231 		ipart := floatBits(imag(c))
    232 		state.update(i)
    233 		state.encodeUint(rpart)
    234 		state.encodeUint(ipart)
    235 	}
    236 }
    237 
    238 // encUint8Array encodes the byte array referenced by v.
    239 // Byte arrays are encoded as an unsigned count followed by the raw bytes.
    240 func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) {
    241 	b := v.Bytes()
    242 	if len(b) > 0 || state.sendZero {
    243 		state.update(i)
    244 		state.encodeUint(uint64(len(b)))
    245 		state.b.Write(b)
    246 	}
    247 }
    248 
    249 // encString encodes the string referenced by v.
    250 // Strings are encoded as an unsigned count followed by the raw bytes.
    251 func encString(i *encInstr, state *encoderState, v reflect.Value) {
    252 	s := v.String()
    253 	if len(s) > 0 || state.sendZero {
    254 		state.update(i)
    255 		state.encodeUint(uint64(len(s)))
    256 		state.b.WriteString(s)
    257 	}
    258 }
    259 
    260 // encStructTerminator encodes the end of an encoded struct
    261 // as delta field number of 0.
    262 func encStructTerminator(i *encInstr, state *encoderState, v reflect.Value) {
    263 	state.encodeUint(0)
    264 }
    265 
    266 // Execution engine
    267 
    268 // encEngine an array of instructions indexed by field number of the encoding
    269 // data, typically a struct. It is executed top to bottom, walking the struct.
    270 type encEngine struct {
    271 	instr []encInstr
    272 }
    273 
    274 const singletonField = 0
    275 
    276 // valid reports whether the value is valid and a non-nil pointer.
    277 // (Slices, maps, and chans take care of themselves.)
    278 func valid(v reflect.Value) bool {
    279 	switch v.Kind() {
    280 	case reflect.Invalid:
    281 		return false
    282 	case reflect.Ptr:
    283 		return !v.IsNil()
    284 	}
    285 	return true
    286 }
    287 
    288 // encodeSingle encodes a single top-level non-struct value.
    289 func (enc *Encoder) encodeSingle(b *encBuffer, engine *encEngine, value reflect.Value) {
    290 	state := enc.newEncoderState(b)
    291 	defer enc.freeEncoderState(state)
    292 	state.fieldnum = singletonField
    293 	// There is no surrounding struct to frame the transmission, so we must
    294 	// generate data even if the item is zero. To do this, set sendZero.
    295 	state.sendZero = true
    296 	instr := &engine.instr[singletonField]
    297 	if instr.indir > 0 {
    298 		value = encIndirect(value, instr.indir)
    299 	}
    300 	if valid(value) {
    301 		instr.op(instr, state, value)
    302 	}
    303 }
    304 
    305 // encodeStruct encodes a single struct value.
    306 func (enc *Encoder) encodeStruct(b *encBuffer, engine *encEngine, value reflect.Value) {
    307 	if !valid(value) {
    308 		return
    309 	}
    310 	state := enc.newEncoderState(b)
    311 	defer enc.freeEncoderState(state)
    312 	state.fieldnum = -1
    313 	for i := 0; i < len(engine.instr); i++ {
    314 		instr := &engine.instr[i]
    315 		if i >= value.NumField() {
    316 			// encStructTerminator
    317 			instr.op(instr, state, reflect.Value{})
    318 			break
    319 		}
    320 		field := value.FieldByIndex(instr.index)
    321 		if instr.indir > 0 {
    322 			field = encIndirect(field, instr.indir)
    323 			// TODO: Is field guaranteed valid? If so we could avoid this check.
    324 			if !valid(field) {
    325 				continue
    326 			}
    327 		}
    328 		instr.op(instr, state, field)
    329 	}
    330 }
    331 
    332 // encodeArray encodes an array.
    333 func (enc *Encoder) encodeArray(b *encBuffer, value reflect.Value, op encOp, elemIndir int, length int, helper encHelper) {
    334 	state := enc.newEncoderState(b)
    335 	defer enc.freeEncoderState(state)
    336 	state.fieldnum = -1
    337 	state.sendZero = true
    338 	state.encodeUint(uint64(length))
    339 	if helper != nil && helper(state, value) {
    340 		return
    341 	}
    342 	for i := 0; i < length; i++ {
    343 		elem := value.Index(i)
    344 		if elemIndir > 0 {
    345 			elem = encIndirect(elem, elemIndir)
    346 			// TODO: Is elem guaranteed valid? If so we could avoid this check.
    347 			if !valid(elem) {
    348 				errorf("encodeArray: nil element")
    349 			}
    350 		}
    351 		op(nil, state, elem)
    352 	}
    353 }
    354 
    355 // encodeReflectValue is a helper for maps. It encodes the value v.
    356 func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
    357 	for i := 0; i < indir && v.IsValid(); i++ {
    358 		v = reflect.Indirect(v)
    359 	}
    360 	if !v.IsValid() {
    361 		errorf("encodeReflectValue: nil element")
    362 	}
    363 	op(nil, state, v)
    364 }
    365 
    366 // encodeMap encodes a map as unsigned count followed by key:value pairs.
    367 func (enc *Encoder) encodeMap(b *encBuffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
    368 	state := enc.newEncoderState(b)
    369 	state.fieldnum = -1
    370 	state.sendZero = true
    371 	keys := mv.MapKeys()
    372 	state.encodeUint(uint64(len(keys)))
    373 	for _, key := range keys {
    374 		encodeReflectValue(state, key, keyOp, keyIndir)
    375 		encodeReflectValue(state, mv.MapIndex(key), elemOp, elemIndir)
    376 	}
    377 	enc.freeEncoderState(state)
    378 }
    379 
    380 // encodeInterface encodes the interface value iv.
    381 // To send an interface, we send a string identifying the concrete type, followed
    382 // by the type identifier (which might require defining that type right now), followed
    383 // by the concrete value. A nil value gets sent as the empty string for the name,
    384 // followed by no value.
    385 func (enc *Encoder) encodeInterface(b *encBuffer, iv reflect.Value) {
    386 	// Gobs can encode nil interface values but not typed interface
    387 	// values holding nil pointers, since nil pointers point to no value.
    388 	elem := iv.Elem()
    389 	if elem.Kind() == reflect.Ptr && elem.IsNil() {
    390 		errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
    391 	}
    392 	state := enc.newEncoderState(b)
    393 	state.fieldnum = -1
    394 	state.sendZero = true
    395 	if iv.IsNil() {
    396 		state.encodeUint(0)
    397 		return
    398 	}
    399 
    400 	ut := userType(iv.Elem().Type())
    401 	namei, ok := concreteTypeToName.Load(ut.base)
    402 	if !ok {
    403 		errorf("type not registered for interface: %s", ut.base)
    404 	}
    405 	name := namei.(string)
    406 
    407 	// Send the name.
    408 	state.encodeUint(uint64(len(name)))
    409 	state.b.WriteString(name)
    410 	// Define the type id if necessary.
    411 	enc.sendTypeDescriptor(enc.writer(), state, ut)
    412 	// Send the type id.
    413 	enc.sendTypeId(state, ut)
    414 	// Encode the value into a new buffer. Any nested type definitions
    415 	// should be written to b, before the encoded value.
    416 	enc.pushWriter(b)
    417 	data := encBufferPool.Get().(*encBuffer)
    418 	data.Write(spaceForLength)
    419 	enc.encode(data, elem, ut)
    420 	if enc.err != nil {
    421 		error_(enc.err)
    422 	}
    423 	enc.popWriter()
    424 	enc.writeMessage(b, data)
    425 	data.Reset()
    426 	encBufferPool.Put(data)
    427 	if enc.err != nil {
    428 		error_(enc.err)
    429 	}
    430 	enc.freeEncoderState(state)
    431 }
    432 
    433 // isZero reports whether the value is the zero of its type.
    434 func isZero(val reflect.Value) bool {
    435 	switch val.Kind() {
    436 	case reflect.Array:
    437 		for i := 0; i < val.Len(); i++ {
    438 			if !isZero(val.Index(i)) {
    439 				return false
    440 			}
    441 		}
    442 		return true
    443 	case reflect.Map, reflect.Slice, reflect.String:
    444 		return val.Len() == 0
    445 	case reflect.Bool:
    446 		return !val.Bool()
    447 	case reflect.Complex64, reflect.Complex128:
    448 		return val.Complex() == 0
    449 	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr:
    450 		return val.IsNil()
    451 	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    452 		return val.Int() == 0
    453 	case reflect.Float32, reflect.Float64:
    454 		return val.Float() == 0
    455 	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
    456 		return val.Uint() == 0
    457 	case reflect.Struct:
    458 		for i := 0; i < val.NumField(); i++ {
    459 			if !isZero(val.Field(i)) {
    460 				return false
    461 			}
    462 		}
    463 		return true
    464 	}
    465 	panic("unknown type in isZero " + val.Type().String())
    466 }
    467 
    468 // encGobEncoder encodes a value that implements the GobEncoder interface.
    469 // The data is sent as a byte array.
    470 func (enc *Encoder) encodeGobEncoder(b *encBuffer, ut *userTypeInfo, v reflect.Value) {
    471 	// TODO: should we catch panics from the called method?
    472 
    473 	var data []byte
    474 	var err error
    475 	// We know it's one of these.
    476 	switch ut.externalEnc {
    477 	case xGob:
    478 		data, err = v.Interface().(GobEncoder).GobEncode()
    479 	case xBinary:
    480 		data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
    481 	case xText:
    482 		data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
    483 	}
    484 	if err != nil {
    485 		error_(err)
    486 	}
    487 	state := enc.newEncoderState(b)
    488 	state.fieldnum = -1
    489 	state.encodeUint(uint64(len(data)))
    490 	state.b.Write(data)
    491 	enc.freeEncoderState(state)
    492 }
    493 
    494 var encOpTable = [...]encOp{
    495 	reflect.Bool:       encBool,
    496 	reflect.Int:        encInt,
    497 	reflect.Int8:       encInt,
    498 	reflect.Int16:      encInt,
    499 	reflect.Int32:      encInt,
    500 	reflect.Int64:      encInt,
    501 	reflect.Uint:       encUint,
    502 	reflect.Uint8:      encUint,
    503 	reflect.Uint16:     encUint,
    504 	reflect.Uint32:     encUint,
    505 	reflect.Uint64:     encUint,
    506 	reflect.Uintptr:    encUint,
    507 	reflect.Float32:    encFloat,
    508 	reflect.Float64:    encFloat,
    509 	reflect.Complex64:  encComplex,
    510 	reflect.Complex128: encComplex,
    511 	reflect.String:     encString,
    512 }
    513 
    514 // encOpFor returns (a pointer to) the encoding op for the base type under rt and
    515 // the indirection count to reach it.
    516 func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
    517 	ut := userType(rt)
    518 	// If the type implements GobEncoder, we handle it without further processing.
    519 	if ut.externalEnc != 0 {
    520 		return gobEncodeOpFor(ut)
    521 	}
    522 	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
    523 	// Return the pointer to the op we're already building.
    524 	if opPtr := inProgress[rt]; opPtr != nil {
    525 		return opPtr, ut.indir
    526 	}
    527 	typ := ut.base
    528 	indir := ut.indir
    529 	k := typ.Kind()
    530 	var op encOp
    531 	if int(k) < len(encOpTable) {
    532 		op = encOpTable[k]
    533 	}
    534 	if op == nil {
    535 		inProgress[rt] = &op
    536 		// Special cases
    537 		switch t := typ; t.Kind() {
    538 		case reflect.Slice:
    539 			if t.Elem().Kind() == reflect.Uint8 {
    540 				op = encUint8Array
    541 				break
    542 			}
    543 			// Slices have a header; we decode it to find the underlying array.
    544 			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
    545 			helper := encSliceHelper[t.Elem().Kind()]
    546 			op = func(i *encInstr, state *encoderState, slice reflect.Value) {
    547 				if !state.sendZero && slice.Len() == 0 {
    548 					return
    549 				}
    550 				state.update(i)
    551 				state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
    552 			}
    553 		case reflect.Array:
    554 			// True arrays have size in the type.
    555 			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
    556 			helper := encArrayHelper[t.Elem().Kind()]
    557 			op = func(i *encInstr, state *encoderState, array reflect.Value) {
    558 				state.update(i)
    559 				state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
    560 			}
    561 		case reflect.Map:
    562 			keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
    563 			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
    564 			op = func(i *encInstr, state *encoderState, mv reflect.Value) {
    565 				// We send zero-length (but non-nil) maps because the
    566 				// receiver might want to use the map.  (Maps don't use append.)
    567 				if !state.sendZero && mv.IsNil() {
    568 					return
    569 				}
    570 				state.update(i)
    571 				state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
    572 			}
    573 		case reflect.Struct:
    574 			// Generate a closure that calls out to the engine for the nested type.
    575 			getEncEngine(userType(typ), building)
    576 			info := mustGetTypeInfo(typ)
    577 			op = func(i *encInstr, state *encoderState, sv reflect.Value) {
    578 				state.update(i)
    579 				// indirect through info to delay evaluation for recursive structs
    580 				enc := info.encoder.Load().(*encEngine)
    581 				state.enc.encodeStruct(state.b, enc, sv)
    582 			}
    583 		case reflect.Interface:
    584 			op = func(i *encInstr, state *encoderState, iv reflect.Value) {
    585 				if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
    586 					return
    587 				}
    588 				state.update(i)
    589 				state.enc.encodeInterface(state.b, iv)
    590 			}
    591 		}
    592 	}
    593 	if op == nil {
    594 		errorf("can't happen: encode type %s", rt)
    595 	}
    596 	return &op, indir
    597 }
    598 
    599 // gobEncodeOpFor returns the op for a type that is known to implement GobEncoder.
    600 func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
    601 	rt := ut.user
    602 	if ut.encIndir == -1 {
    603 		rt = reflect.PtrTo(rt)
    604 	} else if ut.encIndir > 0 {
    605 		for i := int8(0); i < ut.encIndir; i++ {
    606 			rt = rt.Elem()
    607 		}
    608 	}
    609 	var op encOp
    610 	op = func(i *encInstr, state *encoderState, v reflect.Value) {
    611 		if ut.encIndir == -1 {
    612 			// Need to climb up one level to turn value into pointer.
    613 			if !v.CanAddr() {
    614 				errorf("unaddressable value of type %s", rt)
    615 			}
    616 			v = v.Addr()
    617 		}
    618 		if !state.sendZero && isZero(v) {
    619 			return
    620 		}
    621 		state.update(i)
    622 		state.enc.encodeGobEncoder(state.b, ut, v)
    623 	}
    624 	return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
    625 }
    626 
    627 // compileEnc returns the engine to compile the type.
    628 func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
    629 	srt := ut.base
    630 	engine := new(encEngine)
    631 	seen := make(map[reflect.Type]*encOp)
    632 	rt := ut.base
    633 	if ut.externalEnc != 0 {
    634 		rt = ut.user
    635 	}
    636 	if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
    637 		for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
    638 			f := srt.Field(fieldNum)
    639 			if !isSent(&f) {
    640 				continue
    641 			}
    642 			op, indir := encOpFor(f.Type, seen, building)
    643 			engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
    644 			wireFieldNum++
    645 		}
    646 		if srt.NumField() > 0 && len(engine.instr) == 0 {
    647 			errorf("type %s has no exported fields", rt)
    648 		}
    649 		engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
    650 	} else {
    651 		engine.instr = make([]encInstr, 1)
    652 		op, indir := encOpFor(rt, seen, building)
    653 		engine.instr[0] = encInstr{*op, singletonField, nil, indir}
    654 	}
    655 	return engine
    656 }
    657 
    658 // getEncEngine returns the engine to compile the type.
    659 func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
    660 	info, err := getTypeInfo(ut)
    661 	if err != nil {
    662 		error_(err)
    663 	}
    664 	enc, ok := info.encoder.Load().(*encEngine)
    665 	if !ok {
    666 		enc = buildEncEngine(info, ut, building)
    667 	}
    668 	return enc
    669 }
    670 
    671 func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
    672 	// Check for recursive types.
    673 	if building != nil && building[info] {
    674 		return nil
    675 	}
    676 	info.encInit.Lock()
    677 	defer info.encInit.Unlock()
    678 	enc, ok := info.encoder.Load().(*encEngine)
    679 	if !ok {
    680 		if building == nil {
    681 			building = make(map[*typeInfo]bool)
    682 		}
    683 		building[info] = true
    684 		enc = compileEnc(ut, building)
    685 		info.encoder.Store(enc)
    686 	}
    687 	return enc
    688 }
    689 
    690 func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
    691 	defer catchError(&enc.err)
    692 	engine := getEncEngine(ut, nil)
    693 	indir := ut.indir
    694 	if ut.externalEnc != 0 {
    695 		indir = int(ut.encIndir)
    696 	}
    697 	for i := 0; i < indir; i++ {
    698 		value = reflect.Indirect(value)
    699 	}
    700 	if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
    701 		enc.encodeStruct(b, engine, value)
    702 	} else {
    703 		enc.encodeSingle(b, engine, value)
    704 	}
    705 }
    706