39 // A field is a Map if FieldDescriptor.IsMap reports true. |
39 // A field is a Map if FieldDescriptor.IsMap reports true. |
40 // |
40 // |
41 // Converting to/from a Value and a concrete Go value panics on type mismatch. |
41 // Converting to/from a Value and a concrete Go value panics on type mismatch. |
42 // For example, ValueOf("hello").Int() panics because this attempts to |
42 // For example, ValueOf("hello").Int() panics because this attempts to |
43 // retrieve an int64 from a string. |
43 // retrieve an int64 from a string. |
|
44 // |
|
45 // List, Map, and Message Values are called "composite" values. |
|
46 // |
|
47 // A composite Value may alias (reference) memory at some location, |
|
48 // such that changes to the Value updates the that location. |
|
49 // A composite value acquired with a Mutable method, such as Message.Mutable, |
|
50 // always references the source object. |
|
51 // |
|
52 // For example: |
|
53 // |
|
54 // // Append a 0 to a "repeated int32" field. |
|
55 // // Since the Value returned by Mutable is guaranteed to alias |
|
56 // // the source message, modifying the Value modifies the message. |
|
57 // message.Mutable(fieldDesc).(List).Append(protoreflect.ValueOfInt32(0)) |
|
58 // |
|
59 // // Assign [0] to a "repeated int32" field by creating a new Value, |
|
60 // // modifying it, and assigning it. |
|
61 // list := message.NewField(fieldDesc).(List) |
|
62 // list.Append(protoreflect.ValueOfInt32(0)) |
|
63 // message.Set(fieldDesc, list) |
|
64 // // ERROR: Since it is not defined whether Set aliases the source, |
|
65 // // appending to the List here may or may not modify the message. |
|
66 // list.Append(protoreflect.ValueOfInt32(0)) |
|
67 // |
|
68 // Some operations, such as Message.Get, may return an "empty, read-only" |
|
69 // composite Value. Modifying an empty, read-only value panics. |
44 type Value value |
70 type Value value |
45 |
71 |
46 // The protoreflect API uses a custom Value union type instead of interface{} |
72 // The protoreflect API uses a custom Value union type instead of interface{} |
47 // to keep the future open for performance optimizations. Using an interface{} |
73 // to keep the future open for performance optimizations. Using an interface{} |
48 // always incurs an allocation for primitives (e.g., int64) since it needs to |
74 // always incurs an allocation for primitives (e.g., int64) since it needs to |
365 // ║ uint64 │ Uint64Kind, Fixed64Kind ║ |
391 // ║ uint64 │ Uint64Kind, Fixed64Kind ║ |
366 // ║ string │ StringKind ║ |
392 // ║ string │ StringKind ║ |
367 // ╚═════════╧═════════════════════════════════════╝ |
393 // ╚═════════╧═════════════════════════════════════╝ |
368 // |
394 // |
369 // A MapKey is constructed and accessed through a Value: |
395 // A MapKey is constructed and accessed through a Value: |
|
396 // |
370 // k := ValueOf("hash").MapKey() // convert string to MapKey |
397 // k := ValueOf("hash").MapKey() // convert string to MapKey |
371 // s := k.String() // convert MapKey to string |
398 // s := k.String() // convert MapKey to string |
372 // |
399 // |
373 // The MapKey is a strict subset of valid types used in Value; |
400 // The MapKey is a strict subset of valid types used in Value; |
374 // converting a Value to a MapKey with an invalid type panics. |
401 // converting a Value to a MapKey with an invalid type panics. |