vendor/google.golang.org/protobuf/internal/impl/message_reflect.go
changeset 260 445e01aede7e
parent 256 6d9efbef00a9
equal deleted inserted replaced
259:db4911b0c721 260:445e01aede7e
     8 	"fmt"
     8 	"fmt"
     9 	"reflect"
     9 	"reflect"
    10 
    10 
    11 	"google.golang.org/protobuf/internal/detrand"
    11 	"google.golang.org/protobuf/internal/detrand"
    12 	"google.golang.org/protobuf/internal/pragma"
    12 	"google.golang.org/protobuf/internal/pragma"
    13 	pref "google.golang.org/protobuf/reflect/protoreflect"
    13 	"google.golang.org/protobuf/reflect/protoreflect"
    14 )
    14 )
    15 
    15 
    16 type reflectMessageInfo struct {
    16 type reflectMessageInfo struct {
    17 	fields map[pref.FieldNumber]*fieldInfo
    17 	fields map[protoreflect.FieldNumber]*fieldInfo
    18 	oneofs map[pref.Name]*oneofInfo
    18 	oneofs map[protoreflect.Name]*oneofInfo
    19 
    19 
    20 	// fieldTypes contains the zero value of an enum or message field.
    20 	// fieldTypes contains the zero value of an enum or message field.
    21 	// For lists, it contains the element type.
    21 	// For lists, it contains the element type.
    22 	// For maps, it contains the entry value type.
    22 	// For maps, it contains the entry value type.
    23 	fieldTypes map[pref.FieldNumber]interface{}
    23 	fieldTypes map[protoreflect.FieldNumber]interface{}
    24 
    24 
    25 	// denseFields is a subset of fields where:
    25 	// denseFields is a subset of fields where:
    26 	//	0 < fieldDesc.Number() < len(denseFields)
    26 	//	0 < fieldDesc.Number() < len(denseFields)
    27 	// It provides faster access to the fieldInfo, but may be incomplete.
    27 	// It provides faster access to the fieldInfo, but may be incomplete.
    28 	denseFields []*fieldInfo
    28 	denseFields []*fieldInfo
    29 
    29 
    30 	// rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
    30 	// rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
    31 	rangeInfos []interface{} // either *fieldInfo or *oneofInfo
    31 	rangeInfos []interface{} // either *fieldInfo or *oneofInfo
    32 
    32 
    33 	getUnknown   func(pointer) pref.RawFields
    33 	getUnknown   func(pointer) protoreflect.RawFields
    34 	setUnknown   func(pointer, pref.RawFields)
    34 	setUnknown   func(pointer, protoreflect.RawFields)
    35 	extensionMap func(pointer) *extensionMap
    35 	extensionMap func(pointer) *extensionMap
    36 
    36 
    37 	nilMessage atomicNilMessage
    37 	nilMessage atomicNilMessage
    38 }
    38 }
    39 
    39 
    50 // Go struct and matches message fields with struct fields.
    50 // Go struct and matches message fields with struct fields.
    51 //
    51 //
    52 // This code assumes that the struct is well-formed and panics if there are
    52 // This code assumes that the struct is well-formed and panics if there are
    53 // any discrepancies.
    53 // any discrepancies.
    54 func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
    54 func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) {
    55 	mi.fields = map[pref.FieldNumber]*fieldInfo{}
    55 	mi.fields = map[protoreflect.FieldNumber]*fieldInfo{}
    56 	md := mi.Desc
    56 	md := mi.Desc
    57 	fds := md.Fields()
    57 	fds := md.Fields()
    58 	for i := 0; i < fds.Len(); i++ {
    58 	for i := 0; i < fds.Len(); i++ {
    59 		fd := fds.Get(i)
    59 		fd := fds.Get(i)
    60 		fs := si.fieldsByNumber[fd.Number()]
    60 		fs := si.fieldsByNumber[fd.Number()]
    80 			fi = fieldInfoForScalar(fd, fs, mi.Exporter)
    80 			fi = fieldInfoForScalar(fd, fs, mi.Exporter)
    81 		}
    81 		}
    82 		mi.fields[fd.Number()] = &fi
    82 		mi.fields[fd.Number()] = &fi
    83 	}
    83 	}
    84 
    84 
    85 	mi.oneofs = map[pref.Name]*oneofInfo{}
    85 	mi.oneofs = map[protoreflect.Name]*oneofInfo{}
    86 	for i := 0; i < md.Oneofs().Len(); i++ {
    86 	for i := 0; i < md.Oneofs().Len(); i++ {
    87 		od := md.Oneofs().Get(i)
    87 		od := md.Oneofs().Get(i)
    88 		mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter)
    88 		mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter)
    89 	}
    89 	}
    90 
    90 
   115 
   115 
   116 func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {
   116 func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) {
   117 	switch {
   117 	switch {
   118 	case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsAType:
   118 	case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsAType:
   119 		// Handle as []byte.
   119 		// Handle as []byte.
   120 		mi.getUnknown = func(p pointer) pref.RawFields {
   120 		mi.getUnknown = func(p pointer) protoreflect.RawFields {
   121 			if p.IsNil() {
   121 			if p.IsNil() {
   122 				return nil
   122 				return nil
   123 			}
   123 			}
   124 			return *p.Apply(mi.unknownOffset).Bytes()
   124 			return *p.Apply(mi.unknownOffset).Bytes()
   125 		}
   125 		}
   126 		mi.setUnknown = func(p pointer, b pref.RawFields) {
   126 		mi.setUnknown = func(p pointer, b protoreflect.RawFields) {
   127 			if p.IsNil() {
   127 			if p.IsNil() {
   128 				panic("invalid SetUnknown on nil Message")
   128 				panic("invalid SetUnknown on nil Message")
   129 			}
   129 			}
   130 			*p.Apply(mi.unknownOffset).Bytes() = b
   130 			*p.Apply(mi.unknownOffset).Bytes() = b
   131 		}
   131 		}
   132 	case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsBType:
   132 	case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsBType:
   133 		// Handle as *[]byte.
   133 		// Handle as *[]byte.
   134 		mi.getUnknown = func(p pointer) pref.RawFields {
   134 		mi.getUnknown = func(p pointer) protoreflect.RawFields {
   135 			if p.IsNil() {
   135 			if p.IsNil() {
   136 				return nil
   136 				return nil
   137 			}
   137 			}
   138 			bp := p.Apply(mi.unknownOffset).BytesPtr()
   138 			bp := p.Apply(mi.unknownOffset).BytesPtr()
   139 			if *bp == nil {
   139 			if *bp == nil {
   140 				return nil
   140 				return nil
   141 			}
   141 			}
   142 			return **bp
   142 			return **bp
   143 		}
   143 		}
   144 		mi.setUnknown = func(p pointer, b pref.RawFields) {
   144 		mi.setUnknown = func(p pointer, b protoreflect.RawFields) {
   145 			if p.IsNil() {
   145 			if p.IsNil() {
   146 				panic("invalid SetUnknown on nil Message")
   146 				panic("invalid SetUnknown on nil Message")
   147 			}
   147 			}
   148 			bp := p.Apply(mi.unknownOffset).BytesPtr()
   148 			bp := p.Apply(mi.unknownOffset).BytesPtr()
   149 			if *bp == nil {
   149 			if *bp == nil {
   150 				*bp = new([]byte)
   150 				*bp = new([]byte)
   151 			}
   151 			}
   152 			**bp = b
   152 			**bp = b
   153 		}
   153 		}
   154 	default:
   154 	default:
   155 		mi.getUnknown = func(pointer) pref.RawFields {
   155 		mi.getUnknown = func(pointer) protoreflect.RawFields {
   156 			return nil
   156 			return nil
   157 		}
   157 		}
   158 		mi.setUnknown = func(p pointer, _ pref.RawFields) {
   158 		mi.setUnknown = func(p pointer, _ protoreflect.RawFields) {
   159 			if p.IsNil() {
   159 			if p.IsNil() {
   160 				panic("invalid SetUnknown on nil Message")
   160 				panic("invalid SetUnknown on nil Message")
   161 			}
   161 			}
   162 		}
   162 		}
   163 	}
   163 	}
   222 		if isMessage && ft != nil && ft.Kind() != reflect.Ptr {
   222 		if isMessage && ft != nil && ft.Kind() != reflect.Ptr {
   223 			ft = reflect.PtrTo(ft) // never occurs for officially generated message types
   223 			ft = reflect.PtrTo(ft) // never occurs for officially generated message types
   224 		}
   224 		}
   225 		if ft != nil {
   225 		if ft != nil {
   226 			if mi.fieldTypes == nil {
   226 			if mi.fieldTypes == nil {
   227 				mi.fieldTypes = make(map[pref.FieldNumber]interface{})
   227 				mi.fieldTypes = make(map[protoreflect.FieldNumber]interface{})
   228 			}
   228 			}
   229 			mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface()
   229 			mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface()
   230 		}
   230 		}
   231 	}
   231 	}
   232 }
   232 }
   233 
   233 
   234 type extensionMap map[int32]ExtensionField
   234 type extensionMap map[int32]ExtensionField
   235 
   235 
   236 func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
   236 func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
   237 	if m != nil {
   237 	if m != nil {
   238 		for _, x := range *m {
   238 		for _, x := range *m {
   239 			xd := x.Type().TypeDescriptor()
   239 			xd := x.Type().TypeDescriptor()
   240 			v := x.Value()
   240 			v := x.Value()
   241 			if xd.IsList() && v.List().Len() == 0 {
   241 			if xd.IsList() && v.List().Len() == 0 {
   245 				return
   245 				return
   246 			}
   246 			}
   247 		}
   247 		}
   248 	}
   248 	}
   249 }
   249 }
   250 func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) {
   250 func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) {
   251 	if m == nil {
   251 	if m == nil {
   252 		return false
   252 		return false
   253 	}
   253 	}
   254 	xd := xt.TypeDescriptor()
   254 	xd := xt.TypeDescriptor()
   255 	x, ok := (*m)[int32(xd.Number())]
   255 	x, ok := (*m)[int32(xd.Number())]
   264 	case xd.Message() != nil:
   264 	case xd.Message() != nil:
   265 		return x.Value().Message().IsValid()
   265 		return x.Value().Message().IsValid()
   266 	}
   266 	}
   267 	return true
   267 	return true
   268 }
   268 }
   269 func (m *extensionMap) Clear(xt pref.ExtensionType) {
   269 func (m *extensionMap) Clear(xt protoreflect.ExtensionType) {
   270 	delete(*m, int32(xt.TypeDescriptor().Number()))
   270 	delete(*m, int32(xt.TypeDescriptor().Number()))
   271 }
   271 }
   272 func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value {
   272 func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value {
   273 	xd := xt.TypeDescriptor()
   273 	xd := xt.TypeDescriptor()
   274 	if m != nil {
   274 	if m != nil {
   275 		if x, ok := (*m)[int32(xd.Number())]; ok {
   275 		if x, ok := (*m)[int32(xd.Number())]; ok {
   276 			return x.Value()
   276 			return x.Value()
   277 		}
   277 		}
   278 	}
   278 	}
   279 	return xt.Zero()
   279 	return xt.Zero()
   280 }
   280 }
   281 func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) {
   281 func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) {
   282 	xd := xt.TypeDescriptor()
   282 	xd := xt.TypeDescriptor()
   283 	isValid := true
   283 	isValid := true
   284 	switch {
   284 	switch {
   285 	case !xt.IsValidValue(v):
   285 	case !xt.IsValidValue(v):
   286 		isValid = false
   286 		isValid = false
   300 	}
   300 	}
   301 	var x ExtensionField
   301 	var x ExtensionField
   302 	x.Set(xt, v)
   302 	x.Set(xt, v)
   303 	(*m)[int32(xd.Number())] = x
   303 	(*m)[int32(xd.Number())] = x
   304 }
   304 }
   305 func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value {
   305 func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value {
   306 	xd := xt.TypeDescriptor()
   306 	xd := xt.TypeDescriptor()
   307 	if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() {
   307 	if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() {
   308 		panic("invalid Mutable on field with non-composite type")
   308 		panic("invalid Mutable on field with non-composite type")
   309 	}
   309 	}
   310 	if x, ok := (*m)[int32(xd.Number())]; ok {
   310 	if x, ok := (*m)[int32(xd.Number())]; ok {
   311 		return x.Value()
   311 		return x.Value()
   312 	}
   312 	}
   317 
   317 
   318 // MessageState is a data structure that is nested as the first field in a
   318 // MessageState is a data structure that is nested as the first field in a
   319 // concrete message. It provides a way to implement the ProtoReflect method
   319 // concrete message. It provides a way to implement the ProtoReflect method
   320 // in an allocation-free way without needing to have a shadow Go type generated
   320 // in an allocation-free way without needing to have a shadow Go type generated
   321 // for every message type. This technique only works using unsafe.
   321 // for every message type. This technique only works using unsafe.
   322 //
       
   323 //
   322 //
   324 // Example generated code:
   323 // Example generated code:
   325 //
   324 //
   326 //	type M struct {
   325 //	type M struct {
   327 //		state protoimpl.MessageState
   326 //		state protoimpl.MessageState
   349 // By unsafely converting a *M into a *MessageState, the MessageState object
   348 // By unsafely converting a *M into a *MessageState, the MessageState object
   350 // has access to all the information needed to implement protobuf reflection.
   349 // has access to all the information needed to implement protobuf reflection.
   351 // It has access to the message info as its first field, and a pointer to the
   350 // It has access to the message info as its first field, and a pointer to the
   352 // MessageState is identical to a pointer to the concrete message value.
   351 // MessageState is identical to a pointer to the concrete message value.
   353 //
   352 //
   354 //
       
   355 // Requirements:
   353 // Requirements:
   356 //	• The type M must implement protoreflect.ProtoMessage.
   354 //   - The type M must implement protoreflect.ProtoMessage.
   357 //	• The address of m must not be nil.
   355 //   - The address of m must not be nil.
   358 //	• The address of m and the address of m.state must be equal,
   356 //   - The address of m and the address of m.state must be equal,
   359 //	even though they are different Go types.
   357 //     even though they are different Go types.
   360 type MessageState struct {
   358 type MessageState struct {
   361 	pragma.NoUnkeyedLiterals
   359 	pragma.NoUnkeyedLiterals
   362 	pragma.DoNotCompare
   360 	pragma.DoNotCompare
   363 	pragma.DoNotCopy
   361 	pragma.DoNotCopy
   364 
   362 
   366 }
   364 }
   367 
   365 
   368 type messageState MessageState
   366 type messageState MessageState
   369 
   367 
   370 var (
   368 var (
   371 	_ pref.Message = (*messageState)(nil)
   369 	_ protoreflect.Message = (*messageState)(nil)
   372 	_ unwrapper    = (*messageState)(nil)
   370 	_ unwrapper            = (*messageState)(nil)
   373 )
   371 )
   374 
   372 
   375 // messageDataType is a tuple of a pointer to the message data and
   373 // messageDataType is a tuple of a pointer to the message data and
   376 // a pointer to the message type. It is a generalized way of providing a
   374 // a pointer to the message type. It is a generalized way of providing a
   377 // reflective view over a message instance. The disadvantage of this approach
   375 // reflective view over a message instance. The disadvantage of this approach
   385 	messageReflectWrapper messageDataType
   383 	messageReflectWrapper messageDataType
   386 	messageIfaceWrapper   messageDataType
   384 	messageIfaceWrapper   messageDataType
   387 )
   385 )
   388 
   386 
   389 var (
   387 var (
   390 	_ pref.Message      = (*messageReflectWrapper)(nil)
   388 	_ protoreflect.Message      = (*messageReflectWrapper)(nil)
   391 	_ unwrapper         = (*messageReflectWrapper)(nil)
   389 	_ unwrapper                 = (*messageReflectWrapper)(nil)
   392 	_ pref.ProtoMessage = (*messageIfaceWrapper)(nil)
   390 	_ protoreflect.ProtoMessage = (*messageIfaceWrapper)(nil)
   393 	_ unwrapper         = (*messageIfaceWrapper)(nil)
   391 	_ unwrapper                 = (*messageIfaceWrapper)(nil)
   394 )
   392 )
   395 
   393 
   396 // MessageOf returns a reflective view over a message. The input must be a
   394 // MessageOf returns a reflective view over a message. The input must be a
   397 // pointer to a named Go struct. If the provided type has a ProtoReflect method,
   395 // pointer to a named Go struct. If the provided type has a ProtoReflect method,
   398 // it must be implemented by calling this method.
   396 // it must be implemented by calling this method.
   399 func (mi *MessageInfo) MessageOf(m interface{}) pref.Message {
   397 func (mi *MessageInfo) MessageOf(m interface{}) protoreflect.Message {
   400 	if reflect.TypeOf(m) != mi.GoReflectType {
   398 	if reflect.TypeOf(m) != mi.GoReflectType {
   401 		panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
   399 		panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType))
   402 	}
   400 	}
   403 	p := pointerOfIface(m)
   401 	p := pointerOfIface(m)
   404 	if p.IsNil() {
   402 	if p.IsNil() {
   419 	rv := reflect.ValueOf(m.protoUnwrap())
   417 	rv := reflect.ValueOf(m.protoUnwrap())
   420 	if rv.Kind() == reflect.Ptr && !rv.IsNil() {
   418 	if rv.Kind() == reflect.Ptr && !rv.IsNil() {
   421 		rv.Elem().Set(reflect.Zero(rv.Type().Elem()))
   419 		rv.Elem().Set(reflect.Zero(rv.Type().Elem()))
   422 	}
   420 	}
   423 }
   421 }
   424 func (m *messageIfaceWrapper) ProtoReflect() pref.Message {
   422 func (m *messageIfaceWrapper) ProtoReflect() protoreflect.Message {
   425 	return (*messageReflectWrapper)(m)
   423 	return (*messageReflectWrapper)(m)
   426 }
   424 }
   427 func (m *messageIfaceWrapper) protoUnwrap() interface{} {
   425 func (m *messageIfaceWrapper) protoUnwrap() interface{} {
   428 	return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
   426 	return m.p.AsIfaceOf(m.mi.GoReflectType.Elem())
   429 }
   427 }
   430 
   428 
   431 // checkField verifies that the provided field descriptor is valid.
   429 // checkField verifies that the provided field descriptor is valid.
   432 // Exactly one of the returned values is populated.
   430 // Exactly one of the returned values is populated.
   433 func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) {
   431 func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) {
   434 	var fi *fieldInfo
   432 	var fi *fieldInfo
   435 	if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
   433 	if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) {
   436 		fi = mi.denseFields[n]
   434 		fi = mi.denseFields[n]
   437 	} else {
   435 	} else {
   438 		fi = mi.fields[n]
   436 		fi = mi.fields[n]
   453 			panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", fd.FullName(), got, want))
   451 			panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", fd.FullName(), got, want))
   454 		}
   452 		}
   455 		if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
   453 		if !mi.Desc.ExtensionRanges().Has(fd.Number()) {
   456 			panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName()))
   454 			panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName()))
   457 		}
   455 		}
   458 		xtd, ok := fd.(pref.ExtensionTypeDescriptor)
   456 		xtd, ok := fd.(protoreflect.ExtensionTypeDescriptor)
   459 		if !ok {
   457 		if !ok {
   460 			panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
   458 			panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName()))
   461 		}
   459 		}
   462 		return nil, xtd.Type()
   460 		return nil, xtd.Type()
   463 	}
   461 	}