github.com/cosmos/cosmos-proto@v1.0.0-beta.3/features/fastreflection/proto_marshal.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 "sort" 10 "strconv" 11 "strings" 12 ) 13 14 type counter int 15 16 func (cnt *counter) Next() string { 17 *cnt++ 18 return cnt.Current() 19 } 20 21 func (cnt *counter) Current() string { 22 return strconv.Itoa(int(*cnt)) 23 } 24 25 func (g *fastGenerator) genMarshalMethod() { 26 27 var numGen counter 28 // MARSHAL METHOD 29 g.P(`marshal := func(input `, protoifacePkg.Ident("MarshalInput"), `) (`, protoifacePkg.Ident("MarshalOutput"), `, error) {`) 30 31 // setup 32 g.P(`x := input.Message.Interface().(*`, g.message.GoIdent, `)`) 33 g.P("if x == nil {") 34 g.P(`return `, protoifacePkg.Ident("MarshalOutput"), `{`) 35 g.P(` NoUnkeyedLiterals: input.NoUnkeyedLiterals,`) 36 g.P(` Buf: input.Buf,`) 37 g.P("}, nil") 38 g.P("}") 39 40 // core 41 g.P("options := ", runtimePackage.Ident("MarshalInputToOptions"), "(input)") 42 g.P("_ = options") 43 g.P("size := options.Size(x)") 44 g.P(`dAtA := make([]byte, size)`) 45 46 // from here we need to do what MarshalToSizedBuffer was doing 47 g.P("i := len(dAtA)") 48 g.P("_ = i") 49 g.P("var l int") 50 g.P("_ = l") 51 g.P("if x.unknownFields != nil {") 52 g.P("i -= len(x.unknownFields)") 53 g.P("copy(dAtA[i:], x.unknownFields)") 54 g.P("}") 55 56 // oneofs MUST be marshalled first! 57 oneofs := make(map[string]struct{}) 58 for i := len(g.message.Oneofs) - 1; i >= 0; i-- { 59 field := g.message.Oneofs[i] 60 fieldname := field.GoName 61 if _, ok := oneofs[fieldname]; !ok { 62 oneofs[fieldname] = struct{}{} 63 g.P("switch x := x.", fieldname, ".(type) {") 64 for _, ooField := range field.Fields { 65 g.P("case *", ooField.GoIdent, ": ") 66 g.marshalField(true, &numGen, ooField, true) 67 } 68 g.P("}") 69 } 70 } 71 72 // here we deep copy the message.Fields slice, since it can corrupt the order of fields 73 // causing issues for plugins that depend on the order 74 messageFields := make([]*protogen.Field, len(g.message.Fields)) 75 for i := range g.message.Fields { 76 messageFields[i] = g.message.Fields[i] 77 } 78 sort.Slice(messageFields, func(i, j int) bool { 79 return messageFields[i].Desc.Number() < messageFields[j].Desc.Number() 80 }) 81 82 // then we do everything else 83 for i := len(messageFields) - 1; i >= 0; i-- { 84 field := messageFields[i] 85 isOneof := field.Oneof != nil && !field.Oneof.Desc.IsSynthetic() 86 if !isOneof { 87 g.marshalField(true, &numGen, field, false) 88 } 89 } 90 91 g.P("if input.Buf != nil {") 92 g.P(`input.Buf = append(input.Buf, dAtA...)`) 93 g.P("} else {") 94 g.P("input.Buf = dAtA") 95 g.P("}") 96 g.P(`return `, protoifacePkg.Ident("MarshalOutput"), `{`) 97 g.P(` NoUnkeyedLiterals: input.NoUnkeyedLiterals,`) 98 g.P(` Buf: input.Buf,`) 99 g.P("}, nil") 100 g.P("}") 101 } 102 103 func (g *fastGenerator) marshalField(proto3 bool, numGen *counter, field *protogen.Field, oneof bool) { 104 fieldname := field.GoName 105 nullable := field.Message != nil || (field.Oneof != nil && field.Oneof.Desc.IsSynthetic()) 106 repeated := field.Desc.Cardinality() == protoreflect.Repeated 107 if repeated && !oneof { 108 g.P(`if len(x.`, fieldname, `) > 0 {`) 109 } else if nullable && !oneof { 110 g.P(`if x.`, fieldname, ` != nil {`) 111 } 112 packed := field.Desc.IsPacked() 113 wireType := generator.ProtoWireType(field.Desc.Kind()) 114 fieldNumber := field.Desc.Number() 115 if packed { 116 wireType = protowire.BytesType 117 } 118 switch field.Desc.Kind() { 119 case protoreflect.DoubleKind: 120 if packed { 121 val := g.reverseListRange(`x.`, fieldname) 122 g.P(`f`, numGen.Next(), ` := `, g.Ident("math", "Float64bits"), `(float64(`, val, `))`) 123 g.encodeFixed64("f", numGen.Current()) 124 g.P(`}`) 125 g.encodeVarint(`len(x.`, fieldname, `) * 8`) 126 g.encodeKey(fieldNumber, wireType) 127 } else if repeated { 128 val := g.reverseListRange(`x.`, fieldname) 129 g.P(`f`, numGen.Next(), ` := `, g.Ident("math", "Float64bits"), `(float64(`, val, `))`) 130 g.encodeFixed64("f", numGen.Current()) 131 g.encodeKey(fieldNumber, wireType) 132 g.P(`}`) 133 } else if nullable { 134 g.encodeFixed64(g.Ident("math", "Float64bits"), `(float64(*x.`+fieldname, `))`) 135 g.encodeKey(fieldNumber, wireType) 136 } else if proto3 { 137 if !oneof { 138 g.P(`if x.`, fieldname, ` != 0 || `, mathPackage.Ident("Signbit"), `(x.`, fieldname, `) {`) 139 } 140 g.encodeFixed64(g.Ident("math", "Float64bits"), `(float64(x.`, fieldname, `))`) 141 g.encodeKey(fieldNumber, wireType) 142 if !oneof { 143 g.P(`}`) 144 } 145 } else { 146 g.encodeFixed64(g.Ident("math", "Float64bits"), `(float64(x.`+fieldname, `))`) 147 g.encodeKey(fieldNumber, wireType) 148 } 149 case protoreflect.FloatKind: 150 if packed { 151 val := g.reverseListRange(`x.`, fieldname) 152 g.P(`f`, numGen.Next(), ` := `, g.Ident("math", "Float32bits"), `(float32(`, val, `))`) 153 g.encodeFixed32("f" + numGen.Current()) 154 g.P(`}`) 155 g.encodeVarint(`len(x.`, fieldname, `) * 4`) 156 g.encodeKey(fieldNumber, wireType) 157 } else if repeated { 158 val := g.reverseListRange(`x.`, fieldname) 159 g.P(`f`, numGen.Next(), ` := `, g.Ident("math", "Float32bits"), `(float32(`, val, `))`) 160 g.encodeFixed32("f" + numGen.Current()) 161 g.encodeKey(fieldNumber, wireType) 162 g.P(`}`) 163 } else if nullable { 164 g.encodeFixed32(g.Ident("math", "Float32bits"), `(float32(*x.`+fieldname, `))`) 165 g.encodeKey(fieldNumber, wireType) 166 } else if proto3 { 167 if !oneof { 168 g.P(`if x.`, fieldname, ` != 0 || `, mathPackage.Ident("Signbit"), `(float64(x.`, fieldname, `)) {`) 169 } 170 g.encodeFixed32(g.Ident("math", "Float32bits"), `(float32(x.`+fieldname, `))`) 171 g.encodeKey(fieldNumber, wireType) 172 if !oneof { 173 g.P(`}`) 174 } 175 } else { 176 g.encodeFixed32(g.Ident("math", "Float32bits"), `(float32(x.`+fieldname, `))`) 177 g.encodeKey(fieldNumber, wireType) 178 } 179 case protoreflect.Int64Kind, protoreflect.Uint64Kind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.EnumKind: 180 if packed { 181 jvar := "j" + numGen.Next() 182 total := "pksize" + numGen.Next() 183 184 g.P(`var `, total, ` int`) 185 g.P(`for _, num := range x.`, fieldname, ` {`) 186 g.P(total, ` += `, runtimePackage.Ident("Sov"), `(uint64(num))`) 187 g.P(`}`) 188 189 g.P(`i -= `, total) 190 g.P(jvar, `:= i`) 191 192 switch field.Desc.Kind() { 193 case protoreflect.Int64Kind, protoreflect.Int32Kind, protoreflect.EnumKind: 194 g.P(`for _, num1 := range x.`, fieldname, ` {`) 195 g.P(`num := uint64(num1)`) 196 default: 197 g.P(`for _, num := range x.`, fieldname, ` {`) 198 } 199 g.P(`for num >= 1<<7 {`) 200 g.P(`dAtA[`, jvar, `] = uint8(uint64(num)&0x7f|0x80)`) 201 g.P(`num >>= 7`) 202 g.P(jvar, `++`) 203 g.P(`}`) 204 g.P(`dAtA[`, jvar, `] = uint8(num)`) 205 g.P(jvar, `++`) 206 g.P(`}`) 207 208 g.encodeVarint(total) 209 g.encodeKey(fieldNumber, wireType) 210 } else if repeated { 211 val := g.reverseListRange(`x.`, fieldname) 212 g.encodeVarint(val) 213 g.encodeKey(fieldNumber, wireType) 214 g.P(`}`) 215 } else if nullable { 216 g.encodeVarint(`*x.`, fieldname) 217 g.encodeKey(fieldNumber, wireType) 218 } else if proto3 { 219 if !oneof { 220 g.P(`if x.`, fieldname, ` != 0 {`) 221 } 222 g.encodeVarint(`x.`, fieldname) 223 g.encodeKey(fieldNumber, wireType) 224 if !oneof { 225 g.P(`}`) 226 } 227 } else { 228 g.encodeVarint(`x.`, fieldname) 229 g.encodeKey(fieldNumber, wireType) 230 } 231 case protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: 232 if packed { 233 val := g.reverseListRange(`x.`, fieldname) 234 g.encodeFixed64(val) 235 g.P(`}`) 236 g.encodeVarint(`len(x.`, fieldname, `) * 8`) 237 g.encodeKey(fieldNumber, wireType) 238 } else if repeated { 239 val := g.reverseListRange(`x.`, fieldname) 240 g.encodeFixed64(val) 241 g.encodeKey(fieldNumber, wireType) 242 g.P(`}`) 243 } else if nullable { 244 g.encodeFixed64("*x.", fieldname) 245 g.encodeKey(fieldNumber, wireType) 246 } else if proto3 { 247 if !oneof { 248 g.P(`if x.`, fieldname, ` != 0 {`) 249 } 250 g.encodeFixed64("x.", fieldname) 251 g.encodeKey(fieldNumber, wireType) 252 if !oneof { 253 g.P(`}`) 254 } 255 } else { 256 g.encodeFixed64("x.", fieldname) 257 g.encodeKey(fieldNumber, wireType) 258 } 259 case protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: 260 if packed { 261 val := g.reverseListRange(`x.`, fieldname) 262 g.encodeFixed32(val) 263 g.P(`}`) 264 g.encodeVarint(`len(x.`, fieldname, `) * 4`) 265 g.encodeKey(fieldNumber, wireType) 266 } else if repeated { 267 val := g.reverseListRange(`x.`, fieldname) 268 g.encodeFixed32(val) 269 g.encodeKey(fieldNumber, wireType) 270 g.P(`}`) 271 } else if nullable { 272 g.encodeFixed32("*x." + fieldname) 273 g.encodeKey(fieldNumber, wireType) 274 } else if proto3 { 275 if !oneof { 276 g.P(`if x.`, fieldname, ` != 0 {`) 277 } 278 g.encodeFixed32("x." + fieldname) 279 g.encodeKey(fieldNumber, wireType) 280 if !oneof { 281 g.P(`}`) 282 } 283 } else { 284 g.encodeFixed32("x." + fieldname) 285 g.encodeKey(fieldNumber, wireType) 286 } 287 case protoreflect.BoolKind: 288 if packed { 289 val := g.reverseListRange(`x.`, fieldname) 290 g.P(`i--`) 291 g.P(`if `, val, ` {`) 292 g.P(`dAtA[i] = 1`) 293 g.P(`} else {`) 294 g.P(`dAtA[i] = 0`) 295 g.P(`}`) 296 g.P(`}`) 297 g.encodeVarint(`len(x.`, fieldname, `)`) 298 g.encodeKey(fieldNumber, wireType) 299 } else if repeated { 300 val := g.reverseListRange(`x.`, fieldname) 301 g.P(`i--`) 302 g.P(`if `, val, ` {`) 303 g.P(`dAtA[i] = 1`) 304 g.P(`} else {`) 305 g.P(`dAtA[i] = 0`) 306 g.P(`}`) 307 g.encodeKey(fieldNumber, wireType) 308 g.P(`}`) 309 } else if nullable { 310 g.P(`i--`) 311 g.P(`if *x.`, fieldname, ` {`) 312 g.P(`dAtA[i] = 1`) 313 g.P(`} else {`) 314 g.P(`dAtA[i] = 0`) 315 g.P(`}`) 316 g.encodeKey(fieldNumber, wireType) 317 } else if proto3 { 318 if !oneof { 319 g.P(`if x.`, fieldname, ` {`) 320 } 321 g.P(`i--`) 322 g.P(`if x.`, fieldname, ` {`) 323 g.P(`dAtA[i] = 1`) 324 g.P(`} else {`) 325 g.P(`dAtA[i] = 0`) 326 g.P(`}`) 327 g.encodeKey(fieldNumber, wireType) 328 if !oneof { 329 g.P(`}`) 330 } 331 } else { 332 g.P(`i--`) 333 g.P(`if x.`, fieldname, ` {`) 334 g.P(`dAtA[i] = 1`) 335 g.P(`} else {`) 336 g.P(`dAtA[i] = 0`) 337 g.P(`}`) 338 g.encodeKey(fieldNumber, wireType) 339 } 340 case protoreflect.StringKind: 341 if repeated { 342 val := g.reverseListRange(`x.`, fieldname) 343 g.P(`i -= len(`, val, `)`) 344 g.P(`copy(dAtA[i:], `, val, `)`) 345 g.encodeVarint(`len(`, val, `)`) 346 g.encodeKey(fieldNumber, wireType) 347 g.P(`}`) 348 } else if nullable { 349 g.P(`i -= len(*x.`, fieldname, `)`) 350 g.P(`copy(dAtA[i:], *x.`, fieldname, `)`) 351 g.encodeVarint(`len(*x.`, fieldname, `)`) 352 g.encodeKey(fieldNumber, wireType) 353 } else if proto3 { 354 if !oneof { 355 g.P(`if len(x.`, fieldname, `) > 0 {`) 356 } 357 g.P(`i -= len(x.`, fieldname, `)`) 358 g.P(`copy(dAtA[i:], x.`, fieldname, `)`) 359 g.encodeVarint(`len(x.`, fieldname, `)`) 360 g.encodeKey(fieldNumber, wireType) 361 if !oneof { 362 g.P(`}`) 363 } 364 } else { 365 g.P(`i -= len(x.`, fieldname, `)`) 366 g.P(`copy(dAtA[i:], x.`, fieldname, `)`) 367 g.encodeVarint(`len(x.`, fieldname, `)`) 368 g.encodeKey(fieldNumber, wireType) 369 } 370 case protoreflect.GroupKind: 371 panic(fmt.Errorf("marshaler does not support group %v", fieldname)) 372 case protoreflect.MessageKind: 373 if field.Desc.IsMap() { 374 goTypK, _ := g.FieldGoType(field.Message.Fields[0]) 375 goTypV, ptr := g.FieldGoType(field.Message.Fields[1]) 376 if ptr { 377 goTypV = "*" + goTypV 378 } 379 keyKind := field.Message.Fields[0].Desc.Kind() 380 valKind := field.Message.Fields[1].Desc.Kind() 381 382 _, ok := kindToGoType[keyKind] 383 if !ok { 384 panic(fmt.Sprintf("pulsar does not support %s types as map keys", field.Desc.MapKey().Kind().String())) 385 } 386 387 g.P("MaRsHaLmAp := func(k ", goTypK, ", v ", goTypV, ") (", protoifacePkg.Ident("MarshalOutput"), ", error) {") 388 g.P(`baseI := i`) 389 accessor := `v` 390 g.mapField(field.Message.Fields[1], accessor) 391 g.encodeKey(2, generator.ProtoWireType(valKind)) 392 393 g.mapField(field.Message.Fields[0], "k") 394 g.encodeKey(1, generator.ProtoWireType(keyKind)) 395 g.encodeVarint(`baseI - i`) 396 g.encodeKey(fieldNumber, wireType) 397 g.P("return ", protoifacePkg.Ident("MarshalOutput"), "{}, nil") 398 g.P("}") 399 400 var val string 401 g.P("if options.Deterministic {") 402 keysName := `keysFor` + fieldname 403 g.P(keysName, ` := make([]`, goTypK, `, 0, len(x.`, fieldname, `))`) 404 g.P(`for k := range x.`, fieldname, ` {`) 405 g.P(keysName, ` = append(`, keysName, `, `, goTypK, `(k))`) 406 g.P(`}`) 407 g.P(g.Ident("sort", "Slice"), `(`, keysName, `, func(i, j int) bool {`) 408 switch keyKind { 409 case protoreflect.BoolKind: 410 g.P("return !", keysName, "[i] && ", keysName, "[j]") 411 default: 412 g.P(`return `, keysName, `[i] < `, keysName, `[j]`) 413 } 414 g.P(`})`) 415 val = g.reverseListRange(keysName) 416 g.P(`v := x.`, fieldname, `[`, goTypK, `(`, val, `)]`) 417 g.P("out, err := MaRsHaLmAp(", val, ", v)") 418 g.P("if err != nil {") 419 g.P("return out, err") 420 g.P("}") 421 g.P("}") 422 g.P("} else {") 423 424 g.P(`for k := range x.`, fieldname, ` {`) 425 val = "k" 426 g.P(`v := x.`, fieldname, `[`, val, `]`) 427 g.P("out, err := MaRsHaLmAp(k,v)") 428 g.P("if err != nil {") 429 g.P("return out, err") 430 g.P("}") 431 g.P("}") 432 g.P("}") 433 } else if repeated { 434 val := g.reverseListRange(`x.`, fieldname) 435 g.marshalBackward(val, true, field.Message) 436 g.encodeKey(fieldNumber, wireType) 437 g.P(`}`) 438 } else { 439 g.marshalBackward(`x.`+fieldname, true, field.Message) 440 g.encodeKey(fieldNumber, wireType) 441 } 442 case protoreflect.BytesKind: 443 if repeated { 444 val := g.reverseListRange(`x.`, fieldname) 445 g.P(`i -= len(`, val, `)`) 446 g.P(`copy(dAtA[i:], `, val, `)`) 447 g.encodeVarint(`len(`, val, `)`) 448 g.encodeKey(fieldNumber, wireType) 449 g.P(`}`) 450 } else if proto3 { 451 if !oneof { 452 g.P(`if len(x.`, fieldname, `) > 0 {`) 453 } 454 g.P(`i -= len(x.`, fieldname, `)`) 455 g.P(`copy(dAtA[i:], x.`, fieldname, `)`) 456 g.encodeVarint(`len(x.`, fieldname, `)`) 457 g.encodeKey(fieldNumber, wireType) 458 if !oneof { 459 g.P(`}`) 460 } 461 } else { 462 g.P(`i -= len(x.`, fieldname, `)`) 463 g.P(`copy(dAtA[i:], x.`, fieldname, `)`) 464 g.encodeVarint(`len(x.`, fieldname, `)`) 465 g.encodeKey(fieldNumber, wireType) 466 } 467 case protoreflect.Sint32Kind: 468 if packed { 469 jvar := "j" + numGen.Next() 470 total := "pksize" + numGen.Next() 471 472 g.P(`var `, total, ` int`) 473 g.P(`for _, num := range x.`, fieldname, ` {`) 474 g.P(total, ` += `, runtimePackage.Ident("Soz"), `(uint64(num))`) 475 g.P(`}`) 476 g.P(`i -= `, total) 477 g.P(jvar, `:= i`) 478 479 g.P(`for _, num := range x.`, fieldname, ` {`) 480 xvar := "x" + numGen.Next() 481 g.P(xvar, ` := (uint32(num) << 1) ^ uint32((num >> 31))`) 482 g.P(`for `, xvar, ` >= 1<<7 {`) 483 g.P(`dAtA[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) 484 g.P(jvar, `++`) 485 g.P(xvar, ` >>= 7`) 486 g.P(`}`) 487 g.P(`dAtA[`, jvar, `] = uint8(`, xvar, `)`) 488 g.P(jvar, `++`) 489 g.P(`}`) 490 491 g.encodeVarint(total) 492 g.encodeKey(fieldNumber, wireType) 493 } else if repeated { 494 val := g.reverseListRange(`x.`, fieldname) 495 g.P(`x`, numGen.Next(), ` := (uint32(`, val, `) << 1) ^ uint32((`, val, ` >> 31))`) 496 g.encodeVarint(`x`, numGen.Current()) 497 g.encodeKey(fieldNumber, wireType) 498 g.P(`}`) 499 } else if nullable { 500 g.encodeVarint(`(uint32(*x.`, fieldname, `) << 1) ^ uint32((*x.`, fieldname, ` >> 31))`) 501 g.encodeKey(fieldNumber, wireType) 502 } else if proto3 { 503 if !oneof { 504 g.P(`if x.`, fieldname, ` != 0 {`) 505 } 506 g.encodeVarint(`(uint32(x.`, fieldname, `) << 1) ^ uint32((x.`, fieldname, ` >> 31))`) 507 g.encodeKey(fieldNumber, wireType) 508 if !oneof { 509 g.P(`}`) 510 } 511 } else { 512 g.encodeVarint(`(uint32(x.`, fieldname, `) << 1) ^ uint32((x.`, fieldname, ` >> 31))`) 513 g.encodeKey(fieldNumber, wireType) 514 } 515 case protoreflect.Sint64Kind: 516 if packed { 517 jvar := "j" + numGen.Next() 518 total := "pksize" + numGen.Next() 519 520 g.P(`var `, total, ` int`) 521 g.P(`for _, num := range x.`, fieldname, ` {`) 522 g.P(total, ` += `, runtimePackage.Ident("Soz"), `(uint64(num))`) 523 g.P(`}`) 524 g.P(`i -= `, total) 525 g.P(jvar, `:= i`) 526 527 g.P(`for _, num := range x.`, fieldname, ` {`) 528 xvar := "x" + numGen.Next() 529 g.P(xvar, ` := (uint64(num) << 1) ^ uint64((num >> 63))`) 530 g.P(`for `, xvar, ` >= 1<<7 {`) 531 g.P(`dAtA[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`) 532 g.P(jvar, `++`) 533 g.P(xvar, ` >>= 7`) 534 g.P(`}`) 535 g.P(`dAtA[`, jvar, `] = uint8(`, xvar, `)`) 536 g.P(jvar, `++`) 537 g.P(`}`) 538 539 g.encodeVarint(total) 540 g.encodeKey(fieldNumber, wireType) 541 } else if repeated { 542 val := g.reverseListRange(`x.`, fieldname) 543 g.P(`x`, numGen.Next(), ` := (uint64(`, val, `) << 1) ^ uint64((`, val, ` >> 63))`) 544 g.encodeVarint("x" + numGen.Current()) 545 g.encodeKey(fieldNumber, wireType) 546 g.P(`}`) 547 } else if nullable { 548 g.encodeVarint(`(uint64(*x.`, fieldname, `) << 1) ^ uint64((*x.`, fieldname, ` >> 63))`) 549 g.encodeKey(fieldNumber, wireType) 550 } else if proto3 { 551 if !oneof { 552 g.P(`if x.`, fieldname, ` != 0 {`) 553 } 554 g.encodeVarint(`(uint64(x.`, fieldname, `) << 1) ^ uint64((x.`, fieldname, ` >> 63))`) 555 g.encodeKey(fieldNumber, wireType) 556 if !oneof { 557 g.P(`}`) 558 } 559 } else { 560 g.encodeVarint(`(uint64(x.`, fieldname, `) << 1) ^ uint64((x.`, fieldname, ` >> 63))`) 561 g.encodeKey(fieldNumber, wireType) 562 } 563 default: 564 panic("not implemented") 565 } 566 if (repeated || nullable) && !oneof { 567 g.P(`}`) 568 } 569 } 570 571 func (g *fastGenerator) marshalBackward(varName string, varInt bool, message *protogen.Message) { 572 g.P(`encoded, err := `, "options.Marshal(", varName, ")") 573 g.P(`if err != nil {`) 574 g.P(`return `, protoifacePkg.Ident("MarshalOutput"), " {") 575 g.P("NoUnkeyedLiterals: input.NoUnkeyedLiterals,") 576 g.P("Buf: input.Buf,") 577 g.P("}, err") 578 g.P(`}`) 579 g.P(`i -= len(encoded)`) 580 g.P(`copy(dAtA[i:], encoded)`) 581 if varInt { 582 g.encodeVarint(`len(encoded)`) 583 } 584 } 585 586 func (g *fastGenerator) reverseListRange(expression ...string) string { 587 exp := strings.Join(expression, "") 588 g.P(`for iNdEx := len(`, exp, `) - 1; iNdEx >= 0; iNdEx-- {`) 589 return exp + `[iNdEx]` 590 } 591 592 func (g *fastGenerator) encodeFixed64(varName ...string) { 593 g.P(`i -= 8`) 594 g.P(g.Ident("encoding/binary", "LittleEndian"), `.PutUint64(dAtA[i:], uint64(`, strings.Join(varName, ""), `))`) 595 } 596 597 func (g *fastGenerator) encodeFixed32(varName ...string) { 598 g.P(`i -= 4`) 599 g.P(g.Ident("encoding/binary", "LittleEndian"), `.PutUint32(dAtA[i:], uint32(`, strings.Join(varName, ""), `))`) 600 } 601 602 func (g *fastGenerator) encodeVarint(varName ...string) { 603 g.P(`i = `, runtimePackage.Ident("EncodeVarint"), `(dAtA, i, uint64(`, strings.Join(varName, ""), `))`) 604 } 605 606 func (g *fastGenerator) encodeKey(fieldNumber protoreflect.FieldNumber, wireType protowire.Type) { 607 x := uint32(fieldNumber)<<3 | uint32(wireType) 608 i := 0 609 keybuf := make([]byte, 0) 610 for i = 0; x > 127; i++ { 611 keybuf = append(keybuf, 0x80|uint8(x&0x7F)) 612 x >>= 7 613 } 614 keybuf = append(keybuf, uint8(x)) 615 for i = len(keybuf) - 1; i >= 0; i-- { 616 g.P(`i--`) 617 g.P(`dAtA[i] = `, fmt.Sprintf("%#v", keybuf[i])) 618 } 619 } 620 621 func (g *fastGenerator) mapField(kvField *protogen.Field, varName string) { 622 switch kvField.Desc.Kind() { 623 case protoreflect.DoubleKind: 624 g.encodeFixed64(g.Ident("math", "Float64bits"), `(float64(`, varName, `))`) 625 case protoreflect.FloatKind: 626 g.encodeFixed32(g.Ident("math", "Float32bits"), `(float32(`, varName, `))`) 627 case protoreflect.Int64Kind, protoreflect.Uint64Kind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.EnumKind: 628 g.encodeVarint(varName) 629 case protoreflect.Fixed64Kind, protoreflect.Sfixed64Kind: 630 g.encodeFixed64(varName) 631 case protoreflect.Fixed32Kind, protoreflect.Sfixed32Kind: 632 g.encodeFixed32(varName) 633 case protoreflect.BoolKind: 634 g.P(`i--`) 635 g.P(`if `, varName, ` {`) 636 g.P(`dAtA[i] = 1`) 637 g.P(`} else {`) 638 g.P(`dAtA[i] = 0`) 639 g.P(`}`) 640 case protoreflect.StringKind, protoreflect.BytesKind: 641 g.P(`i -= len(`, varName, `)`) 642 g.P(`copy(dAtA[i:], `, varName, `)`) 643 g.encodeVarint(`len(`, varName, `)`) 644 case protoreflect.Sint32Kind: 645 g.encodeVarint(`(uint32(`, varName, `) << 1) ^ uint32((`, varName, ` >> 31))`) 646 case protoreflect.Sint64Kind: 647 g.encodeVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`) 648 case protoreflect.MessageKind: 649 g.marshalBackward(varName, true, kvField.Message) 650 } 651 }