blob: 1d38161031f5be0ac0804c810d9a0f99968e2899 [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001package dynamic
2
3import (
4 "fmt"
5
6 "github.com/golang/protobuf/proto"
7
Scott Baker4a35a702019-11-26 08:17:33 -08008 "github.com/jhump/protoreflect/codec"
Zack Williamse940c7a2019-08-21 14:25:39 -07009 "github.com/jhump/protoreflect/desc"
10)
11
12// SetExtension sets the given extension value. If the given message is not a
13// dynamic message, the given extension may not be recognized (or may differ
14// from the compiled and linked in version of the extension. So in that case,
15// this function will serialize the given value to bytes and then use
16// proto.SetRawExtension to set the value.
17func SetExtension(msg proto.Message, extd *desc.FieldDescriptor, val interface{}) error {
18 if !extd.IsExtension() {
19 return fmt.Errorf("given field %s is not an extension", extd.GetFullyQualifiedName())
20 }
21
22 if dm, ok := msg.(*Message); ok {
23 return dm.TrySetField(extd, val)
24 }
25
26 md, err := desc.LoadMessageDescriptorForMessage(msg)
27 if err != nil {
28 return err
29 }
30 if err := checkField(extd, md); err != nil {
31 return err
32 }
33
34 val, err = validFieldValue(extd, val)
35 if err != nil {
36 return err
37 }
38
Scott Baker4a35a702019-11-26 08:17:33 -080039 var b codec.Buffer
40 b.SetDeterministic(defaultDeterminism)
41 if err := b.EncodeFieldValue(extd, val); err != nil {
Zack Williamse940c7a2019-08-21 14:25:39 -070042 return err
43 }
Scott Baker4a35a702019-11-26 08:17:33 -080044 proto.SetRawExtension(msg, extd.GetNumber(), b.Bytes())
Zack Williamse940c7a2019-08-21 14:25:39 -070045 return nil
46}