func encodeExtensions(e *XXX_InternalExtensions) error {
	m, mu := e.extensionsRead()
	if m == nil {
		return nil  
	}
	mu.Lock()
	defer mu.Unlock()
	return encodeExtensionsMap(m)
}
encode encodes any unmarshaled (unencoded) extensions in e.
package proto
import (
	"errors"
	"fmt"
	"reflect"
	"strconv"
	"sync"
)
var ErrMissingExtension = errors.New("proto: missing extension")
type ExtensionRange struct {
	Start, End int32  
}
type extendableProto interface {
	Message
	ExtensionRangeArray() []ExtensionRange
	extensionsWrite() map[int32]Extension
	extensionsRead() (map[int32]Extension, sync.Locker)
}
type extendableProtoV1 interface {
	Message
	ExtensionRangeArray() []ExtensionRange
	ExtensionMap() map[int32]Extension
}
type extensionAdapter struct {
	extendableProtoV1
}
func (e extensionAdapter) extensionsWrite() map[int32]Extension {
	return e.ExtensionMap()
}
func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
	return e.ExtensionMap(), notLocker{}
}
type notLocker struct{}
func (n notLocker) Lock()   {}
func (n notLocker) Unlock() {}
func extendable(p interface{}) (extendableProto, bool) {
	if ep, ok := p.(extendableProto); ok {
		return ep, ok
	}
	if ep, ok := p.(extendableProtoV1); ok {
		return extensionAdapter{ep}, ok
	}
	return nil, false
}
type XXX_InternalExtensions struct {
	p *struct {
		mu           sync.Mutex
		extensionMap map[int32]Extension
	}
}
func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {
	if e.p == nil {
		e.p = new(struct {
			mu           sync.Mutex
			extensionMap map[int32]Extension
		})
		e.p.extensionMap = make(map[int32]Extension)
	}
	return e.p.extensionMap
}
func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {
	if e.p == nil {
		return nil, nil
	}
	return e.p.extensionMap, &e.p.mu
}
var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
type ExtensionDesc struct {
	ExtendedType  Message      
	ExtensionType interface{}  
	Field         int32        
	Name          string       
	Tag           string       
}
func (ed *ExtensionDesc) repeated() bool {
	t := reflect.TypeOf(ed.ExtensionType)
	return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
}
type Extension struct {
	desc  *ExtensionDesc
	value interface{}
	enc   []byte
}
func SetRawExtension(base Message, id int32, b []byte) {
	epb, ok := extendable(base)
	if !ok {
		return
	}
	extmap := epb.extensionsWrite()
	extmap[id] = Extension{enc: b}
}
func isExtensionField(pb extendableProto, field int32) bool {
	for _, er := range pb.ExtensionRangeArray() {
		if er.Start <= field && field <= er.End {
			return true
		}
	}
	return false
}
func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
	var pbi interface{} = pb
	if ea, ok := pbi.(extensionAdapter); ok {
		pbi = ea.extendableProtoV1
	}
	if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
	}
	if !isExtensionField(pb, extension.Field) {
		return errors.New("proto: bad extension number; not in declared ranges")
	}
	return nil
}
type extPropKey struct {
	base  reflect.Type
	field int32
}
var extProp = struct {
	sync.RWMutex
	m map[extPropKey]*Properties
}{
	m: make(map[extPropKey]*Properties),
}
func extensionProperties(ed *ExtensionDesc) *Properties {
	key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
	extProp.RLock()
	if prop, ok := extProp.m[key]; ok {
		extProp.RUnlock()
		return prop
	}
	extProp.RUnlock()
	extProp.Lock()
	defer extProp.Unlock()
	if prop, ok := extProp.m[key]; ok {
		return prop
	}
	prop := new(Properties)
	prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
	extProp.m[key] = prop
	return prop
}