github.com/cloudwego/kitex@v0.9.0/tool/internal_pkg/pluginmode/thriftgo/struct_tpl.go (about) 1 // Copyright 2021 CloudWeGo Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package thriftgo 16 17 const structLikeCodec = ` 18 {{define "StructLikeCodec"}} 19 {{if GenerateFastAPIs}} 20 {{template "StructLikeFastRead" .}} 21 22 {{template "StructLikeFastReadField" .}} 23 24 {{template "StructLikeFastWrite" .}} 25 26 {{template "StructLikeFastWriteNocopy" .}} 27 28 {{template "StructLikeLength" .}} 29 30 {{template "StructLikeFastWriteField" .}} 31 32 {{template "StructLikeFieldLength" .}} 33 {{- end}}{{/* if GenerateFastAPIs */}} 34 35 {{if GenerateDeepCopyAPIs}} 36 {{template "StructLikeDeepCopy" .}} 37 {{- end}}{{/* if GenerateDeepCopyAPIs */}} 38 {{- end}}{{/* define "StructLikeCodec" */}} 39 ` 40 41 const structLikeFastRead = ` 42 {{define "StructLikeFastRead"}} 43 {{- $TypeName := .GoName}} 44 func (p *{{$TypeName}}) FastRead(buf []byte) (int, error) { 45 var err error 46 var offset int 47 var l int 48 var fieldTypeId thrift.TType 49 var fieldId int16 50 {{- range .Fields}} 51 {{- if .Requiredness.IsRequired}} 52 var isset{{.GoName}} bool = false 53 {{- end}} 54 {{- end}} 55 _, l, err = bthrift.Binary.ReadStructBegin(buf) 56 offset += l 57 if err != nil { 58 goto ReadStructBeginError 59 } 60 61 for { 62 {{- if Features.KeepUnknownFields}} 63 {{- if gt (len .Fields) 0}} 64 var isUnknownField bool 65 {{- end}} 66 var beginOff int = offset 67 {{- end}} 68 _, fieldTypeId, fieldId, l, err = bthrift.Binary.ReadFieldBegin(buf[offset:]) 69 offset += l 70 if err != nil { 71 goto ReadFieldBeginError 72 } 73 if fieldTypeId == thrift.STOP { 74 break; 75 } 76 {{if gt (len .Fields) 0 -}} 77 switch fieldId { 78 {{- range .Fields}} 79 case {{.ID}}: 80 if fieldTypeId == thrift.{{.Type | GetTypeIDConstant }} { 81 l, err = p.FastReadField{{Str .ID}}(buf[offset:]) 82 offset += l 83 if err != nil { 84 goto ReadFieldError 85 } 86 {{- if .Requiredness.IsRequired}} 87 isset{{.GoName}} = true 88 {{- end}} 89 } else { 90 l, err = bthrift.Binary.Skip(buf[offset:], fieldTypeId) 91 offset += l 92 if err != nil { 93 goto SkipFieldError 94 } 95 } 96 {{- end}}{{/* range .Fields */}} 97 default: 98 l, err = bthrift.Binary.Skip(buf[offset:], fieldTypeId) 99 offset += l 100 if err != nil { 101 goto SkipFieldError 102 } 103 {{- if Features.KeepUnknownFields}} 104 isUnknownField = true 105 {{- end}}{{/* if Features.KeepUnknownFields */}} 106 } 107 {{- else -}} 108 l, err = bthrift.Binary.Skip(buf[offset:], fieldTypeId) 109 offset += l 110 if err != nil { 111 goto SkipFieldError 112 } 113 {{- end}}{{/* if len(.Fields) > 0 */}} 114 115 l, err = bthrift.Binary.ReadFieldEnd(buf[offset:]) 116 offset += l 117 if err != nil { 118 goto ReadFieldEndError 119 } 120 121 {{- if Features.KeepUnknownFields}} 122 {{if gt (len .Fields) 0 -}} 123 if isUnknownField { 124 p._unknownFields = append(p._unknownFields, buf[beginOff:offset]...) 125 } 126 {{- else -}} 127 p._unknownFields = append(p._unknownFields, buf[beginOff:offset]...) 128 {{- end}} 129 {{- end}}{{/* if Features.KeepUnknownFields */}} 130 } 131 l, err = bthrift.Binary.ReadStructEnd(buf[offset:]) 132 offset += l 133 if err != nil { 134 goto ReadStructEndError 135 } 136 {{ $NeedRequiredFieldNotSetError := false }} 137 {{- range .Fields}} 138 {{- if .Requiredness.IsRequired}} 139 {{ $NeedRequiredFieldNotSetError = true }} 140 if !isset{{.GoName}} { 141 fieldId = {{.ID}} 142 goto RequiredFieldNotSetError 143 } 144 {{- end}} 145 {{- end}} 146 return offset, nil 147 ReadStructBeginError: 148 return offset, thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err) 149 ReadFieldBeginError: 150 return offset, thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err) 151 {{- if gt (len .Fields) 0}} 152 ReadFieldError: 153 return offset, thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_{{$TypeName}}[fieldId]), err) 154 {{- end}} 155 SkipFieldError: 156 return offset, thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err) 157 ReadFieldEndError: 158 return offset, thrift.PrependError(fmt.Sprintf("%T read field end error", p), err) 159 ReadStructEndError: 160 return offset, thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err) 161 {{- if $NeedRequiredFieldNotSetError }} 162 RequiredFieldNotSetError: 163 return offset, thrift.NewTProtocolExceptionWithType(thrift.INVALID_DATA, fmt.Errorf("required field %s is not set", fieldIDToName_{{$TypeName}}[fieldId])) 164 {{- end}}{{/* if $NeedRequiredFieldNotSetError */}} 165 } 166 {{- end}}{{/* define "StructLikeFastRead" */}} 167 ` 168 169 const structLikeFastReadField = ` 170 {{define "StructLikeFastReadField"}} 171 {{- $TypeName := .GoName}} 172 {{- range .Fields}} 173 {{$FieldName := .GoName}} 174 func (p *{{$TypeName}}) FastReadField{{Str .ID}}(buf []byte) (int, error) { 175 offset := 0 176 {{- $ctx := MkRWCtx .}} 177 {{ template "FieldFastRead" $ctx}} 178 return offset, nil 179 } 180 {{- end}}{{/* range .Fields */}} 181 {{- end}}{{/* define "StructLikeFastReadField" */}} 182 ` 183 184 // TODO: check required 185 const structLikeDeepCopy = ` 186 {{define "StructLikeDeepCopy"}} 187 {{- $TypeName := .GoName}} 188 func (p *{{$TypeName}}) DeepCopy(s interface{}) error { 189 {{if gt (len .Fields) 0 -}} 190 src, ok := s.(*{{$TypeName}}) 191 if !ok { 192 return fmt.Errorf("%T's type not matched %T", s, p) 193 } 194 {{- end -}} 195 {{- range .Fields}} 196 {{- $ctx := MkRWCtx .}} 197 {{ template "FieldDeepCopy" $ctx}} 198 {{- end}}{{/* range .Fields */}} 199 {{/* line break */}} 200 return nil 201 } 202 {{- end}}{{/* define "StructLikeDeepCopy" */}} 203 ` 204 205 const structLikeFastWrite = ` 206 {{define "StructLikeFastWrite"}} 207 {{- $TypeName := .GoName}} 208 // for compatibility 209 func (p *{{$TypeName}}) FastWrite(buf []byte) int { 210 return 0 211 } 212 {{- end}}{{/* define "StructLikeFastWrite" */}} 213 ` 214 215 const structLikeFastWriteNocopy = ` 216 {{define "StructLikeFastWriteNocopy"}} 217 {{- $TypeName := .GoName}} 218 func (p *{{$TypeName}}) FastWriteNocopy(buf []byte, binaryWriter bthrift.BinaryWriter) int { 219 offset := 0 220 {{- if eq .Category "union"}} 221 var c int 222 if p != nil { 223 if c = p.CountSetFields{{$TypeName}}(); c != 1 { 224 goto CountSetFieldsError 225 } 226 } 227 {{- end}} 228 offset += bthrift.Binary.WriteStructBegin(buf[offset:], "{{.Name}}") 229 if p != nil { 230 {{- $reorderedFields := ReorderStructFields .Fields}} 231 {{- range $reorderedFields}} 232 offset += p.fastWriteField{{Str .ID}}(buf[offset:], binaryWriter) 233 {{- end}} 234 {{- if Features.KeepUnknownFields}} 235 offset += copy(buf[offset:], p._unknownFields) 236 {{- end}}{{/* if Features.KeepUnknownFields */}} 237 } 238 offset += bthrift.Binary.WriteFieldStop(buf[offset:]) 239 offset += bthrift.Binary.WriteStructEnd(buf[offset:]) 240 return offset 241 {{- if eq .Category "union"}} 242 CountSetFieldsError: 243 panic(fmt.Errorf("%T write union: exactly one field must be set (%d set).", p, c)) 244 {{- end}} 245 } 246 {{- end}}{{/* define "StructLikeFastWriteNocopy" */}} 247 ` 248 249 const structLikeLength = ` 250 {{define "StructLikeLength"}} 251 {{- $TypeName := .GoName}} 252 func (p *{{$TypeName}}) BLength() int { 253 l := 0 254 {{- if eq .Category "union"}} 255 var c int 256 if p != nil { 257 if c = p.CountSetFields{{$TypeName}}(); c != 1 { 258 goto CountSetFieldsError 259 } 260 } 261 {{- end}} 262 l += bthrift.Binary.StructBeginLength("{{.Name}}") 263 if p != nil { 264 {{- range .Fields}} 265 l += p.field{{Str .ID}}Length() 266 {{- end}} 267 {{- if Features.KeepUnknownFields}} 268 l += len(p._unknownFields) 269 {{- end}}{{/* if Features.KeepUnknownFields */}} 270 } 271 l += bthrift.Binary.FieldStopLength() 272 l += bthrift.Binary.StructEndLength() 273 return l 274 {{- if eq .Category "union"}} 275 CountSetFieldsError: 276 panic(fmt.Errorf("%T write union: exactly one field must be set (%d set).", p, c)) 277 {{- end}} 278 } 279 {{- end}}{{/* define "StructLikeLength" */}} 280 ` 281 282 const structLikeFastWriteField = ` 283 {{define "StructLikeFastWriteField"}} 284 {{- $TypeName := .GoName}} 285 {{- range .Fields}} 286 {{- $FieldName := .GoName}} 287 {{- $TypeID := .Type | GetTypeIDConstant }} 288 func (p *{{$TypeName}}) fastWriteField{{Str .ID}}(buf []byte, binaryWriter bthrift.BinaryWriter) int { 289 offset := 0 290 {{- if .Requiredness.IsOptional}} 291 if p.{{.IsSetter}}() { 292 {{- end}} 293 offset += bthrift.Binary.WriteFieldBegin(buf[offset:], "{{.Name}}", thrift.{{$TypeID}}, {{.ID}}) 294 {{- $ctx := MkRWCtx .}} 295 {{- template "FieldFastWrite" $ctx}} 296 offset += bthrift.Binary.WriteFieldEnd(buf[offset:]) 297 {{- if .Requiredness.IsOptional}} 298 } 299 {{- end}} 300 return offset 301 } 302 {{end}}{{/* range .Fields */}} 303 {{- end}}{{/* define "StructLikeFastWriteField" */}} 304 ` 305 306 const structLikeFieldLength = ` 307 {{define "StructLikeFieldLength"}} 308 {{- $TypeName := .GoName}} 309 {{- range .Fields}} 310 {{- $FieldName := .GoName}} 311 {{- $TypeID := .Type | GetTypeIDConstant }} 312 func (p *{{$TypeName}}) field{{Str .ID}}Length() int { 313 l := 0 314 {{- if .Requiredness.IsOptional}} 315 if p.{{.IsSetter}}() { 316 {{- end}} 317 l += bthrift.Binary.FieldBeginLength("{{.Name}}", thrift.{{$TypeID}}, {{.ID}}) 318 {{- $ctx := MkRWCtx .}} 319 {{- template "FieldLength" $ctx}} 320 l += bthrift.Binary.FieldEndLength() 321 {{- if .Requiredness.IsOptional}} 322 } 323 {{- end}} 324 return l 325 } 326 {{end}}{{/* range .Fields */}} 327 {{- end}}{{/* define "StructLikeFieldLength" */}} 328 ` 329 330 const fieldFastRead = ` 331 {{define "FieldFastRead"}} 332 {{- if .Type.Category.IsStructLike}} 333 {{- template "FieldFastReadStructLike" .}} 334 {{- else if .Type.Category.IsContainerType}} 335 {{- template "FieldFastReadContainer" .}} 336 {{- else}}{{/* IsBaseType */}} 337 {{- template "FieldFastReadBaseType" .}} 338 {{- end}} 339 {{- end}}{{/* define "FieldFastRead" */}} 340 ` 341 342 const fieldFastReadStructLike = ` 343 {{define "FieldFastReadStructLike"}} 344 {{- if .NeedDecl}} 345 {{- .Target}} := {{.TypeName.Deref.NewFunc}}() 346 {{- else}} 347 tmp := {{.TypeName.Deref.NewFunc}}() 348 {{- end}} 349 if l, err := {{- if .NeedDecl}}{{.Target}}{{else}}tmp{{end}}.FastRead(buf[offset:]); err != nil { 350 return offset, err 351 } else { 352 offset += l 353 } 354 {{if not .NeedDecl}}{{- .Target}} = tmp{{end}} 355 {{- end}}{{/* define "FieldFastReadStructLike" */}} 356 ` 357 358 const fieldFastReadBaseType = ` 359 {{define "FieldFastReadBaseType"}} 360 {{- $DiffType := or .Type.Category.IsEnum .Type.Category.IsBinary}} 361 {{- if .NeedDecl}} 362 var {{.Target}} {{.TypeName}} 363 {{- end}} 364 if v, l, err := bthrift.Binary.Read{{.TypeID}}(buf[offset:]); err != nil { 365 return offset, err 366 } else { 367 offset += l 368 {{ if .IsPointer}} 369 {{- if $DiffType}} 370 tmp := {{.TypeName.Deref}}(v) 371 {{.Target}} = &tmp 372 {{- else -}} 373 {{.Target}} = &v 374 {{- end}} 375 {{ else}} 376 {{- if $DiffType}} 377 {{.Target}} = {{.TypeName}}(v) 378 {{- else}} 379 {{.Target}} = v 380 {{- end}} 381 {{ end}} 382 } 383 {{- end}}{{/* define "FieldFastReadBaseType" */}} 384 ` 385 386 const fieldFastReadContainer = ` 387 {{define "FieldFastReadContainer"}} 388 {{- if eq "Map" .TypeID}} 389 {{- template "FieldFastReadMap" .}} 390 {{- else if eq "List" .TypeID}} 391 {{- template "FieldFastReadList" .}} 392 {{- else}} 393 {{- template "FieldFastReadSet" .}} 394 {{- end}} 395 {{- end}}{{/* define "FieldFastReadContainer" */}} 396 ` 397 398 const fieldFastReadMap = ` 399 {{define "FieldFastReadMap"}} 400 _, _, size, l, err := bthrift.Binary.ReadMapBegin(buf[offset:]) 401 offset += l 402 if err != nil { 403 return offset, err 404 } 405 {{.Target}} {{if .NeedDecl}}:{{end}}= make({{.TypeName}}, size) 406 for i := 0; i < size; i++ { 407 {{- $key := .GenID "_key"}} 408 {{- $ctx := .KeyCtx.WithDecl.WithTarget $key}} 409 {{- template "FieldFastRead" $ctx}} 410 {{/* line break */}} 411 {{- $val := .GenID "_val"}} 412 {{- $ctx := .ValCtx.WithDecl.WithTarget $val}} 413 {{- template "FieldFastRead" $ctx}} 414 415 {{if and .ValCtx.Type.Category.IsStructLike Features.ValueTypeForSIC}} 416 {{$val = printf "*%s" $val}} 417 {{end}} 418 419 {{.Target}}[{{$key}}] = {{$val}} 420 } 421 if l, err := bthrift.Binary.ReadMapEnd(buf[offset:]); err != nil { 422 return offset, err 423 } else { 424 offset += l 425 } 426 {{- end}}{{/* define "FieldFastReadMap" */}} 427 ` 428 429 const fieldFastReadSet = ` 430 {{define "FieldFastReadSet"}} 431 _, size, l, err := bthrift.Binary.ReadSetBegin(buf[offset:]) 432 offset += l 433 if err != nil { 434 return offset, err 435 } 436 {{.Target}} {{if .NeedDecl}}:{{end}}= make({{.TypeName}}, 0, size) 437 for i := 0; i < size; i++ { 438 {{- $val := .GenID "_elem"}} 439 {{- $ctx := .ValCtx.WithDecl.WithTarget $val}} 440 {{- template "FieldFastRead" $ctx}} 441 442 {{if and .ValCtx.Type.Category.IsStructLike Features.ValueTypeForSIC}} 443 {{$val = printf "*%s" $val}} 444 {{end}} 445 446 {{.Target}} = append({{.Target}}, {{$val}}) 447 } 448 if l, err := bthrift.Binary.ReadSetEnd(buf[offset:]); err != nil { 449 return offset, err 450 } else { 451 offset += l 452 } 453 {{- end}}{{/* define "FieldFastReadSet" */}} 454 ` 455 456 const fieldFastReadList = ` 457 {{define "FieldFastReadList"}} 458 _, size, l, err := bthrift.Binary.ReadListBegin(buf[offset:]) 459 offset += l 460 if err != nil { 461 return offset, err 462 } 463 {{.Target}} {{if .NeedDecl}}:{{end}}= make({{.TypeName}}, 0, size) 464 for i := 0; i < size; i++ { 465 {{- $val := .GenID "_elem"}} 466 {{- $ctx := .ValCtx.WithDecl.WithTarget $val}} 467 {{- template "FieldFastRead" $ctx}} 468 469 {{if and .ValCtx.Type.Category.IsStructLike Features.ValueTypeForSIC}} 470 {{$val = printf "*%s" $val}} 471 {{end}} 472 473 {{.Target}} = append({{.Target}}, {{$val}}) 474 } 475 if l, err := bthrift.Binary.ReadListEnd(buf[offset:]); err != nil { 476 return offset, err 477 } else { 478 offset += l 479 } 480 {{- end}}{{/* define "FieldFastReadList" */}} 481 ` 482 483 const fieldDeepCopy = ` 484 {{define "FieldDeepCopy"}} 485 {{- if .Type.Category.IsStructLike}} 486 {{- template "FieldDeepCopyStructLike" .}} 487 {{- else if .Type.Category.IsContainerType}} 488 {{- template "FieldDeepCopyContainer" .}} 489 {{- else}}{{/* IsBaseType */}} 490 {{- template "FieldDeepCopyBaseType" .}} 491 {{- end}} 492 {{- end}}{{/* define "FieldDeepCopy" */}} 493 ` 494 495 const fieldDeepCopyStructLike = ` 496 {{define "FieldDeepCopyStructLike"}} 497 {{- $Src := SourceTarget .Target}} 498 {{- if .NeedDecl}} 499 var {{.Target}} *{{.TypeName.Deref}} 500 {{- else}} 501 var _{{FieldName .Target}} *{{.TypeName.Deref}} 502 {{- end}} 503 if {{$Src}} != nil { 504 {{- if .NeedDecl}}{{.Target}}{{else}}_{{FieldName .Target}}{{end}} = &{{.TypeName.Deref}}{} 505 if err := {{- if .NeedDecl}}{{.Target}}{{else}}_{{FieldName .Target}}{{end}}.DeepCopy({{$Src}}); err != nil { 506 return err 507 } 508 } 509 {{if not .NeedDecl}}{{- .Target}} = _{{FieldName .Target}}{{end}} 510 {{- end}}{{/* define "FieldDeepCopyStructLike" */}} 511 ` 512 513 const fieldDeepCopyContainer = ` 514 {{define "FieldDeepCopyContainer"}} 515 {{- if eq "Map" .TypeID}} 516 {{- template "FieldDeepCopyMap" .}} 517 {{- else if eq "List" .TypeID}} 518 {{- template "FieldDeepCopyList" .}} 519 {{- else}} 520 {{- template "FieldDeepCopySet" .}} 521 {{- end}} 522 {{- end}}{{/* define "FieldDeepCopyContainer" */}} 523 ` 524 525 const fieldDeepCopyMap = ` 526 {{define "FieldDeepCopyMap"}} 527 {{- $Src := SourceTarget .Target}} 528 {{- if .NeedDecl}}var {{.Target}} {{.TypeName}}{{- end}} 529 if {{$Src}} != nil { 530 {{.Target}} = make({{.TypeName}}, len({{$Src}})) 531 {{- $key := .GenID "_key"}} 532 {{- $val := .GenID "_val"}} 533 for {{SourceTarget $key}}, {{SourceTarget $val}} := range {{$Src}} { 534 {{- $ctx := .KeyCtx.WithDecl.WithTarget $key}} 535 {{- template "FieldDeepCopy" $ctx}} 536 {{/* line break */}} 537 {{- $ctx := .ValCtx.WithDecl.WithTarget $val}} 538 {{- template "FieldDeepCopy" $ctx}} 539 540 {{- if and .ValCtx.Type.Category.IsStructLike Features.ValueTypeForSIC}} 541 {{$val = printf "*%s" $val}} 542 {{- end}} 543 544 {{.Target}}[{{$key}}] = {{$val}} 545 } 546 } 547 {{- end}}{{/* define "FieldDeepCopyMap" */}} 548 ` 549 550 const fieldDeepCopyList = ` 551 {{define "FieldDeepCopyList"}} 552 {{- $Src := SourceTarget .Target}} 553 {{if .NeedDecl}}var {{.Target}} {{.TypeName}}{{end}} 554 if {{$Src}} != nil { 555 {{.Target}} = make({{.TypeName}}, 0, len({{$Src}})) 556 {{- $val := .GenID "_elem"}} 557 for _, {{SourceTarget $val}} := range {{$Src}} { 558 {{- $ctx := .ValCtx.WithDecl.WithTarget $val}} 559 {{- template "FieldDeepCopy" $ctx}} 560 561 {{- if and .ValCtx.Type.Category.IsStructLike Features.ValueTypeForSIC}} 562 {{$val = printf "*%s" $val}} 563 {{- end}} 564 565 {{.Target}} = append({{.Target}}, {{$val}}) 566 } 567 } 568 {{- end}}{{/* define "FieldDeepCopyList" */}} 569 ` 570 571 const fieldDeepCopySet = ` 572 {{define "FieldDeepCopySet"}} 573 {{- $Src := SourceTarget .Target}} 574 {{if .NeedDecl}}var {{.Target}} {{.TypeName}}{{end}} 575 if {{$Src}} != nil { 576 {{.Target}} = make({{.TypeName}}, 0, len({{$Src}})) 577 {{- $val := .GenID "_elem"}} 578 for _, {{SourceTarget $val}} := range {{$Src}} { 579 {{- $ctx := .ValCtx.WithDecl.WithTarget $val}} 580 {{- template "FieldDeepCopy" $ctx}} 581 582 {{- if and .ValCtx.Type.Category.IsStructLike Features.ValueTypeForSIC}} 583 {{$val = printf "*%s" $val}} 584 {{- end}} 585 586 {{.Target}} = append({{.Target}}, {{$val}}) 587 } 588 } 589 {{- end}}{{/* define "FieldDeepCopySet" */}} 590 ` 591 592 const fieldDeepCopyBaseType = ` 593 {{define "FieldDeepCopyBaseType"}} 594 {{- $Src := SourceTarget .Target}} 595 {{- if .NeedDecl}} 596 var {{.Target}} {{.TypeName}} 597 {{- end}} 598 {{- if .IsPointer}} 599 if {{$Src}} != nil { 600 {{- if IsGoStringType .TypeName}} 601 if *{{$Src}} != "" { 602 tmp := kutils.StringDeepCopy(*{{$Src}}) 603 {{.Target}} = &tmp 604 } 605 {{- else if .Type.Category.IsBinary}} 606 if len(*{{$Src}}) != 0 { 607 tmp := make([]byte, len(*{{$Src}})) 608 copy(tmp, *{{$Src}}) 609 {{.Target}} = &tmp 610 } 611 {{- else}} 612 tmp := *{{$Src}} 613 {{.Target}} = &tmp 614 {{- end}} 615 } 616 {{- else}} 617 {{- if IsGoStringType .TypeName}} 618 if {{$Src}} != "" { 619 {{.Target}} = kutils.StringDeepCopy({{$Src}}) 620 } 621 {{- else if .Type.Category.IsBinary}} 622 if len({{$Src}}) != 0 { 623 tmp := make([]byte, len({{$Src}})) 624 copy(tmp, {{$Src}}) 625 {{.Target}} = tmp 626 } 627 {{- else}} 628 {{.Target}} = {{$Src}} 629 {{- end}} 630 {{- end}} 631 {{- end}}{{/* define "FieldDeepCopyBaseType" */}} 632 ` 633 634 const fieldFastWrite = ` 635 {{define "FieldFastWrite"}} 636 {{- if .Type.Category.IsStructLike}} 637 {{- template "FieldFastWriteStructLike" . -}} 638 {{- else if .Type.Category.IsContainerType}} 639 {{- template "FieldFastWriteContainer" . -}} 640 {{- else}}{{/* IsBaseType */}} 641 {{- template "FieldFastWriteBaseType" . -}} 642 {{- end}} 643 {{- end}}{{/* define "FieldFastWrite" */}} 644 ` 645 646 const fieldLength = ` 647 {{define "FieldLength"}} 648 {{- if .Type.Category.IsStructLike}} 649 {{- template "FieldStructLikeLength" . -}} 650 {{- else if .Type.Category.IsContainerType}} 651 {{- template "FieldContainerLength" . -}} 652 {{- else}}{{/* IsBaseType */}} 653 {{- template "FieldBaseTypeLength" . -}} 654 {{- end}} 655 {{- end}}{{/* define "FieldLength" */}} 656 ` 657 658 const fieldFastWriteStructLike = ` 659 {{define "FieldFastWriteStructLike"}} 660 offset += {{.Target}}.FastWriteNocopy(buf[offset:], binaryWriter) 661 {{- end}}{{/* define "FieldFastWriteStructLike" */}} 662 ` 663 664 const fieldStructLikeLength = ` 665 {{define "FieldStructLikeLength"}} 666 l += {{.Target}}.BLength() 667 {{- end}}{{/* define "FieldStructLikeLength" */}} 668 ` 669 670 const fieldFastWriteBaseType = ` 671 {{define "FieldFastWriteBaseType"}} 672 {{- $Value := .Target}} 673 {{- if .IsPointer}}{{$Value = printf "*%s" $Value}}{{end}} 674 {{- if .Type.Category.IsEnum}}{{$Value = printf "int32(%s)" $Value}}{{end}} 675 {{- if .Type.Category.IsBinary}}{{$Value = printf "[]byte(%s)" $Value}}{{end}} 676 {{- if IsBinaryOrStringType .Type}} 677 offset += bthrift.Binary.Write{{.TypeID}}Nocopy(buf[offset:], binaryWriter, {{$Value}}) 678 {{else}} 679 offset += bthrift.Binary.Write{{.TypeID}}(buf[offset:], {{$Value}}) 680 {{end}} 681 {{- end}}{{/* define "FieldFastWriteBaseType" */}} 682 ` 683 684 const fieldBaseTypeLength = ` 685 {{define "FieldBaseTypeLength"}} 686 {{- $Value := .Target}} 687 {{- if .IsPointer}}{{$Value = printf "*%s" $Value}}{{end}} 688 {{- if .Type.Category.IsEnum}}{{$Value = printf "int32(%s)" $Value}}{{end}} 689 {{- if .Type.Category.IsBinary}}{{$Value = printf "[]byte(%s)" $Value}}{{end}} 690 {{- if IsBinaryOrStringType .Type}} 691 l += bthrift.Binary.{{.TypeID}}LengthNocopy({{$Value}}) 692 {{else}} 693 l += bthrift.Binary.{{.TypeID}}Length({{$Value}}) 694 {{end}} 695 {{- end}}{{/* define "FieldBaseTypeLength" */}} 696 ` 697 698 const fieldFixedLengthTypeLength = ` 699 {{define "FieldFixedLengthTypeLength"}} 700 {{- $Value := .Target -}} 701 bthrift.Binary.{{.TypeID}}Length({{TypeIDToGoType .TypeID}}({{$Value}})) 702 {{- end -}}{{/* define "FieldFixedLengthTypeLength" */}} 703 ` 704 705 const fieldFastWriteContainer = ` 706 {{define "FieldFastWriteContainer"}} 707 {{- if eq "Map" .TypeID}} 708 {{- template "FieldFastWriteMap" .}} 709 {{- else if eq "List" .TypeID}} 710 {{- template "FieldFastWriteList" .}} 711 {{- else}} 712 {{- template "FieldFastWriteSet" .}} 713 {{- end}} 714 {{- end}}{{/* define "FieldFastWriteContainer" */}} 715 ` 716 717 const fieldContainerLength = ` 718 {{define "FieldContainerLength"}} 719 {{- if eq "Map" .TypeID}} 720 {{- template "FieldMapLength" .}} 721 {{- else if eq "List" .TypeID}} 722 {{- template "FieldListLength" .}} 723 {{- else}} 724 {{- template "FieldSetLength" .}} 725 {{- end}} 726 {{- end}}{{/* define "FieldContainerLength" */}} 727 ` 728 729 const fieldFastWriteMap = ` 730 {{define "FieldFastWriteMap"}} 731 mapBeginOffset := offset 732 offset += bthrift.Binary.MapBeginLength(thrift. 733 {{- .KeyCtx.Type | GetTypeIDConstant -}} 734 , thrift.{{- .ValCtx.Type | GetTypeIDConstant -}}, 0) 735 var length int 736 for k, v := range {{.Target}}{ 737 length++ 738 {{$ctx := .KeyCtx.WithTarget "k"}} 739 {{- template "FieldFastWrite" $ctx}} 740 {{$ctx := .ValCtx.WithTarget "v"}} 741 {{- template "FieldFastWrite" $ctx}} 742 } 743 bthrift.Binary.WriteMapBegin(buf[mapBeginOffset:], thrift. 744 {{- .KeyCtx.Type | GetTypeIDConstant -}} 745 , thrift.{{- .ValCtx.Type | GetTypeIDConstant -}} 746 , length) 747 offset += bthrift.Binary.WriteMapEnd(buf[offset:]) 748 {{- end}}{{/* define "FieldFastWriteMap" */}} 749 ` 750 751 const fieldMapLength = ` 752 {{define "FieldMapLength"}} 753 l += bthrift.Binary.MapBeginLength(thrift. 754 {{- .KeyCtx.Type | GetTypeIDConstant -}} 755 , thrift.{{- .ValCtx.Type | GetTypeIDConstant -}} 756 , len({{.Target}})) 757 {{- if and (IsFixedLengthType .KeyCtx.Type) (IsFixedLengthType .ValCtx.Type)}} 758 var tmpK {{.KeyCtx.TypeName}} 759 var tmpV {{.ValCtx.TypeName}} 760 l += ({{- $ctx := .KeyCtx.WithTarget "tmpK" -}} 761 {{- template "FieldFixedLengthTypeLength" $ctx}} + 762 {{- $ctx := .ValCtx.WithTarget "tmpV" -}} 763 {{- template "FieldFixedLengthTypeLength" $ctx}}) * len({{.Target}}) 764 {{- else}} 765 for k, v := range {{.Target}}{ 766 {{$ctx := .KeyCtx.WithTarget "k"}} 767 {{- template "FieldLength" $ctx}} 768 {{$ctx := .ValCtx.WithTarget "v"}} 769 {{- template "FieldLength" $ctx}} 770 } 771 {{- end}}{{/* if */}} 772 l += bthrift.Binary.MapEndLength() 773 {{- end}}{{/* define "FieldMapLength" */}} 774 ` 775 776 const fieldFastWriteSet = ` 777 {{define "FieldFastWriteSet"}} 778 setBeginOffset := offset 779 offset += bthrift.Binary.SetBeginLength(thrift. 780 {{- .ValCtx.Type | GetTypeIDConstant -}}, 0) 781 {{template "ValidateSet" .}} 782 var length int 783 for _, v := range {{.Target}} { 784 length++ 785 {{- $ctx := .ValCtx.WithTarget "v"}} 786 {{- template "FieldFastWrite" $ctx}} 787 } 788 bthrift.Binary.WriteSetBegin(buf[setBeginOffset:], thrift. 789 {{- .ValCtx.Type | GetTypeIDConstant -}} 790 , length) 791 offset += bthrift.Binary.WriteSetEnd(buf[offset:]) 792 {{- end}}{{/* define "FieldFastWriteSet" */}} 793 ` 794 795 const fieldSetLength = ` 796 {{define "FieldSetLength"}} 797 l += bthrift.Binary.SetBeginLength(thrift. 798 {{- .ValCtx.Type | GetTypeIDConstant -}} 799 , len({{.Target}})) 800 {{template "ValidateSet" .}} 801 {{- if IsFixedLengthType .ValCtx.Type}} 802 var tmpV {{.ValCtx.TypeName}} 803 l += {{- $ctx := .ValCtx.WithTarget "tmpV" -}} 804 {{- template "FieldFixedLengthTypeLength" $ctx -}} * len({{.Target}}) 805 {{- else}} 806 for _, v := range {{.Target}} { 807 {{- $ctx := .ValCtx.WithTarget "v"}} 808 {{- template "FieldLength" $ctx}} 809 } 810 {{- end}}{{/* if */}} 811 l += bthrift.Binary.SetEndLength() 812 {{- end}}{{/* define "FieldSetLength" */}} 813 ` 814 815 const fieldFastWriteList = ` 816 {{define "FieldFastWriteList"}} 817 listBeginOffset := offset 818 offset += bthrift.Binary.ListBeginLength(thrift. 819 {{- .ValCtx.Type | GetTypeIDConstant -}}, 0) 820 var length int 821 for _, v := range {{.Target}} { 822 length++ 823 {{- $ctx := .ValCtx.WithTarget "v"}} 824 {{- template "FieldFastWrite" $ctx}} 825 } 826 bthrift.Binary.WriteListBegin(buf[listBeginOffset:], thrift. 827 {{- .ValCtx.Type | GetTypeIDConstant -}} 828 , length) 829 offset += bthrift.Binary.WriteListEnd(buf[offset:]) 830 {{- end}}{{/* define "FieldFastWriteList" */}} 831 ` 832 833 const fieldListLength = ` 834 {{define "FieldListLength"}} 835 l += bthrift.Binary.ListBeginLength(thrift. 836 {{- .ValCtx.Type | GetTypeIDConstant -}} 837 , len({{.Target}})) 838 {{- if IsFixedLengthType .ValCtx.Type}} 839 var tmpV {{.ValCtx.TypeName}} 840 l += {{- $ctx := .ValCtx.WithTarget "tmpV" -}} 841 {{- template "FieldFixedLengthTypeLength" $ctx -}} * len({{.Target}}) 842 {{- else}} 843 for _, v := range {{.Target}} { 844 {{- $ctx := .ValCtx.WithTarget "v"}} 845 {{- template "FieldLength" $ctx}} 846 } 847 {{- end}}{{/* if */}} 848 l += bthrift.Binary.ListEndLength() 849 {{- end}}{{/* define "FieldListLength" */}} 850 ` 851 852 const processor = ` 853 {{define "Processor"}} 854 {{- range .Functions}} 855 {{$ArgsType := .ArgType}} 856 {{template "StructLikeCodec" $ArgsType}} 857 {{- if not .Oneway}} 858 {{$ResType := .ResType}} 859 {{template "StructLikeCodec" $ResType}} 860 {{- end}} 861 {{- end}}{{/* range .Functions */}} 862 {{- end}}{{/* define "Processor" */}} 863 ` 864 865 const validateSet = ` 866 {{define "ValidateSet"}} 867 {{- if Features.ValidateSet}} 868 {{- $ctx := (.ValCtx.WithTarget "tgt").WithSource "src"}} 869 for i := 0; i < len({{.Target}}); i++ { 870 for j := i + 1; j < len({{.Target}}); j++ { 871 {{- if Features.GenDeepEqual}} 872 if func(tgt, src {{$ctx.TypeName}}) bool { 873 {{- template "FieldDeepEqual" $ctx}} 874 return true 875 }({{.Target}}[i], {{.Target}}[j]) { 876 {{- else}} 877 if reflect.DeepEqual({{.Target}}[i], {{.Target}}[j]) { 878 {{- end}} 879 panic(fmt.Errorf("%T error writing set field: slice is not unique", {{.Target}}[i])) 880 } 881 } 882 } 883 {{- end}} 884 {{- end}}{{/* define "ValidateSet" */}}`