From 05be61fde35dcaa3502f4430edee444a294d41c3 Mon Sep 17 00:00:00 2001 From: Damien Neil Date: Tue, 3 Aug 2021 11:02:15 -0700 Subject: [PATCH] reflect/protoreflect: add more docs on Value aliasing Fixes golang/protobuf#1346 Change-Id: I9deb36e1c5e4f28c1c7e99ca64260c7a86af4ea1 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/339569 Trust: Damien Neil Trust: Joe Tsai Run-TryBot: Damien Neil Reviewed-by: Joe Tsai --- reflect/protoreflect/value_union.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/reflect/protoreflect/value_union.go b/reflect/protoreflect/value_union.go index 5a3414724..eb7764c30 100644 --- a/reflect/protoreflect/value_union.go +++ b/reflect/protoreflect/value_union.go @@ -41,6 +41,31 @@ import ( // Converting to/from a Value and a concrete Go value panics on type mismatch. // For example, ValueOf("hello").Int() panics because this attempts to // retrieve an int64 from a string. +// +// List, Map, and Message Values are called "composite" values. +// +// A composite Value may alias (reference) memory at some location, +// such that changes to the Value updates the that location. +// A composite value acquired with a Mutable method, such as Message.Mutable, +// always references the source object. +// +// For example: +// // Append a 0 to a "repeated int32" field. +// // Since the Value returned by Mutable is guaranteed to alias +// // the source message, modifying the Value modifies the message. +// message.Mutable(fieldDesc).(List).Append(protoreflect.ValueOfInt32(0)) +// +// // Assign [0] to a "repeated int32" field by creating a new Value, +// // modifying it, and assigning it. +// list := message.NewField(fieldDesc).(List) +// list.Append(protoreflect.ValueOfInt32(0)) +// message.Set(fieldDesc, list) +// // ERROR: Since it is not defined whether Set aliases the source, +// // appending to the List here may or may not modify the message. +// list.Append(protoreflect.ValueOfInt32(0)) +// +// Some operations, such as Message.Get, may return an "empty, read-only" +// composite Value. Modifying an empty, read-only value panics. type Value value // The protoreflect API uses a custom Value union type instead of interface{}