MCPcopy
hub / github.com/golang/protobuf / UnmarshalNext

Method UnmarshalNext

jsonpb/decode.go:73–133  ·  view source on GitHub ↗

UnmarshalNext unmarshals the next JSON object from d into m.

(d *json.Decoder, m proto.Message)

Source from the content-addressed store, hash-verified

71
72// UnmarshalNext unmarshals the next JSON object from d into m.
73func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error {
74 if m == nil {
75 return errors.New("invalid nil message")
76 }
77
78 // Parse the next JSON object from the stream.
79 raw := json.RawMessage{}
80 if err := d.Decode(&raw); err != nil {
81 return err
82 }
83
84 // Check for custom unmarshalers first since they may not properly
85 // implement protobuf reflection that the logic below relies on.
86 if jsu, ok := m.(JSONPBUnmarshaler); ok {
87 return jsu.UnmarshalJSONPB(u, raw)
88 }
89
90 mr := proto.MessageReflect(m)
91
92 // NOTE: For historical reasons, a top-level null is treated as a noop.
93 // This is incorrect, but kept for compatibility.
94 if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" {
95 return nil
96 }
97
98 if wrapJSONUnmarshalV2 {
99 // NOTE: If input message is non-empty, we need to preserve merge semantics
100 // of the old jsonpb implementation. These semantics are not supported by
101 // the protobuf JSON specification.
102 isEmpty := true
103 mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool {
104 isEmpty = false // at least one iteration implies non-empty
105 return false
106 })
107 if !isEmpty {
108 // Perform unmarshaling into a newly allocated, empty message.
109 mr = mr.New()
110
111 // Use a defer to copy all unmarshaled fields into the original message.
112 dst := proto.MessageReflect(m)
113 defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
114 dst.Set(fd, v)
115 return true
116 })
117 }
118
119 // Unmarshal using the v2 JSON unmarshaler.
120 opts := protojson.UnmarshalOptions{
121 DiscardUnknown: u.AllowUnknownFields,
122 }
123 if u.AnyResolver != nil {
124 opts.Resolver = anyResolver{u.AnyResolver}
125 }
126 return opts.Unmarshal(raw, mr.Interface())
127 } else {
128 if err := u.unmarshalMessage(mr, raw); err != nil {
129 return err
130 }

Callers 3

UnmarshalMethod · 0.95
TestUnmarshalNextFunction · 0.80
UnmarshalNextFunction · 0.80

Implementers 3

Bufferproto/buffer.go
InternalMessageInfoproto/deprecated.go
Unmarshalerjsonpb/decode.go

Calls 6

unmarshalMessageMethod · 0.95
InterfaceMethod · 0.80
UnmarshalJSONPBMethod · 0.65
DescriptorMethod · 0.65
UnmarshalMethod · 0.65
NewMethod · 0.45

Tested by 1

TestUnmarshalNextFunction · 0.64