func getMarshalInfo(t reflect.Type) *marshalInfo {
	marshalInfoLock.Lock()
	u, ok := marshalInfoMap[t]
	if !ok {
		u = &marshalInfo{typ: t}
		marshalInfoMap[t] = u
	}
	marshalInfoLock.Unlock()
	return u
}
getMarshalInfo returns the information to marshal a given type of message.
The info it returns may not necessarily initialized.
t is the type of the message (NOT the pointer to it).
package proto
import (
	"errors"
	"fmt"
	"math"
	"reflect"
	"sort"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"unicode/utf8"
)
type sizer func(pointer, int) int
type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)
type marshalInfo struct {
	typ          reflect.Type
	fields       []*marshalFieldInfo
	unrecognized field                       
	extensions   field                       
	v1extensions field                       
	sizecache    field                       
	initialized  int32                       
	messageset   bool                        
	hasmarshaler bool                        
	sync.RWMutex                             
	extElems     map[int32]*marshalElemInfo  
}
type marshalFieldInfo struct {
	field      field
	wiretag    uint64  
	tagsize    int     
	sizer      sizer
	marshaler  marshaler
	isPointer  bool
	required   bool                               
	name       string                             
	oneofElems map[reflect.Type]*marshalElemInfo  
}
type marshalElemInfo struct {
	wiretag   uint64  
	tagsize   int     
	sizer     sizer
	marshaler marshaler
	isptr     bool  
}
var (
	marshalInfoMap  = map[reflect.Type]*marshalInfo{}
	marshalInfoLock sync.Mutex
)