123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- // 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 (
- pref "google.golang.org/protobuf/reflect/protoreflect"
- "google.golang.org/protobuf/runtime/protoimpl"
- )
- // SetDefaults sets unset protocol buffer fields to their default values.
- // It only modifies fields that are both unset and have defined defaults.
- // It recursively sets default values in any non-nil sub-messages.
- // It does not descend into extension fields that are sub-messages.
- func SetDefaults(m Message) {
- setDefaults(protoimpl.X.MessageOf(m))
- }
- func setDefaults(m pref.Message) {
- fieldDescs := m.Descriptor().Fields()
- for i := 0; i < fieldDescs.Len(); i++ {
- fd := fieldDescs.Get(i)
- if !m.Has(fd) {
- if fd.HasDefault() {
- v := fd.Default()
- if fd.Kind() == pref.BytesKind {
- v = pref.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes
- }
- m.Set(fd, v)
- }
- continue
- }
- switch {
- // Handle singular message.
- case fd.Cardinality() != pref.Repeated:
- if k := fd.Kind(); k == pref.MessageKind || k == pref.GroupKind {
- setDefaults(m.Get(fd).Message())
- }
- // Handle list of messages.
- case !fd.IsMap():
- if k := fd.Kind(); k == pref.MessageKind || k == pref.GroupKind {
- ls := m.Get(fd).List()
- for i := 0; i < ls.Len(); i++ {
- setDefaults(ls.Get(i).Message())
- }
- }
- // Handle map of messages.
- default:
- k := fd.Message().Fields().ByNumber(2).Kind()
- if k == pref.MessageKind || k == pref.GroupKind {
- ms := m.Get(fd).Map()
- ms.Range(func(_ pref.MapKey, v pref.Value) bool {
- setDefaults(v.Message())
- return true
- })
- }
- }
- }
- // NOTE: Historically, this function has never set the defaults for
- // extension fields, nor recursively visited sub-messages of such fields.
- }
|