vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
     9 	"math"
     9 	"math"
    10 	"reflect"
    10 	"reflect"
    11 	"sync"
    11 	"sync"
    12 
    12 
    13 	"google.golang.org/protobuf/internal/flags"
    13 	"google.golang.org/protobuf/internal/flags"
    14 	pref "google.golang.org/protobuf/reflect/protoreflect"
    14 	"google.golang.org/protobuf/reflect/protoreflect"
    15 	preg "google.golang.org/protobuf/reflect/protoregistry"
    15 	"google.golang.org/protobuf/reflect/protoregistry"
    16 )
    16 )
    17 
    17 
    18 type fieldInfo struct {
    18 type fieldInfo struct {
    19 	fieldDesc pref.FieldDescriptor
    19 	fieldDesc protoreflect.FieldDescriptor
    20 
    20 
    21 	// These fields are used for protobuf reflection support.
    21 	// These fields are used for protobuf reflection support.
    22 	has        func(pointer) bool
    22 	has        func(pointer) bool
    23 	clear      func(pointer)
    23 	clear      func(pointer)
    24 	get        func(pointer) pref.Value
    24 	get        func(pointer) protoreflect.Value
    25 	set        func(pointer, pref.Value)
    25 	set        func(pointer, protoreflect.Value)
    26 	mutable    func(pointer) pref.Value
    26 	mutable    func(pointer) protoreflect.Value
    27 	newMessage func() pref.Message
    27 	newMessage func() protoreflect.Message
    28 	newField   func() pref.Value
    28 	newField   func() protoreflect.Value
    29 }
    29 }
    30 
    30 
    31 func fieldInfoForMissing(fd pref.FieldDescriptor) fieldInfo {
    31 func fieldInfoForMissing(fd protoreflect.FieldDescriptor) fieldInfo {
    32 	// This never occurs for generated message types.
    32 	// This never occurs for generated message types.
    33 	// It implies that a hand-crafted type has missing Go fields
    33 	// It implies that a hand-crafted type has missing Go fields
    34 	// for specific protobuf message fields.
    34 	// for specific protobuf message fields.
    35 	return fieldInfo{
    35 	return fieldInfo{
    36 		fieldDesc: fd,
    36 		fieldDesc: fd,
    38 			return false
    38 			return false
    39 		},
    39 		},
    40 		clear: func(p pointer) {
    40 		clear: func(p pointer) {
    41 			panic("missing Go struct field for " + string(fd.FullName()))
    41 			panic("missing Go struct field for " + string(fd.FullName()))
    42 		},
    42 		},
    43 		get: func(p pointer) pref.Value {
    43 		get: func(p pointer) protoreflect.Value {
    44 			return fd.Default()
    44 			return fd.Default()
    45 		},
    45 		},
    46 		set: func(p pointer, v pref.Value) {
    46 		set: func(p pointer, v protoreflect.Value) {
    47 			panic("missing Go struct field for " + string(fd.FullName()))
    47 			panic("missing Go struct field for " + string(fd.FullName()))
    48 		},
    48 		},
    49 		mutable: func(p pointer) pref.Value {
    49 		mutable: func(p pointer) protoreflect.Value {
    50 			panic("missing Go struct field for " + string(fd.FullName()))
    50 			panic("missing Go struct field for " + string(fd.FullName()))
    51 		},
    51 		},
    52 		newMessage: func() pref.Message {
    52 		newMessage: func() protoreflect.Message {
    53 			panic("missing Go struct field for " + string(fd.FullName()))
    53 			panic("missing Go struct field for " + string(fd.FullName()))
    54 		},
    54 		},
    55 		newField: func() pref.Value {
    55 		newField: func() protoreflect.Value {
    56 			if v := fd.Default(); v.IsValid() {
    56 			if v := fd.Default(); v.IsValid() {
    57 				return v
    57 				return v
    58 			}
    58 			}
    59 			panic("missing Go struct field for " + string(fd.FullName()))
    59 			panic("missing Go struct field for " + string(fd.FullName()))
    60 		},
    60 		},
    61 	}
    61 	}
    62 }
    62 }
    63 
    63 
    64 func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
    64 func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo {
    65 	ft := fs.Type
    65 	ft := fs.Type
    66 	if ft.Kind() != reflect.Interface {
    66 	if ft.Kind() != reflect.Interface {
    67 		panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft))
    67 		panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft))
    68 	}
    68 	}
    69 	if ot.Kind() != reflect.Struct {
    69 	if ot.Kind() != reflect.Struct {
   100 				// so that (*OneofWrapperType)(nil) gets cleared to nil.
   100 				// so that (*OneofWrapperType)(nil) gets cleared to nil.
   101 				return
   101 				return
   102 			}
   102 			}
   103 			rv.Set(reflect.Zero(rv.Type()))
   103 			rv.Set(reflect.Zero(rv.Type()))
   104 		},
   104 		},
   105 		get: func(p pointer) pref.Value {
   105 		get: func(p pointer) protoreflect.Value {
   106 			if p.IsNil() {
   106 			if p.IsNil() {
   107 				return conv.Zero()
   107 				return conv.Zero()
   108 			}
   108 			}
   109 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   109 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   110 			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
   110 			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
   111 				return conv.Zero()
   111 				return conv.Zero()
   112 			}
   112 			}
   113 			rv = rv.Elem().Elem().Field(0)
   113 			rv = rv.Elem().Elem().Field(0)
   114 			return conv.PBValueOf(rv)
   114 			return conv.PBValueOf(rv)
   115 		},
   115 		},
   116 		set: func(p pointer, v pref.Value) {
   116 		set: func(p pointer, v protoreflect.Value) {
   117 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   117 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   118 			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
   118 			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
   119 				rv.Set(reflect.New(ot))
   119 				rv.Set(reflect.New(ot))
   120 			}
   120 			}
   121 			rv = rv.Elem().Elem().Field(0)
   121 			rv = rv.Elem().Elem().Field(0)
   122 			rv.Set(conv.GoValueOf(v))
   122 			rv.Set(conv.GoValueOf(v))
   123 		},
   123 		},
   124 		mutable: func(p pointer) pref.Value {
   124 		mutable: func(p pointer) protoreflect.Value {
   125 			if !isMessage {
   125 			if !isMessage {
   126 				panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName()))
   126 				panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName()))
   127 			}
   127 			}
   128 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   128 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   129 			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
   129 			if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() {
   130 				rv.Set(reflect.New(ot))
   130 				rv.Set(reflect.New(ot))
   131 			}
   131 			}
   132 			rv = rv.Elem().Elem().Field(0)
   132 			rv = rv.Elem().Elem().Field(0)
   133 			if rv.Kind() == reflect.Ptr && rv.IsNil() {
   133 			if rv.Kind() == reflect.Ptr && rv.IsNil() {
   134 				rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message())))
   134 				rv.Set(conv.GoValueOf(protoreflect.ValueOfMessage(conv.New().Message())))
   135 			}
   135 			}
   136 			return conv.PBValueOf(rv)
   136 			return conv.PBValueOf(rv)
   137 		},
   137 		},
   138 		newMessage: func() pref.Message {
   138 		newMessage: func() protoreflect.Message {
   139 			return conv.New().Message()
   139 			return conv.New().Message()
   140 		},
   140 		},
   141 		newField: func() pref.Value {
   141 		newField: func() protoreflect.Value {
   142 			return conv.New()
   142 			return conv.New()
   143 		},
   143 		},
   144 	}
   144 	}
   145 }
   145 }
   146 
   146 
   147 func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   147 func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   148 	ft := fs.Type
   148 	ft := fs.Type
   149 	if ft.Kind() != reflect.Map {
   149 	if ft.Kind() != reflect.Map {
   150 		panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft))
   150 		panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft))
   151 	}
   151 	}
   152 	conv := NewConverter(ft, fd)
   152 	conv := NewConverter(ft, fd)
   164 		},
   164 		},
   165 		clear: func(p pointer) {
   165 		clear: func(p pointer) {
   166 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   166 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   167 			rv.Set(reflect.Zero(rv.Type()))
   167 			rv.Set(reflect.Zero(rv.Type()))
   168 		},
   168 		},
   169 		get: func(p pointer) pref.Value {
   169 		get: func(p pointer) protoreflect.Value {
   170 			if p.IsNil() {
   170 			if p.IsNil() {
   171 				return conv.Zero()
   171 				return conv.Zero()
   172 			}
   172 			}
   173 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   173 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   174 			if rv.Len() == 0 {
   174 			if rv.Len() == 0 {
   175 				return conv.Zero()
   175 				return conv.Zero()
   176 			}
   176 			}
   177 			return conv.PBValueOf(rv)
   177 			return conv.PBValueOf(rv)
   178 		},
   178 		},
   179 		set: func(p pointer, v pref.Value) {
   179 		set: func(p pointer, v protoreflect.Value) {
   180 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   180 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   181 			pv := conv.GoValueOf(v)
   181 			pv := conv.GoValueOf(v)
   182 			if pv.IsNil() {
   182 			if pv.IsNil() {
   183 				panic(fmt.Sprintf("map field %v cannot be set with read-only value", fd.FullName()))
   183 				panic(fmt.Sprintf("map field %v cannot be set with read-only value", fd.FullName()))
   184 			}
   184 			}
   185 			rv.Set(pv)
   185 			rv.Set(pv)
   186 		},
   186 		},
   187 		mutable: func(p pointer) pref.Value {
   187 		mutable: func(p pointer) protoreflect.Value {
   188 			v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   188 			v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   189 			if v.IsNil() {
   189 			if v.IsNil() {
   190 				v.Set(reflect.MakeMap(fs.Type))
   190 				v.Set(reflect.MakeMap(fs.Type))
   191 			}
   191 			}
   192 			return conv.PBValueOf(v)
   192 			return conv.PBValueOf(v)
   193 		},
   193 		},
   194 		newField: func() pref.Value {
   194 		newField: func() protoreflect.Value {
   195 			return conv.New()
   195 			return conv.New()
   196 		},
   196 		},
   197 	}
   197 	}
   198 }
   198 }
   199 
   199 
   200 func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   200 func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   201 	ft := fs.Type
   201 	ft := fs.Type
   202 	if ft.Kind() != reflect.Slice {
   202 	if ft.Kind() != reflect.Slice {
   203 		panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft))
   203 		panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft))
   204 	}
   204 	}
   205 	conv := NewConverter(reflect.PtrTo(ft), fd)
   205 	conv := NewConverter(reflect.PtrTo(ft), fd)
   217 		},
   217 		},
   218 		clear: func(p pointer) {
   218 		clear: func(p pointer) {
   219 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   219 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   220 			rv.Set(reflect.Zero(rv.Type()))
   220 			rv.Set(reflect.Zero(rv.Type()))
   221 		},
   221 		},
   222 		get: func(p pointer) pref.Value {
   222 		get: func(p pointer) protoreflect.Value {
   223 			if p.IsNil() {
   223 			if p.IsNil() {
   224 				return conv.Zero()
   224 				return conv.Zero()
   225 			}
   225 			}
   226 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type)
   226 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type)
   227 			if rv.Elem().Len() == 0 {
   227 			if rv.Elem().Len() == 0 {
   228 				return conv.Zero()
   228 				return conv.Zero()
   229 			}
   229 			}
   230 			return conv.PBValueOf(rv)
   230 			return conv.PBValueOf(rv)
   231 		},
   231 		},
   232 		set: func(p pointer, v pref.Value) {
   232 		set: func(p pointer, v protoreflect.Value) {
   233 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   233 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   234 			pv := conv.GoValueOf(v)
   234 			pv := conv.GoValueOf(v)
   235 			if pv.IsNil() {
   235 			if pv.IsNil() {
   236 				panic(fmt.Sprintf("list field %v cannot be set with read-only value", fd.FullName()))
   236 				panic(fmt.Sprintf("list field %v cannot be set with read-only value", fd.FullName()))
   237 			}
   237 			}
   238 			rv.Set(pv.Elem())
   238 			rv.Set(pv.Elem())
   239 		},
   239 		},
   240 		mutable: func(p pointer) pref.Value {
   240 		mutable: func(p pointer) protoreflect.Value {
   241 			v := p.Apply(fieldOffset).AsValueOf(fs.Type)
   241 			v := p.Apply(fieldOffset).AsValueOf(fs.Type)
   242 			return conv.PBValueOf(v)
   242 			return conv.PBValueOf(v)
   243 		},
   243 		},
   244 		newField: func() pref.Value {
   244 		newField: func() protoreflect.Value {
   245 			return conv.New()
   245 			return conv.New()
   246 		},
   246 		},
   247 	}
   247 	}
   248 }
   248 }
   249 
   249 
   250 var (
   250 var (
   251 	nilBytes   = reflect.ValueOf([]byte(nil))
   251 	nilBytes   = reflect.ValueOf([]byte(nil))
   252 	emptyBytes = reflect.ValueOf([]byte{})
   252 	emptyBytes = reflect.ValueOf([]byte{})
   253 )
   253 )
   254 
   254 
   255 func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   255 func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   256 	ft := fs.Type
   256 	ft := fs.Type
   257 	nullable := fd.HasPresence()
   257 	nullable := fd.HasPresence()
   258 	isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
   258 	isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8
   259 	if nullable {
   259 	if nullable {
   260 		if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
   260 		if ft.Kind() != reflect.Ptr && ft.Kind() != reflect.Slice {
   298 		},
   298 		},
   299 		clear: func(p pointer) {
   299 		clear: func(p pointer) {
   300 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   300 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   301 			rv.Set(reflect.Zero(rv.Type()))
   301 			rv.Set(reflect.Zero(rv.Type()))
   302 		},
   302 		},
   303 		get: func(p pointer) pref.Value {
   303 		get: func(p pointer) protoreflect.Value {
   304 			if p.IsNil() {
   304 			if p.IsNil() {
   305 				return conv.Zero()
   305 				return conv.Zero()
   306 			}
   306 			}
   307 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   307 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   308 			if nullable {
   308 			if nullable {
   313 					rv = rv.Elem()
   313 					rv = rv.Elem()
   314 				}
   314 				}
   315 			}
   315 			}
   316 			return conv.PBValueOf(rv)
   316 			return conv.PBValueOf(rv)
   317 		},
   317 		},
   318 		set: func(p pointer, v pref.Value) {
   318 		set: func(p pointer, v protoreflect.Value) {
   319 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   319 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   320 			if nullable && rv.Kind() == reflect.Ptr {
   320 			if nullable && rv.Kind() == reflect.Ptr {
   321 				if rv.IsNil() {
   321 				if rv.IsNil() {
   322 					rv.Set(reflect.New(ft))
   322 					rv.Set(reflect.New(ft))
   323 				}
   323 				}
   330 				} else {
   330 				} else {
   331 					rv.Set(nilBytes) // do not preserve presence
   331 					rv.Set(nilBytes) // do not preserve presence
   332 				}
   332 				}
   333 			}
   333 			}
   334 		},
   334 		},
   335 		newField: func() pref.Value {
   335 		newField: func() protoreflect.Value {
   336 			return conv.New()
   336 			return conv.New()
   337 		},
   337 		},
   338 	}
   338 	}
   339 }
   339 }
   340 
   340 
   341 func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo {
   341 func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo {
   342 	if !flags.ProtoLegacy {
   342 	if !flags.ProtoLegacy {
   343 		panic("no support for proto1 weak fields")
   343 		panic("no support for proto1 weak fields")
   344 	}
   344 	}
   345 
   345 
   346 	var once sync.Once
   346 	var once sync.Once
   347 	var messageType pref.MessageType
   347 	var messageType protoreflect.MessageType
   348 	lazyInit := func() {
   348 	lazyInit := func() {
   349 		once.Do(func() {
   349 		once.Do(func() {
   350 			messageName := fd.Message().FullName()
   350 			messageName := fd.Message().FullName()
   351 			messageType, _ = preg.GlobalTypes.FindMessageByName(messageName)
   351 			messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName)
   352 			if messageType == nil {
   352 			if messageType == nil {
   353 				panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName()))
   353 				panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName()))
   354 			}
   354 			}
   355 		})
   355 		})
   356 	}
   356 	}
   366 			return ok
   366 			return ok
   367 		},
   367 		},
   368 		clear: func(p pointer) {
   368 		clear: func(p pointer) {
   369 			p.Apply(weakOffset).WeakFields().clear(num)
   369 			p.Apply(weakOffset).WeakFields().clear(num)
   370 		},
   370 		},
   371 		get: func(p pointer) pref.Value {
   371 		get: func(p pointer) protoreflect.Value {
   372 			lazyInit()
   372 			lazyInit()
   373 			if p.IsNil() {
   373 			if p.IsNil() {
   374 				return pref.ValueOfMessage(messageType.Zero())
   374 				return protoreflect.ValueOfMessage(messageType.Zero())
   375 			}
   375 			}
   376 			m, ok := p.Apply(weakOffset).WeakFields().get(num)
   376 			m, ok := p.Apply(weakOffset).WeakFields().get(num)
   377 			if !ok {
   377 			if !ok {
   378 				return pref.ValueOfMessage(messageType.Zero())
   378 				return protoreflect.ValueOfMessage(messageType.Zero())
   379 			}
   379 			}
   380 			return pref.ValueOfMessage(m.ProtoReflect())
   380 			return protoreflect.ValueOfMessage(m.ProtoReflect())
   381 		},
   381 		},
   382 		set: func(p pointer, v pref.Value) {
   382 		set: func(p pointer, v protoreflect.Value) {
   383 			lazyInit()
   383 			lazyInit()
   384 			m := v.Message()
   384 			m := v.Message()
   385 			if m.Descriptor() != messageType.Descriptor() {
   385 			if m.Descriptor() != messageType.Descriptor() {
   386 				if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want {
   386 				if got, want := m.Descriptor().FullName(), messageType.Descriptor().FullName(); got != want {
   387 					panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want))
   387 					panic(fmt.Sprintf("field %v has mismatching message descriptor: got %v, want %v", fd.FullName(), got, want))
   388 				}
   388 				}
   389 				panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName()))
   389 				panic(fmt.Sprintf("field %v has mismatching message descriptor: %v", fd.FullName(), m.Descriptor().FullName()))
   390 			}
   390 			}
   391 			p.Apply(weakOffset).WeakFields().set(num, m.Interface())
   391 			p.Apply(weakOffset).WeakFields().set(num, m.Interface())
   392 		},
   392 		},
   393 		mutable: func(p pointer) pref.Value {
   393 		mutable: func(p pointer) protoreflect.Value {
   394 			lazyInit()
   394 			lazyInit()
   395 			fs := p.Apply(weakOffset).WeakFields()
   395 			fs := p.Apply(weakOffset).WeakFields()
   396 			m, ok := fs.get(num)
   396 			m, ok := fs.get(num)
   397 			if !ok {
   397 			if !ok {
   398 				m = messageType.New().Interface()
   398 				m = messageType.New().Interface()
   399 				fs.set(num, m)
   399 				fs.set(num, m)
   400 			}
   400 			}
   401 			return pref.ValueOfMessage(m.ProtoReflect())
   401 			return protoreflect.ValueOfMessage(m.ProtoReflect())
   402 		},
   402 		},
   403 		newMessage: func() pref.Message {
   403 		newMessage: func() protoreflect.Message {
   404 			lazyInit()
   404 			lazyInit()
   405 			return messageType.New()
   405 			return messageType.New()
   406 		},
   406 		},
   407 		newField: func() pref.Value {
   407 		newField: func() protoreflect.Value {
   408 			lazyInit()
   408 			lazyInit()
   409 			return pref.ValueOfMessage(messageType.New())
   409 			return protoreflect.ValueOfMessage(messageType.New())
   410 		},
   410 		},
   411 	}
   411 	}
   412 }
   412 }
   413 
   413 
   414 func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   414 func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo {
   415 	ft := fs.Type
   415 	ft := fs.Type
   416 	conv := NewConverter(ft, fd)
   416 	conv := NewConverter(ft, fd)
   417 
   417 
   418 	// TODO: Implement unsafe fast path?
   418 	// TODO: Implement unsafe fast path?
   419 	fieldOffset := offsetOf(fs, x)
   419 	fieldOffset := offsetOf(fs, x)
   431 		},
   431 		},
   432 		clear: func(p pointer) {
   432 		clear: func(p pointer) {
   433 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   433 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   434 			rv.Set(reflect.Zero(rv.Type()))
   434 			rv.Set(reflect.Zero(rv.Type()))
   435 		},
   435 		},
   436 		get: func(p pointer) pref.Value {
   436 		get: func(p pointer) protoreflect.Value {
   437 			if p.IsNil() {
   437 			if p.IsNil() {
   438 				return conv.Zero()
   438 				return conv.Zero()
   439 			}
   439 			}
   440 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   440 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   441 			return conv.PBValueOf(rv)
   441 			return conv.PBValueOf(rv)
   442 		},
   442 		},
   443 		set: func(p pointer, v pref.Value) {
   443 		set: func(p pointer, v protoreflect.Value) {
   444 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   444 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   445 			rv.Set(conv.GoValueOf(v))
   445 			rv.Set(conv.GoValueOf(v))
   446 			if fs.Type.Kind() == reflect.Ptr && rv.IsNil() {
   446 			if fs.Type.Kind() == reflect.Ptr && rv.IsNil() {
   447 				panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName()))
   447 				panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName()))
   448 			}
   448 			}
   449 		},
   449 		},
   450 		mutable: func(p pointer) pref.Value {
   450 		mutable: func(p pointer) protoreflect.Value {
   451 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   451 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   452 			if fs.Type.Kind() == reflect.Ptr && rv.IsNil() {
   452 			if fs.Type.Kind() == reflect.Ptr && rv.IsNil() {
   453 				rv.Set(conv.GoValueOf(conv.New()))
   453 				rv.Set(conv.GoValueOf(conv.New()))
   454 			}
   454 			}
   455 			return conv.PBValueOf(rv)
   455 			return conv.PBValueOf(rv)
   456 		},
   456 		},
   457 		newMessage: func() pref.Message {
   457 		newMessage: func() protoreflect.Message {
   458 			return conv.New().Message()
   458 			return conv.New().Message()
   459 		},
   459 		},
   460 		newField: func() pref.Value {
   460 		newField: func() protoreflect.Value {
   461 			return conv.New()
   461 			return conv.New()
   462 		},
   462 		},
   463 	}
   463 	}
   464 }
   464 }
   465 
   465 
   466 type oneofInfo struct {
   466 type oneofInfo struct {
   467 	oneofDesc pref.OneofDescriptor
   467 	oneofDesc protoreflect.OneofDescriptor
   468 	which     func(pointer) pref.FieldNumber
   468 	which     func(pointer) protoreflect.FieldNumber
   469 }
   469 }
   470 
   470 
   471 func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
   471 func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo {
   472 	oi := &oneofInfo{oneofDesc: od}
   472 	oi := &oneofInfo{oneofDesc: od}
   473 	if od.IsSynthetic() {
   473 	if od.IsSynthetic() {
   474 		fs := si.fieldsByNumber[od.Fields().Get(0).Number()]
   474 		fs := si.fieldsByNumber[od.Fields().Get(0).Number()]
   475 		fieldOffset := offsetOf(fs, x)
   475 		fieldOffset := offsetOf(fs, x)
   476 		oi.which = func(p pointer) pref.FieldNumber {
   476 		oi.which = func(p pointer) protoreflect.FieldNumber {
   477 			if p.IsNil() {
   477 			if p.IsNil() {
   478 				return 0
   478 				return 0
   479 			}
   479 			}
   480 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   480 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   481 			if rv.IsNil() { // valid on either *T or []byte
   481 			if rv.IsNil() { // valid on either *T or []byte
   484 			return od.Fields().Get(0).Number()
   484 			return od.Fields().Get(0).Number()
   485 		}
   485 		}
   486 	} else {
   486 	} else {
   487 		fs := si.oneofsByName[od.Name()]
   487 		fs := si.oneofsByName[od.Name()]
   488 		fieldOffset := offsetOf(fs, x)
   488 		fieldOffset := offsetOf(fs, x)
   489 		oi.which = func(p pointer) pref.FieldNumber {
   489 		oi.which = func(p pointer) protoreflect.FieldNumber {
   490 			if p.IsNil() {
   490 			if p.IsNil() {
   491 				return 0
   491 				return 0
   492 			}
   492 			}
   493 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   493 			rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem()
   494 			if rv.IsNil() {
   494 			if rv.IsNil() {