blob: c5863311b616ce6b8c2ca0c2ec2e144a5ed03775 [file] [log] [blame]
Herbie Ong800c9902018-12-06 15:28:53 -08001// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package textpb
6
7import (
8 "fmt"
Herbie Ong0dcfb9a2019-01-14 15:32:26 -08009 "strings"
Herbie Ong21a39742019-04-08 17:32:44 -070010 "unicode/utf8"
Herbie Ong800c9902018-12-06 15:28:53 -080011
12 "github.com/golang/protobuf/v2/internal/encoding/text"
13 "github.com/golang/protobuf/v2/internal/errors"
Herbie Onge1e34932019-03-29 01:05:57 -070014 "github.com/golang/protobuf/v2/internal/fieldnum"
Herbie Ong800c9902018-12-06 15:28:53 -080015 "github.com/golang/protobuf/v2/internal/pragma"
16 "github.com/golang/protobuf/v2/internal/set"
17 "github.com/golang/protobuf/v2/proto"
18 pref "github.com/golang/protobuf/v2/reflect/protoreflect"
Herbie Ongc525c972018-12-18 18:04:31 -080019 "github.com/golang/protobuf/v2/reflect/protoregistry"
Herbie Ong800c9902018-12-06 15:28:53 -080020)
21
22// Unmarshal reads the given []byte into the given proto.Message.
Herbie Ong800c9902018-12-06 15:28:53 -080023func Unmarshal(m proto.Message, b []byte) error {
24 return UnmarshalOptions{}.Unmarshal(m, b)
25}
26
Herbie Ong42577ea2019-03-26 16:26:22 -070027// UnmarshalOptions is a configurable textproto format unmarshaler.
Herbie Ong800c9902018-12-06 15:28:53 -080028type UnmarshalOptions struct {
29 pragma.NoUnkeyedLiterals
Herbie Ongc525c972018-12-18 18:04:31 -080030
Herbie Ong42577ea2019-03-26 16:26:22 -070031 // AllowPartial accepts input for messages that will result in missing
32 // required fields. If AllowPartial is false (the default), Unmarshal will
33 // return error if there are any missing required fields.
34 AllowPartial bool
35
Herbie Ongc525c972018-12-18 18:04:31 -080036 // Resolver is the registry used for type lookups when unmarshaling extensions
37 // and processing Any. If Resolver is not set, unmarshaling will default to
38 // using protoregistry.GlobalTypes.
39 Resolver *protoregistry.Types
Herbie Ong800c9902018-12-06 15:28:53 -080040}
41
42// Unmarshal reads the given []byte and populates the given proto.Message using options in
43// UnmarshalOptions object.
44func (o UnmarshalOptions) Unmarshal(m proto.Message, b []byte) error {
45 var nerr errors.NonFatal
46
47 mr := m.ProtoReflect()
48 // Clear all fields before populating it.
49 // TODO: Determine if this needs to be consistent with jsonpb and binary unmarshal where
50 // behavior is to merge values into existing message. If decision is to not clear the fields
51 // ahead, code will need to be updated properly when merging nested messages.
52 resetMessage(mr)
53
54 // Parse into text.Value of message type.
55 val, err := text.Unmarshal(b)
56 if !nerr.Merge(err) {
57 return err
58 }
59
Herbie Ongc525c972018-12-18 18:04:31 -080060 if o.Resolver == nil {
61 o.Resolver = protoregistry.GlobalTypes
62 }
Herbie Ong800c9902018-12-06 15:28:53 -080063 err = o.unmarshalMessage(val.Message(), mr)
64 if !nerr.Merge(err) {
65 return err
66 }
67
Damien Neil4686e232019-04-05 13:31:40 -070068 if !o.AllowPartial {
69 nerr.Merge(proto.IsInitialized(m))
70 }
71
Herbie Ong800c9902018-12-06 15:28:53 -080072 return nerr.E
73}
74
75// resetMessage clears all fields of given protoreflect.Message.
76// TODO: This should go into the proto package.
77func resetMessage(m pref.Message) {
78 knownFields := m.KnownFields()
79 knownFields.Range(func(num pref.FieldNumber, _ pref.Value) bool {
80 knownFields.Clear(num)
81 return true
82 })
83 unknownFields := m.UnknownFields()
84 unknownFields.Range(func(num pref.FieldNumber, _ pref.RawFields) bool {
85 unknownFields.Set(num, nil)
86 return true
87 })
Herbie Ong800c9902018-12-06 15:28:53 -080088 extTypes := knownFields.ExtensionTypes()
89 extTypes.Range(func(xt pref.ExtensionType) bool {
90 extTypes.Remove(xt)
91 return true
92 })
93}
94
95// unmarshalMessage unmarshals a [][2]text.Value message into the given protoreflect.Message.
96func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message) error {
97 var nerr errors.NonFatal
98
Joe Tsai0fc49f82019-05-01 12:29:25 -070099 messageDesc := m.Descriptor()
Herbie Ong66c365c2019-01-04 14:08:41 -0800100 knownFields := m.KnownFields()
101
102 // Handle expanded Any message.
Joe Tsai0fc49f82019-05-01 12:29:25 -0700103 if messageDesc.FullName() == "google.protobuf.Any" && isExpandedAny(tmsg) {
Herbie Ong66c365c2019-01-04 14:08:41 -0800104 return o.unmarshalAny(tmsg[0], knownFields)
105 }
106
Joe Tsai0fc49f82019-05-01 12:29:25 -0700107 fieldDescs := messageDesc.Fields()
108 reservedNames := messageDesc.ReservedNames()
Herbie Ongc525c972018-12-18 18:04:31 -0800109 xtTypes := knownFields.ExtensionTypes()
Herbie Ong800c9902018-12-06 15:28:53 -0800110 var seenNums set.Ints
Herbie Ong8a1d4602019-04-02 20:19:36 -0700111 var seenOneofs set.Ints
Herbie Ong800c9902018-12-06 15:28:53 -0800112
113 for _, tfield := range tmsg {
114 tkey := tfield[0]
115 tval := tfield[1]
116
117 var fd pref.FieldDescriptor
Herbie Ongc525c972018-12-18 18:04:31 -0800118 var name pref.Name
119 switch tkey.Type() {
120 case text.Name:
121 name, _ = tkey.Name()
Herbie Ong800c9902018-12-06 15:28:53 -0800122 fd = fieldDescs.ByName(name)
Herbie Ong0dcfb9a2019-01-14 15:32:26 -0800123 if fd == nil {
124 // Check if this is a group field.
125 fd = fieldDescs.ByName(pref.Name(strings.ToLower(string(name))))
126 }
Herbie Ongc525c972018-12-18 18:04:31 -0800127 case text.String:
Herbie Ong66c365c2019-01-04 14:08:41 -0800128 // Handle extensions only. This code path is not for Any.
Joe Tsai0fc49f82019-05-01 12:29:25 -0700129 if messageDesc.FullName() == "google.protobuf.Any" {
Herbie Ong66c365c2019-01-04 14:08:41 -0800130 break
131 }
132 // Extensions have to be registered first in the message's
Herbie Ongc525c972018-12-18 18:04:31 -0800133 // ExtensionTypes before setting a value to it.
134 xtName := pref.FullName(tkey.String())
Herbie Ong66c365c2019-01-04 14:08:41 -0800135 // Check first if it is already registered. This is the case for
136 // repeated fields.
Herbie Ongc525c972018-12-18 18:04:31 -0800137 xt := xtTypes.ByName(xtName)
138 if xt == nil {
139 var err error
Herbie Ong6470ea62019-01-07 18:56:57 -0800140 xt, err = o.findExtension(xtName)
Herbie Ongc525c972018-12-18 18:04:31 -0800141 if err != nil && err != protoregistry.NotFound {
Herbie Ong66c365c2019-01-04 14:08:41 -0800142 return errors.New("unable to resolve [%v]: %v", xtName, err)
Herbie Ongc525c972018-12-18 18:04:31 -0800143 }
144 if xt != nil {
145 xtTypes.Register(xt)
146 }
147 }
Joe Tsai0fc49f82019-05-01 12:29:25 -0700148 if xt != nil {
149 fd = xt.Descriptor()
150 }
Herbie Ong800c9902018-12-06 15:28:53 -0800151 }
Herbie Ongc525c972018-12-18 18:04:31 -0800152
Herbie Ong800c9902018-12-06 15:28:53 -0800153 if fd == nil {
Herbie Ong7c624e22018-12-13 14:41:22 -0800154 // Ignore reserved names.
155 if reservedNames.Has(name) {
156 continue
157 }
Herbie Ong800c9902018-12-06 15:28:53 -0800158 // TODO: Can provide option to ignore unknown message fields.
Joe Tsai0fc49f82019-05-01 12:29:25 -0700159 return errors.New("%v contains unknown field: %v", messageDesc.FullName(), tkey)
Herbie Ong800c9902018-12-06 15:28:53 -0800160 }
161
Joe Tsaiac31a352019-05-13 14:32:56 -0700162 switch {
163 case fd.IsList():
164 // If input is not a list, turn it into a list.
165 var items []text.Value
166 if tval.Type() != text.List {
167 items = []text.Value{tval}
168 } else {
169 items = tval.List()
170 }
171
172 list := knownFields.Get(fd.Number()).List()
173 if err := o.unmarshalList(items, fd, list); !nerr.Merge(err) {
Herbie Ong800c9902018-12-06 15:28:53 -0800174 return err
175 }
Joe Tsaiac31a352019-05-13 14:32:56 -0700176 case fd.IsMap():
177 // If input is not a list, turn it into a list.
178 var items []text.Value
179 if tval.Type() != text.List {
180 items = []text.Value{tval}
181 } else {
182 items = tval.List()
183 }
184
185 mmap := knownFields.Get(fd.Number()).Map()
186 if err := o.unmarshalMap(items, fd, mmap); !nerr.Merge(err) {
187 return err
188 }
189 default:
Herbie Ong8a1d4602019-04-02 20:19:36 -0700190 // If field is a oneof, check if it has already been set.
Joe Tsaiac31a352019-05-13 14:32:56 -0700191 if od := fd.ContainingOneof(); od != nil {
Herbie Ong8a1d4602019-04-02 20:19:36 -0700192 idx := uint64(od.Index())
193 if seenOneofs.Has(idx) {
194 return errors.New("oneof %v is already set", od.FullName())
195 }
196 seenOneofs.Set(idx)
197 }
198
Herbie Ong800c9902018-12-06 15:28:53 -0800199 // Required or optional fields.
200 num := uint64(fd.Number())
201 if seenNums.Has(num) {
202 return errors.New("non-repeated field %v is repeated", fd.FullName())
203 }
204 if err := o.unmarshalSingular(tval, fd, knownFields); !nerr.Merge(err) {
205 return err
206 }
Herbie Ong800c9902018-12-06 15:28:53 -0800207 seenNums.Set(num)
208 }
209 }
210
Herbie Ong800c9902018-12-06 15:28:53 -0800211 return nerr.E
212}
213
Herbie Ong6470ea62019-01-07 18:56:57 -0800214// findExtension returns protoreflect.ExtensionType from the Resolver if found.
215func (o UnmarshalOptions) findExtension(xtName pref.FullName) (pref.ExtensionType, error) {
216 xt, err := o.Resolver.FindExtensionByName(xtName)
217 if err == nil {
218 return xt, nil
219 }
220
221 // Check if this is a MessageSet extension field.
222 xt, err = o.Resolver.FindExtensionByName(xtName + ".message_set_extension")
223 if err == nil && isMessageSetExtension(xt) {
224 return xt, nil
225 }
226 return nil, protoregistry.NotFound
227}
228
Herbie Ong800c9902018-12-06 15:28:53 -0800229// unmarshalSingular unmarshals given text.Value into the non-repeated field.
230func (o UnmarshalOptions) unmarshalSingular(input text.Value, fd pref.FieldDescriptor, knownFields pref.KnownFields) error {
231 num := fd.Number()
232
233 var nerr errors.NonFatal
234 var val pref.Value
235 switch fd.Kind() {
236 case pref.MessageKind, pref.GroupKind:
237 if input.Type() != text.Message {
238 return errors.New("%v contains invalid message/group value: %v", fd.FullName(), input)
239 }
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800240 m := knownFields.NewMessage(num)
Herbie Ong800c9902018-12-06 15:28:53 -0800241 if err := o.unmarshalMessage(input.Message(), m); !nerr.Merge(err) {
242 return err
243 }
244 val = pref.ValueOf(m)
245 default:
246 var err error
247 val, err = unmarshalScalar(input, fd)
248 if !nerr.Merge(err) {
249 return err
250 }
251 }
252 knownFields.Set(num, val)
253
254 return nerr.E
255}
256
Herbie Ong800c9902018-12-06 15:28:53 -0800257// unmarshalScalar converts the given text.Value to a scalar/enum protoreflect.Value specified in
258// the given FieldDescriptor. Caller should not pass in a FieldDescriptor for a message/group kind.
259func unmarshalScalar(input text.Value, fd pref.FieldDescriptor) (pref.Value, error) {
260 const b32 = false
261 const b64 = true
262
263 switch kind := fd.Kind(); kind {
264 case pref.BoolKind:
265 if b, ok := input.Bool(); ok {
266 return pref.ValueOf(bool(b)), nil
267 }
268 case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
269 if n, ok := input.Int(b32); ok {
270 return pref.ValueOf(int32(n)), nil
271 }
272 case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
273 if n, ok := input.Int(b64); ok {
274 return pref.ValueOf(int64(n)), nil
275 }
276 case pref.Uint32Kind, pref.Fixed32Kind:
277 if n, ok := input.Uint(b32); ok {
278 return pref.ValueOf(uint32(n)), nil
279 }
280 case pref.Uint64Kind, pref.Fixed64Kind:
281 if n, ok := input.Uint(b64); ok {
282 return pref.ValueOf(uint64(n)), nil
283 }
284 case pref.FloatKind:
Herbie Ong250c6ea2019-03-12 20:55:10 -0700285 if n, ok := input.Float(b32); ok {
Herbie Ong800c9902018-12-06 15:28:53 -0800286 return pref.ValueOf(float32(n)), nil
287 }
288 case pref.DoubleKind:
Herbie Ong250c6ea2019-03-12 20:55:10 -0700289 if n, ok := input.Float(b64); ok {
Herbie Ong800c9902018-12-06 15:28:53 -0800290 return pref.ValueOf(float64(n)), nil
291 }
292 case pref.StringKind:
293 if input.Type() == text.String {
Herbie Ong21a39742019-04-08 17:32:44 -0700294 s := input.String()
295 if utf8.ValidString(s) {
296 return pref.ValueOf(s), nil
297 }
298 var nerr errors.NonFatal
299 nerr.AppendInvalidUTF8(string(fd.FullName()))
300 return pref.ValueOf(s), nerr.E
Herbie Ong800c9902018-12-06 15:28:53 -0800301 }
302 case pref.BytesKind:
303 if input.Type() == text.String {
304 return pref.ValueOf([]byte(input.String())), nil
305 }
306 case pref.EnumKind:
307 // If input is int32, use directly.
308 if n, ok := input.Int(b32); ok {
309 return pref.ValueOf(pref.EnumNumber(n)), nil
Herbie Ong66c365c2019-01-04 14:08:41 -0800310 }
311 if name, ok := input.Name(); ok {
312 // Lookup EnumNumber based on name.
Joe Tsaid24bc722019-04-15 23:39:09 -0700313 if enumVal := fd.Enum().Values().ByName(name); enumVal != nil {
Herbie Ong66c365c2019-01-04 14:08:41 -0800314 return pref.ValueOf(enumVal.Number()), nil
Herbie Ong800c9902018-12-06 15:28:53 -0800315 }
316 }
317 default:
318 panic(fmt.Sprintf("invalid scalar kind %v", kind))
319 }
320
321 return pref.Value{}, errors.New("%v contains invalid scalar value: %v", fd.FullName(), input)
322}
323
324// unmarshalList unmarshals given []text.Value into given protoreflect.List.
325func (o UnmarshalOptions) unmarshalList(inputList []text.Value, fd pref.FieldDescriptor, list pref.List) error {
326 var nerr errors.NonFatal
327
328 switch fd.Kind() {
329 case pref.MessageKind, pref.GroupKind:
330 for _, input := range inputList {
331 if input.Type() != text.Message {
332 return errors.New("%v contains invalid message/group value: %v", fd.FullName(), input)
333 }
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800334 m := list.NewMessage()
Herbie Ong800c9902018-12-06 15:28:53 -0800335 if err := o.unmarshalMessage(input.Message(), m); !nerr.Merge(err) {
336 return err
337 }
338 list.Append(pref.ValueOf(m))
339 }
340 default:
341 for _, input := range inputList {
342 val, err := unmarshalScalar(input, fd)
343 if !nerr.Merge(err) {
344 return err
345 }
346 list.Append(val)
347 }
348 }
349
350 return nerr.E
351}
352
353// unmarshalMap unmarshals given []text.Value into given protoreflect.Map.
354func (o UnmarshalOptions) unmarshalMap(input []text.Value, fd pref.FieldDescriptor, mmap pref.Map) error {
355 var nerr errors.NonFatal
Herbie Ong800c9902018-12-06 15:28:53 -0800356
357 // Determine ahead whether map entry is a scalar type or a message type in order to call the
358 // appropriate unmarshalMapValue func inside the for loop below.
Herbie Ong66c365c2019-01-04 14:08:41 -0800359 unmarshalMapValue := unmarshalMapScalarValue
Joe Tsaiac31a352019-05-13 14:32:56 -0700360 switch fd.MapValue().Kind() {
Herbie Ong800c9902018-12-06 15:28:53 -0800361 case pref.MessageKind, pref.GroupKind:
362 unmarshalMapValue = o.unmarshalMapMessageValue
363 }
364
365 for _, entry := range input {
366 if entry.Type() != text.Message {
367 return errors.New("%v contains invalid map entry: %v", fd.FullName(), entry)
368 }
369 tkey, tval, err := parseMapEntry(entry.Message(), fd.FullName())
370 if !nerr.Merge(err) {
371 return err
372 }
Joe Tsaiac31a352019-05-13 14:32:56 -0700373 pkey, err := unmarshalMapKey(tkey, fd.MapKey())
Herbie Ong800c9902018-12-06 15:28:53 -0800374 if !nerr.Merge(err) {
375 return err
376 }
Joe Tsaiac31a352019-05-13 14:32:56 -0700377 err = unmarshalMapValue(tval, pkey, fd.MapValue(), mmap)
Herbie Ong800c9902018-12-06 15:28:53 -0800378 if !nerr.Merge(err) {
379 return err
380 }
381 }
382
383 return nerr.E
384}
385
386// parseMapEntry parses [][2]text.Value for field names key and value, and return corresponding
387// field values. If there are duplicate field names, the value for the last field is returned. If
388// the field name does not exist, it will return the zero value of text.Value. It will return an
389// error if there are unknown field names.
390func parseMapEntry(mapEntry [][2]text.Value, name pref.FullName) (key text.Value, value text.Value, err error) {
391 for _, field := range mapEntry {
392 keyStr, ok := field[0].Name()
393 if ok {
394 switch keyStr {
395 case "key":
396 if key.Type() != 0 {
397 return key, value, errors.New("%v contains duplicate key field", name)
398 }
399 key = field[1]
400 case "value":
401 if value.Type() != 0 {
402 return key, value, errors.New("%v contains duplicate value field", name)
403 }
404 value = field[1]
405 default:
406 ok = false
407 }
408 }
409 if !ok {
410 // TODO: Do not return error if ignore unknown option is added and enabled.
411 return key, value, errors.New("%v contains unknown map entry name: %v", name, field[0])
412 }
413 }
414 return key, value, nil
415}
416
417// unmarshalMapKey converts given text.Value into a protoreflect.MapKey. A map key type is any
418// integral or string type.
419func unmarshalMapKey(input text.Value, fd pref.FieldDescriptor) (pref.MapKey, error) {
420 // If input is not set, use the zero value.
421 if input.Type() == 0 {
422 return fd.Default().MapKey(), nil
423 }
424
Herbie Ong21a39742019-04-08 17:32:44 -0700425 var nerr errors.NonFatal
Herbie Ong800c9902018-12-06 15:28:53 -0800426 val, err := unmarshalScalar(input, fd)
Herbie Ong21a39742019-04-08 17:32:44 -0700427 if !nerr.Merge(err) {
Herbie Ong800c9902018-12-06 15:28:53 -0800428 return pref.MapKey{}, errors.New("%v contains invalid key: %v", fd.FullName(), input)
429 }
Herbie Ong21a39742019-04-08 17:32:44 -0700430 return val.MapKey(), nerr.E
Herbie Ong800c9902018-12-06 15:28:53 -0800431}
432
433// unmarshalMapMessageValue unmarshals given message-type text.Value into a protoreflect.Map for
434// the given MapKey.
435func (o UnmarshalOptions) unmarshalMapMessageValue(input text.Value, pkey pref.MapKey, _ pref.FieldDescriptor, mmap pref.Map) error {
436 var nerr errors.NonFatal
437 var value [][2]text.Value
438 if input.Type() != 0 {
439 value = input.Message()
440 }
Joe Tsai3bc7d6f2019-01-09 02:57:13 -0800441 m := mmap.NewMessage()
Herbie Ong800c9902018-12-06 15:28:53 -0800442 if err := o.unmarshalMessage(value, m); !nerr.Merge(err) {
443 return err
444 }
445 mmap.Set(pkey, pref.ValueOf(m))
446 return nerr.E
447}
448
449// unmarshalMapScalarValue unmarshals given scalar-type text.Value into a protoreflect.Map
450// for the given MapKey.
Herbie Ong66c365c2019-01-04 14:08:41 -0800451func unmarshalMapScalarValue(input text.Value, pkey pref.MapKey, fd pref.FieldDescriptor, mmap pref.Map) error {
Herbie Ong21a39742019-04-08 17:32:44 -0700452 var nerr errors.NonFatal
Herbie Ong800c9902018-12-06 15:28:53 -0800453 var val pref.Value
454 if input.Type() == 0 {
455 val = fd.Default()
456 } else {
457 var err error
458 val, err = unmarshalScalar(input, fd)
Herbie Ong21a39742019-04-08 17:32:44 -0700459 if !nerr.Merge(err) {
Herbie Ong800c9902018-12-06 15:28:53 -0800460 return err
461 }
462 }
463 mmap.Set(pkey, val)
Herbie Ong21a39742019-04-08 17:32:44 -0700464 return nerr.E
Herbie Ong800c9902018-12-06 15:28:53 -0800465}
Herbie Ong66c365c2019-01-04 14:08:41 -0800466
467// isExpandedAny returns true if given [][2]text.Value may be an expanded Any that contains only one
468// field with key type of text.String type and value type of text.Message.
469func isExpandedAny(tmsg [][2]text.Value) bool {
470 if len(tmsg) != 1 {
471 return false
472 }
473
474 field := tmsg[0]
475 return field[0].Type() == text.String && field[1].Type() == text.Message
476}
477
478// unmarshalAny unmarshals an expanded Any textproto. This method assumes that the given
479// tfield has key type of text.String and value type of text.Message.
480func (o UnmarshalOptions) unmarshalAny(tfield [2]text.Value, knownFields pref.KnownFields) error {
481 var nerr errors.NonFatal
482
483 typeURL := tfield[0].String()
484 value := tfield[1].Message()
485
486 mt, err := o.Resolver.FindMessageByURL(typeURL)
487 if !nerr.Merge(err) {
488 return errors.New("unable to resolve message [%v]: %v", typeURL, err)
489 }
490 // Create new message for the embedded message type and unmarshal the
491 // value into it.
492 m := mt.New()
493 if err := o.unmarshalMessage(value, m); !nerr.Merge(err) {
494 return err
495 }
496 // Serialize the embedded message and assign the resulting bytes to the value field.
Herbie Ong9c100452019-05-06 18:45:33 -0700497 // TODO: If binary marshaling returns required not set error, need to
498 // return another required not set error that contains both the path to this
499 // field and the path inside the embedded message.
Damien Neil96c229a2019-04-03 12:17:24 -0700500 b, err := proto.MarshalOptions{
501 AllowPartial: o.AllowPartial,
502 Deterministic: true,
503 }.Marshal(m.Interface())
Herbie Ong66c365c2019-01-04 14:08:41 -0800504 if !nerr.Merge(err) {
505 return err
506 }
507
Herbie Onge1e34932019-03-29 01:05:57 -0700508 knownFields.Set(fieldnum.Any_TypeUrl, pref.ValueOf(typeURL))
509 knownFields.Set(fieldnum.Any_Value, pref.ValueOf(b))
Herbie Ong66c365c2019-01-04 14:08:41 -0800510
511 return nerr.E
512}