// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2016 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package proto

import (
	
	
	
	
	
	
	
	
	
	
)

// a sizer takes a pointer to a field and the size of its tag, computes the size of
// the encoded data.
type sizer func(pointer, int) int

// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
// marshals the field to the end of the slice, returns the slice and error (if any).
type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)

// marshalInfo is the information used for marshaling a message.
type marshalInfo struct {
	typ          reflect.Type
	fields       []*marshalFieldInfo
	unrecognized field                      // offset of XXX_unrecognized
	extensions   field                      // offset of XXX_InternalExtensions
	v1extensions field                      // offset of XXX_extensions
	sizecache    field                      // offset of XXX_sizecache
	initialized  int32                      // 0 -- only typ is set, 1 -- fully initialized
	messageset   bool                       // uses message set wire format
	hasmarshaler bool                       // has custom marshaler
	sync.RWMutex                            // protect extElems map, also for initialization
	extElems     map[int32]*marshalElemInfo // info of extension elements

	hassizer      bool // has custom sizer
	hasprotosizer bool // has custom protosizer

	bytesExtensions field // offset of XXX_extensions where the field type is []byte
}

// marshalFieldInfo is the information used for marshaling a field of a message.
type marshalFieldInfo struct {
	field      field
	wiretag    uint64 // tag in wire format
	tagsize    int    // size of tag in wire format
	sizer      sizer
	marshaler  marshaler
	isPointer  bool
	required   bool                              // field is required
	name       string                            // name of the field, for error reporting
	oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements
}

// marshalElemInfo is the information used for marshaling an extension or oneof element.
type marshalElemInfo struct {
	wiretag   uint64 // tag in wire format
	tagsize   int    // size of tag in wire format
	sizer     sizer
	marshaler marshaler
	isptr     bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
}

var (
	marshalInfoMap  = map[reflect.Type]*marshalInfo{}
	marshalInfoLock sync.Mutex

	uint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind()
)

// 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).
func getMarshalInfo( reflect.Type) *marshalInfo {
	marshalInfoLock.Lock()
	,  := marshalInfoMap[]
	if ! {
		 = &marshalInfo{typ: }
		marshalInfoMap[] = 
	}
	marshalInfoLock.Unlock()
	return 
}

// Size is the entry point from generated code,
// and should be ONLY called by generated code.
// It computes the size of encoded data of msg.
// a is a pointer to a place to store cached marshal info.
func ( *InternalMessageInfo) ( Message) int {
	 := getMessageMarshalInfo(, )
	 := toPointer(&)
	if .isNil() {
		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
		// so it satisfies the interface, and msg == nil wouldn't
		// catch it. We don't want crash in this case.
		return 0
	}
	return .size()
}

// Marshal is the entry point from generated code,
// and should be ONLY called by generated code.
// It marshals msg to the end of b.
// a is a pointer to a place to store cached marshal info.
func ( *InternalMessageInfo) ( []byte,  Message,  bool) ([]byte, error) {
	 := getMessageMarshalInfo(, )
	 := toPointer(&)
	if .isNil() {
		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
		// so it satisfies the interface, and msg == nil wouldn't
		// catch it. We don't want crash in this case.
		return , ErrNil
	}
	return .marshal(, , )
}

func getMessageMarshalInfo( interface{},  *InternalMessageInfo) *marshalInfo {
	// u := a.marshal, but atomically.
	// We use an atomic here to ensure memory consistency.
	 := atomicLoadMarshalInfo(&.marshal)
	if  == nil {
		// Get marshal information from type of message.
		 := reflect.ValueOf().Type()
		if .Kind() != reflect.Ptr {
			panic(fmt.Sprintf("cannot handle non-pointer message type %v", ))
		}
		 = getMarshalInfo(.Elem())
		// Store it in the cache for later users.
		// a.marshal = u, but atomically.
		atomicStoreMarshalInfo(&.marshal, )
	}
	return 
}

// size is the main function to compute the size of the encoded data of a message.
// ptr is the pointer to the message.
func ( *marshalInfo) ( pointer) int {
	if atomic.LoadInt32(&.initialized) == 0 {
		.computeMarshalInfo()
	}

	// If the message can marshal itself, let it do it, for compatibility.
	// NOTE: This is not efficient.
	if .hasmarshaler {
		// Uses the message's Size method if available
		if .hassizer {
			 := .asPointerTo(.typ).Interface().(Sizer)
			return .Size()
		}
		// Uses the message's ProtoSize method if available
		if .hasprotosizer {
			 := .asPointerTo(.typ).Interface().(ProtoSizer)
			return .ProtoSize()
		}

		 := .asPointerTo(.typ).Interface().(Marshaler)
		,  := .Marshal()
		return len()
	}

	 := 0
	for ,  := range .fields {
		if .isPointer && .offset(.field).getPointer().isNil() {
			// nil pointer always marshals to nothing
			continue
		}
		 += .sizer(.offset(.field), .tagsize)
	}
	if .extensions.IsValid() {
		 := .offset(.extensions).toExtensions()
		if .messageset {
			 += .sizeMessageSet()
		} else {
			 += .sizeExtensions()
		}
	}
	if .v1extensions.IsValid() {
		 := *.offset(.v1extensions).toOldExtensions()
		 += .sizeV1Extensions()
	}
	if .bytesExtensions.IsValid() {
		 := *.offset(.bytesExtensions).toBytes()
		 += len()
	}
	if .unrecognized.IsValid() {
		 := *.offset(.unrecognized).toBytes()
		 += len()
	}

	// cache the result for use in marshal
	if .sizecache.IsValid() {
		atomic.StoreInt32(.offset(.sizecache).toInt32(), int32())
	}
	return 
}

// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
// fall back to compute the size.
func ( *marshalInfo) ( pointer) int {
	if .sizecache.IsValid() {
		return int(atomic.LoadInt32(.offset(.sizecache).toInt32()))
	}
	return .size()
}

// marshal is the main function to marshal a message. It takes a byte slice and appends
// the encoded data to the end of the slice, returns the slice and error (if any).
// ptr is the pointer to the message.
// If deterministic is true, map is marshaled in deterministic order.
func ( *marshalInfo) ( []byte,  pointer,  bool) ([]byte, error) {
	if atomic.LoadInt32(&.initialized) == 0 {
		.computeMarshalInfo()
	}

	// If the message can marshal itself, let it do it, for compatibility.
	// NOTE: This is not efficient.
	if .hasmarshaler {
		 := .asPointerTo(.typ).Interface().(Marshaler)
		,  := .Marshal()
		 = append(, ...)
		return , 
	}

	var ,  error
	// The old marshaler encodes extensions at beginning.
	if .extensions.IsValid() {
		 := .offset(.extensions).toExtensions()
		if .messageset {
			,  = .appendMessageSet(, , )
		} else {
			,  = .appendExtensions(, , )
		}
		if  != nil {
			return , 
		}
	}
	if .v1extensions.IsValid() {
		 := *.offset(.v1extensions).toOldExtensions()
		,  = .appendV1Extensions(, , )
		if  != nil {
			return , 
		}
	}
	if .bytesExtensions.IsValid() {
		 := *.offset(.bytesExtensions).toBytes()
		 = append(, ...)
	}
	for ,  := range .fields {
		if .required {
			if .isPointer && .offset(.field).getPointer().isNil() {
				// Required field is not set.
				// We record the error but keep going, to give a complete marshaling.
				if  == nil {
					 = &RequiredNotSetError{.name}
				}
				continue
			}
		}
		if .isPointer && .offset(.field).getPointer().isNil() {
			// nil pointer always marshals to nothing
			continue
		}
		,  = .marshaler(, .offset(.field), .wiretag, )
		if  != nil {
			if ,  := .(*RequiredNotSetError);  {
				// Required field in submessage is not set.
				// We record the error but keep going, to give a complete marshaling.
				if  == nil {
					 = &RequiredNotSetError{.name + "." + .field}
				}
				continue
			}
			if  == errRepeatedHasNil {
				 = errors.New("proto: repeated field " + .name + " has nil element")
			}
			if  == errInvalidUTF8 {
				if  == nil {
					 := revProtoTypes[reflect.PtrTo(.typ)] + "." + .name
					 = &invalidUTF8Error{}
				}
				continue
			}
			return , 
		}
	}
	if .unrecognized.IsValid() {
		 := *.offset(.unrecognized).toBytes()
		 = append(, ...)
	}
	return , 
}

// computeMarshalInfo initializes the marshal info.
func ( *marshalInfo) () {
	.Lock()
	defer .Unlock()
	if .initialized != 0 { // non-atomic read is ok as it is protected by the lock
		return
	}

	 := .typ
	.unrecognized = invalidField
	.extensions = invalidField
	.v1extensions = invalidField
	.bytesExtensions = invalidField
	.sizecache = invalidField
	 := false

	if reflect.PtrTo().Implements(sizerType) {
		.hassizer = true
	}
	if reflect.PtrTo().Implements(protosizerType) {
		.hasprotosizer = true
	}
	// If the message can marshal itself, let it do it, for compatibility.
	// NOTE: This is not efficient.
	if reflect.PtrTo().Implements(marshalerType) {
		.hasmarshaler = true
		atomic.StoreInt32(&.initialized, 1)
		return
	}

	 := .NumField()

	// deal with XXX fields first
	for  := 0;  < .NumField(); ++ {
		 := .Field()
		if .Tag.Get("protobuf_oneof") != "" {
			 = true
		}
		if !strings.HasPrefix(.Name, "XXX_") {
			continue
		}
		switch .Name {
		case "XXX_sizecache":
			.sizecache = toField(&)
		case "XXX_unrecognized":
			.unrecognized = toField(&)
		case "XXX_InternalExtensions":
			.extensions = toField(&)
			.messageset = .Tag.Get("protobuf_messageset") == "1"
		case "XXX_extensions":
			if .Type.Kind() == reflect.Map {
				.v1extensions = toField(&)
			} else {
				.bytesExtensions = toField(&)
			}
		case "XXX_NoUnkeyedLiteral":
			// nothing to do
		default:
			panic("unknown XXX field: " + .Name)
		}
		--
	}

	// get oneof implementers
	var  []interface{}
	// gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler
	if  {
		switch m := reflect.Zero(reflect.PtrTo()).Interface().(type) {
		case oneofFuncsIface:
			_, _, _,  = .XXX_OneofFuncs()
		case oneofWrappersIface:
			 = .XXX_OneofWrappers()
		}
	}

	// normal fields
	 := make([]marshalFieldInfo, ) // batch allocation
	.fields = make([]*marshalFieldInfo, 0, )
	for ,  := 0, 0;  < .NumField(); ++ {
		 := .Field()

		if strings.HasPrefix(.Name, "XXX_") {
			continue
		}
		 := &[]
		++
		.name = .Name
		.fields = append(.fields, )
		if .Tag.Get("protobuf_oneof") != "" {
			.computeOneofFieldInfo(&, )
			continue
		}
		if .Tag.Get("protobuf") == "" {
			// field has no tag (not in generated message), ignore it
			.fields = .fields[:len(.fields)-1]
			--
			continue
		}
		.computeMarshalFieldInfo(&)
	}

	// fields are marshaled in tag order on the wire.
	sort.Sort(byTag(.fields))

	atomic.StoreInt32(&.initialized, 1)
}

// helper for sorting fields by tag
type byTag []*marshalFieldInfo

func ( byTag) () int           { return len() }
func ( byTag) (,  int)      { [], [] = [], [] }
func ( byTag) (,  int) bool { return [].wiretag < [].wiretag }

// getExtElemInfo returns the information to marshal an extension element.
// The info it returns is initialized.
func ( *marshalInfo) ( *ExtensionDesc) *marshalElemInfo {
	// get from cache first
	.RLock()
	,  := .extElems[.Field]
	.RUnlock()
	if  {
		return 
	}

	 := reflect.TypeOf(.ExtensionType) // pointer or slice to basic type or struct
	 := strings.Split(.Tag, ",")
	,  := strconv.Atoi([1])
	if  != nil {
		panic("tag is not an integer")
	}
	 := wiretype([0])
	,  := typeMarshaler(, , false, false)
	 = &marshalElemInfo{
		wiretag:   uint64()<<3 | ,
		tagsize:   SizeVarint(uint64() << 3),
		sizer:     ,
		marshaler: ,
		isptr:     .Kind() == reflect.Ptr,
	}

	// update cache
	.Lock()
	if .extElems == nil {
		.extElems = make(map[int32]*marshalElemInfo)
	}
	.extElems[.Field] = 
	.Unlock()
	return 
}

// computeMarshalFieldInfo fills up the information to marshal a field.
func ( *marshalFieldInfo) ( *reflect.StructField) {
	// parse protobuf tag of the field.
	// tag has format of "bytes,49,opt,name=foo,def=hello!"
	 := strings.Split(.Tag.Get("protobuf"), ",")
	if [0] == "" {
		return
	}
	,  := strconv.Atoi([1])
	if  != nil {
		panic("tag is not an integer")
	}
	 := wiretype([0])
	if [2] == "req" {
		.required = true
	}
	.setTag(, , )
	.setMarshaler(, )
}

func ( *marshalFieldInfo) ( *reflect.StructField,  []interface{}) {
	.field = toField()
	.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
	.isPointer = true
	.sizer, .marshaler = makeOneOfMarshaler(, )
	.oneofElems = make(map[reflect.Type]*marshalElemInfo)

	 := .Type // interface type
	for ,  := range  {
		 := reflect.TypeOf()
		if !.Implements() {
			continue
		}
		 := .Elem().Field(0) // oneof implementer is a struct with a single field
		 := strings.Split(.Tag.Get("protobuf"), ",")
		,  := strconv.Atoi([1])
		if  != nil {
			panic("tag is not an integer")
		}
		 := wiretype([0])
		,  := typeMarshaler(.Type, , false, true) // oneof should not omit any zero value
		.oneofElems[.Elem()] = &marshalElemInfo{
			wiretag:   uint64()<<3 | ,
			tagsize:   SizeVarint(uint64() << 3),
			sizer:     ,
			marshaler: ,
		}
	}
}

// wiretype returns the wire encoding of the type.
func wiretype( string) uint64 {
	switch  {
	case "fixed32":
		return WireFixed32
	case "fixed64":
		return WireFixed64
	case "varint", "zigzag32", "zigzag64":
		return WireVarint
	case "bytes":
		return WireBytes
	case "group":
		return WireStartGroup
	}
	panic("unknown wire type " + )
}

// setTag fills up the tag (in wire format) and its size in the info of a field.
func ( *marshalFieldInfo) ( *reflect.StructField,  int,  uint64) {
	.field = toField()
	.wiretag = uint64()<<3 | 
	.tagsize = SizeVarint(uint64() << 3)
}

// setMarshaler fills up the sizer and marshaler in the info of a field.
func ( *marshalFieldInfo) ( *reflect.StructField,  []string) {
	switch .Type.Kind() {
	case reflect.Map:
		// map field
		.isPointer = true
		.sizer, .marshaler = makeMapMarshaler()
		return
	case reflect.Ptr, reflect.Slice:
		.isPointer = true
	}
	.sizer, .marshaler = typeMarshaler(.Type, , true, false)
}

// typeMarshaler returns the sizer and marshaler of a given field.
// t is the type of the field.
// tags is the generated "protobuf" tag of the field.
// If nozero is true, zero value is not marshaled to the wire.
// If oneof is true, it is a oneof field.
func typeMarshaler( reflect.Type,  []string, ,  bool) (sizer, marshaler) {
	 := [0]

	 := false
	 := false
	if .Kind() == reflect.Slice && .Elem().Kind() != reflect.Uint8 {
		 = true
		 = .Elem()
	}
	if .Kind() == reflect.Ptr {
		 = true
		 = .Elem()
	}

	 := false
	 := false
	 := false
	 := false
	 := false
	 := false
	 := true
	for  := 2;  < len(); ++ {
		if [] == "packed" {
			 = true
		}
		if [] == "proto3" {
			 = true
		}
		if strings.HasPrefix([], "customtype=") {
			 = true
		}
		if [] == "stdtime" {
			 = true
		}
		if [] == "stdduration" {
			 = true
		}
		if [] == "wktptr" {
			 = true
		}
	}
	 =  && 
	if ! && ! && ! {
		 = false
	}

	if  {
		if reflect.PtrTo().Implements(customType) {
			if  {
				return makeMessageRefSliceMarshaler(getMarshalInfo())
			}
			if  {
				return makeCustomPtrMarshaler(getMarshalInfo())
			}
			return makeCustomMarshaler(getMarshalInfo())
		} else {
			panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", ))
		}
	}

	if  {
		if  {
			if  {
				return makeTimePtrSliceMarshaler(getMarshalInfo())
			}
			return makeTimePtrMarshaler(getMarshalInfo())
		}
		if  {
			return makeTimeSliceMarshaler(getMarshalInfo())
		}
		return makeTimeMarshaler(getMarshalInfo())
	}

	if  {
		if  {
			if  {
				return makeDurationPtrSliceMarshaler(getMarshalInfo())
			}
			return makeDurationPtrMarshaler(getMarshalInfo())
		}
		if  {
			return makeDurationSliceMarshaler(getMarshalInfo())
		}
		return makeDurationMarshaler(getMarshalInfo())
	}

	if  {
		switch .Kind() {
		case reflect.Float64:
			if  {
				if  {
					return makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdDoubleValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdDoubleValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdDoubleValueMarshaler(getMarshalInfo())
		case reflect.Float32:
			if  {
				if  {
					return makeStdFloatValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdFloatValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdFloatValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdFloatValueMarshaler(getMarshalInfo())
		case reflect.Int64:
			if  {
				if  {
					return makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdInt64ValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdInt64ValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdInt64ValueMarshaler(getMarshalInfo())
		case reflect.Uint64:
			if  {
				if  {
					return makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdUInt64ValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdUInt64ValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdUInt64ValueMarshaler(getMarshalInfo())
		case reflect.Int32:
			if  {
				if  {
					return makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdInt32ValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdInt32ValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdInt32ValueMarshaler(getMarshalInfo())
		case reflect.Uint32:
			if  {
				if  {
					return makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdUInt32ValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdUInt32ValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdUInt32ValueMarshaler(getMarshalInfo())
		case reflect.Bool:
			if  {
				if  {
					return makeStdBoolValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdBoolValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdBoolValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdBoolValueMarshaler(getMarshalInfo())
		case reflect.String:
			if  {
				if  {
					return makeStdStringValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdStringValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdStringValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdStringValueMarshaler(getMarshalInfo())
		case uint8SliceType:
			if  {
				if  {
					return makeStdBytesValuePtrSliceMarshaler(getMarshalInfo())
				}
				return makeStdBytesValuePtrMarshaler(getMarshalInfo())
			}
			if  {
				return makeStdBytesValueSliceMarshaler(getMarshalInfo())
			}
			return makeStdBytesValueMarshaler(getMarshalInfo())
		default:
			panic(fmt.Sprintf("unknown wktpointer type %#v", ))
		}
	}

	switch .Kind() {
	case reflect.Bool:
		if  {
			return sizeBoolPtr, appendBoolPtr
		}
		if  {
			if  {
				return sizeBoolPackedSlice, appendBoolPackedSlice
			}
			return sizeBoolSlice, appendBoolSlice
		}
		if  {
			return sizeBoolValueNoZero, appendBoolValueNoZero
		}
		return sizeBoolValue, appendBoolValue
	case reflect.Uint32:
		switch  {
		case "fixed32":
			if  {
				return sizeFixed32Ptr, appendFixed32Ptr
			}
			if  {
				if  {
					return sizeFixed32PackedSlice, appendFixed32PackedSlice
				}
				return sizeFixed32Slice, appendFixed32Slice
			}
			if  {
				return sizeFixed32ValueNoZero, appendFixed32ValueNoZero
			}
			return sizeFixed32Value, appendFixed32Value
		case "varint":
			if  {
				return sizeVarint32Ptr, appendVarint32Ptr
			}
			if  {
				if  {
					return sizeVarint32PackedSlice, appendVarint32PackedSlice
				}
				return sizeVarint32Slice, appendVarint32Slice
			}
			if  {
				return sizeVarint32ValueNoZero, appendVarint32ValueNoZero
			}
			return sizeVarint32Value, appendVarint32Value
		}
	case reflect.Int32:
		switch  {
		case "fixed32":
			if  {
				return sizeFixedS32Ptr, appendFixedS32Ptr
			}
			if  {
				if  {
					return sizeFixedS32PackedSlice, appendFixedS32PackedSlice
				}
				return sizeFixedS32Slice, appendFixedS32Slice
			}
			if  {
				return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero
			}
			return sizeFixedS32Value, appendFixedS32Value
		case "varint":
			if  {
				return sizeVarintS32Ptr, appendVarintS32Ptr
			}
			if  {
				if  {
					return sizeVarintS32PackedSlice, appendVarintS32PackedSlice
				}
				return sizeVarintS32Slice, appendVarintS32Slice
			}
			if  {
				return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero
			}
			return sizeVarintS32Value, appendVarintS32Value
		case "zigzag32":
			if  {
				return sizeZigzag32Ptr, appendZigzag32Ptr
			}
			if  {
				if  {
					return sizeZigzag32PackedSlice, appendZigzag32PackedSlice
				}
				return sizeZigzag32Slice, appendZigzag32Slice
			}
			if  {
				return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero
			}
			return sizeZigzag32Value, appendZigzag32Value
		}
	case reflect.Uint64:
		switch  {
		case "fixed64":
			if  {
				return sizeFixed64Ptr, appendFixed64Ptr
			}
			if  {
				if  {
					return sizeFixed64PackedSlice, appendFixed64PackedSlice
				}
				return sizeFixed64Slice, appendFixed64Slice
			}
			if  {
				return sizeFixed64ValueNoZero, appendFixed64ValueNoZero
			}
			return sizeFixed64Value, appendFixed64Value
		case "varint":
			if  {
				return sizeVarint64Ptr, appendVarint64Ptr
			}
			if  {
				if  {
					return sizeVarint64PackedSlice, appendVarint64PackedSlice
				}
				return sizeVarint64Slice, appendVarint64Slice
			}
			if  {
				return sizeVarint64ValueNoZero, appendVarint64ValueNoZero
			}
			return sizeVarint64Value, appendVarint64Value
		}
	case reflect.Int64:
		switch  {
		case "fixed64":
			if  {
				return sizeFixedS64Ptr, appendFixedS64Ptr
			}
			if  {
				if  {
					return sizeFixedS64PackedSlice, appendFixedS64PackedSlice
				}
				return sizeFixedS64Slice, appendFixedS64Slice
			}
			if  {
				return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero
			}
			return sizeFixedS64Value, appendFixedS64Value
		case "varint":
			if  {
				return sizeVarintS64Ptr, appendVarintS64Ptr
			}
			if  {
				if  {
					return sizeVarintS64PackedSlice, appendVarintS64PackedSlice
				}
				return sizeVarintS64Slice, appendVarintS64Slice
			}
			if  {
				return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero
			}
			return sizeVarintS64Value, appendVarintS64Value
		case "zigzag64":
			if  {
				return sizeZigzag64Ptr, appendZigzag64Ptr
			}
			if  {
				if  {
					return sizeZigzag64PackedSlice, appendZigzag64PackedSlice
				}
				return sizeZigzag64Slice, appendZigzag64Slice
			}
			if  {
				return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero
			}
			return sizeZigzag64Value, appendZigzag64Value
		}
	case reflect.Float32:
		if  {
			return sizeFloat32Ptr, appendFloat32Ptr
		}
		if  {
			if  {
				return sizeFloat32PackedSlice, appendFloat32PackedSlice
			}
			return sizeFloat32Slice, appendFloat32Slice
		}
		if  {
			return sizeFloat32ValueNoZero, appendFloat32ValueNoZero
		}
		return sizeFloat32Value, appendFloat32Value
	case reflect.Float64:
		if  {
			return sizeFloat64Ptr, appendFloat64Ptr
		}
		if  {
			if  {
				return sizeFloat64PackedSlice, appendFloat64PackedSlice
			}
			return sizeFloat64Slice, appendFloat64Slice
		}
		if  {
			return sizeFloat64ValueNoZero, appendFloat64ValueNoZero
		}
		return sizeFloat64Value, appendFloat64Value
	case reflect.String:
		if  {
			if  {
				return sizeStringPtr, appendUTF8StringPtr
			}
			if  {
				return sizeStringSlice, appendUTF8StringSlice
			}
			if  {
				return sizeStringValueNoZero, appendUTF8StringValueNoZero
			}
			return sizeStringValue, appendUTF8StringValue
		}
		if  {
			return sizeStringPtr, appendStringPtr
		}
		if  {
			return sizeStringSlice, appendStringSlice
		}
		if  {
			return sizeStringValueNoZero, appendStringValueNoZero
		}
		return sizeStringValue, appendStringValue
	case reflect.Slice:
		if  {
			return sizeBytesSlice, appendBytesSlice
		}
		if  {
			// Oneof bytes field may also have "proto3" tag.
			// We want to marshal it as a oneof field. Do this
			// check before the proto3 check.
			return sizeBytesOneof, appendBytesOneof
		}
		if  {
			return sizeBytes3, appendBytes3
		}
		return sizeBytes, appendBytes
	case reflect.Struct:
		switch  {
		case "group":
			if  {
				return makeGroupSliceMarshaler(getMarshalInfo())
			}
			return makeGroupMarshaler(getMarshalInfo())
		case "bytes":
			if  {
				if  {
					return makeMessageSliceMarshaler(getMarshalInfo())
				}
				return makeMessageMarshaler(getMarshalInfo())
			} else {
				if  {
					return makeMessageRefSliceMarshaler(getMarshalInfo())
				}
				return makeMessageRefMarshaler(getMarshalInfo())
			}
		}
	}
	panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", , ))
}

// Below are functions to size/marshal a specific type of a field.
// They are stored in the field's info, and called by function pointers.
// They have type sizer or marshaler.

func sizeFixed32Value( pointer,  int) int {
	return 4 + 
}
func sizeFixed32ValueNoZero( pointer,  int) int {
	 := *.toUint32()
	if  == 0 {
		return 0
	}
	return 4 + 
}
func sizeFixed32Ptr( pointer,  int) int {
	 := *.toUint32Ptr()
	if  == nil {
		return 0
	}
	return 4 + 
}
func sizeFixed32Slice( pointer,  int) int {
	 := *.toUint32Slice()
	return (4 + ) * len()
}
func sizeFixed32PackedSlice( pointer,  int) int {
	 := *.toUint32Slice()
	if len() == 0 {
		return 0
	}
	return 4*len() + SizeVarint(uint64(4*len())) + 
}
func sizeFixedS32Value( pointer,  int) int {
	return 4 + 
}
func sizeFixedS32ValueNoZero( pointer,  int) int {
	 := *.toInt32()
	if  == 0 {
		return 0
	}
	return 4 + 
}
func sizeFixedS32Ptr( pointer,  int) int {
	 := .getInt32Ptr()
	if  == nil {
		return 0
	}
	return 4 + 
}
func sizeFixedS32Slice( pointer,  int) int {
	 := .getInt32Slice()
	return (4 + ) * len()
}
func sizeFixedS32PackedSlice( pointer,  int) int {
	 := .getInt32Slice()
	if len() == 0 {
		return 0
	}
	return 4*len() + SizeVarint(uint64(4*len())) + 
}
func sizeFloat32Value( pointer,  int) int {
	return 4 + 
}
func sizeFloat32ValueNoZero( pointer,  int) int {
	 := math.Float32bits(*.toFloat32())
	if  == 0 {
		return 0
	}
	return 4 + 
}
func sizeFloat32Ptr( pointer,  int) int {
	 := *.toFloat32Ptr()
	if  == nil {
		return 0
	}
	return 4 + 
}
func sizeFloat32Slice( pointer,  int) int {
	 := *.toFloat32Slice()
	return (4 + ) * len()
}
func sizeFloat32PackedSlice( pointer,  int) int {
	 := *.toFloat32Slice()
	if len() == 0 {
		return 0
	}
	return 4*len() + SizeVarint(uint64(4*len())) + 
}
func sizeFixed64Value( pointer,  int) int {
	return 8 + 
}
func sizeFixed64ValueNoZero( pointer,  int) int {
	 := *.toUint64()
	if  == 0 {
		return 0
	}
	return 8 + 
}
func sizeFixed64Ptr( pointer,  int) int {
	 := *.toUint64Ptr()
	if  == nil {
		return 0
	}
	return 8 + 
}
func sizeFixed64Slice( pointer,  int) int {
	 := *.toUint64Slice()
	return (8 + ) * len()
}
func sizeFixed64PackedSlice( pointer,  int) int {
	 := *.toUint64Slice()
	if len() == 0 {
		return 0
	}
	return 8*len() + SizeVarint(uint64(8*len())) + 
}
func sizeFixedS64Value( pointer,  int) int {
	return 8 + 
}
func sizeFixedS64ValueNoZero( pointer,  int) int {
	 := *.toInt64()
	if  == 0 {
		return 0
	}
	return 8 + 
}
func sizeFixedS64Ptr( pointer,  int) int {
	 := *.toInt64Ptr()
	if  == nil {
		return 0
	}
	return 8 + 
}
func sizeFixedS64Slice( pointer,  int) int {
	 := *.toInt64Slice()
	return (8 + ) * len()
}
func sizeFixedS64PackedSlice( pointer,  int) int {
	 := *.toInt64Slice()
	if len() == 0 {
		return 0
	}
	return 8*len() + SizeVarint(uint64(8*len())) + 
}
func sizeFloat64Value( pointer,  int) int {
	return 8 + 
}
func sizeFloat64ValueNoZero( pointer,  int) int {
	 := math.Float64bits(*.toFloat64())
	if  == 0 {
		return 0
	}
	return 8 + 
}
func sizeFloat64Ptr( pointer,  int) int {
	 := *.toFloat64Ptr()
	if  == nil {
		return 0
	}
	return 8 + 
}
func sizeFloat64Slice( pointer,  int) int {
	 := *.toFloat64Slice()
	return (8 + ) * len()
}
func sizeFloat64PackedSlice( pointer,  int) int {
	 := *.toFloat64Slice()
	if len() == 0 {
		return 0
	}
	return 8*len() + SizeVarint(uint64(8*len())) + 
}
func sizeVarint32Value( pointer,  int) int {
	 := *.toUint32()
	return SizeVarint(uint64()) + 
}
func sizeVarint32ValueNoZero( pointer,  int) int {
	 := *.toUint32()
	if  == 0 {
		return 0
	}
	return SizeVarint(uint64()) + 
}
func sizeVarint32Ptr( pointer,  int) int {
	 := *.toUint32Ptr()
	if  == nil {
		return 0
	}
	return SizeVarint(uint64(*)) + 
}
func sizeVarint32Slice( pointer,  int) int {
	 := *.toUint32Slice()
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64()) + 
	}
	return 
}
func sizeVarint32PackedSlice( pointer,  int) int {
	 := *.toUint32Slice()
	if len() == 0 {
		return 0
	}
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64())
	}
	return  + SizeVarint(uint64()) + 
}
func sizeVarintS32Value( pointer,  int) int {
	 := *.toInt32()
	return SizeVarint(uint64()) + 
}
func sizeVarintS32ValueNoZero( pointer,  int) int {
	 := *.toInt32()
	if  == 0 {
		return 0
	}
	return SizeVarint(uint64()) + 
}
func sizeVarintS32Ptr( pointer,  int) int {
	 := .getInt32Ptr()
	if  == nil {
		return 0
	}
	return SizeVarint(uint64(*)) + 
}
func sizeVarintS32Slice( pointer,  int) int {
	 := .getInt32Slice()
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64()) + 
	}
	return 
}
func sizeVarintS32PackedSlice( pointer,  int) int {
	 := .getInt32Slice()
	if len() == 0 {
		return 0
	}
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64())
	}
	return  + SizeVarint(uint64()) + 
}
func sizeVarint64Value( pointer,  int) int {
	 := *.toUint64()
	return SizeVarint() + 
}
func sizeVarint64ValueNoZero( pointer,  int) int {
	 := *.toUint64()
	if  == 0 {
		return 0
	}
	return SizeVarint() + 
}
func sizeVarint64Ptr( pointer,  int) int {
	 := *.toUint64Ptr()
	if  == nil {
		return 0
	}
	return SizeVarint(*) + 
}
func sizeVarint64Slice( pointer,  int) int {
	 := *.toUint64Slice()
	 := 0
	for ,  := range  {
		 += SizeVarint() + 
	}
	return 
}
func sizeVarint64PackedSlice( pointer,  int) int {
	 := *.toUint64Slice()
	if len() == 0 {
		return 0
	}
	 := 0
	for ,  := range  {
		 += SizeVarint()
	}
	return  + SizeVarint(uint64()) + 
}
func sizeVarintS64Value( pointer,  int) int {
	 := *.toInt64()
	return SizeVarint(uint64()) + 
}
func sizeVarintS64ValueNoZero( pointer,  int) int {
	 := *.toInt64()
	if  == 0 {
		return 0
	}
	return SizeVarint(uint64()) + 
}
func sizeVarintS64Ptr( pointer,  int) int {
	 := *.toInt64Ptr()
	if  == nil {
		return 0
	}
	return SizeVarint(uint64(*)) + 
}
func sizeVarintS64Slice( pointer,  int) int {
	 := *.toInt64Slice()
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64()) + 
	}
	return 
}
func sizeVarintS64PackedSlice( pointer,  int) int {
	 := *.toInt64Slice()
	if len() == 0 {
		return 0
	}
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64())
	}
	return  + SizeVarint(uint64()) + 
}
func sizeZigzag32Value( pointer,  int) int {
	 := *.toInt32()
	return SizeVarint(uint64((uint32()<<1)^uint32((int32()>>31)))) + 
}
func sizeZigzag32ValueNoZero( pointer,  int) int {
	 := *.toInt32()
	if  == 0 {
		return 0
	}
	return SizeVarint(uint64((uint32()<<1)^uint32((int32()>>31)))) + 
}
func sizeZigzag32Ptr( pointer,  int) int {
	 := .getInt32Ptr()
	if  == nil {
		return 0
	}
	 := *
	return SizeVarint(uint64((uint32()<<1)^uint32((int32()>>31)))) + 
}
func sizeZigzag32Slice( pointer,  int) int {
	 := .getInt32Slice()
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64((uint32()<<1)^uint32((int32()>>31)))) + 
	}
	return 
}
func sizeZigzag32PackedSlice( pointer,  int) int {
	 := .getInt32Slice()
	if len() == 0 {
		return 0
	}
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64((uint32() << 1) ^ uint32((int32() >> 31))))
	}
	return  + SizeVarint(uint64()) + 
}
func sizeZigzag64Value( pointer,  int) int {
	 := *.toInt64()
	return SizeVarint(uint64(<<1)^uint64((int64()>>63))) + 
}
func sizeZigzag64ValueNoZero( pointer,  int) int {
	 := *.toInt64()
	if  == 0 {
		return 0
	}
	return SizeVarint(uint64(<<1)^uint64((int64()>>63))) + 
}
func sizeZigzag64Ptr( pointer,  int) int {
	 := *.toInt64Ptr()
	if  == nil {
		return 0
	}
	 := *
	return SizeVarint(uint64(<<1)^uint64((int64()>>63))) + 
}
func sizeZigzag64Slice( pointer,  int) int {
	 := *.toInt64Slice()
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64(<<1)^uint64((int64()>>63))) + 
	}
	return 
}
func sizeZigzag64PackedSlice( pointer,  int) int {
	 := *.toInt64Slice()
	if len() == 0 {
		return 0
	}
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64(<<1) ^ uint64((int64() >> 63)))
	}
	return  + SizeVarint(uint64()) + 
}
func sizeBoolValue( pointer,  int) int {
	return 1 + 
}
func sizeBoolValueNoZero( pointer,  int) int {
	 := *.toBool()
	if ! {
		return 0
	}
	return 1 + 
}
func sizeBoolPtr( pointer,  int) int {
	 := *.toBoolPtr()
	if  == nil {
		return 0
	}
	return 1 + 
}
func sizeBoolSlice( pointer,  int) int {
	 := *.toBoolSlice()
	return (1 + ) * len()
}
func sizeBoolPackedSlice( pointer,  int) int {
	 := *.toBoolSlice()
	if len() == 0 {
		return 0
	}
	return len() + SizeVarint(uint64(len())) + 
}
func sizeStringValue( pointer,  int) int {
	 := *.toString()
	return len() + SizeVarint(uint64(len())) + 
}
func sizeStringValueNoZero( pointer,  int) int {
	 := *.toString()
	if  == "" {
		return 0
	}
	return len() + SizeVarint(uint64(len())) + 
}
func sizeStringPtr( pointer,  int) int {
	 := *.toStringPtr()
	if  == nil {
		return 0
	}
	 := *
	return len() + SizeVarint(uint64(len())) + 
}
func sizeStringSlice( pointer,  int) int {
	 := *.toStringSlice()
	 := 0
	for ,  := range  {
		 += len() + SizeVarint(uint64(len())) + 
	}
	return 
}
func sizeBytes( pointer,  int) int {
	 := *.toBytes()
	if  == nil {
		return 0
	}
	return len() + SizeVarint(uint64(len())) + 
}
func sizeBytes3( pointer,  int) int {
	 := *.toBytes()
	if len() == 0 {
		return 0
	}
	return len() + SizeVarint(uint64(len())) + 
}
func sizeBytesOneof( pointer,  int) int {
	 := *.toBytes()
	return len() + SizeVarint(uint64(len())) + 
}
func sizeBytesSlice( pointer,  int) int {
	 := *.toBytesSlice()
	 := 0
	for ,  := range  {
		 += len() + SizeVarint(uint64(len())) + 
	}
	return 
}

// appendFixed32 appends an encoded fixed32 to b.
func appendFixed32( []byte,  uint32) []byte {
	 = append(,
		byte(),
		byte(>>8),
		byte(>>16),
		byte(>>24))
	return 
}

// appendFixed64 appends an encoded fixed64 to b.
func appendFixed64( []byte,  uint64) []byte {
	 = append(,
		byte(),
		byte(>>8),
		byte(>>16),
		byte(>>24),
		byte(>>32),
		byte(>>40),
		byte(>>48),
		byte(>>56))
	return 
}

// appendVarint appends an encoded varint to b.
func appendVarint( []byte,  uint64) []byte {
	// TODO: make 1-byte (maybe 2-byte) case inline-able, once we
	// have non-leaf inliner.
	switch {
	case  < 1<<7:
		 = append(, byte())
	case  < 1<<14:
		 = append(,
			byte(&0x7f|0x80),
			byte(>>7))
	case  < 1<<21:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte(>>14))
	case  < 1<<28:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte(>>21))
	case  < 1<<35:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte((>>21)&0x7f|0x80),
			byte(>>28))
	case  < 1<<42:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte((>>21)&0x7f|0x80),
			byte((>>28)&0x7f|0x80),
			byte(>>35))
	case  < 1<<49:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte((>>21)&0x7f|0x80),
			byte((>>28)&0x7f|0x80),
			byte((>>35)&0x7f|0x80),
			byte(>>42))
	case  < 1<<56:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte((>>21)&0x7f|0x80),
			byte((>>28)&0x7f|0x80),
			byte((>>35)&0x7f|0x80),
			byte((>>42)&0x7f|0x80),
			byte(>>49))
	case  < 1<<63:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte((>>21)&0x7f|0x80),
			byte((>>28)&0x7f|0x80),
			byte((>>35)&0x7f|0x80),
			byte((>>42)&0x7f|0x80),
			byte((>>49)&0x7f|0x80),
			byte(>>56))
	default:
		 = append(,
			byte(&0x7f|0x80),
			byte((>>7)&0x7f|0x80),
			byte((>>14)&0x7f|0x80),
			byte((>>21)&0x7f|0x80),
			byte((>>28)&0x7f|0x80),
			byte((>>35)&0x7f|0x80),
			byte((>>42)&0x7f|0x80),
			byte((>>49)&0x7f|0x80),
			byte((>>56)&0x7f|0x80),
			1)
	}
	return 
}

func appendFixed32Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32()
	 = appendVarint(, )
	 = appendFixed32(, )
	return , nil
}
func appendFixed32ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed32(, )
	return , nil
}
func appendFixed32Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed32(, *)
	return , nil
}
func appendFixed32Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendFixed32(, )
	}
	return , nil
}
func appendFixed32PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(4*len()))
	for ,  := range  {
		 = appendFixed32(, )
	}
	return , nil
}
func appendFixedS32Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt32()
	 = appendVarint(, )
	 = appendFixed32(, uint32())
	return , nil
}
func appendFixedS32ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt32()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed32(, uint32())
	return , nil
}
func appendFixedS32Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed32(, uint32(*))
	return , nil
}
func appendFixedS32Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendFixed32(, uint32())
	}
	return , nil
}
func appendFixedS32PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(4*len()))
	for ,  := range  {
		 = appendFixed32(, uint32())
	}
	return , nil
}
func appendFloat32Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := math.Float32bits(*.toFloat32())
	 = appendVarint(, )
	 = appendFixed32(, )
	return , nil
}
func appendFloat32ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := math.Float32bits(*.toFloat32())
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed32(, )
	return , nil
}
func appendFloat32Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toFloat32Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed32(, math.Float32bits(*))
	return , nil
}
func appendFloat32Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toFloat32Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendFixed32(, math.Float32bits())
	}
	return , nil
}
func appendFloat32PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toFloat32Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(4*len()))
	for ,  := range  {
		 = appendFixed32(, math.Float32bits())
	}
	return , nil
}
func appendFixed64Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64()
	 = appendVarint(, )
	 = appendFixed64(, )
	return , nil
}
func appendFixed64ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed64(, )
	return , nil
}
func appendFixed64Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed64(, *)
	return , nil
}
func appendFixed64Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendFixed64(, )
	}
	return , nil
}
func appendFixed64PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(8*len()))
	for ,  := range  {
		 = appendFixed64(, )
	}
	return , nil
}
func appendFixedS64Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64()
	 = appendVarint(, )
	 = appendFixed64(, uint64())
	return , nil
}
func appendFixedS64ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed64(, uint64())
	return , nil
}
func appendFixedS64Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed64(, uint64(*))
	return , nil
}
func appendFixedS64Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendFixed64(, uint64())
	}
	return , nil
}
func appendFixedS64PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(8*len()))
	for ,  := range  {
		 = appendFixed64(, uint64())
	}
	return , nil
}
func appendFloat64Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := math.Float64bits(*.toFloat64())
	 = appendVarint(, )
	 = appendFixed64(, )
	return , nil
}
func appendFloat64ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := math.Float64bits(*.toFloat64())
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed64(, )
	return , nil
}
func appendFloat64Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toFloat64Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendFixed64(, math.Float64bits(*))
	return , nil
}
func appendFloat64Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toFloat64Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendFixed64(, math.Float64bits())
	}
	return , nil
}
func appendFloat64PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toFloat64Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(8*len()))
	for ,  := range  {
		 = appendFixed64(, math.Float64bits())
	}
	return , nil
}
func appendVarint32Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32()
	 = appendVarint(, )
	 = appendVarint(, uint64())
	return , nil
}
func appendVarint32ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64())
	return , nil
}
func appendVarint32Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(*))
	return , nil
}
func appendVarint32Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64())
	}
	return , nil
}
func appendVarint32PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint32Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	// compute size
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64())
	}
	 = appendVarint(, uint64())
	for ,  := range  {
		 = appendVarint(, uint64())
	}
	return , nil
}
func appendVarintS32Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt32()
	 = appendVarint(, )
	 = appendVarint(, uint64())
	return , nil
}
func appendVarintS32ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt32()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64())
	return , nil
}
func appendVarintS32Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(*))
	return , nil
}
func appendVarintS32Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64())
	}
	return , nil
}
func appendVarintS32PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	// compute size
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64())
	}
	 = appendVarint(, uint64())
	for ,  := range  {
		 = appendVarint(, uint64())
	}
	return , nil
}
func appendVarint64Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64()
	 = appendVarint(, )
	 = appendVarint(, )
	return , nil
}
func appendVarint64ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, )
	return , nil
}
func appendVarint64Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, *)
	return , nil
}
func appendVarint64Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, )
	}
	return , nil
}
func appendVarint64PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toUint64Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	// compute size
	 := 0
	for ,  := range  {
		 += SizeVarint()
	}
	 = appendVarint(, uint64())
	for ,  := range  {
		 = appendVarint(, )
	}
	return , nil
}
func appendVarintS64Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64()
	 = appendVarint(, )
	 = appendVarint(, uint64())
	return , nil
}
func appendVarintS64ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64())
	return , nil
}
func appendVarintS64Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(*))
	return , nil
}
func appendVarintS64Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64())
	}
	return , nil
}
func appendVarintS64PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	// compute size
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64())
	}
	 = appendVarint(, uint64())
	for ,  := range  {
		 = appendVarint(, uint64())
	}
	return , nil
}
func appendZigzag32Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt32()
	 = appendVarint(, )
	 = appendVarint(, uint64((uint32()<<1)^uint32((int32()>>31))))
	return , nil
}
func appendZigzag32ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt32()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64((uint32()<<1)^uint32((int32()>>31))))
	return , nil
}
func appendZigzag32Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 := *
	 = appendVarint(, uint64((uint32()<<1)^uint32((int32()>>31))))
	return , nil
}
func appendZigzag32Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64((uint32()<<1)^uint32((int32()>>31))))
	}
	return , nil
}
func appendZigzag32PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := .getInt32Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	// compute size
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64((uint32() << 1) ^ uint32((int32() >> 31))))
	}
	 = appendVarint(, uint64())
	for ,  := range  {
		 = appendVarint(, uint64((uint32()<<1)^uint32((int32()>>31))))
	}
	return , nil
}
func appendZigzag64Value( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64()
	 = appendVarint(, )
	 = appendVarint(, uint64(<<1)^uint64((int64()>>63)))
	return , nil
}
func appendZigzag64ValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64()
	if  == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(<<1)^uint64((int64()>>63)))
	return , nil
}
func appendZigzag64Ptr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Ptr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 := *
	 = appendVarint(, uint64(<<1)^uint64((int64()>>63)))
	return , nil
}
func appendZigzag64Slice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Slice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64(<<1)^uint64((int64()>>63)))
	}
	return , nil
}
func appendZigzag64PackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toInt64Slice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	// compute size
	 := 0
	for ,  := range  {
		 += SizeVarint(uint64(<<1) ^ uint64((int64() >> 63)))
	}
	 = appendVarint(, uint64())
	for ,  := range  {
		 = appendVarint(, uint64(<<1)^uint64((int64()>>63)))
	}
	return , nil
}
func appendBoolValue( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBool()
	 = appendVarint(, )
	if  {
		 = append(, 1)
	} else {
		 = append(, 0)
	}
	return , nil
}
func appendBoolValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBool()
	if ! {
		return , nil
	}
	 = appendVarint(, )
	 = append(, 1)
	return , nil
}

func appendBoolPtr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBoolPtr()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	if * {
		 = append(, 1)
	} else {
		 = append(, 0)
	}
	return , nil
}
func appendBoolSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBoolSlice()
	for ,  := range  {
		 = appendVarint(, )
		if  {
			 = append(, 1)
		} else {
			 = append(, 0)
		}
	}
	return , nil
}
func appendBoolPackedSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBoolSlice()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, &^7|WireBytes)
	 = appendVarint(, uint64(len()))
	for ,  := range  {
		if  {
			 = append(, 1)
		} else {
			 = append(, 0)
		}
	}
	return , nil
}
func appendStringValue( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toString()
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	return , nil
}
func appendStringValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toString()
	if  == "" {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	return , nil
}
func appendStringPtr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toStringPtr()
	if  == nil {
		return , nil
	}
	 := *
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	return , nil
}
func appendStringSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toStringSlice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64(len()))
		 = append(, ...)
	}
	return , nil
}
func appendUTF8StringValue( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	var  bool
	 := *.toString()
	if !utf8.ValidString() {
		 = true
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	if  {
		return , errInvalidUTF8
	}
	return , nil
}
func appendUTF8StringValueNoZero( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	var  bool
	 := *.toString()
	if  == "" {
		return , nil
	}
	if !utf8.ValidString() {
		 = true
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	if  {
		return , errInvalidUTF8
	}
	return , nil
}
func appendUTF8StringPtr( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	var  bool
	 := *.toStringPtr()
	if  == nil {
		return , nil
	}
	 := *
	if !utf8.ValidString() {
		 = true
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	if  {
		return , errInvalidUTF8
	}
	return , nil
}
func appendUTF8StringSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	var  bool
	 := *.toStringSlice()
	for ,  := range  {
		if !utf8.ValidString() {
			 = true
		}
		 = appendVarint(, )
		 = appendVarint(, uint64(len()))
		 = append(, ...)
	}
	if  {
		return , errInvalidUTF8
	}
	return , nil
}
func appendBytes( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBytes()
	if  == nil {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	return , nil
}
func appendBytes3( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBytes()
	if len() == 0 {
		return , nil
	}
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	return , nil
}
func appendBytesOneof( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBytes()
	 = appendVarint(, )
	 = appendVarint(, uint64(len()))
	 = append(, ...)
	return , nil
}
func appendBytesSlice( []byte,  pointer,  uint64,  bool) ([]byte, error) {
	 := *.toBytesSlice()
	for ,  := range  {
		 = appendVarint(, )
		 = appendVarint(, uint64(len()))
		 = append(, ...)
	}
	return , nil
}

// makeGroupMarshaler returns the sizer and marshaler for a group.
// u is the marshal info of the underlying message.
func makeGroupMarshaler( *marshalInfo) (sizer, marshaler) {
	return func( pointer,  int) int {
			 := .getPointer()
			if .isNil() {
				return 0
			}
			return .size() + 2*
		},
		func( []byte,  pointer,  uint64,  bool) ([]byte, error) {
			 := .getPointer()
			if .isNil() {
				return , nil
			}
			var  error
			 = appendVarint(, ) // start group
			,  = .marshal(, , )
			 = appendVarint(, +(WireEndGroup-WireStartGroup)) // end group
			return , 
		}
}

// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.
// u is the marshal info of the underlying message.
func makeGroupSliceMarshaler( *marshalInfo) (sizer, marshaler) {
	return func( pointer,  int) int {
			 := .getPointerSlice()
			 := 0
			for ,  := range  {
				if .isNil() {
					continue
				}
				 += .size() + 2*
			}
			return 
		},
		func( []byte,  pointer,  uint64,  bool) ([]byte, error) {
			 := .getPointerSlice()
			var  error
			var  nonFatal
			for ,  := range  {
				if .isNil() {
					return , errRepeatedHasNil
				}
				 = appendVarint(, ) // start group
				,  = .marshal(, , )
				 = appendVarint(, +(WireEndGroup-WireStartGroup)) // end group
				if !.Merge() {
					if  == ErrNil {
						 = errRepeatedHasNil
					}
					return , 
				}
			}
			return , .E
		}
}

// makeMessageMarshaler returns the sizer and marshaler for a message field.
// u is the marshal info of the message.
func makeMessageMarshaler( *marshalInfo) (sizer, marshaler) {
	return func( pointer,  int) int {
			 := .getPointer()
			if .isNil() {
				return 0
			}
			 := .size()
			return  + SizeVarint(uint64()) + 
		},
		func( []byte,  pointer,  uint64,  bool) ([]byte, error) {
			 := .getPointer()
			if .isNil() {
				return , nil
			}
			 = appendVarint(, )
			 := .cachedsize()
			 = appendVarint(, uint64())
			return .marshal(, , )
		}
}

// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.
// u is the marshal info of the message.
func makeMessageSliceMarshaler( *marshalInfo) (sizer, marshaler) {
	return func( pointer,  int) int {
			 := .getPointerSlice()
			 := 0
			for ,  := range  {
				if .isNil() {
					continue
				}
				 := .size()
				 +=  + SizeVarint(uint64()) + 
			}
			return 
		},
		func( []byte,  pointer,  uint64,  bool) ([]byte, error) {
			 := .getPointerSlice()
			var  error
			var  nonFatal
			for ,  := range  {
				if .isNil() {
					return , errRepeatedHasNil
				}
				 = appendVarint(, )
				 := .cachedsize()
				 = appendVarint(, uint64())
				,  = .marshal(, , )

				if !.Merge() {
					if  == ErrNil {
						 = errRepeatedHasNil
					}
					return , 
				}
			}
			return , .E
		}
}

// makeMapMarshaler returns the sizer and marshaler for a map field.
// f is the pointer to the reflect data structure of the field.
func makeMapMarshaler( *reflect.StructField) (sizer, marshaler) {
	// figure out key and value type
	 := .Type
	 := .Key()
	 := .Elem()
	 := strings.Split(.Tag.Get("protobuf"), ",")
	 := strings.Split(.Tag.Get("protobuf_key"), ",")
	 := strings.Split(.Tag.Get("protobuf_val"), ",")
	 := false
	for ,  := range  {
		if strings.HasPrefix(, "customtype=") {
			 = append(, )
		}
		if  == "stdtime" {
			 = append(, )
			 = true
		}
		if  == "stdduration" {
			 = append(, )
			 = true
		}
		if  == "wktptr" {
			 = append(, )
		}
	}
	,  := typeMarshaler(, , false, false) // don't omit zero value in map
	,  := typeMarshaler(, , false, false) // don't omit zero value in map
	 := 1<<3 | wiretype([0])
	 := 2<<3 | wiretype([0])

	// We create an interface to get the addresses of the map key and value.
	// If value is pointer-typed, the interface is a direct interface, the
	// idata itself is the value. Otherwise, the idata is the pointer to the
	// value.
	// Key cannot be pointer-typed.
	 := .Kind() == reflect.Ptr

	// If value is a message with nested maps, calling
	// valSizer in marshal may be quadratic. We should use
	// cached version in marshal (but not in size).
	// If value is not message type, we don't have size cache,
	// but it cannot be nested either. Just use valSizer.
	 := 
	if  && ! && .Elem().Kind() == reflect.Struct {
		 := getMarshalInfo(.Elem())
		 = func( pointer,  int) int {
			// Same as message sizer, but use cache.
			 := .getPointer()
			if .isNil() {
				return 0
			}
			 := .cachedsize()
			return  + SizeVarint(uint64()) + 
		}
	}
	return func( pointer,  int) int {
			 := .asPointerTo().Elem() // the map
			 := 0
			for ,  := range .MapKeys() {
				 := .Interface()
				 := .MapIndex().Interface()
				 := toAddrPointer(&, false)             // pointer to key
				 := toAddrPointer(&, )          // pointer to value
				 := (, 1) + (, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
				 +=  + SizeVarint(uint64()) + 
			}
			return 
		},
		func( []byte,  pointer,  uint64,  bool) ([]byte, error) {
			 := .asPointerTo().Elem() // the map
			var  error
			 := .MapKeys()
			if len() > 1 &&  {
				sort.Sort(mapKeys())
			}

			var  nonFatal
			for ,  := range  {
				 := .Interface()
				 := .MapIndex().Interface()
				 := toAddrPointer(&, false)    // pointer to key
				 := toAddrPointer(&, ) // pointer to value
				 = appendVarint(, )
				 := (, 1) + (, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
				 = appendVarint(, uint64())
				,  = (, , , )
				if !.Merge() {
					return , 
				}
				,  = (, , , )
				if  != ErrNil && !.Merge() { // allow nil value in map
					return , 
				}
			}
			return , .E
		}
}

// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.
// fi is the marshal info of the field.
// f is the pointer to the reflect data structure of the field.
func makeOneOfMarshaler( *marshalFieldInfo,  *reflect.StructField) (sizer, marshaler) {
	// Oneof field is an interface. We need to get the actual data type on the fly.
	 := .Type
	return func( pointer,  int) int {
			 := .getInterfacePointer()
			if .isNil() {
				return 0
			}
			 := .asPointerTo().Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
			 := .Type()
			 := .oneofElems[]
			return .sizer(, .tagsize)
		},
		func( []byte,  pointer,  uint64,  bool) ([]byte, error) {
			 := .getInterfacePointer()
			if .isNil() {
				return , nil
			}
			 := .asPointerTo().Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
			 := .Type()
			if .Field(0).Type.Kind() == reflect.Ptr && .getPointer().isNil() {
				return , errOneofHasNil
			}
			 := .oneofElems[]
			return .marshaler(, , .wiretag, )
		}
}

// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.
func ( *marshalInfo) ( *XXX_InternalExtensions) int {
	,  := .extensionsRead()
	if  == nil {
		return 0
	}
	.Lock()

	 := 0
	for ,  := range  {
		if .value == nil || .desc == nil {
			// Extension is only in its encoded form.
			 += len(.enc)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.
		 := .getExtElemInfo(.desc)
		 := .value
		 := toAddrPointer(&, .isptr)
		 += .sizer(, .tagsize)
	}
	.Unlock()
	return 
}

// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.
func ( *marshalInfo) ( []byte,  *XXX_InternalExtensions,  bool) ([]byte, error) {
	,  := .extensionsRead()
	if  == nil {
		return , nil
	}
	.Lock()
	defer .Unlock()

	var  error
	var  nonFatal

	// Fast-path for common cases: zero or one extensions.
	// Don't bother sorting the keys.
	if len() <= 1 {
		for ,  := range  {
			if .value == nil || .desc == nil {
				// Extension is only in its encoded form.
				 = append(, .enc...)
				continue
			}

			// We don't skip extensions that have an encoded form set,
			// because the extension value may have been mutated after
			// the last time this function was called.

			 := .getExtElemInfo(.desc)
			 := .value
			 := toAddrPointer(&, .isptr)
			,  = .marshaler(, , .wiretag, )
			if !.Merge() {
				return , 
			}
		}
		return , .E
	}

	// Sort the keys to provide a deterministic encoding.
	// Not sure this is required, but the old code does it.
	 := make([]int, 0, len())
	for  := range  {
		 = append(, int())
	}
	sort.Ints()

	for ,  := range  {
		 := [int32()]
		if .value == nil || .desc == nil {
			// Extension is only in its encoded form.
			 = append(, .enc...)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		 := .getExtElemInfo(.desc)
		 := .value
		 := toAddrPointer(&, .isptr)
		,  = .marshaler(, , .wiretag, )
		if !.Merge() {
			return , 
		}
	}
	return , .E
}

// message set format is:
//   message MessageSet {
//     repeated group Item = 1 {
//       required int32 type_id = 2;
//       required string message = 3;
//     };
//   }

// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field
// in message set format (above).
func ( *marshalInfo) ( *XXX_InternalExtensions) int {
	,  := .extensionsRead()
	if  == nil {
		return 0
	}
	.Lock()

	 := 0
	for ,  := range  {
		 += 2                          // start group, end group. tag = 1 (size=1)
		 += SizeVarint(uint64()) + 1 // type_id, tag = 2 (size=1)

		if .value == nil || .desc == nil {
			// Extension is only in its encoded form.
			 := skipVarint(.enc) // skip old tag, but leave the length varint
			 := len()
			 +=  + 1 // message, tag = 3 (size=1)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		 := .getExtElemInfo(.desc)
		 := .value
		 := toAddrPointer(&, .isptr)
		 += .sizer(, 1) // message, tag = 3 (size=1)
	}
	.Unlock()
	return 
}

// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)
// to the end of byte slice b.
func ( *marshalInfo) ( []byte,  *XXX_InternalExtensions,  bool) ([]byte, error) {
	,  := .extensionsRead()
	if  == nil {
		return , nil
	}
	.Lock()
	defer .Unlock()

	var  error
	var  nonFatal

	// Fast-path for common cases: zero or one extensions.
	// Don't bother sorting the keys.
	if len() <= 1 {
		for ,  := range  {
			 = append(, 1<<3|WireStartGroup)
			 = append(, 2<<3|WireVarint)
			 = appendVarint(, uint64())

			if .value == nil || .desc == nil {
				// Extension is only in its encoded form.
				 := skipVarint(.enc) // skip old tag, but leave the length varint
				 = append(, 3<<3|WireBytes)
				 = append(, ...)
				 = append(, 1<<3|WireEndGroup)
				continue
			}

			// We don't skip extensions that have an encoded form set,
			// because the extension value may have been mutated after
			// the last time this function was called.

			 := .getExtElemInfo(.desc)
			 := .value
			 := toAddrPointer(&, .isptr)
			,  = .marshaler(, , 3<<3|WireBytes, )
			if !.Merge() {
				return , 
			}
			 = append(, 1<<3|WireEndGroup)
		}
		return , .E
	}

	// Sort the keys to provide a deterministic encoding.
	 := make([]int, 0, len())
	for  := range  {
		 = append(, int())
	}
	sort.Ints()

	for ,  := range  {
		 := [int32()]
		 = append(, 1<<3|WireStartGroup)
		 = append(, 2<<3|WireVarint)
		 = appendVarint(, uint64())

		if .value == nil || .desc == nil {
			// Extension is only in its encoded form.
			 := skipVarint(.enc) // skip old tag, but leave the length varint
			 = append(, 3<<3|WireBytes)
			 = append(, ...)
			 = append(, 1<<3|WireEndGroup)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		 := .getExtElemInfo(.desc)
		 := .value
		 := toAddrPointer(&, .isptr)
		,  = .marshaler(, , 3<<3|WireBytes, )
		 = append(, 1<<3|WireEndGroup)
		if !.Merge() {
			return , 
		}
	}
	return , .E
}

// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
func ( *marshalInfo) ( map[int32]Extension) int {
	if  == nil {
		return 0
	}

	 := 0
	for ,  := range  {
		if .value == nil || .desc == nil {
			// Extension is only in its encoded form.
			 += len(.enc)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		 := .getExtElemInfo(.desc)
		 := .value
		 := toAddrPointer(&, .isptr)
		 += .sizer(, .tagsize)
	}
	return 
}

// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.
func ( *marshalInfo) ( []byte,  map[int32]Extension,  bool) ([]byte, error) {
	if  == nil {
		return , nil
	}

	// Sort the keys to provide a deterministic encoding.
	 := make([]int, 0, len())
	for  := range  {
		 = append(, int())
	}
	sort.Ints()

	var  error
	var  nonFatal
	for ,  := range  {
		 := [int32()]
		if .value == nil || .desc == nil {
			// Extension is only in its encoded form.
			 = append(, .enc...)
			continue
		}

		// We don't skip extensions that have an encoded form set,
		// because the extension value may have been mutated after
		// the last time this function was called.

		 := .getExtElemInfo(.desc)
		 := .value
		 := toAddrPointer(&, .isptr)
		,  = .marshaler(, , .wiretag, )
		if !.Merge() {
			return , 
		}
	}
	return , .E
}

// newMarshaler is the interface representing objects that can marshal themselves.
//
// This exists to support protoc-gen-go generated messages.
// The proto package will stop type-asserting to this interface in the future.
//
// DO NOT DEPEND ON THIS.
type newMarshaler interface {
	XXX_Size() int
	XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
}

// Size returns the encoded size of a protocol buffer message.
// This is the main entry point.
func ( Message) int {
	if ,  := .(newMarshaler);  {
		return .XXX_Size()
	}
	if ,  := .(Marshaler);  {
		// If the message can marshal itself, let it do it, for compatibility.
		// NOTE: This is not efficient.
		,  := .Marshal()
		return len()
	}
	// in case somehow we didn't generate the wrapper
	if  == nil {
		return 0
	}
	var  InternalMessageInfo
	return .Size()
}

// Marshal takes a protocol buffer message
// and encodes it into the wire format, returning the data.
// This is the main entry point.
func ( Message) ([]byte, error) {
	if ,  := .(newMarshaler);  {
		 := .XXX_Size()
		 := make([]byte, 0, )
		return .XXX_Marshal(, false)
	}
	if ,  := .(Marshaler);  {
		// If the message can marshal itself, let it do it, for compatibility.
		// NOTE: This is not efficient.
		return .Marshal()
	}
	// in case somehow we didn't generate the wrapper
	if  == nil {
		return nil, ErrNil
	}
	var  InternalMessageInfo
	 := .Size()
	 := make([]byte, 0, )
	return .Marshal(, , false)
}

// Marshal takes a protocol buffer message
// and encodes it into the wire format, writing the result to the
// Buffer.
// This is an alternative entry point. It is not necessary to use
// a Buffer for most applications.
func ( *Buffer) ( Message) error {
	var  error
	if .deterministic {
		if ,  := .(Marshaler);  {
			return fmt.Errorf("proto: deterministic not supported by the Marshal method of %T", )
		}
	}
	if ,  := .(newMarshaler);  {
		 := .XXX_Size()
		.grow() // make sure buf has enough capacity
		 := .buf[len(.buf) : len(.buf) : len(.buf)+]
		,  = .XXX_Marshal(, .deterministic)
		.buf = append(.buf, ...)
		return 
	}
	if ,  := .(Marshaler);  {
		// If the message can marshal itself, let it do it, for compatibility.
		// NOTE: This is not efficient.
		var  []byte
		,  = .Marshal()
		.buf = append(.buf, ...)
		return 
	}
	// in case somehow we didn't generate the wrapper
	if  == nil {
		return ErrNil
	}
	var  InternalMessageInfo
	 := .Size()
	.grow() // make sure buf has enough capacity
	.buf,  = .Marshal(.buf, , .deterministic)
	return 
}

// grow grows the buffer's capacity, if necessary, to guarantee space for
// another n bytes. After grow(n), at least n bytes can be written to the
// buffer without another allocation.
func ( *Buffer) ( int) {
	 := len(.buf) + 
	if  <= cap(.buf) {
		return
	}
	 := len(.buf) * 2
	if  <  {
		 = 
	}
	.buf = append(make([]byte, 0, ), .buf...)
}