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