// Copyright 2024 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 (
	
	
	

	
	
	
	
	piface 
)

func ( *MessageInfo) ( reflect.Type,  opaqueStructInfo) {
	.sizecacheOffset = .sizecacheOffset
	.unknownOffset = .unknownOffset
	.unknownPtrKind = .unknownType.Kind() == reflect.Ptr
	.extensionOffset = .extensionOffset
	.lazyOffset = .lazyOffset
	.presenceOffset = .presenceOffset

	.coderFields = make(map[protowire.Number]*coderFieldInfo)
	 := .Desc.Fields()
	for  := 0;  < .Len(); ++ {
		 := .Get()

		 := .fieldsByNumber[.Number()]
		if .ContainingOneof() != nil && !.ContainingOneof().IsSynthetic() {
			 = .oneofsByName[.ContainingOneof().Name()]
		}
		 := .Type
		var  uint64
		if !.IsPacked() {
			 = protowire.EncodeTag(.Number(), wireTypes[.Kind()])
		} else {
			 = protowire.EncodeTag(.Number(), protowire.BytesType)
		}
		var  offset
		var  pointerCoderFuncs
		var  *MessageInfo
		switch {
		case .ContainingOneof() != nil && !.ContainingOneof().IsSynthetic():
			 = offsetOf()
		case .Message() != nil && !.IsMap():
			 = offsetOf()
			if .IsList() {
				,  = makeOpaqueRepeatedMessageFieldCoder(, )
			} else {
				,  = makeOpaqueMessageFieldCoder(, )
			}
		default:
			 = offsetOf()
			,  = fieldCoder(, )
		}
		 := &coderFieldInfo{
			num:        .Number(),
			offset:     ,
			wiretag:    ,
			ft:         ,
			tagsize:    protowire.SizeVarint(),
			funcs:      ,
			mi:         ,
			validation: newFieldValidationInfo(, .structInfo, , ),
			isPointer: (.Cardinality() == protoreflect.Repeated ||
				.Kind() == protoreflect.MessageKind ||
				.Kind() == protoreflect.GroupKind),
			isRequired:    .Cardinality() == protoreflect.Required,
			presenceIndex: noPresence,
		}

		// TODO: Use presence for all fields.
		//
		// In some cases, such as maps, presence means only "might be set" rather
		// than "is definitely set", but every field should have a presence bit to
		// permit us to skip over definitely-unset fields at marshal time.

		var  bool
		, .isLazy = usePresenceForField(, )

		if  {
			.presenceIndex, .presenceSize = presenceIndex(.Desc, )
		}

		.orderedCoderFields = append(.orderedCoderFields, )
		.coderFields[.num] = 
	}
	for ,  := 0, .Desc.Oneofs();  < .Len(); ++ {
		if  := .Get(); !.IsSynthetic() {
			.initOneofFieldCoders(, .structInfo)
		}
	}
	if messageset.IsMessageSet(.Desc) {
		if !.extensionOffset.IsValid() {
			panic(fmt.Sprintf("%v: MessageSet with no extensions field", .Desc.FullName()))
		}
		if !.unknownOffset.IsValid() {
			panic(fmt.Sprintf("%v: MessageSet with no unknown field", .Desc.FullName()))
		}
		.isMessageSet = true
	}
	sort.Slice(.orderedCoderFields, func(,  int) bool {
		return .orderedCoderFields[].num < .orderedCoderFields[].num
	})

	var  protoreflect.FieldNumber
	for ,  := range .orderedCoderFields {
		if .num >= 16 && .num >= 2* {
			break
		}
		 = .num
	}
	.denseCoderFields = make([]*coderFieldInfo, +1)
	for ,  := range .orderedCoderFields {
		if int(.num) > len(.denseCoderFields) {
			break
		}
		.denseCoderFields[.num] = 
	}

	// To preserve compatibility with historic wire output, marshal oneofs last.
	if .Desc.Oneofs().Len() > 0 {
		sort.Slice(.orderedCoderFields, func(,  int) bool {
			 := .ByNumber(.orderedCoderFields[].num)
			 := .ByNumber(.orderedCoderFields[].num)
			return order.LegacyFieldOrder(, )
		})
	}

	.needsInitCheck = needsInitCheck(.Desc)
	if .methods.Marshal == nil && .methods.Size == nil {
		.methods.Flags |= piface.SupportMarshalDeterministic
		.methods.Marshal = .marshal
		.methods.Size = .size
	}
	if .methods.Unmarshal == nil {
		.methods.Flags |= piface.SupportUnmarshalDiscardUnknown
		.methods.Unmarshal = .unmarshal
	}
	if .methods.CheckInitialized == nil {
		.methods.CheckInitialized = .checkInitialized
	}
	if .methods.Merge == nil {
		.methods.Merge = .merge
	}
	if .methods.Equal == nil {
		.methods.Equal = equal
	}
}