unmarshalMessage unmarshals a message into the given protoreflect.Message.
(m protoreflect.Message, skipTypeURL bool)
| 122 | |
| 123 | // unmarshalMessage unmarshals a message into the given protoreflect.Message. |
| 124 | func (d decoder) unmarshalMessage(m protoreflect.Message, skipTypeURL bool) error { |
| 125 | d.opts.RecursionLimit-- |
| 126 | if d.opts.RecursionLimit < 0 { |
| 127 | return errors.New("exceeded max recursion depth") |
| 128 | } |
| 129 | if unmarshal := wellKnownTypeUnmarshaler(m.Descriptor().FullName()); unmarshal != nil { |
| 130 | return unmarshal(d, m) |
| 131 | } |
| 132 | |
| 133 | tok, err := d.Read() |
| 134 | if err != nil { |
| 135 | return err |
| 136 | } |
| 137 | if tok.Kind() != json.ObjectOpen { |
| 138 | return d.unexpectedTokenError(tok) |
| 139 | } |
| 140 | |
| 141 | messageDesc := m.Descriptor() |
| 142 | if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { |
| 143 | return errors.New("no support for proto1 MessageSets") |
| 144 | } |
| 145 | |
| 146 | var seenNums set.Ints |
| 147 | var seenOneofs set.Ints |
| 148 | fieldDescs := messageDesc.Fields() |
| 149 | for { |
| 150 | // Read field name. |
| 151 | tok, err := d.Read() |
| 152 | if err != nil { |
| 153 | return err |
| 154 | } |
| 155 | switch tok.Kind() { |
| 156 | default: |
| 157 | return d.unexpectedTokenError(tok) |
| 158 | case json.ObjectClose: |
| 159 | return nil |
| 160 | case json.Name: |
| 161 | // Continue below. |
| 162 | } |
| 163 | |
| 164 | name := tok.Name() |
| 165 | // Unmarshaling a non-custom embedded message in Any will contain the |
| 166 | // JSON field "@type" which should be skipped because it is not a field |
| 167 | // of the embedded message, but simply an artifact of the Any format. |
| 168 | if skipTypeURL && name == "@type" { |
| 169 | d.Read() |
| 170 | continue |
| 171 | } |
| 172 | |
| 173 | // Get the FieldDescriptor. |
| 174 | var fd protoreflect.FieldDescriptor |
| 175 | if strings.HasPrefix(name, "[") && strings.HasSuffix(name, "]") { |
| 176 | // Only extension names are in [name] format. |
| 177 | extName := protoreflect.FullName(name[1 : len(name)-1]) |
| 178 | extType, err := d.opts.Resolver.FindExtensionByName(extName) |
| 179 | if err != nil && err != protoregistry.NotFound { |
| 180 | return d.newError(tok.Pos(), "unable to resolve %s: %v", tok.RawString(), err) |
| 181 | } |
no test coverage detected