...

Source file src/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go

Documentation: github.com/gogo/protobuf/plugin/unmarshal

     1  // Protocol Buffers for Go with Gadgets
     2  //
     3  // Copyright (c) 2013, The GoGo Authors. All rights reserved.
     4  // http://github.com/gogo/protobuf
     5  //
     6  // Redistribution and use in source and binary forms, with or without
     7  // modification, are permitted provided that the following conditions are
     8  // met:
     9  //
    10  //     * Redistributions of source code must retain the above copyright
    11  // notice, this list of conditions and the following disclaimer.
    12  //     * Redistributions in binary form must reproduce the above
    13  // copyright notice, this list of conditions and the following disclaimer
    14  // in the documentation and/or other materials provided with the
    15  // distribution.
    16  //
    17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    18  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    19  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    20  // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    21  // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    22  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    23  // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    24  // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    25  // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    26  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    27  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    28  
    29  /*
    30  The unmarshal plugin generates a Unmarshal method for each message.
    31  The `Unmarshal([]byte) error` method results in the fact that the message
    32  implements the Unmarshaler interface.
    33  The allows proto.Unmarshal to be faster by calling the generated Unmarshal method rather than using reflect.
    34  
    35  If is enabled by the following extensions:
    36  
    37    - unmarshaler
    38    - unmarshaler_all
    39  
    40  Or the following extensions:
    41  
    42    - unsafe_unmarshaler
    43    - unsafe_unmarshaler_all
    44  
    45  That is if you want to use the unsafe package in your generated code.
    46  The speed up using the unsafe package is not very significant.
    47  
    48  The generation of unmarshalling tests are enabled using one of the following extensions:
    49  
    50    - testgen
    51    - testgen_all
    52  
    53  And benchmarks given it is enabled using one of the following extensions:
    54  
    55    - benchgen
    56    - benchgen_all
    57  
    58  Let us look at:
    59  
    60    github.com/gogo/protobuf/test/example/example.proto
    61  
    62  Btw all the output can be seen at:
    63  
    64    github.com/gogo/protobuf/test/example/*
    65  
    66  The following message:
    67  
    68    option (gogoproto.unmarshaler_all) = true;
    69  
    70    message B {
    71  	option (gogoproto.description) = true;
    72  	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
    73  	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
    74    }
    75  
    76  given to the unmarshal plugin, will generate the following code:
    77  
    78    func (m *B) Unmarshal(dAtA []byte) error {
    79  	l := len(dAtA)
    80  	iNdEx := 0
    81  	for iNdEx < l {
    82  		var wire uint64
    83  		for shift := uint(0); ; shift += 7 {
    84  			if iNdEx >= l {
    85  				return io.ErrUnexpectedEOF
    86  			}
    87  			b := dAtA[iNdEx]
    88  			iNdEx++
    89  			wire |= (uint64(b) & 0x7F) << shift
    90  			if b < 0x80 {
    91  				break
    92  			}
    93  		}
    94  		fieldNum := int32(wire >> 3)
    95  		wireType := int(wire & 0x7)
    96  		switch fieldNum {
    97  		case 1:
    98  			if wireType != 2 {
    99  				return proto.ErrWrongType
   100  			}
   101  			var msglen int
   102  			for shift := uint(0); ; shift += 7 {
   103  				if iNdEx >= l {
   104  					return io.ErrUnexpectedEOF
   105  				}
   106  				b := dAtA[iNdEx]
   107  				iNdEx++
   108  				msglen |= (int(b) & 0x7F) << shift
   109  				if b < 0x80 {
   110  					break
   111  				}
   112  			}
   113  			postIndex := iNdEx + msglen
   114  			if postIndex > l {
   115  				return io.ErrUnexpectedEOF
   116  			}
   117  			if err := m.A.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
   118  				return err
   119  			}
   120  			iNdEx = postIndex
   121  		case 2:
   122  			if wireType != 2 {
   123  				return proto.ErrWrongType
   124  			}
   125  			var byteLen int
   126  			for shift := uint(0); ; shift += 7 {
   127  				if iNdEx >= l {
   128  					return io.ErrUnexpectedEOF
   129  				}
   130  				b := dAtA[iNdEx]
   131  				iNdEx++
   132  				byteLen |= (int(b) & 0x7F) << shift
   133  				if b < 0x80 {
   134  					break
   135  				}
   136  			}
   137  			postIndex := iNdEx + byteLen
   138  			if postIndex > l {
   139  				return io.ErrUnexpectedEOF
   140  			}
   141  			m.G = append(m.G, github_com_gogo_protobuf_test_custom.Uint128{})
   142  			if err := m.G[len(m.G)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
   143  				return err
   144  			}
   145  			iNdEx = postIndex
   146  		default:
   147  			var sizeOfWire int
   148  			for {
   149  				sizeOfWire++
   150  				wire >>= 7
   151  				if wire == 0 {
   152  					break
   153  				}
   154  			}
   155  			iNdEx -= sizeOfWire
   156  			skippy, err := skip(dAtA[iNdEx:])
   157  			if err != nil {
   158  				return err
   159  			}
   160  			if (iNdEx + skippy) > l {
   161  				return io.ErrUnexpectedEOF
   162  			}
   163  			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
   164  			iNdEx += skippy
   165  		}
   166  	}
   167  	return nil
   168    }
   169  
   170  Remember when using this code to call proto.Unmarshal.
   171  This will call m.Reset and invoke the generated Unmarshal method for you.
   172  If you call m.Unmarshal without m.Reset you could be merging protocol buffers.
   173  
   174  */
   175  package unmarshal
   176  
   177  import (
   178  	"fmt"
   179  	"strconv"
   180  	"strings"
   181  
   182  	"github.com/gogo/protobuf/gogoproto"
   183  	"github.com/gogo/protobuf/proto"
   184  	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
   185  	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
   186  )
   187  
   188  type unmarshal struct {
   189  	*generator.Generator
   190  	generator.PluginImports
   191  	atleastOne bool
   192  	ioPkg      generator.Single
   193  	mathPkg    generator.Single
   194  	typesPkg   generator.Single
   195  	binaryPkg  generator.Single
   196  	localName  string
   197  }
   198  
   199  func NewUnmarshal() *unmarshal {
   200  	return &unmarshal{}
   201  }
   202  
   203  func (p *unmarshal) Name() string {
   204  	return "unmarshal"
   205  }
   206  
   207  func (p *unmarshal) Init(g *generator.Generator) {
   208  	p.Generator = g
   209  }
   210  
   211  func (p *unmarshal) decodeVarint(varName string, typName string) {
   212  	p.P(`for shift := uint(0); ; shift += 7 {`)
   213  	p.In()
   214  	p.P(`if shift >= 64 {`)
   215  	p.In()
   216  	p.P(`return ErrIntOverflow` + p.localName)
   217  	p.Out()
   218  	p.P(`}`)
   219  	p.P(`if iNdEx >= l {`)
   220  	p.In()
   221  	p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   222  	p.Out()
   223  	p.P(`}`)
   224  	p.P(`b := dAtA[iNdEx]`)
   225  	p.P(`iNdEx++`)
   226  	p.P(varName, ` |= `, typName, `(b&0x7F) << shift`)
   227  	p.P(`if b < 0x80 {`)
   228  	p.In()
   229  	p.P(`break`)
   230  	p.Out()
   231  	p.P(`}`)
   232  	p.Out()
   233  	p.P(`}`)
   234  }
   235  
   236  func (p *unmarshal) decodeFixed32(varName string, typeName string) {
   237  	p.P(`if (iNdEx+4) > l {`)
   238  	p.In()
   239  	p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   240  	p.Out()
   241  	p.P(`}`)
   242  	p.P(varName, ` = `, typeName, `(`, p.binaryPkg.Use(), `.LittleEndian.Uint32(dAtA[iNdEx:]))`)
   243  	p.P(`iNdEx += 4`)
   244  }
   245  
   246  func (p *unmarshal) decodeFixed64(varName string, typeName string) {
   247  	p.P(`if (iNdEx+8) > l {`)
   248  	p.In()
   249  	p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   250  	p.Out()
   251  	p.P(`}`)
   252  	p.P(varName, ` = `, typeName, `(`, p.binaryPkg.Use(), `.LittleEndian.Uint64(dAtA[iNdEx:]))`)
   253  	p.P(`iNdEx += 8`)
   254  }
   255  
   256  func (p *unmarshal) declareMapField(varName string, nullable bool, customType bool, field *descriptor.FieldDescriptorProto) {
   257  	switch field.GetType() {
   258  	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
   259  		p.P(`var `, varName, ` float64`)
   260  	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
   261  		p.P(`var `, varName, ` float32`)
   262  	case descriptor.FieldDescriptorProto_TYPE_INT64:
   263  		p.P(`var `, varName, ` int64`)
   264  	case descriptor.FieldDescriptorProto_TYPE_UINT64:
   265  		p.P(`var `, varName, ` uint64`)
   266  	case descriptor.FieldDescriptorProto_TYPE_INT32:
   267  		p.P(`var `, varName, ` int32`)
   268  	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
   269  		p.P(`var `, varName, ` uint64`)
   270  	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
   271  		p.P(`var `, varName, ` uint32`)
   272  	case descriptor.FieldDescriptorProto_TYPE_BOOL:
   273  		p.P(`var `, varName, ` bool`)
   274  	case descriptor.FieldDescriptorProto_TYPE_STRING:
   275  		cast, _ := p.GoType(nil, field)
   276  		cast = strings.Replace(cast, "*", "", 1)
   277  		p.P(`var `, varName, ` `, cast)
   278  	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
   279  		if gogoproto.IsStdTime(field) {
   280  			p.P(varName, ` := new(time.Time)`)
   281  		} else if gogoproto.IsStdDuration(field) {
   282  			p.P(varName, ` := new(time.Duration)`)
   283  		} else if gogoproto.IsStdDouble(field) {
   284  			p.P(varName, ` := new(float64)`)
   285  		} else if gogoproto.IsStdFloat(field) {
   286  			p.P(varName, ` := new(float32)`)
   287  		} else if gogoproto.IsStdInt64(field) {
   288  			p.P(varName, ` := new(int64)`)
   289  		} else if gogoproto.IsStdUInt64(field) {
   290  			p.P(varName, ` := new(uint64)`)
   291  		} else if gogoproto.IsStdInt32(field) {
   292  			p.P(varName, ` := new(int32)`)
   293  		} else if gogoproto.IsStdUInt32(field) {
   294  			p.P(varName, ` := new(uint32)`)
   295  		} else if gogoproto.IsStdBool(field) {
   296  			p.P(varName, ` := new(bool)`)
   297  		} else if gogoproto.IsStdString(field) {
   298  			p.P(varName, ` := new(string)`)
   299  		} else if gogoproto.IsStdBytes(field) {
   300  			p.P(varName, ` := new([]byte)`)
   301  		} else {
   302  			desc := p.ObjectNamed(field.GetTypeName())
   303  			msgname := p.TypeName(desc)
   304  			if nullable {
   305  				p.P(`var `, varName, ` *`, msgname)
   306  			} else {
   307  				p.P(varName, ` := &`, msgname, `{}`)
   308  			}
   309  		}
   310  	case descriptor.FieldDescriptorProto_TYPE_BYTES:
   311  		if customType {
   312  			_, ctyp, err := generator.GetCustomType(field)
   313  			if err != nil {
   314  				panic(err)
   315  			}
   316  			p.P(`var `, varName, `1 `, ctyp)
   317  			p.P(`var `, varName, ` = &`, varName, `1`)
   318  		} else {
   319  			p.P(varName, ` := []byte{}`)
   320  		}
   321  	case descriptor.FieldDescriptorProto_TYPE_UINT32:
   322  		p.P(`var `, varName, ` uint32`)
   323  	case descriptor.FieldDescriptorProto_TYPE_ENUM:
   324  		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
   325  		p.P(`var `, varName, ` `, typName)
   326  	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
   327  		p.P(`var `, varName, ` int32`)
   328  	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
   329  		p.P(`var `, varName, ` int64`)
   330  	case descriptor.FieldDescriptorProto_TYPE_SINT32:
   331  		p.P(`var `, varName, ` int32`)
   332  	case descriptor.FieldDescriptorProto_TYPE_SINT64:
   333  		p.P(`var `, varName, ` int64`)
   334  	}
   335  }
   336  
   337  func (p *unmarshal) mapField(varName string, customType bool, field *descriptor.FieldDescriptorProto) {
   338  	switch field.GetType() {
   339  	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
   340  		p.P(`var `, varName, `temp uint64`)
   341  		p.decodeFixed64(varName+"temp", "uint64")
   342  		p.P(varName, ` = `, p.mathPkg.Use(), `.Float64frombits(`, varName, `temp)`)
   343  	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
   344  		p.P(`var `, varName, `temp uint32`)
   345  		p.decodeFixed32(varName+"temp", "uint32")
   346  		p.P(varName, ` = `, p.mathPkg.Use(), `.Float32frombits(`, varName, `temp)`)
   347  	case descriptor.FieldDescriptorProto_TYPE_INT64:
   348  		p.decodeVarint(varName, "int64")
   349  	case descriptor.FieldDescriptorProto_TYPE_UINT64:
   350  		p.decodeVarint(varName, "uint64")
   351  	case descriptor.FieldDescriptorProto_TYPE_INT32:
   352  		p.decodeVarint(varName, "int32")
   353  	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
   354  		p.decodeFixed64(varName, "uint64")
   355  	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
   356  		p.decodeFixed32(varName, "uint32")
   357  	case descriptor.FieldDescriptorProto_TYPE_BOOL:
   358  		p.P(`var `, varName, `temp int`)
   359  		p.decodeVarint(varName+"temp", "int")
   360  		p.P(varName, ` = bool(`, varName, `temp != 0)`)
   361  	case descriptor.FieldDescriptorProto_TYPE_STRING:
   362  		p.P(`var stringLen`, varName, ` uint64`)
   363  		p.decodeVarint("stringLen"+varName, "uint64")
   364  		p.P(`intStringLen`, varName, ` := int(stringLen`, varName, `)`)
   365  		p.P(`if intStringLen`, varName, ` < 0 {`)
   366  		p.In()
   367  		p.P(`return ErrInvalidLength` + p.localName)
   368  		p.Out()
   369  		p.P(`}`)
   370  		p.P(`postStringIndex`, varName, ` := iNdEx + intStringLen`, varName)
   371  		p.P(`if postStringIndex`, varName, ` < 0 {`)
   372  		p.In()
   373  		p.P(`return ErrInvalidLength` + p.localName)
   374  		p.Out()
   375  		p.P(`}`)
   376  		p.P(`if postStringIndex`, varName, ` > l {`)
   377  		p.In()
   378  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   379  		p.Out()
   380  		p.P(`}`)
   381  		cast, _ := p.GoType(nil, field)
   382  		cast = strings.Replace(cast, "*", "", 1)
   383  		p.P(varName, ` = `, cast, `(dAtA[iNdEx:postStringIndex`, varName, `])`)
   384  		p.P(`iNdEx = postStringIndex`, varName)
   385  	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
   386  		p.P(`var mapmsglen int`)
   387  		p.decodeVarint("mapmsglen", "int")
   388  		p.P(`if mapmsglen < 0 {`)
   389  		p.In()
   390  		p.P(`return ErrInvalidLength` + p.localName)
   391  		p.Out()
   392  		p.P(`}`)
   393  		p.P(`postmsgIndex := iNdEx + mapmsglen`)
   394  		p.P(`if postmsgIndex < 0 {`)
   395  		p.In()
   396  		p.P(`return ErrInvalidLength` + p.localName)
   397  		p.Out()
   398  		p.P(`}`)
   399  		p.P(`if postmsgIndex > l {`)
   400  		p.In()
   401  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   402  		p.Out()
   403  		p.P(`}`)
   404  		buf := `dAtA[iNdEx:postmsgIndex]`
   405  		if gogoproto.IsStdTime(field) {
   406  			p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   407  		} else if gogoproto.IsStdDuration(field) {
   408  			p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   409  		} else if gogoproto.IsStdDouble(field) {
   410  			p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   411  		} else if gogoproto.IsStdFloat(field) {
   412  			p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   413  		} else if gogoproto.IsStdInt64(field) {
   414  			p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(`, varName, `, `, buf, `); err != nil {`)
   415  		} else if gogoproto.IsStdUInt64(field) {
   416  			p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(`, varName, `, `, buf, `); err != nil {`)
   417  		} else if gogoproto.IsStdInt32(field) {
   418  			p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(`, varName, `, `, buf, `); err != nil {`)
   419  		} else if gogoproto.IsStdUInt32(field) {
   420  			p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(`, varName, `, `, buf, `); err != nil {`)
   421  		} else if gogoproto.IsStdBool(field) {
   422  			p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   423  		} else if gogoproto.IsStdString(field) {
   424  			p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   425  		} else if gogoproto.IsStdBytes(field) {
   426  			p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(`, varName, `, `, buf, `); err != nil {`)
   427  		} else {
   428  			desc := p.ObjectNamed(field.GetTypeName())
   429  			msgname := p.TypeName(desc)
   430  			p.P(varName, ` = &`, msgname, `{}`)
   431  			p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`)
   432  		}
   433  		p.In()
   434  		p.P(`return err`)
   435  		p.Out()
   436  		p.P(`}`)
   437  		p.P(`iNdEx = postmsgIndex`)
   438  	case descriptor.FieldDescriptorProto_TYPE_BYTES:
   439  		p.P(`var mapbyteLen uint64`)
   440  		p.decodeVarint("mapbyteLen", "uint64")
   441  		p.P(`intMapbyteLen := int(mapbyteLen)`)
   442  		p.P(`if intMapbyteLen < 0 {`)
   443  		p.In()
   444  		p.P(`return ErrInvalidLength` + p.localName)
   445  		p.Out()
   446  		p.P(`}`)
   447  		p.P(`postbytesIndex := iNdEx + intMapbyteLen`)
   448  		p.P(`if postbytesIndex < 0 {`)
   449  		p.In()
   450  		p.P(`return ErrInvalidLength` + p.localName)
   451  		p.Out()
   452  		p.P(`}`)
   453  		p.P(`if postbytesIndex > l {`)
   454  		p.In()
   455  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   456  		p.Out()
   457  		p.P(`}`)
   458  		if customType {
   459  			p.P(`if err := `, varName, `.Unmarshal(dAtA[iNdEx:postbytesIndex]); err != nil {`)
   460  			p.In()
   461  			p.P(`return err`)
   462  			p.Out()
   463  			p.P(`}`)
   464  		} else {
   465  			p.P(varName, ` = make([]byte, mapbyteLen)`)
   466  			p.P(`copy(`, varName, `, dAtA[iNdEx:postbytesIndex])`)
   467  		}
   468  		p.P(`iNdEx = postbytesIndex`)
   469  	case descriptor.FieldDescriptorProto_TYPE_UINT32:
   470  		p.decodeVarint(varName, "uint32")
   471  	case descriptor.FieldDescriptorProto_TYPE_ENUM:
   472  		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
   473  		p.decodeVarint(varName, typName)
   474  	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
   475  		p.decodeFixed32(varName, "int32")
   476  	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
   477  		p.decodeFixed64(varName, "int64")
   478  	case descriptor.FieldDescriptorProto_TYPE_SINT32:
   479  		p.P(`var `, varName, `temp int32`)
   480  		p.decodeVarint(varName+"temp", "int32")
   481  		p.P(varName, `temp = int32((uint32(`, varName, `temp) >> 1) ^ uint32(((`, varName, `temp&1)<<31)>>31))`)
   482  		p.P(varName, ` = int32(`, varName, `temp)`)
   483  	case descriptor.FieldDescriptorProto_TYPE_SINT64:
   484  		p.P(`var `, varName, `temp uint64`)
   485  		p.decodeVarint(varName+"temp", "uint64")
   486  		p.P(varName, `temp = (`, varName, `temp >> 1) ^ uint64((int64(`, varName, `temp&1)<<63)>>63)`)
   487  		p.P(varName, ` = int64(`, varName, `temp)`)
   488  	}
   489  }
   490  
   491  func (p *unmarshal) noStarOrSliceType(msg *generator.Descriptor, field *descriptor.FieldDescriptorProto) string {
   492  	typ, _ := p.GoType(msg, field)
   493  	if typ[0] == '*' {
   494  		return typ[1:]
   495  	}
   496  	if typ[0] == '[' && typ[1] == ']' {
   497  		return typ[2:]
   498  	}
   499  	return typ
   500  }
   501  
   502  func (p *unmarshal) field(file *generator.FileDescriptor, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) {
   503  	repeated := field.IsRepeated()
   504  	nullable := gogoproto.IsNullable(field)
   505  	typ := p.noStarOrSliceType(msg, field)
   506  	oneof := field.OneofIndex != nil
   507  	switch *field.Type {
   508  	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
   509  		p.P(`var v uint64`)
   510  		p.decodeFixed64("v", "uint64")
   511  		if oneof {
   512  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))}`)
   513  		} else if repeated {
   514  			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`)
   515  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`)
   516  		} else if proto3 || !nullable {
   517  			p.P(`m.`, fieldname, ` = `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`)
   518  		} else {
   519  			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`)
   520  			p.P(`m.`, fieldname, ` = &v2`)
   521  		}
   522  	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
   523  		p.P(`var v uint32`)
   524  		p.decodeFixed32("v", "uint32")
   525  		if oneof {
   526  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))}`)
   527  		} else if repeated {
   528  			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`)
   529  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`)
   530  		} else if proto3 || !nullable {
   531  			p.P(`m.`, fieldname, ` = `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`)
   532  		} else {
   533  			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`)
   534  			p.P(`m.`, fieldname, ` = &v2`)
   535  		}
   536  	case descriptor.FieldDescriptorProto_TYPE_INT64:
   537  		if oneof {
   538  			p.P(`var v `, typ)
   539  			p.decodeVarint("v", typ)
   540  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
   541  		} else if repeated {
   542  			p.P(`var v `, typ)
   543  			p.decodeVarint("v", typ)
   544  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
   545  		} else if proto3 || !nullable {
   546  			p.P(`m.`, fieldname, ` = 0`)
   547  			p.decodeVarint("m."+fieldname, typ)
   548  		} else {
   549  			p.P(`var v `, typ)
   550  			p.decodeVarint("v", typ)
   551  			p.P(`m.`, fieldname, ` = &v`)
   552  		}
   553  	case descriptor.FieldDescriptorProto_TYPE_UINT64:
   554  		if oneof {
   555  			p.P(`var v `, typ)
   556  			p.decodeVarint("v", typ)
   557  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
   558  		} else if repeated {
   559  			p.P(`var v `, typ)
   560  			p.decodeVarint("v", typ)
   561  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
   562  		} else if proto3 || !nullable {
   563  			p.P(`m.`, fieldname, ` = 0`)
   564  			p.decodeVarint("m."+fieldname, typ)
   565  		} else {
   566  			p.P(`var v `, typ)
   567  			p.decodeVarint("v", typ)
   568  			p.P(`m.`, fieldname, ` = &v`)
   569  		}
   570  	case descriptor.FieldDescriptorProto_TYPE_INT32:
   571  		if oneof {
   572  			p.P(`var v `, typ)
   573  			p.decodeVarint("v", typ)
   574  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
   575  		} else if repeated {
   576  			p.P(`var v `, typ)
   577  			p.decodeVarint("v", typ)
   578  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
   579  		} else if proto3 || !nullable {
   580  			p.P(`m.`, fieldname, ` = 0`)
   581  			p.decodeVarint("m."+fieldname, typ)
   582  		} else {
   583  			p.P(`var v `, typ)
   584  			p.decodeVarint("v", typ)
   585  			p.P(`m.`, fieldname, ` = &v`)
   586  		}
   587  	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
   588  		if oneof {
   589  			p.P(`var v `, typ)
   590  			p.decodeFixed64("v", typ)
   591  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
   592  		} else if repeated {
   593  			p.P(`var v `, typ)
   594  			p.decodeFixed64("v", typ)
   595  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
   596  		} else if proto3 || !nullable {
   597  			p.P(`m.`, fieldname, ` = 0`)
   598  			p.decodeFixed64("m."+fieldname, typ)
   599  		} else {
   600  			p.P(`var v `, typ)
   601  			p.decodeFixed64("v", typ)
   602  			p.P(`m.`, fieldname, ` = &v`)
   603  		}
   604  	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
   605  		if oneof {
   606  			p.P(`var v `, typ)
   607  			p.decodeFixed32("v", typ)
   608  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
   609  		} else if repeated {
   610  			p.P(`var v `, typ)
   611  			p.decodeFixed32("v", typ)
   612  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
   613  		} else if proto3 || !nullable {
   614  			p.P(`m.`, fieldname, ` = 0`)
   615  			p.decodeFixed32("m."+fieldname, typ)
   616  		} else {
   617  			p.P(`var v `, typ)
   618  			p.decodeFixed32("v", typ)
   619  			p.P(`m.`, fieldname, ` = &v`)
   620  		}
   621  	case descriptor.FieldDescriptorProto_TYPE_BOOL:
   622  		p.P(`var v int`)
   623  		p.decodeVarint("v", "int")
   624  		if oneof {
   625  			p.P(`b := `, typ, `(v != 0)`)
   626  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{b}`)
   627  		} else if repeated {
   628  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(v != 0))`)
   629  		} else if proto3 || !nullable {
   630  			p.P(`m.`, fieldname, ` = `, typ, `(v != 0)`)
   631  		} else {
   632  			p.P(`b := `, typ, `(v != 0)`)
   633  			p.P(`m.`, fieldname, ` = &b`)
   634  		}
   635  	case descriptor.FieldDescriptorProto_TYPE_STRING:
   636  		p.P(`var stringLen uint64`)
   637  		p.decodeVarint("stringLen", "uint64")
   638  		p.P(`intStringLen := int(stringLen)`)
   639  		p.P(`if intStringLen < 0 {`)
   640  		p.In()
   641  		p.P(`return ErrInvalidLength` + p.localName)
   642  		p.Out()
   643  		p.P(`}`)
   644  		p.P(`postIndex := iNdEx + intStringLen`)
   645  		p.P(`if postIndex < 0 {`)
   646  		p.In()
   647  		p.P(`return ErrInvalidLength` + p.localName)
   648  		p.Out()
   649  		p.P(`}`)
   650  		p.P(`if postIndex > l {`)
   651  		p.In()
   652  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   653  		p.Out()
   654  		p.P(`}`)
   655  		if oneof {
   656  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, `(dAtA[iNdEx:postIndex])}`)
   657  		} else if repeated {
   658  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(dAtA[iNdEx:postIndex]))`)
   659  		} else if proto3 || !nullable {
   660  			p.P(`m.`, fieldname, ` = `, typ, `(dAtA[iNdEx:postIndex])`)
   661  		} else {
   662  			p.P(`s := `, typ, `(dAtA[iNdEx:postIndex])`)
   663  			p.P(`m.`, fieldname, ` = &s`)
   664  		}
   665  		p.P(`iNdEx = postIndex`)
   666  	case descriptor.FieldDescriptorProto_TYPE_GROUP:
   667  		panic(fmt.Errorf("unmarshaler does not support group %v", fieldname))
   668  	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
   669  		desc := p.ObjectNamed(field.GetTypeName())
   670  		msgname := p.TypeName(desc)
   671  		p.P(`var msglen int`)
   672  		p.decodeVarint("msglen", "int")
   673  		p.P(`if msglen < 0 {`)
   674  		p.In()
   675  		p.P(`return ErrInvalidLength` + p.localName)
   676  		p.Out()
   677  		p.P(`}`)
   678  		p.P(`postIndex := iNdEx + msglen`)
   679  		p.P(`if postIndex < 0 {`)
   680  		p.In()
   681  		p.P(`return ErrInvalidLength` + p.localName)
   682  		p.Out()
   683  		p.P(`}`)
   684  		p.P(`if postIndex > l {`)
   685  		p.In()
   686  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   687  		p.Out()
   688  		p.P(`}`)
   689  		if oneof {
   690  			buf := `dAtA[iNdEx:postIndex]`
   691  			if gogoproto.IsStdTime(field) {
   692  				if nullable {
   693  					p.P(`v := new(time.Time)`)
   694  					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(v, `, buf, `); err != nil {`)
   695  				} else {
   696  					p.P(`v := time.Time{}`)
   697  					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&v, `, buf, `); err != nil {`)
   698  				}
   699  			} else if gogoproto.IsStdDuration(field) {
   700  				if nullable {
   701  					p.P(`v := new(time.Duration)`)
   702  					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(v, `, buf, `); err != nil {`)
   703  				} else {
   704  					p.P(`v := time.Duration(0)`)
   705  					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&v, `, buf, `); err != nil {`)
   706  				}
   707  			} else if gogoproto.IsStdDouble(field) {
   708  				if nullable {
   709  					p.P(`v := new(float64)`)
   710  					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(v, `, buf, `); err != nil {`)
   711  				} else {
   712  					p.P(`v := 0`)
   713  					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(&v, `, buf, `); err != nil {`)
   714  				}
   715  			} else if gogoproto.IsStdFloat(field) {
   716  				if nullable {
   717  					p.P(`v := new(float32)`)
   718  					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(v, `, buf, `); err != nil {`)
   719  				} else {
   720  					p.P(`v := 0`)
   721  					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(&v, `, buf, `); err != nil {`)
   722  				}
   723  			} else if gogoproto.IsStdInt64(field) {
   724  				if nullable {
   725  					p.P(`v := new(int64)`)
   726  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(v, `, buf, `); err != nil {`)
   727  				} else {
   728  					p.P(`v := 0`)
   729  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(&v, `, buf, `); err != nil {`)
   730  				}
   731  			} else if gogoproto.IsStdUInt64(field) {
   732  				if nullable {
   733  					p.P(`v := new(uint64)`)
   734  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(v, `, buf, `); err != nil {`)
   735  				} else {
   736  					p.P(`v := 0`)
   737  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(&v, `, buf, `); err != nil {`)
   738  				}
   739  			} else if gogoproto.IsStdInt32(field) {
   740  				if nullable {
   741  					p.P(`v := new(int32)`)
   742  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(v, `, buf, `); err != nil {`)
   743  				} else {
   744  					p.P(`v := 0`)
   745  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(&v, `, buf, `); err != nil {`)
   746  				}
   747  			} else if gogoproto.IsStdUInt32(field) {
   748  				if nullable {
   749  					p.P(`v := new(uint32)`)
   750  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(v, `, buf, `); err != nil {`)
   751  				} else {
   752  					p.P(`v := 0`)
   753  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(&v, `, buf, `); err != nil {`)
   754  				}
   755  			} else if gogoproto.IsStdBool(field) {
   756  				if nullable {
   757  					p.P(`v := new(bool)`)
   758  					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(v, `, buf, `); err != nil {`)
   759  				} else {
   760  					p.P(`v := false`)
   761  					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(&v, `, buf, `); err != nil {`)
   762  				}
   763  			} else if gogoproto.IsStdString(field) {
   764  				if nullable {
   765  					p.P(`v := new(string)`)
   766  					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(v, `, buf, `); err != nil {`)
   767  				} else {
   768  					p.P(`v := ""`)
   769  					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(&v, `, buf, `); err != nil {`)
   770  				}
   771  			} else if gogoproto.IsStdBytes(field) {
   772  				if nullable {
   773  					p.P(`v := new([]byte)`)
   774  					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(v, `, buf, `); err != nil {`)
   775  				} else {
   776  					p.P(`var v []byte`)
   777  					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(&v, `, buf, `); err != nil {`)
   778  				}
   779  			} else {
   780  				p.P(`v := &`, msgname, `{}`)
   781  				p.P(`if err := v.Unmarshal(`, buf, `); err != nil {`)
   782  			}
   783  			p.In()
   784  			p.P(`return err`)
   785  			p.Out()
   786  			p.P(`}`)
   787  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
   788  		} else if p.IsMap(field) {
   789  			m := p.GoMapType(nil, field)
   790  
   791  			keygoTyp, _ := p.GoType(nil, m.KeyField)
   792  			keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField)
   793  			// keys may not be pointers
   794  			keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
   795  			keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
   796  
   797  			valuegoTyp, _ := p.GoType(nil, m.ValueField)
   798  			valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
   799  
   800  			// if the map type is an alias and key or values are aliases (type Foo map[Bar]Baz),
   801  			// we need to explicitly record their use here.
   802  			if gogoproto.IsCastKey(field) {
   803  				p.RecordTypeUse(m.KeyAliasField.GetTypeName())
   804  			}
   805  			if gogoproto.IsCastValue(field) {
   806  				p.RecordTypeUse(m.ValueAliasField.GetTypeName())
   807  			}
   808  
   809  			nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
   810  			if gogoproto.IsStdType(field) {
   811  				valuegoTyp = valuegoAliasTyp
   812  			}
   813  
   814  			p.P(`if m.`, fieldname, ` == nil {`)
   815  			p.In()
   816  			p.P(`m.`, fieldname, ` = make(`, m.GoType, `)`)
   817  			p.Out()
   818  			p.P(`}`)
   819  
   820  			p.declareMapField("mapkey", false, false, m.KeyAliasField)
   821  			p.declareMapField("mapvalue", nullable, gogoproto.IsCustomType(field), m.ValueAliasField)
   822  			p.P(`for iNdEx < postIndex {`)
   823  			p.In()
   824  
   825  			p.P(`entryPreIndex := iNdEx`)
   826  			p.P(`var wire uint64`)
   827  			p.decodeVarint("wire", "uint64")
   828  			p.P(`fieldNum := int32(wire >> 3)`)
   829  
   830  			p.P(`if fieldNum == 1 {`)
   831  			p.In()
   832  			p.mapField("mapkey", false, m.KeyAliasField)
   833  			p.Out()
   834  			p.P(`} else if fieldNum == 2 {`)
   835  			p.In()
   836  			p.mapField("mapvalue", gogoproto.IsCustomType(field), m.ValueAliasField)
   837  			p.Out()
   838  			p.P(`} else {`)
   839  			p.In()
   840  			p.P(`iNdEx = entryPreIndex`)
   841  			p.P(`skippy, err := skip`, p.localName, `(dAtA[iNdEx:])`)
   842  			p.P(`if err != nil {`)
   843  			p.In()
   844  			p.P(`return err`)
   845  			p.Out()
   846  			p.P(`}`)
   847  			p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
   848  			p.In()
   849  			p.P(`return ErrInvalidLength`, p.localName)
   850  			p.Out()
   851  			p.P(`}`)
   852  			p.P(`if (iNdEx + skippy) > postIndex {`)
   853  			p.In()
   854  			p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
   855  			p.Out()
   856  			p.P(`}`)
   857  			p.P(`iNdEx += skippy`)
   858  			p.Out()
   859  			p.P(`}`)
   860  
   861  			p.Out()
   862  			p.P(`}`)
   863  
   864  			s := `m.` + fieldname
   865  			if keygoTyp == keygoAliasTyp {
   866  				s += `[mapkey]`
   867  			} else {
   868  				s += `[` + keygoAliasTyp + `(mapkey)]`
   869  			}
   870  
   871  			v := `mapvalue`
   872  			if (m.ValueField.IsMessage() || gogoproto.IsCustomType(field)) && !nullable {
   873  				v = `*` + v
   874  			}
   875  			if valuegoTyp != valuegoAliasTyp {
   876  				v = `((` + valuegoAliasTyp + `)(` + v + `))`
   877  			}
   878  
   879  			p.P(s, ` = `, v)
   880  		} else if repeated {
   881  			if gogoproto.IsStdTime(field) {
   882  				if nullable {
   883  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(time.Time))`)
   884  				} else {
   885  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, time.Time{})`)
   886  				}
   887  			} else if gogoproto.IsStdDuration(field) {
   888  				if nullable {
   889  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(time.Duration))`)
   890  				} else {
   891  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, time.Duration(0))`)
   892  				}
   893  			} else if gogoproto.IsStdDouble(field) {
   894  				if nullable {
   895  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(float64))`)
   896  				} else {
   897  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
   898  				}
   899  			} else if gogoproto.IsStdFloat(field) {
   900  				if nullable {
   901  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(float32))`)
   902  				} else {
   903  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
   904  				}
   905  			} else if gogoproto.IsStdInt64(field) {
   906  				if nullable {
   907  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(int64))`)
   908  				} else {
   909  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
   910  				}
   911  			} else if gogoproto.IsStdUInt64(field) {
   912  				if nullable {
   913  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(uint64))`)
   914  				} else {
   915  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
   916  				}
   917  			} else if gogoproto.IsStdInt32(field) {
   918  				if nullable {
   919  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(int32))`)
   920  				} else {
   921  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
   922  				}
   923  			} else if gogoproto.IsStdUInt32(field) {
   924  				if nullable {
   925  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(uint32))`)
   926  				} else {
   927  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
   928  				}
   929  			} else if gogoproto.IsStdBool(field) {
   930  				if nullable {
   931  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(bool))`)
   932  				} else {
   933  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, false)`)
   934  				}
   935  			} else if gogoproto.IsStdString(field) {
   936  				if nullable {
   937  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(string))`)
   938  				} else {
   939  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, "")`)
   940  				}
   941  			} else if gogoproto.IsStdBytes(field) {
   942  				if nullable {
   943  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new([]byte))`)
   944  				} else {
   945  					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, []byte{})`)
   946  				}
   947  			} else if nullable && !gogoproto.IsCustomType(field) {
   948  				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, &`, msgname, `{})`)
   949  			} else {
   950  				goType, _ := p.GoType(nil, field)
   951  				// remove the slice from the type, i.e. []*T -> *T
   952  				goType = goType[2:]
   953  				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, goType, `{})`)
   954  			}
   955  			varName := `m.` + fieldname + `[len(m.` + fieldname + `)-1]`
   956  			buf := `dAtA[iNdEx:postIndex]`
   957  			if gogoproto.IsStdTime(field) {
   958  				if nullable {
   959  					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `,`, buf, `); err != nil {`)
   960  				} else {
   961  					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   962  				}
   963  			} else if gogoproto.IsStdDuration(field) {
   964  				if nullable {
   965  					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `,`, buf, `); err != nil {`)
   966  				} else {
   967  					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   968  				}
   969  			} else if gogoproto.IsStdDouble(field) {
   970  				if nullable {
   971  					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(`, varName, `,`, buf, `); err != nil {`)
   972  				} else {
   973  					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   974  				}
   975  			} else if gogoproto.IsStdFloat(field) {
   976  				if nullable {
   977  					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(`, varName, `,`, buf, `); err != nil {`)
   978  				} else {
   979  					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   980  				}
   981  			} else if gogoproto.IsStdInt64(field) {
   982  				if nullable {
   983  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(`, varName, `,`, buf, `); err != nil {`)
   984  				} else {
   985  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   986  				}
   987  			} else if gogoproto.IsStdUInt64(field) {
   988  				if nullable {
   989  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(`, varName, `,`, buf, `); err != nil {`)
   990  				} else {
   991  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   992  				}
   993  			} else if gogoproto.IsStdInt32(field) {
   994  				if nullable {
   995  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(`, varName, `,`, buf, `); err != nil {`)
   996  				} else {
   997  					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
   998  				}
   999  			} else if gogoproto.IsStdUInt32(field) {
  1000  				if nullable {
  1001  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(`, varName, `,`, buf, `); err != nil {`)
  1002  				} else {
  1003  					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
  1004  				}
  1005  			} else if gogoproto.IsStdBool(field) {
  1006  				if nullable {
  1007  					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(`, varName, `,`, buf, `); err != nil {`)
  1008  				} else {
  1009  					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
  1010  				}
  1011  			} else if gogoproto.IsStdString(field) {
  1012  				if nullable {
  1013  					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(`, varName, `,`, buf, `); err != nil {`)
  1014  				} else {
  1015  					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
  1016  				}
  1017  			} else if gogoproto.IsStdBytes(field) {
  1018  				if nullable {
  1019  					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(`, varName, `,`, buf, `); err != nil {`)
  1020  				} else {
  1021  					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
  1022  				}
  1023  			} else {
  1024  				p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`)
  1025  			}
  1026  			p.In()
  1027  			p.P(`return err`)
  1028  			p.Out()
  1029  			p.P(`}`)
  1030  		} else if nullable {
  1031  			p.P(`if m.`, fieldname, ` == nil {`)
  1032  			p.In()
  1033  			if gogoproto.IsStdTime(field) {
  1034  				p.P(`m.`, fieldname, ` = new(time.Time)`)
  1035  			} else if gogoproto.IsStdDuration(field) {
  1036  				p.P(`m.`, fieldname, ` = new(time.Duration)`)
  1037  			} else if gogoproto.IsStdDouble(field) {
  1038  				p.P(`m.`, fieldname, ` = new(float64)`)
  1039  			} else if gogoproto.IsStdFloat(field) {
  1040  				p.P(`m.`, fieldname, ` = new(float32)`)
  1041  			} else if gogoproto.IsStdInt64(field) {
  1042  				p.P(`m.`, fieldname, ` = new(int64)`)
  1043  			} else if gogoproto.IsStdUInt64(field) {
  1044  				p.P(`m.`, fieldname, ` = new(uint64)`)
  1045  			} else if gogoproto.IsStdInt32(field) {
  1046  				p.P(`m.`, fieldname, ` = new(int32)`)
  1047  			} else if gogoproto.IsStdUInt32(field) {
  1048  				p.P(`m.`, fieldname, ` = new(uint32)`)
  1049  			} else if gogoproto.IsStdBool(field) {
  1050  				p.P(`m.`, fieldname, ` = new(bool)`)
  1051  			} else if gogoproto.IsStdString(field) {
  1052  				p.P(`m.`, fieldname, ` = new(string)`)
  1053  			} else if gogoproto.IsStdBytes(field) {
  1054  				p.P(`m.`, fieldname, ` = new([]byte)`)
  1055  			} else {
  1056  				goType, _ := p.GoType(nil, field)
  1057  				// remove the star from the type
  1058  				p.P(`m.`, fieldname, ` = &`, goType[1:], `{}`)
  1059  			}
  1060  			p.Out()
  1061  			p.P(`}`)
  1062  			if gogoproto.IsStdTime(field) {
  1063  				p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1064  			} else if gogoproto.IsStdDuration(field) {
  1065  				p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1066  			} else if gogoproto.IsStdDouble(field) {
  1067  				p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1068  			} else if gogoproto.IsStdFloat(field) {
  1069  				p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1070  			} else if gogoproto.IsStdInt64(field) {
  1071  				p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1072  			} else if gogoproto.IsStdUInt64(field) {
  1073  				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1074  			} else if gogoproto.IsStdInt32(field) {
  1075  				p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1076  			} else if gogoproto.IsStdUInt32(field) {
  1077  				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1078  			} else if gogoproto.IsStdBool(field) {
  1079  				p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1080  			} else if gogoproto.IsStdString(field) {
  1081  				p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1082  			} else if gogoproto.IsStdBytes(field) {
  1083  				p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1084  			} else {
  1085  				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
  1086  			}
  1087  			p.In()
  1088  			p.P(`return err`)
  1089  			p.Out()
  1090  			p.P(`}`)
  1091  		} else {
  1092  			if gogoproto.IsStdTime(field) {
  1093  				p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1094  			} else if gogoproto.IsStdDuration(field) {
  1095  				p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1096  			} else if gogoproto.IsStdDouble(field) {
  1097  				p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1098  			} else if gogoproto.IsStdFloat(field) {
  1099  				p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1100  			} else if gogoproto.IsStdInt64(field) {
  1101  				p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1102  			} else if gogoproto.IsStdUInt64(field) {
  1103  				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1104  			} else if gogoproto.IsStdInt32(field) {
  1105  				p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1106  			} else if gogoproto.IsStdUInt32(field) {
  1107  				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1108  			} else if gogoproto.IsStdBool(field) {
  1109  				p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1110  			} else if gogoproto.IsStdString(field) {
  1111  				p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1112  			} else if gogoproto.IsStdBytes(field) {
  1113  				p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
  1114  			} else {
  1115  				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
  1116  			}
  1117  			p.In()
  1118  			p.P(`return err`)
  1119  			p.Out()
  1120  			p.P(`}`)
  1121  		}
  1122  		p.P(`iNdEx = postIndex`)
  1123  
  1124  	case descriptor.FieldDescriptorProto_TYPE_BYTES:
  1125  		p.P(`var byteLen int`)
  1126  		p.decodeVarint("byteLen", "int")
  1127  		p.P(`if byteLen < 0 {`)
  1128  		p.In()
  1129  		p.P(`return ErrInvalidLength` + p.localName)
  1130  		p.Out()
  1131  		p.P(`}`)
  1132  		p.P(`postIndex := iNdEx + byteLen`)
  1133  		p.P(`if postIndex < 0 {`)
  1134  		p.In()
  1135  		p.P(`return ErrInvalidLength` + p.localName)
  1136  		p.Out()
  1137  		p.P(`}`)
  1138  		p.P(`if postIndex > l {`)
  1139  		p.In()
  1140  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
  1141  		p.Out()
  1142  		p.P(`}`)
  1143  		if !gogoproto.IsCustomType(field) {
  1144  			if oneof {
  1145  				p.P(`v := make([]byte, postIndex-iNdEx)`)
  1146  				p.P(`copy(v, dAtA[iNdEx:postIndex])`)
  1147  				p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
  1148  			} else if repeated {
  1149  				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`)
  1150  				p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], dAtA[iNdEx:postIndex])`)
  1151  			} else {
  1152  				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , dAtA[iNdEx:postIndex]...)`)
  1153  				p.P(`if m.`, fieldname, ` == nil {`)
  1154  				p.In()
  1155  				p.P(`m.`, fieldname, ` = []byte{}`)
  1156  				p.Out()
  1157  				p.P(`}`)
  1158  			}
  1159  		} else {
  1160  			_, ctyp, err := generator.GetCustomType(field)
  1161  			if err != nil {
  1162  				panic(err)
  1163  			}
  1164  			if oneof {
  1165  				p.P(`var vv `, ctyp)
  1166  				p.P(`v := &vv`)
  1167  				p.P(`if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
  1168  				p.In()
  1169  				p.P(`return err`)
  1170  				p.Out()
  1171  				p.P(`}`)
  1172  				p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{*v}`)
  1173  			} else if repeated {
  1174  				p.P(`var v `, ctyp)
  1175  				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
  1176  				p.P(`if err := m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
  1177  				p.In()
  1178  				p.P(`return err`)
  1179  				p.Out()
  1180  				p.P(`}`)
  1181  			} else if nullable {
  1182  				p.P(`var v `, ctyp)
  1183  				p.P(`m.`, fieldname, ` = &v`)
  1184  				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
  1185  				p.In()
  1186  				p.P(`return err`)
  1187  				p.Out()
  1188  				p.P(`}`)
  1189  			} else {
  1190  				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
  1191  				p.In()
  1192  				p.P(`return err`)
  1193  				p.Out()
  1194  				p.P(`}`)
  1195  			}
  1196  		}
  1197  		p.P(`iNdEx = postIndex`)
  1198  	case descriptor.FieldDescriptorProto_TYPE_UINT32:
  1199  		if oneof {
  1200  			p.P(`var v `, typ)
  1201  			p.decodeVarint("v", typ)
  1202  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
  1203  		} else if repeated {
  1204  			p.P(`var v `, typ)
  1205  			p.decodeVarint("v", typ)
  1206  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
  1207  		} else if proto3 || !nullable {
  1208  			p.P(`m.`, fieldname, ` = 0`)
  1209  			p.decodeVarint("m."+fieldname, typ)
  1210  		} else {
  1211  			p.P(`var v `, typ)
  1212  			p.decodeVarint("v", typ)
  1213  			p.P(`m.`, fieldname, ` = &v`)
  1214  		}
  1215  	case descriptor.FieldDescriptorProto_TYPE_ENUM:
  1216  		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
  1217  		if oneof {
  1218  			p.P(`var v `, typName)
  1219  			p.decodeVarint("v", typName)
  1220  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
  1221  		} else if repeated {
  1222  			p.P(`var v `, typName)
  1223  			p.decodeVarint("v", typName)
  1224  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
  1225  		} else if proto3 || !nullable {
  1226  			p.P(`m.`, fieldname, ` = 0`)
  1227  			p.decodeVarint("m."+fieldname, typName)
  1228  		} else {
  1229  			p.P(`var v `, typName)
  1230  			p.decodeVarint("v", typName)
  1231  			p.P(`m.`, fieldname, ` = &v`)
  1232  		}
  1233  	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
  1234  		if oneof {
  1235  			p.P(`var v `, typ)
  1236  			p.decodeFixed32("v", typ)
  1237  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
  1238  		} else if repeated {
  1239  			p.P(`var v `, typ)
  1240  			p.decodeFixed32("v", typ)
  1241  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
  1242  		} else if proto3 || !nullable {
  1243  			p.P(`m.`, fieldname, ` = 0`)
  1244  			p.decodeFixed32("m."+fieldname, typ)
  1245  		} else {
  1246  			p.P(`var v `, typ)
  1247  			p.decodeFixed32("v", typ)
  1248  			p.P(`m.`, fieldname, ` = &v`)
  1249  		}
  1250  	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
  1251  		if oneof {
  1252  			p.P(`var v `, typ)
  1253  			p.decodeFixed64("v", typ)
  1254  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
  1255  		} else if repeated {
  1256  			p.P(`var v `, typ)
  1257  			p.decodeFixed64("v", typ)
  1258  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
  1259  		} else if proto3 || !nullable {
  1260  			p.P(`m.`, fieldname, ` = 0`)
  1261  			p.decodeFixed64("m."+fieldname, typ)
  1262  		} else {
  1263  			p.P(`var v `, typ)
  1264  			p.decodeFixed64("v", typ)
  1265  			p.P(`m.`, fieldname, ` = &v`)
  1266  		}
  1267  	case descriptor.FieldDescriptorProto_TYPE_SINT32:
  1268  		p.P(`var v `, typ)
  1269  		p.decodeVarint("v", typ)
  1270  		p.P(`v = `, typ, `((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))`)
  1271  		if oneof {
  1272  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
  1273  		} else if repeated {
  1274  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
  1275  		} else if proto3 || !nullable {
  1276  			p.P(`m.`, fieldname, ` = v`)
  1277  		} else {
  1278  			p.P(`m.`, fieldname, ` = &v`)
  1279  		}
  1280  	case descriptor.FieldDescriptorProto_TYPE_SINT64:
  1281  		p.P(`var v uint64`)
  1282  		p.decodeVarint("v", "uint64")
  1283  		p.P(`v = (v >> 1) ^ uint64((int64(v&1)<<63)>>63)`)
  1284  		if oneof {
  1285  			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, `(v)}`)
  1286  		} else if repeated {
  1287  			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(v))`)
  1288  		} else if proto3 || !nullable {
  1289  			p.P(`m.`, fieldname, ` = `, typ, `(v)`)
  1290  		} else {
  1291  			p.P(`v2 := `, typ, `(v)`)
  1292  			p.P(`m.`, fieldname, ` = &v2`)
  1293  		}
  1294  	default:
  1295  		panic("not implemented")
  1296  	}
  1297  }
  1298  
  1299  func (p *unmarshal) Generate(file *generator.FileDescriptor) {
  1300  	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
  1301  	p.PluginImports = generator.NewPluginImports(p.Generator)
  1302  	p.atleastOne = false
  1303  	p.localName = generator.FileName(file)
  1304  
  1305  	p.ioPkg = p.NewImport("io")
  1306  	p.mathPkg = p.NewImport("math")
  1307  	p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
  1308  	p.binaryPkg = p.NewImport("encoding/binary")
  1309  	fmtPkg := p.NewImport("fmt")
  1310  	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
  1311  	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
  1312  		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
  1313  	}
  1314  
  1315  	for _, message := range file.Messages() {
  1316  		ccTypeName := generator.CamelCaseSlice(message.TypeName())
  1317  		if !gogoproto.IsUnmarshaler(file.FileDescriptorProto, message.DescriptorProto) &&
  1318  			!gogoproto.IsUnsafeUnmarshaler(file.FileDescriptorProto, message.DescriptorProto) {
  1319  			continue
  1320  		}
  1321  		if message.DescriptorProto.GetOptions().GetMapEntry() {
  1322  			continue
  1323  		}
  1324  		p.atleastOne = true
  1325  
  1326  		// build a map required field_id -> bitmask offset
  1327  		rfMap := make(map[int32]uint)
  1328  		rfNextId := uint(0)
  1329  		for _, field := range message.Field {
  1330  			if field.IsRequired() {
  1331  				rfMap[field.GetNumber()] = rfNextId
  1332  				rfNextId++
  1333  			}
  1334  		}
  1335  		rfCount := len(rfMap)
  1336  
  1337  		p.P(`func (m *`, ccTypeName, `) Unmarshal(dAtA []byte) error {`)
  1338  		p.In()
  1339  		if rfCount > 0 {
  1340  			p.P(`var hasFields [`, strconv.Itoa(1+(rfCount-1)/64), `]uint64`)
  1341  		}
  1342  		p.P(`l := len(dAtA)`)
  1343  		p.P(`iNdEx := 0`)
  1344  		p.P(`for iNdEx < l {`)
  1345  		p.In()
  1346  		p.P(`preIndex := iNdEx`)
  1347  		p.P(`var wire uint64`)
  1348  		p.decodeVarint("wire", "uint64")
  1349  		p.P(`fieldNum := int32(wire >> 3)`)
  1350  		if len(message.Field) > 0 || !message.IsGroup() {
  1351  			p.P(`wireType := int(wire & 0x7)`)
  1352  		}
  1353  		if !message.IsGroup() {
  1354  			p.P(`if wireType == `, strconv.Itoa(proto.WireEndGroup), ` {`)
  1355  			p.In()
  1356  			p.P(`return `, fmtPkg.Use(), `.Errorf("proto: `+message.GetName()+`: wiretype end group for non-group")`)
  1357  			p.Out()
  1358  			p.P(`}`)
  1359  		}
  1360  		p.P(`if fieldNum <= 0 {`)
  1361  		p.In()
  1362  		p.P(`return `, fmtPkg.Use(), `.Errorf("proto: `+message.GetName()+`: illegal tag %d (wire type %d)", fieldNum, wire)`)
  1363  		p.Out()
  1364  		p.P(`}`)
  1365  		p.P(`switch fieldNum {`)
  1366  		p.In()
  1367  		for _, field := range message.Field {
  1368  			fieldname := p.GetFieldName(message, field)
  1369  			errFieldname := fieldname
  1370  			if field.OneofIndex != nil {
  1371  				errFieldname = p.GetOneOfFieldName(message, field)
  1372  			}
  1373  			possiblyPacked := field.IsScalar() && field.IsRepeated()
  1374  			p.P(`case `, strconv.Itoa(int(field.GetNumber())), `:`)
  1375  			p.In()
  1376  			wireType := field.WireType()
  1377  			if possiblyPacked {
  1378  				p.P(`if wireType == `, strconv.Itoa(wireType), `{`)
  1379  				p.In()
  1380  				p.field(file, message, field, fieldname, false)
  1381  				p.Out()
  1382  				p.P(`} else if wireType == `, strconv.Itoa(proto.WireBytes), `{`)
  1383  				p.In()
  1384  				p.P(`var packedLen int`)
  1385  				p.decodeVarint("packedLen", "int")
  1386  				p.P(`if packedLen < 0 {`)
  1387  				p.In()
  1388  				p.P(`return ErrInvalidLength` + p.localName)
  1389  				p.Out()
  1390  				p.P(`}`)
  1391  				p.P(`postIndex := iNdEx + packedLen`)
  1392  				p.P(`if postIndex < 0 {`)
  1393  				p.In()
  1394  				p.P(`return ErrInvalidLength` + p.localName)
  1395  				p.Out()
  1396  				p.P(`}`)
  1397  				p.P(`if postIndex > l {`)
  1398  				p.In()
  1399  				p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
  1400  				p.Out()
  1401  				p.P(`}`)
  1402  
  1403  				p.P(`var elementCount int`)
  1404  				switch *field.Type {
  1405  				case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64:
  1406  					p.P(`elementCount = packedLen/`, 8)
  1407  				case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32:
  1408  					p.P(`elementCount = packedLen/`, 4)
  1409  				case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64:
  1410  					p.P(`var count int`)
  1411  					p.P(`for _, integer := range dAtA[iNdEx:postIndex] {`)
  1412  					p.In()
  1413  					p.P(`if integer < 128 {`)
  1414  					p.In()
  1415  					p.P(`count++`)
  1416  					p.Out()
  1417  					p.P(`}`)
  1418  					p.Out()
  1419  					p.P(`}`)
  1420  					p.P(`elementCount = count`)
  1421  				case descriptor.FieldDescriptorProto_TYPE_BOOL:
  1422  					p.P(`elementCount = packedLen`)
  1423  				}
  1424  				p.P(`if elementCount != 0 && len(m.`, fieldname, `) == 0 {`)
  1425  				p.In()
  1426  				p.P(`m.`, fieldname, ` = make([]`, p.noStarOrSliceType(message, field), `, 0, elementCount)`)
  1427  				p.Out()
  1428  				p.P(`}`)
  1429  
  1430  				p.P(`for iNdEx < postIndex {`)
  1431  				p.In()
  1432  				p.field(file, message, field, fieldname, false)
  1433  				p.Out()
  1434  				p.P(`}`)
  1435  				p.Out()
  1436  				p.P(`} else {`)
  1437  				p.In()
  1438  				p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`)
  1439  				p.Out()
  1440  				p.P(`}`)
  1441  			} else {
  1442  				p.P(`if wireType != `, strconv.Itoa(wireType), `{`)
  1443  				p.In()
  1444  				p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`)
  1445  				p.Out()
  1446  				p.P(`}`)
  1447  				p.field(file, message, field, fieldname, proto3)
  1448  			}
  1449  
  1450  			if field.IsRequired() {
  1451  				fieldBit, ok := rfMap[field.GetNumber()]
  1452  				if !ok {
  1453  					panic("field is required, but no bit registered")
  1454  				}
  1455  				p.P(`hasFields[`, strconv.Itoa(int(fieldBit/64)), `] |= uint64(`, fmt.Sprintf("0x%08x", uint64(1)<<(fieldBit%64)), `)`)
  1456  			}
  1457  		}
  1458  		p.Out()
  1459  		p.P(`default:`)
  1460  		p.In()
  1461  		if message.DescriptorProto.HasExtension() {
  1462  			c := []string{}
  1463  			for _, erange := range message.GetExtensionRange() {
  1464  				c = append(c, `((fieldNum >= `+strconv.Itoa(int(erange.GetStart()))+") && (fieldNum<"+strconv.Itoa(int(erange.GetEnd()))+`))`)
  1465  			}
  1466  			p.P(`if `, strings.Join(c, "||"), `{`)
  1467  			p.In()
  1468  			p.P(`var sizeOfWire int`)
  1469  			p.P(`for {`)
  1470  			p.In()
  1471  			p.P(`sizeOfWire++`)
  1472  			p.P(`wire >>= 7`)
  1473  			p.P(`if wire == 0 {`)
  1474  			p.In()
  1475  			p.P(`break`)
  1476  			p.Out()
  1477  			p.P(`}`)
  1478  			p.Out()
  1479  			p.P(`}`)
  1480  			p.P(`iNdEx-=sizeOfWire`)
  1481  			p.P(`skippy, err := skip`, p.localName+`(dAtA[iNdEx:])`)
  1482  			p.P(`if err != nil {`)
  1483  			p.In()
  1484  			p.P(`return err`)
  1485  			p.Out()
  1486  			p.P(`}`)
  1487  			p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
  1488  			p.In()
  1489  			p.P(`return ErrInvalidLength`, p.localName)
  1490  			p.Out()
  1491  			p.P(`}`)
  1492  			p.P(`if (iNdEx + skippy) > l {`)
  1493  			p.In()
  1494  			p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
  1495  			p.Out()
  1496  			p.P(`}`)
  1497  			p.P(protoPkg.Use(), `.AppendExtension(m, int32(fieldNum), dAtA[iNdEx:iNdEx+skippy])`)
  1498  			p.P(`iNdEx += skippy`)
  1499  			p.Out()
  1500  			p.P(`} else {`)
  1501  			p.In()
  1502  		}
  1503  		p.P(`iNdEx=preIndex`)
  1504  		p.P(`skippy, err := skip`, p.localName, `(dAtA[iNdEx:])`)
  1505  		p.P(`if err != nil {`)
  1506  		p.In()
  1507  		p.P(`return err`)
  1508  		p.Out()
  1509  		p.P(`}`)
  1510  		p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
  1511  		p.In()
  1512  		p.P(`return ErrInvalidLength`, p.localName)
  1513  		p.Out()
  1514  		p.P(`}`)
  1515  		p.P(`if (iNdEx + skippy) > l {`)
  1516  		p.In()
  1517  		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
  1518  		p.Out()
  1519  		p.P(`}`)
  1520  		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
  1521  			p.P(`m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)`)
  1522  		}
  1523  		p.P(`iNdEx += skippy`)
  1524  		p.Out()
  1525  		if message.DescriptorProto.HasExtension() {
  1526  			p.Out()
  1527  			p.P(`}`)
  1528  		}
  1529  		p.Out()
  1530  		p.P(`}`)
  1531  		p.Out()
  1532  		p.P(`}`)
  1533  
  1534  		for _, field := range message.Field {
  1535  			if !field.IsRequired() {
  1536  				continue
  1537  			}
  1538  
  1539  			fieldBit, ok := rfMap[field.GetNumber()]
  1540  			if !ok {
  1541  				panic("field is required, but no bit registered")
  1542  			}
  1543  
  1544  			p.P(`if hasFields[`, strconv.Itoa(int(fieldBit/64)), `] & uint64(`, fmt.Sprintf("0x%08x", uint64(1)<<(fieldBit%64)), `) == 0 {`)
  1545  			p.In()
  1546  			if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
  1547  				p.P(`return new(`, protoPkg.Use(), `.RequiredNotSetError)`)
  1548  			} else {
  1549  				p.P(`return `, protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`)
  1550  			}
  1551  			p.Out()
  1552  			p.P(`}`)
  1553  		}
  1554  		p.P()
  1555  		p.P(`if iNdEx > l {`)
  1556  		p.In()
  1557  		p.P(`return ` + p.ioPkg.Use() + `.ErrUnexpectedEOF`)
  1558  		p.Out()
  1559  		p.P(`}`)
  1560  		p.P(`return nil`)
  1561  		p.Out()
  1562  		p.P(`}`)
  1563  	}
  1564  	if !p.atleastOne {
  1565  		return
  1566  	}
  1567  
  1568  	p.P(`func skip` + p.localName + `(dAtA []byte) (n int, err error) {
  1569  		l := len(dAtA)
  1570  		iNdEx := 0
  1571  		depth := 0
  1572  		for iNdEx < l {
  1573  			var wire uint64
  1574  			for shift := uint(0); ; shift += 7 {
  1575  				if shift >= 64 {
  1576  					return 0, ErrIntOverflow` + p.localName + `
  1577  				}
  1578  				if iNdEx >= l {
  1579  					return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
  1580  				}
  1581  				b := dAtA[iNdEx]
  1582  				iNdEx++
  1583  				wire |= (uint64(b) & 0x7F) << shift
  1584  				if b < 0x80 {
  1585  					break
  1586  				}
  1587  			}
  1588  			wireType := int(wire & 0x7)
  1589  			switch wireType {
  1590  			case 0:
  1591  				for shift := uint(0); ; shift += 7 {
  1592  					if shift >= 64 {
  1593  						return 0, ErrIntOverflow` + p.localName + `
  1594  					}
  1595  					if iNdEx >= l {
  1596  						return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
  1597  					}
  1598  					iNdEx++
  1599  					if dAtA[iNdEx-1] < 0x80 {
  1600  						break
  1601  					}
  1602  				}
  1603  			case 1:
  1604  				iNdEx += 8
  1605  			case 2:
  1606  				var length int
  1607  				for shift := uint(0); ; shift += 7 {
  1608  					if shift >= 64 {
  1609  						return 0, ErrIntOverflow` + p.localName + `
  1610  					}
  1611  					if iNdEx >= l {
  1612  						return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
  1613  					}
  1614  					b := dAtA[iNdEx]
  1615  					iNdEx++
  1616  					length |= (int(b) & 0x7F) << shift
  1617  					if b < 0x80 {
  1618  						break
  1619  					}
  1620  				}
  1621  				if length < 0 {
  1622  					return 0, ErrInvalidLength` + p.localName + `
  1623  				}
  1624  				iNdEx += length
  1625  			case 3:
  1626  				depth++
  1627  			case 4:
  1628  				if depth == 0 {
  1629  					return 0, ErrUnexpectedEndOfGroup` + p.localName + `
  1630  				}
  1631  				depth--
  1632  			case 5:
  1633  				iNdEx += 4
  1634  			default:
  1635  				return 0, ` + fmtPkg.Use() + `.Errorf("proto: illegal wireType %d", wireType)
  1636  			}
  1637  			if iNdEx < 0 {
  1638  				return 0, ErrInvalidLength` + p.localName + `
  1639  			}
  1640  			if depth == 0 {
  1641  				return iNdEx, nil
  1642  			}
  1643  		}
  1644  		return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
  1645  	}
  1646  
  1647  	var (
  1648  		ErrInvalidLength` + p.localName + ` = ` + fmtPkg.Use() + `.Errorf("proto: negative length found during unmarshaling")
  1649  		ErrIntOverflow` + p.localName + ` = ` + fmtPkg.Use() + `.Errorf("proto: integer overflow")
  1650  		ErrUnexpectedEndOfGroup` + p.localName + ` = ` + fmtPkg.Use() + `.Errorf("proto: unexpected end of group")
  1651  	)
  1652  	`)
  1653  }
  1654  
  1655  func init() {
  1656  	generator.RegisterPlugin(NewUnmarshal())
  1657  }
  1658  

View as plain text