Copyright 2019 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package impl

import (
	
	

	
	pref 
)

type reflectMessageInfo struct {
	fields map[pref.FieldNumber]*fieldInfo
	oneofs map[pref.Name]*oneofInfo
denseFields is a subset of fields where: 0 < fieldDesc.Number() < len(denseFields) It provides faster access to the fieldInfo, but may be incomplete.
rangeInfos is a list of all fields (not belonging to a oneof) and oneofs.
	rangeInfos []interface{} // either *fieldInfo or *oneofInfo

	getUnknown   func(pointer) pref.RawFields
	setUnknown   func(pointer, pref.RawFields)
	extensionMap func(pointer) *extensionMap

	nilMessage atomicNilMessage
}
makeReflectFuncs generates the set of functions to support reflection.
makeKnownFieldsFunc generates functions for operations that can be performed on each protobuf message field. It takes in a reflect.Type representing the Go struct and matches message fields with struct fields. This code assumes that the struct is well-formed and panics if there are any discrepancies.
func ( *MessageInfo) ( structInfo) {
	.fields = map[pref.FieldNumber]*fieldInfo{}
	 := .Desc
	 := .Fields()
	for  := 0;  < .Len(); ++ {
		 := .Get()
		 := .fieldsByNumber[.Number()]
		var  fieldInfo
		switch {
		case .ContainingOneof() != nil && !.ContainingOneof().IsSynthetic():
			 = fieldInfoForOneof(, .oneofsByName[.ContainingOneof().Name()], .Exporter, .oneofWrappersByNumber[.Number()])
		case .IsMap():
			 = fieldInfoForMap(, , .Exporter)
		case .IsList():
			 = fieldInfoForList(, , .Exporter)
		case .IsWeak():
			 = fieldInfoForWeakMessage(, .weakOffset)
		case .Kind() == pref.MessageKind || .Kind() == pref.GroupKind:
			 = fieldInfoForMessage(, , .Exporter)
		default:
			 = fieldInfoForScalar(, , .Exporter)
		}
		.fields[.Number()] = &
	}

	.oneofs = map[pref.Name]*oneofInfo{}
	for  := 0;  < .Oneofs().Len(); ++ {
		 := .Oneofs().Get()
		.oneofs[.Name()] = makeOneofInfo(, , .Exporter)
	}

	.denseFields = make([]*fieldInfo, .Len()*2)
	for  := 0;  < .Len(); ++ {
		if  := .Get(); int(.Number()) < len(.denseFields) {
			.denseFields[.Number()] = .fields[.Number()]
		}
	}

	for  := 0;  < .Len(); {
		 := .Get()
		if  := .ContainingOneof();  != nil && !.IsSynthetic() {
			.rangeInfos = append(.rangeInfos, .oneofs[.Name()])
			 += .Fields().Len()
		} else {
			.rangeInfos = append(.rangeInfos, .fields[.Number()])
			++
		}
	}
}

func ( *MessageInfo) ( reflect.Type,  structInfo) {
	.getUnknown = func(pointer) pref.RawFields { return nil }
	.setUnknown = func(pointer, pref.RawFields) { return }
	if .unknownOffset.IsValid() {
		.getUnknown = func( pointer) pref.RawFields {
			if .IsNil() {
				return nil
			}
			 := .Apply(.unknownOffset).AsValueOf(unknownFieldsType)
			return pref.RawFields(*.Interface().(*[]byte))
		}
		.setUnknown = func( pointer,  pref.RawFields) {
			if .IsNil() {
				panic("invalid SetUnknown on nil Message")
			}
			 := .Apply(.unknownOffset).AsValueOf(unknownFieldsType)
			*.Interface().(*[]byte) = []byte()
		}
	} else {
		.getUnknown = func(pointer) pref.RawFields {
			return nil
		}
		.setUnknown = func( pointer,  pref.RawFields) {
			if .IsNil() {
				panic("invalid SetUnknown on nil Message")
			}
		}
	}
}

func ( *MessageInfo) ( reflect.Type,  structInfo) {
	if .extensionOffset.IsValid() {
		.extensionMap = func( pointer) *extensionMap {
			if .IsNil() {
				return (*extensionMap)(nil)
			}
			 := .Apply(.extensionOffset).AsValueOf(extensionFieldsType)
			return (*extensionMap)(.Interface().(*map[int32]ExtensionField))
		}
	} else {
		.extensionMap = func(pointer) *extensionMap {
			return (*extensionMap)(nil)
		}
	}
}

type extensionMap map[int32]ExtensionField

func ( *extensionMap) ( func(pref.FieldDescriptor, pref.Value) bool) {
	if  != nil {
		for ,  := range * {
			 := .Type().TypeDescriptor()
			 := .Value()
			if .IsList() && .List().Len() == 0 {
				continue
			}
			if !(, ) {
				return
			}
		}
	}
}
func ( *extensionMap) ( pref.ExtensionType) ( bool) {
	if  == nil {
		return false
	}
	 := .TypeDescriptor()
	,  := (*)[int32(.Number())]
	if ! {
		return false
	}
	switch {
	case .IsList():
		return .Value().List().Len() > 0
	case .IsMap():
		return .Value().Map().Len() > 0
	case .Message() != nil:
		return .Value().Message().IsValid()
	}
	return true
}
func ( *extensionMap) ( pref.ExtensionType) {
	delete(*, int32(.TypeDescriptor().Number()))
}
func ( *extensionMap) ( pref.ExtensionType) pref.Value {
	 := .TypeDescriptor()
	if  != nil {
		if ,  := (*)[int32(.Number())];  {
			return .Value()
		}
	}
	return .Zero()
}
func ( *extensionMap) ( pref.ExtensionType,  pref.Value) {
	 := .TypeDescriptor()
	 := true
	switch {
	case !.IsValidValue():
		 = false
	case .IsList():
		 = .List().IsValid()
	case .IsMap():
		 = .Map().IsValid()
	case .Message() != nil:
		 = .Message().IsValid()
	}
	if ! {
		panic(fmt.Sprintf("%v: assigning invalid value", .TypeDescriptor().FullName()))
	}

	if * == nil {
		* = make(map[int32]ExtensionField)
	}
	var  ExtensionField
	.Set(, )
	(*)[int32(.Number())] = 
}
func ( *extensionMap) ( pref.ExtensionType) pref.Value {
	 := .TypeDescriptor()
	if .Kind() != pref.MessageKind && .Kind() != pref.GroupKind && !.IsList() && !.IsMap() {
		panic("invalid Mutable on field with non-composite type")
	}
	if ,  := (*)[int32(.Number())];  {
		return .Value()
	}
	 := .New()
	.Set(, )
	return 
}
MessageState is a data structure that is nested as the first field in a concrete message. It provides a way to implement the ProtoReflect method in an allocation-free way without needing to have a shadow Go type generated for every message type. This technique only works using unsafe. Example generated code: type M struct { state protoimpl.MessageState Field1 int32 Field2 string Field3 *BarMessage ... } func (m *M) ProtoReflect() protoreflect.Message { mi := &file_fizz_buzz_proto_msgInfos[5] if protoimpl.UnsafeEnabled && m != nil { ms := protoimpl.X.MessageStateOf(Pointer(m)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(m) } The MessageState type holds a *MessageInfo, which must be atomically set to the message info associated with a given message instance. By unsafely converting a *M into a *MessageState, the MessageState object has access to all the information needed to implement protobuf reflection. It has access to the message info as its first field, and a pointer to the MessageState is identical to a pointer to the concrete message value. Requirements: • The type M must implement protoreflect.ProtoMessage. • The address of m must not be nil. • The address of m and the address of m.state must be equal, even though they are different Go types.
messageDataType is a tuple of a pointer to the message data and a pointer to the message type. It is a generalized way of providing a reflective view over a message instance. The disadvantage of this approach is the need to allocate this tuple of 16B.
MessageOf returns a reflective view over a message. The input must be a pointer to a named Go struct. If the provided type has a ProtoReflect method, it must be implemented by calling this method.
TODO: Switch the input to be an opaque Pointer.
	if reflect.TypeOf() != .GoReflectType {
		panic(fmt.Sprintf("type mismatch: got %T, want %v", , .GoReflectType))
	}
	 := pointerOfIface()
	if .IsNil() {
		return .nilMessage.Init()
	}
	return &messageReflectWrapper{, }
}

func ( *messageReflectWrapper) () pointer          { return .p }
func ( *messageReflectWrapper) () *MessageInfo { return .mi }

func ( *messageIfaceWrapper) () pref.Message {
	return (*messageReflectWrapper)()
}
func ( *messageIfaceWrapper) () interface{} {
	return .p.AsIfaceOf(.mi.GoReflectType.Elem())
}
checkField verifies that the provided field descriptor is valid. Exactly one of the returned values is populated.
func ( *MessageInfo) ( pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) {
	var  *fieldInfo
	if  := .Number(); 0 <  && int() < len(.denseFields) {
		 = .denseFields[]
	} else {
		 = .fields[]
	}
	if  != nil {
		if .fieldDesc !=  {
			if ,  := .FullName(), .fieldDesc.FullName();  !=  {
				panic(fmt.Sprintf("mismatching field: got %v, want %v", , ))
			}
			panic(fmt.Sprintf("mismatching field: %v", .FullName()))
		}
		return , nil
	}

	if .IsExtension() {
TODO: Should this be exact containing message descriptor match?
			panic(fmt.Sprintf("extension %v has mismatching containing message: got %v, want %v", .FullName(), , ))
		}
		if !.Desc.ExtensionRanges().Has(.Number()) {
			panic(fmt.Sprintf("extension %v extends %v outside the extension range", .FullName(), .Desc.FullName()))
		}
		,  := .(pref.ExtensionTypeDescriptor)
		if ! {
			panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", .FullName()))
		}
		return nil, .Type()
	}
	panic(fmt.Sprintf("field %v is invalid", .FullName()))