12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- // Copyright 2019 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package proto
- import (
- "google.golang.org/protobuf/reflect/protoreflect"
- )
- // DiscardUnknown recursively discards all unknown fields from this message
- // and all embedded messages.
- //
- // When unmarshaling a message with unrecognized fields, the tags and values
- // of such fields are preserved in the Message. This allows a later call to
- // marshal to be able to produce a message that continues to have those
- // unrecognized fields. To avoid this, DiscardUnknown is used to
- // explicitly clear the unknown fields after unmarshaling.
- func DiscardUnknown(m Message) {
- if m != nil {
- discardUnknown(MessageReflect(m))
- }
- }
- func discardUnknown(m protoreflect.Message) {
- m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool {
- switch {
- // Handle singular message.
- case fd.Cardinality() != protoreflect.Repeated:
- if fd.Message() != nil {
- discardUnknown(m.Get(fd).Message())
- }
- // Handle list of messages.
- case fd.IsList():
- if fd.Message() != nil {
- ls := m.Get(fd).List()
- for i := 0; i < ls.Len(); i++ {
- discardUnknown(ls.Get(i).Message())
- }
- }
- // Handle map of messages.
- case fd.IsMap():
- if fd.MapValue().Message() != nil {
- ms := m.Get(fd).Map()
- ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {
- discardUnknown(v.Message())
- return true
- })
- }
- }
- return true
- })
- // Discard unknown fields.
- if len(m.GetUnknown()) > 0 {
- m.SetUnknown(nil)
- }
- }
|