github.com/cosmos/cosmos-proto@v1.0.0-beta.3/features/fastreflection/proto_unmarshal.go (about)

     1  package fastreflection
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/cosmos/cosmos-proto/generator"
     6  	"google.golang.org/protobuf/compiler/protogen"
     7  	"google.golang.org/protobuf/encoding/protowire"
     8  	"google.golang.org/protobuf/reflect/protoreflect"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  func (g *fastGenerator) genUnmarshalMethod() {
    14  
    15  	required := g.message.Desc.RequiredNumbers()
    16  
    17  	// UNMARSHAL METHOD
    18  	g.P(`unmarshal := func(input `, protoifacePkg.Ident("UnmarshalInput"), `) (`, protoifacePkg.Ident("UnmarshalOutput"), `, error) {`)
    19  	g.P(`x := input.Message.Interface().(*`, g.message.GoIdent, `)`)
    20  	g.P(`if x == nil {`)
    21  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), ` {`)
    22  	g.P("NoUnkeyedLiterals: input.NoUnkeyedLiterals,")
    23  	g.P("Flags:               input.Flags,")
    24  	g.P("}, nil")
    25  	g.P("}")
    26  	g.P("options := ", runtimePackage.Ident("UnmarshalInputToOptions"), "(input)")
    27  	g.P("_ = options")
    28  	g.P("dAtA := input.Buf")
    29  	// body
    30  	if required.Len() > 0 {
    31  		g.P(`var hasFields [`, strconv.Itoa(1+(required.Len()-1)/64), `]uint64`)
    32  	}
    33  	g.P(`l := len(dAtA)`)
    34  	g.P(`iNdEx := 0`)
    35  	g.P(`for iNdEx < l {`)
    36  	g.P(`preIndex := iNdEx`)
    37  	g.P(`var wire uint64`)
    38  	g.decodeVarint("wire", "uint64")
    39  	g.P(`fieldNum := int32(wire >> 3)`)
    40  	g.P(`wireType := int(wire & 0x7)`)
    41  	g.P(`if wireType == `, strconv.Itoa(int(protowire.EndGroupType)), ` {`)
    42  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("fmt", "Errorf"), `("proto: `, g.message.GoIdent.GoName, `: wiretype end group for non-group")`)
    43  	g.P(`}`)
    44  	g.P(`if fieldNum <= 0 {`)
    45  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("fmt", "Errorf"), `("proto: `, g.message.GoIdent.GoName, `: illegal tag %d (wire type %d)", fieldNum, wire)`)
    46  	g.P(`}`)
    47  	g.P(`switch fieldNum {`)
    48  	for _, field := range g.message.Fields {
    49  		g.unmarshalField(field, g.message, true, required)
    50  	}
    51  	g.P(`default:`)
    52  	if len(g.message.Extensions) > 0 {
    53  		c := []string{}
    54  		eranges := g.message.Desc.ExtensionRanges()
    55  		for e := 0; e < eranges.Len(); e++ {
    56  			erange := eranges.Get(e)
    57  			c = append(c, `((fieldNum >= `, strconv.Itoa(int(erange[0])), ") && (fieldNum < ", strconv.Itoa(int(erange[1])), `))`)
    58  		}
    59  		g.P(`if `, strings.Join(c, "||"), `{`)
    60  		g.P(`var sizeOfWire int`)
    61  		g.P(`for {`)
    62  		g.P(`sizeOfWire++`)
    63  		g.P(`wire >>= 7`)
    64  		g.P(`if wire == 0 {`)
    65  		g.P(`break`)
    66  		g.P(`}`)
    67  		g.P(`}`)
    68  		g.P(`iNdEx-=sizeOfWire`)
    69  		g.P(`skippy, err := `, runtimePackage.Ident("Skip"), `(dAtA[iNdEx:])`)
    70  		g.P(`if err != nil {`)
    71  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", `err`)
    72  		g.P(`}`)
    73  		g.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
    74  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
    75  		g.P(`}`)
    76  		g.P(`if (iNdEx + skippy) > l {`)
    77  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
    78  		g.P(`}`)
    79  		g.P(g.Ident(generator.ProtoPkg, "AppendExtension"), `(m, int32(fieldNum), dAtA[iNdEx:iNdEx+skippy])`)
    80  		g.P(`iNdEx += skippy`)
    81  		g.P(`} else {`)
    82  	}
    83  	g.P(`iNdEx=preIndex`)
    84  	g.P(`skippy, err := `, runtimePackage.Ident("Skip"), `(dAtA[iNdEx:])`)
    85  	g.P(`if err != nil {`)
    86  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", `err`)
    87  	g.P(`}`)
    88  	g.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
    89  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
    90  	g.P(`}`)
    91  	g.P(`if (iNdEx + skippy) > l {`)
    92  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
    93  	g.P(`}`)
    94  	g.P("if !options.DiscardUnknown {")
    95  	g.P(`x.unknownFields = append(x.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)`)
    96  	g.P("}")
    97  	g.P(`iNdEx += skippy`)
    98  	if len(g.message.Extensions) > 0 {
    99  		g.P(`}`)
   100  	}
   101  	g.P(`}`)
   102  	g.P(`}`)
   103  
   104  	for _, field := range g.message.Fields {
   105  		if field.Desc.Cardinality() != protoreflect.Required {
   106  			continue
   107  		}
   108  		var fieldBit int
   109  		for fieldBit = 0; fieldBit < required.Len(); fieldBit++ {
   110  			if required.Get(fieldBit) == field.Desc.Number() {
   111  				break
   112  			}
   113  		}
   114  		if fieldBit == required.Len() {
   115  			panic("missing required field")
   116  		}
   117  		g.P(`if hasFields[`, strconv.Itoa(fieldBit/64), `] & uint64(`, fmt.Sprintf("0x%08x", uint64(1)<<(fieldBit%64)), `) == 0 {`)
   118  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", `new(`, g.Ident(generator.ProtoPkg, "RequiredNotSetError"), `)`)
   119  		g.P(`}`)
   120  	}
   121  	g.P()
   122  	g.P(`if iNdEx > l {`)
   123  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, ", g.Ident("io", `ErrUnexpectedEOF`))
   124  	g.P(`}`)
   125  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, ", `nil`)
   126  	g.P(`}`)
   127  }
   128  
   129  func (g *fastGenerator) decodeVarint(varName string, typName string) {
   130  	g.P(`for shift := uint(0); ; shift += 7 {`)
   131  	g.P(`if shift >= 64 {`)
   132  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, ", runtimePackage.Ident("ErrIntOverflow"))
   133  	g.P(`}`)
   134  	g.P(`if iNdEx >= l {`)
   135  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, ", g.Ident("io", `ErrUnexpectedEOF`))
   136  	g.P(`}`)
   137  	g.P(`b := dAtA[iNdEx]`)
   138  	g.P(`iNdEx++`)
   139  	g.P(varName, ` |= `, typName, `(b&0x7F) << shift`)
   140  	g.P(`if b < 0x80 {`)
   141  	g.P(`break`)
   142  	g.P(`}`)
   143  	g.P(`}`)
   144  }
   145  
   146  func (g *fastGenerator) unmarshalField(field *protogen.Field, message *protogen.Message, proto3 bool, required protoreflect.FieldNumbers) {
   147  	fieldname := field.GoName
   148  	errFieldname := fieldname
   149  	if field.Oneof != nil && !field.Oneof.Desc.IsSynthetic() {
   150  		fieldname = field.Oneof.GoName
   151  	}
   152  
   153  	g.P(`case `, strconv.Itoa(int(field.Desc.Number())), `:`)
   154  	wireType := generator.ProtoWireType(field.Desc.Kind())
   155  	if field.Desc.IsList() && wireType != protowire.BytesType {
   156  		g.P(`if wireType == `, strconv.Itoa(int(wireType)), `{`)
   157  		g.fieldItem(field, fieldname, message, false)
   158  		g.P(`} else if wireType == `, strconv.Itoa(int(protowire.BytesType)), `{`)
   159  		g.P(`var packedLen int`)
   160  		g.decodeVarint("packedLen", "int")
   161  		g.P(`if packedLen < 0 {`)
   162  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   163  		g.P(`}`)
   164  		g.P(`postIndex := iNdEx + packedLen`)
   165  		g.P(`if postIndex < 0 {`)
   166  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   167  		g.P(`}`)
   168  		g.P(`if postIndex > l {`)
   169  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", "ErrUnexpectedEOF"))
   170  		g.P(`}`)
   171  
   172  		g.P(`var elementCount int`)
   173  		switch field.Desc.Kind() {
   174  		case protoreflect.DoubleKind, protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind:
   175  			g.P(`elementCount = packedLen/`, 8)
   176  		case protoreflect.FloatKind, protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind:
   177  			g.P(`elementCount = packedLen/`, 4)
   178  		case protoreflect.Int64Kind, protoreflect.Uint64Kind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Sint32Kind, protoreflect.Sint64Kind:
   179  			g.P(`var count int`)
   180  			g.P(`for _, integer := range dAtA[iNdEx:postIndex] {`)
   181  			g.P(`if integer < 128 {`)
   182  			g.P(`count++`)
   183  			g.P(`}`)
   184  			g.P(`}`)
   185  			g.P(`elementCount = count`)
   186  		case protoreflect.BoolKind:
   187  			g.P(`elementCount = packedLen`)
   188  		}
   189  
   190  		g.P(`if elementCount != 0 && len(x.`, fieldname, `) == 0 {`)
   191  
   192  		fieldtyp, _ := g.FieldGoType(field)
   193  		g.P(`x.`, fieldname, ` = make(`, fieldtyp, `, 0, elementCount)`)
   194  		g.P(`}`)
   195  
   196  		g.P(`for iNdEx < postIndex {`)
   197  		g.fieldItem(field, fieldname, message, false)
   198  		g.P(`}`)
   199  		g.P(`} else {`)
   200  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("fmt", "Errorf"), `("proto: wrong wireType = %d for field `, errFieldname, `", wireType)`)
   201  		g.P(`}`)
   202  	} else {
   203  		g.P(`if wireType != `, strconv.Itoa(int(wireType)), `{`)
   204  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("fmt", "Errorf"), `("proto: wrong wireType = %d for field `, errFieldname, `", wireType)`)
   205  		g.P(`}`)
   206  		g.fieldItem(field, fieldname, message, proto3)
   207  	}
   208  
   209  	if field.Desc.Cardinality() == protoreflect.Required {
   210  		var fieldBit int
   211  		for fieldBit = 0; fieldBit < required.Len(); fieldBit++ {
   212  			if required.Get(fieldBit) == field.Desc.Number() {
   213  				break
   214  			}
   215  		}
   216  		if fieldBit == required.Len() {
   217  			panic("missing required field")
   218  		}
   219  		g.P(`hasFields[`, strconv.Itoa(fieldBit/64), `] |= uint64(`, fmt.Sprintf("0x%08x", uint64(1)<<(fieldBit%64)), `)`)
   220  	}
   221  }
   222  
   223  func (g *fastGenerator) fieldItem(field *protogen.Field, fieldname string, message *protogen.Message, proto3 bool) {
   224  	repeated := field.Desc.Cardinality() == protoreflect.Repeated
   225  	typ := g.noStarOrSliceType(field)
   226  	oneof := field.Oneof != nil && !field.Oneof.Desc.IsSynthetic()
   227  	nullable := field.Oneof != nil && field.Oneof.Desc.IsSynthetic()
   228  
   229  	switch field.Desc.Kind() {
   230  	case protoreflect.DoubleKind:
   231  		g.P(`var v uint64`)
   232  		g.decodeFixed64("v", "uint64")
   233  		if oneof {
   234  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{`, typ, "(", g.Ident("math", `Float64frombits`), `(v))}`)
   235  		} else if repeated {
   236  			g.P(`v2 := `, typ, "(", g.Ident("math", "Float64frombits"), `(v))`)
   237  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v2)`)
   238  		} else if proto3 && !nullable {
   239  			g.P(`x.`, fieldname, ` = `, typ, "(", g.Ident("math", "Float64frombits"), `(v))`)
   240  		} else {
   241  			g.P(`v2 := `, typ, "(", g.Ident("math", "Float64frombits"), `(v))`)
   242  			g.P(`x.`, fieldname, ` = &v2`)
   243  		}
   244  	case protoreflect.FloatKind:
   245  		g.P(`var v uint32`)
   246  		g.decodeFixed32("v", "uint32")
   247  		if oneof {
   248  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{`, typ, "(", g.Ident("math", "Float32frombits"), `(v))}`)
   249  		} else if repeated {
   250  			g.P(`v2 := `, typ, "(", g.Ident("math", "Float32frombits"), `(v))`)
   251  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v2)`)
   252  		} else if proto3 && !nullable {
   253  			g.P(`x.`, fieldname, ` = `, typ, "(", g.Ident("math", "Float32frombits"), `(v))`)
   254  		} else {
   255  			g.P(`v2 := `, typ, "(", g.Ident("math", "Float32frombits"), `(v))`)
   256  			g.P(`x.`, fieldname, ` = &v2`)
   257  		}
   258  	case protoreflect.Int64Kind:
   259  		if oneof {
   260  			g.P(`var v `, typ)
   261  			g.decodeVarint("v", typ)
   262  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   263  		} else if repeated {
   264  			g.P(`var v `, typ)
   265  			g.decodeVarint("v", typ)
   266  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   267  		} else if proto3 && !nullable {
   268  			g.P(`x.`, fieldname, ` = 0`)
   269  			g.decodeVarint("x."+fieldname, typ)
   270  		} else {
   271  			g.P(`var v `, typ)
   272  			g.decodeVarint("v", typ)
   273  			g.P(`x.`, fieldname, ` = &v`)
   274  		}
   275  	case protoreflect.Uint64Kind:
   276  		if oneof {
   277  			g.P(`var v `, typ)
   278  			g.decodeVarint("v", typ)
   279  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   280  		} else if repeated {
   281  			g.P(`var v `, typ)
   282  			g.decodeVarint("v", typ)
   283  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   284  		} else if proto3 && !nullable {
   285  			g.P(`x.`, fieldname, ` = 0`)
   286  			g.decodeVarint("x."+fieldname, typ)
   287  		} else {
   288  			g.P(`var v `, typ)
   289  			g.decodeVarint("v", typ)
   290  			g.P(`x.`, fieldname, ` = &v`)
   291  		}
   292  	case protoreflect.Int32Kind:
   293  		if oneof {
   294  			g.P(`var v `, typ)
   295  			g.decodeVarint("v", typ)
   296  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   297  		} else if repeated {
   298  			g.P(`var v `, typ)
   299  			g.decodeVarint("v", typ)
   300  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   301  		} else if proto3 && !nullable {
   302  			g.P(`x.`, fieldname, ` = 0`)
   303  			g.decodeVarint("x."+fieldname, typ)
   304  		} else {
   305  			g.P(`var v `, typ)
   306  			g.decodeVarint("v", typ)
   307  			g.P(`x.`, fieldname, ` = &v`)
   308  		}
   309  	case protoreflect.Fixed64Kind:
   310  		if oneof {
   311  			g.P(`var v `, typ)
   312  			g.decodeFixed64("v", typ)
   313  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   314  		} else if repeated {
   315  			g.P(`var v `, typ)
   316  			g.decodeFixed64("v", typ)
   317  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   318  		} else if proto3 && !nullable {
   319  			g.P(`x.`, fieldname, ` = 0`)
   320  			g.decodeFixed64("x."+fieldname, typ)
   321  		} else {
   322  			g.P(`var v `, typ)
   323  			g.decodeFixed64("v", typ)
   324  			g.P(`x.`, fieldname, ` = &v`)
   325  		}
   326  	case protoreflect.Fixed32Kind:
   327  		if oneof {
   328  			g.P(`var v `, typ)
   329  			g.decodeFixed32("v", typ)
   330  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   331  		} else if repeated {
   332  			g.P(`var v `, typ)
   333  			g.decodeFixed32("v", typ)
   334  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   335  		} else if proto3 && !nullable {
   336  			g.P(`x.`, fieldname, ` = 0`)
   337  			g.decodeFixed32("x."+fieldname, typ)
   338  		} else {
   339  			g.P(`var v `, typ)
   340  			g.decodeFixed32("v", typ)
   341  			g.P(`x.`, fieldname, ` = &v`)
   342  		}
   343  	case protoreflect.BoolKind:
   344  		g.P(`var v int`)
   345  		g.decodeVarint("v", "int")
   346  		if oneof {
   347  			g.P(`b := `, typ, `(v != 0)`)
   348  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{b}`)
   349  		} else if repeated {
   350  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, `, typ, `(v != 0))`)
   351  		} else if proto3 && !nullable {
   352  			g.P(`x.`, fieldname, ` = `, typ, `(v != 0)`)
   353  		} else {
   354  			g.P(`b := `, typ, `(v != 0)`)
   355  			g.P(`x.`, fieldname, ` = &b`)
   356  		}
   357  	case protoreflect.StringKind:
   358  		g.P(`var stringLen uint64`)
   359  		g.decodeVarint("stringLen", "uint64")
   360  		g.P(`intStringLen := int(stringLen)`)
   361  		g.P(`if intStringLen < 0 {`)
   362  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   363  		g.P(`}`)
   364  		g.P(`postIndex := iNdEx + intStringLen`)
   365  		g.P(`if postIndex < 0 {`)
   366  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   367  		g.P(`}`)
   368  		g.P(`if postIndex > l {`)
   369  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   370  		g.P(`}`)
   371  		if oneof {
   372  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{`, typ, `(dAtA[iNdEx:postIndex])}`)
   373  		} else if repeated {
   374  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, `, typ, `(dAtA[iNdEx:postIndex]))`)
   375  		} else if proto3 && !nullable {
   376  			g.P(`x.`, fieldname, ` = `, typ, `(dAtA[iNdEx:postIndex])`)
   377  		} else {
   378  			g.P(`s := `, typ, `(dAtA[iNdEx:postIndex])`)
   379  			g.P(`x.`, fieldname, ` = &s`)
   380  		}
   381  		g.P(`iNdEx = postIndex`)
   382  	case protoreflect.GroupKind:
   383  		panic(fmt.Errorf("unmarshaler does not support group %v", fieldname))
   384  	case protoreflect.MessageKind:
   385  		g.P(`var msglen int`)
   386  		g.decodeVarint("msglen", "int")
   387  		g.P(`if msglen < 0 {`)
   388  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   389  		g.P(`}`)
   390  		g.P(`postIndex := iNdEx + msglen`)
   391  		g.P(`if postIndex < 0 {`)
   392  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   393  		g.P(`}`)
   394  		g.P(`if postIndex > l {`)
   395  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   396  		g.P(`}`)
   397  		if oneof {
   398  			buf := `dAtA[iNdEx:postIndex]`
   399  			msgname := g.noStarOrSliceType(field)
   400  			g.P(`v := &`, msgname, `{}`)
   401  			g.decodeMessage("v", buf, field.Message)
   402  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   403  
   404  		} else if field.Desc.IsMap() {
   405  			goTyp, _ := g.FieldGoType(field)
   406  			goTypK, _ := g.FieldGoType(field.Message.Fields[0])
   407  			goTypV, _ := g.FieldGoType(field.Message.Fields[1])
   408  
   409  			g.P(`if x.`, fieldname, ` == nil {`)
   410  			g.P(`x.`, fieldname, ` = make(`, goTyp, `)`)
   411  			g.P(`}`)
   412  
   413  			g.P("var mapkey ", goTypK)
   414  			g.P("var mapvalue ", goTypV)
   415  			g.P(`for iNdEx < postIndex {`)
   416  
   417  			g.P(`entryPreIndex := iNdEx`)
   418  			g.P(`var wire uint64`)
   419  			g.decodeVarint("wire", "uint64")
   420  			g.P(`fieldNum := int32(wire >> 3)`)
   421  
   422  			g.P(`if fieldNum == 1 {`)
   423  			g.unmarshalMapField("mapkey", field.Message.Fields[0])
   424  			g.P(`} else if fieldNum == 2 {`)
   425  			g.unmarshalMapField("mapvalue", field.Message.Fields[1])
   426  			g.P(`} else {`)
   427  			g.P(`iNdEx = entryPreIndex`)
   428  			g.P(`skippy, err := `, runtimePackage.Ident("Skip"), `(dAtA[iNdEx:])`)
   429  			g.P(`if err != nil {`)
   430  			g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", `err`)
   431  			g.P(`}`)
   432  			g.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
   433  			g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   434  			g.P(`}`)
   435  			g.P(`if (iNdEx + skippy) > postIndex {`)
   436  			g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   437  			g.P(`}`)
   438  			g.P(`iNdEx += skippy`)
   439  			g.P(`}`)
   440  			g.P(`}`)
   441  			g.P(`x.`, fieldname, `[mapkey] = mapvalue`)
   442  		} else if repeated {
   443  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, &`, field.Message.GoIdent, `{})`)
   444  
   445  			varname := fmt.Sprintf("x.%s[len(x.%s) - 1]", fieldname, fieldname)
   446  			buf := `dAtA[iNdEx:postIndex]`
   447  			g.decodeMessage(varname, buf, field.Message)
   448  		} else {
   449  			g.P(`if x.`, fieldname, ` == nil {`)
   450  			g.P(`x.`, fieldname, ` = &`, field.Message.GoIdent, `{}`)
   451  			g.P(`}`)
   452  			g.decodeMessage("x."+fieldname, "dAtA[iNdEx:postIndex]", field.Message)
   453  		}
   454  		g.P(`iNdEx = postIndex`)
   455  
   456  	case protoreflect.BytesKind:
   457  		g.P(`var byteLen int`)
   458  		g.decodeVarint("byteLen", "int")
   459  		g.P(`if byteLen < 0 {`)
   460  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   461  		g.P(`}`)
   462  		g.P(`postIndex := iNdEx + byteLen`)
   463  		g.P(`if postIndex < 0 {`)
   464  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   465  		g.P(`}`)
   466  		g.P(`if postIndex > l {`)
   467  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   468  		g.P(`}`)
   469  		if oneof {
   470  			g.P(`v := make([]byte, postIndex-iNdEx)`)
   471  			g.P(`copy(v, dAtA[iNdEx:postIndex])`)
   472  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   473  		} else if repeated {
   474  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, make([]byte, postIndex-iNdEx))`)
   475  			g.P(`copy(x.`, fieldname, `[len(x.`, fieldname, `)-1], dAtA[iNdEx:postIndex])`)
   476  		} else {
   477  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `[:0] , dAtA[iNdEx:postIndex]...)`)
   478  			g.P(`if x.`, fieldname, ` == nil {`)
   479  			g.P(`x.`, fieldname, ` = []byte{}`)
   480  			g.P(`}`)
   481  		}
   482  		g.P(`iNdEx = postIndex`)
   483  	case protoreflect.Uint32Kind:
   484  		if oneof {
   485  			g.P(`var v `, typ)
   486  			g.decodeVarint("v", typ)
   487  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   488  		} else if repeated {
   489  			g.P(`var v `, typ)
   490  			g.decodeVarint("v", typ)
   491  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   492  		} else if proto3 && !nullable {
   493  			g.P(`x.`, fieldname, ` = 0`)
   494  			g.decodeVarint("x."+fieldname, typ)
   495  		} else {
   496  			g.P(`var v `, typ)
   497  			g.decodeVarint("v", typ)
   498  			g.P(`x.`, fieldname, ` = &v`)
   499  		}
   500  	case protoreflect.EnumKind:
   501  		if oneof {
   502  			g.P(`var v `, typ)
   503  			g.decodeVarint("v", typ)
   504  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   505  		} else if repeated {
   506  			g.P(`var v `, typ)
   507  			g.decodeVarint("v", typ)
   508  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   509  		} else if proto3 && !nullable {
   510  			g.P(`x.`, fieldname, ` = 0`)
   511  			g.decodeVarint("x."+fieldname, typ)
   512  		} else {
   513  			g.P(`var v `, typ)
   514  			g.decodeVarint("v", typ)
   515  			g.P(`x.`, fieldname, ` = &v`)
   516  		}
   517  	case protoreflect.Sfixed32Kind:
   518  		if oneof {
   519  			g.P(`var v `, typ)
   520  			g.decodeFixed32("v", typ)
   521  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   522  		} else if repeated {
   523  			g.P(`var v `, typ)
   524  			g.decodeFixed32("v", typ)
   525  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   526  		} else if proto3 && !nullable {
   527  			g.P(`x.`, fieldname, ` = 0`)
   528  			g.decodeFixed32("x."+fieldname, typ)
   529  		} else {
   530  			g.P(`var v `, typ)
   531  			g.decodeFixed32("v", typ)
   532  			g.P(`x.`, fieldname, ` = &v`)
   533  		}
   534  	case protoreflect.Sfixed64Kind:
   535  		if oneof {
   536  			g.P(`var v `, typ)
   537  			g.decodeFixed64("v", typ)
   538  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   539  		} else if repeated {
   540  			g.P(`var v `, typ)
   541  			g.decodeFixed64("v", typ)
   542  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   543  		} else if proto3 && !nullable {
   544  			g.P(`x.`, fieldname, ` = 0`)
   545  			g.decodeFixed64("x."+fieldname, typ)
   546  		} else {
   547  			g.P(`var v `, typ)
   548  			g.decodeFixed64("v", typ)
   549  			g.P(`x.`, fieldname, ` = &v`)
   550  		}
   551  	case protoreflect.Sint32Kind:
   552  		g.P(`var v `, typ)
   553  		g.decodeVarint("v", typ)
   554  		g.P(`v = `, typ, `((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))`)
   555  		if oneof {
   556  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{v}`)
   557  		} else if repeated {
   558  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, v)`)
   559  		} else if proto3 && !nullable {
   560  			g.P(`x.`, fieldname, ` = v`)
   561  		} else {
   562  			g.P(`x.`, fieldname, ` = &v`)
   563  		}
   564  	case protoreflect.Sint64Kind:
   565  		g.P(`var v uint64`)
   566  		g.decodeVarint("v", "uint64")
   567  		g.P(`v = (v >> 1) ^ uint64((int64(v&1)<<63)>>63)`)
   568  		if oneof {
   569  			g.P(`x.`, fieldname, ` = &`, field.GoIdent, `{`, typ, `(v)}`)
   570  		} else if repeated {
   571  			g.P(`x.`, fieldname, ` = append(x.`, fieldname, `, `, typ, `(v))`)
   572  		} else if proto3 && !nullable {
   573  			g.P(`x.`, fieldname, ` = `, typ, `(v)`)
   574  		} else {
   575  			g.P(`v2 := `, typ, `(v)`)
   576  			g.P(`x.`, fieldname, ` = &v2`)
   577  		}
   578  	default:
   579  		panic("not implemented")
   580  	}
   581  }
   582  
   583  func (g *fastGenerator) noStarOrSliceType(field *protogen.Field) string {
   584  	typ, _ := g.FieldGoType(field)
   585  	if typ[0] == '[' && typ[1] == ']' {
   586  		typ = typ[2:]
   587  	}
   588  	if typ[0] == '*' {
   589  		typ = typ[1:]
   590  	}
   591  	return typ
   592  }
   593  
   594  func (g *fastGenerator) decodeFixed64(varName string, typeName string) {
   595  	g.P(`if (iNdEx+8) > l {`)
   596  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   597  	g.P(`}`)
   598  	g.P(varName, ` = `, typeName, `(`, g.Ident("encoding/binary", "LittleEndian"), `.Uint64(dAtA[iNdEx:]))`)
   599  	g.P(`iNdEx += 8`)
   600  }
   601  
   602  func (g *fastGenerator) decodeFixed32(varName string, typeName string) {
   603  	g.P(`if (iNdEx+4) > l {`)
   604  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   605  	g.P(`}`)
   606  	g.P(varName, ` = `, typeName, `(`, g.Ident("encoding/binary", "LittleEndian"), `.Uint32(dAtA[iNdEx:]))`)
   607  	g.P(`iNdEx += 4`)
   608  }
   609  
   610  func (g *fastGenerator) decodeMessage(varName, buf string, message *protogen.Message) {
   611  
   612  	g.P("if err := options.Unmarshal(", buf, ", ", varName, "); err != nil {")
   613  	g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", `err`)
   614  	g.P(`}`)
   615  
   616  }
   617  
   618  func (g *fastGenerator) unmarshalMapField(varName string, field *protogen.Field) {
   619  	switch field.Desc.Kind() {
   620  	case protoreflect.DoubleKind:
   621  		g.P(`var `, varName, `temp uint64`)
   622  		g.decodeFixed64(varName+"temp", "uint64")
   623  		g.P(varName, ` = `, g.Ident("math", "Float64frombits"), `(`, varName, `temp)`)
   624  	case protoreflect.FloatKind:
   625  		g.P(`var `, varName, `temp uint32`)
   626  		g.decodeFixed32(varName+"temp", "uint32")
   627  		g.P(varName, ` = `, g.Ident("math", "Float32frombits"), `(`, varName, `temp)`)
   628  	case protoreflect.Int64Kind:
   629  		g.decodeVarint(varName, "int64")
   630  	case protoreflect.Uint64Kind:
   631  		g.decodeVarint(varName, "uint64")
   632  	case protoreflect.Int32Kind:
   633  		g.decodeVarint(varName, "int32")
   634  	case protoreflect.Fixed64Kind:
   635  		g.decodeFixed64(varName, "uint64")
   636  	case protoreflect.Fixed32Kind:
   637  		g.decodeFixed32(varName, "uint32")
   638  	case protoreflect.BoolKind:
   639  		g.P(`var `, varName, `temp int`)
   640  		g.decodeVarint(varName+"temp", "int")
   641  		g.P(varName, ` = bool(`, varName, `temp != 0)`)
   642  	case protoreflect.StringKind:
   643  		g.P(`var stringLen`, varName, ` uint64`)
   644  		g.decodeVarint("stringLen"+varName, "uint64")
   645  		g.P(`intStringLen`, varName, ` := int(stringLen`, varName, `)`)
   646  		g.P(`if intStringLen`, varName, ` < 0 {`)
   647  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   648  		g.P(`}`)
   649  		g.P(`postStringIndex`, varName, ` := iNdEx + intStringLen`, varName)
   650  		g.P(`if postStringIndex`, varName, ` < 0 {`)
   651  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   652  		g.P(`}`)
   653  		g.P(`if postStringIndex`, varName, ` > l {`)
   654  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   655  		g.P(`}`)
   656  		g.P(varName, ` = `, "string", `(dAtA[iNdEx:postStringIndex`, varName, `])`)
   657  		g.P(`iNdEx = postStringIndex`, varName)
   658  	case protoreflect.MessageKind:
   659  		g.P(`var mapmsglen int`)
   660  		g.decodeVarint("mapmsglen", "int")
   661  		g.P(`if mapmsglen < 0 {`)
   662  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   663  		g.P(`}`)
   664  		g.P(`postmsgIndex := iNdEx + mapmsglen`)
   665  		g.P(`if postmsgIndex < 0 {`)
   666  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   667  		g.P(`}`)
   668  		g.P(`if postmsgIndex > l {`)
   669  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   670  		g.P(`}`)
   671  		buf := `dAtA[iNdEx:postmsgIndex]`
   672  		g.P(varName, ` = &`, g.noStarOrSliceType(field), `{}`)
   673  		g.decodeMessage(varName, buf, field.Message)
   674  		g.P(`iNdEx = postmsgIndex`)
   675  	case protoreflect.BytesKind:
   676  		g.P(`var mapbyteLen uint64`)
   677  		g.decodeVarint("mapbyteLen", "uint64")
   678  		g.P(`intMapbyteLen := int(mapbyteLen)`)
   679  		g.P(`if intMapbyteLen < 0 {`)
   680  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   681  		g.P(`}`)
   682  		g.P(`postbytesIndex := iNdEx + intMapbyteLen`)
   683  		g.P(`if postbytesIndex < 0 {`)
   684  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", runtimePackage.Ident("ErrInvalidLength"))
   685  		g.P(`}`)
   686  		g.P(`if postbytesIndex > l {`)
   687  		g.P(`return `, protoifacePkg.Ident("UnmarshalOutput"), "{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags},", g.Ident("io", `ErrUnexpectedEOF`))
   688  		g.P(`}`)
   689  		g.P(varName, ` = make([]byte, mapbyteLen)`)
   690  		g.P(`copy(`, varName, `, dAtA[iNdEx:postbytesIndex])`)
   691  		g.P(`iNdEx = postbytesIndex`)
   692  	case protoreflect.Uint32Kind:
   693  		g.decodeVarint(varName, "uint32")
   694  	case protoreflect.EnumKind:
   695  		goTypV, _ := g.FieldGoType(field)
   696  		g.decodeVarint(varName, goTypV)
   697  	case protoreflect.Sfixed32Kind:
   698  		g.decodeFixed32(varName, "int32")
   699  	case protoreflect.Sfixed64Kind:
   700  		g.decodeFixed64(varName, "int64")
   701  	case protoreflect.Sint32Kind:
   702  		g.P(`var `, varName, `temp int32`)
   703  		g.decodeVarint(varName+"temp", "int32")
   704  		g.P(varName, `temp = int32((uint32(`, varName, `temp) >> 1) ^ uint32(((`, varName, `temp&1)<<31)>>31))`)
   705  		g.P(varName, ` = int32(`, varName, `temp)`)
   706  	case protoreflect.Sint64Kind:
   707  		g.P(`var `, varName, `temp uint64`)
   708  		g.decodeVarint(varName+"temp", "uint64")
   709  		g.P(varName, `temp = (`, varName, `temp >> 1) ^ uint64((int64(`, varName, `temp&1)<<63)>>63)`)
   710  		g.P(varName, ` = int64(`, varName, `temp)`)
   711  	}
   712  }