@@ -517,30 +517,39 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
517
517
return err
518
518
}
519
519
520
- sprops := proto .GetProperties (targetType )
521
- for i := 0 ; i < target .NumField (); i ++ {
522
- ft := target .Type ().Field (i )
523
- if strings .HasPrefix (ft .Name , "XXX_" ) {
524
- continue
525
- }
520
+ consumeField := func (prop * proto.Properties ) (json.RawMessage , bool ) {
526
521
// Be liberal in what names we accept; both orig_name and camelName are okay.
527
- fieldNames := acceptedJSONFieldNames (ft )
522
+ fieldNames := acceptedJSONFieldNames (prop )
528
523
529
524
vOrig , okOrig := jsonFields [fieldNames .orig ]
530
525
vCamel , okCamel := jsonFields [fieldNames .camel ]
531
526
if ! okOrig && ! okCamel {
532
- continue
527
+ return nil , false
533
528
}
534
529
// If, for some reason, both are present in the data, favour the camelName.
535
- var valueForField json.RawMessage
530
+ var raw json.RawMessage
536
531
if okOrig {
537
- valueForField = vOrig
532
+ raw = vOrig
538
533
delete (jsonFields , fieldNames .orig )
539
534
}
540
535
if okCamel {
541
- valueForField = vCamel
536
+ raw = vCamel
542
537
delete (jsonFields , fieldNames .camel )
543
538
}
539
+ return raw , true
540
+ }
541
+
542
+ sprops := proto .GetProperties (targetType )
543
+ for i := 0 ; i < target .NumField (); i ++ {
544
+ ft := target .Type ().Field (i )
545
+ if strings .HasPrefix (ft .Name , "XXX_" ) {
546
+ continue
547
+ }
548
+
549
+ valueForField , ok := consumeField (sprops .Prop [i ])
550
+ if ! ok {
551
+ continue
552
+ }
544
553
545
554
// Handle enums, which have an underlying type of int32,
546
555
// and may appear as strings. We do this while handling
@@ -570,14 +579,17 @@ func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error {
570
579
}
571
580
}
572
581
// Check for any oneof fields.
573
- for fname , raw := range jsonFields {
574
- if oop , ok := sprops .OneofTypes [fname ]; ok {
582
+ if len (jsonFields ) > 0 {
583
+ for _ , oop := range sprops .OneofTypes {
584
+ raw , ok := consumeField (oop .Prop )
585
+ if ! ok {
586
+ continue
587
+ }
575
588
nv := reflect .New (oop .Type .Elem ())
576
589
target .Field (oop .Field ).Set (nv )
577
590
if err := unmarshalValue (nv .Elem ().Field (0 ), raw ); err != nil {
578
591
return err
579
592
}
580
- delete (jsonFields , fname )
581
593
}
582
594
}
583
595
if len (jsonFields ) > 0 {
@@ -663,9 +675,7 @@ type fieldNames struct {
663
675
orig , camel string
664
676
}
665
677
666
- func acceptedJSONFieldNames (f reflect.StructField ) fieldNames {
667
- var prop proto.Properties
668
- prop .Init (f .Type , f .Name , f .Tag .Get ("protobuf" ), & f )
678
+ func acceptedJSONFieldNames (prop * proto.Properties ) fieldNames {
669
679
opts := fieldNames {orig : prop .OrigName , camel : prop .OrigName }
670
680
if prop .JSONName != "" {
671
681
opts .camel = prop .JSONName
0 commit comments