// 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 internal_gengo

import (
	"fmt"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"

	"google.golang.org/protobuf/compiler/protogen"
	"google.golang.org/protobuf/internal/genid"
	"google.golang.org/protobuf/reflect/protoreflect"

	"google.golang.org/protobuf/types/descriptorpb"
)

func opaqueGenMessageHook(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo) bool {
	opaqueGenMessage(g, f, message)
	return true
}

func opaqueGenMessage(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo) {
	// Message type declaration.
	g.AnnotateSymbol(message.GoIdent.GoName, protogen.Annotation{Location: message.Location})
	leadingComments := appendDeprecationSuffix(message.Comments.Leading,
		message.Desc.ParentFile(),
		message.Desc.Options().(*descriptorpb.MessageOptions).GetDeprecated())
	g.P(leadingComments,
		"type ", message.GoIdent, " struct {")

	sf := f.allMessageFieldsByPtr[message]
	if sf == nil {
		sf = new(structFields)
		f.allMessageFieldsByPtr[message] = sf
	}

	var tags structTags
	switch {
	case message.isOpen():
		tags = structTags{{"protogen", "open.v1"}}
	case message.isHybrid():
		tags = structTags{{"protogen", "hybrid.v1"}}
	case message.isOpaque():
		tags = structTags{{"protogen", "opaque.v1"}}
	}

	g.P(genid.State_goname, " ", protoimplPackage.Ident("MessageState"), tags)
	sf.append(genid.State_goname)
	fields := message.Fields
	for _, field := range fields {
		opaqueGenMessageField(g, f, message, field, sf)
	}
	opaqueGenMessageInternalFields(g, f, message, sf)
	g.P("}")
	g.P()

	genMessageKnownFunctions(g, f, message)
	genMessageDefaultDecls(g, f, message)
	opaqueGenMessageMethods(g, f, message)
	opaqueGenMessageBuilder(g, f, message)
	opaqueGenOneofWrapperTypes(g, f, message)
}

// opaqueGenMessageField generates a struct field.
func opaqueGenMessageField(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field, sf *structFields) {
	if oneof := field.Oneof; oneof != nil && !oneof.Desc.IsSynthetic() {
		// It would be a bit simpler to iterate over the oneofs below,
		// but generating the field here keeps the contents of the Go
		// struct in the same order as the contents of the source
		// .proto file.
		if field != oneof.Fields[0] {
			return
		}
		opaqueGenOneofFields(g, f, message, oneof, sf)
		return
	}

	goType, pointer := opaqueFieldGoType(g, f, message, field)
	if pointer {
		goType = "*" + goType
	}
	protobufTagValue := fieldProtobufTagValue(field)
	jsonTagValue := fieldJSONTagValue(field)
	if g.InternalStripForEditionsDiff() {
		if field.Desc.ContainingOneof() != nil && field.Desc.ContainingOneof().IsSynthetic() {
			protobufTagValue = strings.ReplaceAll(protobufTagValue, ",oneof", "")
		}
		protobufTagValue = strings.ReplaceAll(protobufTagValue, ",proto3", "")
	}
	tags := structTags{
		{"protobuf", protobufTagValue},
	}
	if !message.isOpaque() {
		tags = append(tags, structTags{{"json", jsonTagValue}}...)
	}
	if field.Desc.IsMap() {
		keyTagValue := fieldProtobufTagValue(field.Message.Fields[0])
		valTagValue := fieldProtobufTagValue(field.Message.Fields[1])
		keyTagValue = strings.ReplaceAll(keyTagValue, ",proto3", "")
		valTagValue = strings.ReplaceAll(valTagValue, ",proto3", "")
		tags = append(tags, structTags{
			{"protobuf_key", keyTagValue},
			{"protobuf_val", valTagValue},
		}...)
	}

	name := field.GoName
	if field.Desc.IsWeak() {
		g.P("// Deprecated: Do not use. This will be deleted in the near future.")
		name = genid.WeakFieldPrefix_goname + name
	} else if message.isOpaque() {
		name = "xxx_hidden_" + name
	}

	if message.isOpaque() && !field.Desc.IsWeak() {
		g.P(name, " ", goType, tags)
		sf.append(name)
		if message.isTracked {
			g.P("// Deprecated: Do not use. This will be deleted in the near future.")
			g.P("XXX_ft_", field.GoName, " struct{} `go:\"track\"`")
			sf.append("XXX_ft_" + field.GoName)
		}
	} else {
		if message.isTracked {
			tags = append(tags, structTags{
				{"go", "track"},
			}...)
		}
		g.AnnotateSymbol(field.Parent.GoIdent.GoName+"."+name, protogen.Annotation{Location: field.Location})
		leadingComments := appendDeprecationSuffix(field.Comments.Leading,
			field.Desc.ParentFile(),
			field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
		g.P(leadingComments,
			name, " ", goType, tags,
			trailingComment(field.Comments.Trailing))
		sf.append(name)
	}
}

// opaqueGenOneofFields generates the message fields for a oneof.
func opaqueGenOneofFields(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, oneof *protogen.Oneof, sf *structFields) {
	tags := structTags{
		{"protobuf_oneof", string(oneof.Desc.Name())},
	}
	if message.isTracked {
		tags = append(tags, structTags{
			{"go", "track"},
		}...)
	}

	oneofName := opaqueOneofFieldName(oneof, message.isOpaque())
	goType := opaqueOneofInterfaceName(oneof)

	if message.isOpaque() {
		g.P(oneofName, " ", goType, tags)
		sf.append(oneofName)
		if message.isTracked {
			g.P("// Deprecated: Do not use. This will be deleted in the near future.")
			g.P("XXX_ft_", oneof.GoName, " struct{} `go:\"track\"`")
			sf.append("XXX_ft_" + oneof.GoName)
		}
		return
	}

	leadingComments := oneof.Comments.Leading
	if leadingComments != "" {
		leadingComments += "\n"
	}
	// NOTE(rsc): The extra \n here is working around #52605,
	// making the comment be in Go 1.19 doc comment format
	// even though it's not really a doc comment.
	ss := []string{" Types that are valid to be assigned to ", oneofName, ":\n\n"}
	for _, field := range oneof.Fields {
		ss = append(ss, "\t*"+opaqueFieldOneofType(field, message.isOpaque()).GoName+"\n")
	}
	leadingComments += protogen.Comments(strings.Join(ss, ""))
	g.P(leadingComments, oneofName, " ", goType, tags)
	sf.append(oneofName)
}

// opaqueGenMessageInternalFields adds additional XXX_ fields to a message struct.
func opaqueGenMessageInternalFields(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, sf *structFields) {
	if opaqueNeedsPresenceArray(message) {
		if opaqueNeedsLazyStruct(message) {
			g.P("// Deprecated: Do not use. This will be deleted in the near future.")
			g.P("XXX_lazyUnmarshalInfo ", protoimplPackage.Ident("LazyUnmarshalInfo"))
			sf.append("XXX_lazyUnmarshalInfo")
		}
		g.P("XXX_raceDetectHookData ", protoimplPackage.Ident("RaceDetectHookData"))
		sf.append("XXX_raceDetectHookData")

		// Presence must be stored in a data type no larger than 32 bit:
		//
		// Presence used to be a uint64, accessed with atomic.LoadUint64, but it
		// turns out that on 32-bit platforms like GOARCH=arm, the struct field
		// was 32-bit aligned (not 64-bit aligned) and hence atomic accesses
		// failed.
		//
		// The easiest solution was to switch to a uint32 on all platforms,
		// which did not come with a performance penalty.
		g.P("XXX_presence [", (opaqueNumPresenceFields(message)+31)/32, "]uint32")
		sf.append("XXX_presence")
	}
	if message.hasWeak {
		g.P(genid.WeakFields_goname, " ", protoimplPackage.Ident("WeakFields"))
		sf.append(genid.WeakFields_goname)
	}
	if message.Desc.ExtensionRanges().Len() > 0 {
		g.P(genid.ExtensionFields_goname, " ", protoimplPackage.Ident("ExtensionFields"))
		sf.append(genid.ExtensionFields_goname)
	}
	g.P(genid.UnknownFields_goname, " ", protoimplPackage.Ident("UnknownFields"))
	sf.append(genid.UnknownFields_goname)
	g.P(genid.SizeCache_goname, " ", protoimplPackage.Ident("SizeCache"))
	sf.append(genid.SizeCache_goname)
}

func opaqueGenMessageMethods(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo) {
	genMessageBaseMethods(g, f, message)

	isRepeated := func(field *protogen.Field) bool {
		return field.Desc.Cardinality() == protoreflect.Repeated
	}

	for _, field := range message.Fields {
		if isFirstOneofField(field) && !message.isOpaque() {
			opaqueGenGetOneof(g, f, message, field.Oneof)
		}
		opaqueGenGet(g, f, message, field)
	}
	for _, field := range message.Fields {
		// For the plain open mode, we only have set methods for weak fields.
		if message.isOpen() && !field.Desc.IsWeak() {
			continue
		}
		opaqueGenSet(g, f, message, field)
	}
	for _, field := range message.Fields {
		// Open API does not have Has method.
		// Repeated (includes map) fields do not have Has method.
		if message.isOpen() || isRepeated(field) {
			continue
		}

		if !field.Desc.HasPresence() {
			continue
		}

		if isFirstOneofField(field) {
			opaqueGenHasOneof(g, f, message, field.Oneof)
		}
		opaqueGenHas(g, f, message, field)
	}
	for _, field := range message.Fields {
		// Open API does not have Clear method.
		// Repeated (includes map) fields do not have Clear method.
		if message.isOpen() || isRepeated(field) {
			continue
		}
		if !field.Desc.HasPresence() {
			continue
		}

		if isFirstOneofField(field) {
			opaqueGenClearOneof(g, f, message, field.Oneof)
		}
		opaqueGenClear(g, f, message, field)
	}
	// Plain open protos do not have which methods.
	if !message.isOpen() {
		opaqueGenWhichOneof(g, f, message)
	}

	if g.InternalStripForEditionsDiff() {
		return
	}
}

func isLazy(field *protogen.Field) bool {
	// Prerequisite: field is of kind message
	if field.Message == nil {
		return false
	}

	// Was the field marked as [lazy = true] in the .proto file?
	fopts := field.Desc.Options().(*descriptorpb.FieldOptions)
	return fopts.GetLazy()
}

// opaqueGenGet generates a Get method for a field.
func opaqueGenGet(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field) {
	goType, pointer := opaqueFieldGoType(g, f, message, field)
	getterName, bcName := field.MethodName("Get")

	// If we need a backwards compatible getter name, we add it now.
	if bcName != "" {
		defer func() {
			g.P("// Deprecated: Use ", getterName, " instead.")
			g.P("func (x *", message.GoIdent, ") ", bcName, "() ", goType, " {")
			g.P("return x.", getterName, "()")
			g.P("}")
			g.P()
		}()
	}

	leadingComments := appendDeprecationSuffix("",
		field.Desc.ParentFile(),
		field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
	fieldtrackNoInterface(g, message.isTracked)
	g.AnnotateSymbol(message.GoIdent.GoName+"."+getterName, protogen.Annotation{Location: field.Location})

	// Weak field.
	if field.Desc.IsWeak() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", getterName, "() ", protoPackage.Ident("Message"), "{")
		g.P("var w ", protoimplPackage.Ident("WeakFields"))
		g.P("if x != nil {")
		g.P("w = x.", genid.WeakFields_goname)
		if message.isTracked {
			g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName)
		}
		g.P("}")
		g.P("return ", protoimplPackage.Ident("X"), ".GetWeak(w, ", field.Desc.Number(), ", ", strconv.Quote(string(field.Message.Desc.FullName())), ")")
		g.P("}")
		g.P()
		return
	}

	defaultValue := fieldDefaultValue(g, f, message, field)

	// Oneof field.
	if oneof := field.Oneof; oneof != nil && !oneof.Desc.IsSynthetic() {
		structPtr := "x"
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", getterName, "() ", goType, " {")
		g.P("if x != nil {")
		if message.isOpaque() && message.isTracked {
			g.P("_ = ", structPtr, ".XXX_ft_", field.Oneof.GoName)
		}
		g.P("if x, ok := ", structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), ".(*", opaqueFieldOneofType(field, message.isOpaque()), "); ok {")
		g.P("return x.", field.GoName)
		g.P("}")
		// End if m != nil {.
		g.P("}")
		g.P("return ", defaultValue)
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field for open type message.
	if !message.isOpaque() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", getterName, "() ", goType, " {")
		if !field.Desc.HasPresence() || defaultValue == "nil" {
			g.P("if x != nil {")
		} else {
			g.P("if x != nil && x.", field.GoName, " != nil {")
		}
		star := ""
		if pointer {
			star = "*"
		}
		g.P("return ", star, " x.", field.GoName)
		g.P("}")
		g.P("return ", defaultValue)
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field for opaque type message.
	g.P(leadingComments, "func (x *", message.GoIdent, ") ", getterName, "() ", goType, "{")
	structPtr := "x"
	g.P("if x != nil {")
	if message.isTracked {
		g.P("_ = ", structPtr, ".XXX_ft_", field.GoName)
	}
	if usePresence(message, field) {
		pi := opaqueFieldPresenceIndex(field)
		ai := pi / 32
		// For
		//
		//  1. Message fields of lazy messages (unmarshalled lazily),
		//  2. Fields with a default value,
		//  3. Closed enums
		//
		// ...we check presence, but for other fields using presence, we can return
		// whatever is there and it should be correct regardless of presence, which
		// saves us an atomic operation.
		isEnum := field.Desc.Kind() == protoreflect.EnumKind
		usePresenceForRead := (isLazy(field)) ||
			field.Desc.HasDefault() || isEnum

		if usePresenceForRead {
			g.P("if ", protoimplPackage.Ident("X"), ".Present(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ") {")
		}
		// For lazy, check if pointer is nil and optionally unmarshal
		if isLazy(field) {
			// Since pointer to lazily unmarshaled sub-message can be written during a conceptual
			// "read" operation, all read/write accesses to the pointer must be atomic.  This
			// function gets inlined on x86 as just a simple get and compare. Still need to make the
			// slice accesses be atomic.
			g.P("if ", protoimplPackage.Ident("X"), ".AtomicCheckPointerIsNil(&", structPtr, ".xxx_hidden_", field.GoName, ") {")
			g.P(protoimplPackage.Ident("X"), ".UnmarshalField(", structPtr, ", ", field.Desc.Number(), ")")
			g.P("}")
		}
		if field.Message == nil || field.Desc.IsMap() {
			star := ""
			if pointer {
				star = "*"
			}
			if pointer {
				g.P("if ", structPtr, ".xxx_hidden_", field.GoName, "!= nil {")
			}

			g.P("return ", star, structPtr, ".xxx_hidden_", field.GoName)
			if pointer {
				g.P("}")
				g.P("return ", defaultValue)
			}
		} else {
			// We need to do an atomic load of the msg pointer field, but cannot explicitly use
			// unsafe pointers here.  We load the value and store into rv, via protoimpl.Pointer,
			// which is aliased to unsafe.Pointer in pointer_unsafe.go, but is aliased to
			// interface{} in pointer_reflect.go
			star := ""
			if pointer {
				star = "*"
			}
			if isLazy(field) {
				g.P("var rv ", star, goType)
				g.P(protoimplPackage.Ident("X"), ".AtomicLoadPointer(", protoimplPackage.Ident("Pointer"), "(&", structPtr, ".xxx_hidden_", field.GoName, "), ", protoimplPackage.Ident("Pointer"), "(&rv))")
				g.P("return ", star, "rv")
			} else {
				if pointer {
					g.P("if ", structPtr, ".xxx_hidden_", field.GoName, "!= nil {")
				}
				g.P("return ", star, structPtr, ".xxx_hidden_", field.GoName)
				if pointer {
					g.P("}")
				}
			}
		}
		if usePresenceForRead {
			g.P("}")
		}
	} else if pointer {
		g.P("if ", structPtr, ".xxx_hidden_", field.GoName, " != nil {")
		g.P("return *", structPtr, ".xxx_hidden_", field.GoName)
		g.P("}")
	} else {
		g.P("return ", structPtr, ".xxx_hidden_", field.GoName)
	}
	// End if m != nil {.
	g.P("}")
	g.P("return ", defaultValue)
	g.P("}")
	g.P()
}

// opaqueGenSet generates a Set method for a field.
func opaqueGenSet(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field) {
	goType, pointer := opaqueFieldGoType(g, f, message, field)
	setterName, bcName := field.MethodName("Set")

	// If we need a backwards compatible setter name, we add it now.
	if bcName != "" {
		defer func() {
			g.P("// Deprecated: Use ", setterName, " instead.")
			g.P("func (x *", message.GoIdent, ") ", bcName, "(v ", goType, ") {")
			g.P("x.", setterName, "(v)")
			g.P("}")
			g.P()
		}()
	}

	leadingComments := appendDeprecationSuffix("",
		field.Desc.ParentFile(),
		field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
	g.AnnotateSymbol(message.GoIdent.GoName+"."+setterName, protogen.Annotation{
		Location: field.Location,
		Semantic: descriptorpb.GeneratedCodeInfo_Annotation_SET.Enum(),
	})
	fieldtrackNoInterface(g, message.noInterface)

	// Weak field.
	if field.Desc.IsWeak() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", setterName, "(v ", protoPackage.Ident("Message"), ") {")
		g.P("var w *", protoimplPackage.Ident("WeakFields"))
		g.P("if x != nil {")
		g.P("w = &x.", genid.WeakFields_goname)
		if message.isTracked {
			g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName)
		}
		g.P("}")
		g.P(protoimplPackage.Ident("X"), ".SetWeak(w, ", field.Desc.Number(), ", ", strconv.Quote(string(field.Message.Desc.FullName())), ", v)")
		g.P("}")
		g.P()
		return
	}

	// Oneof field.
	if oneof := field.Oneof; oneof != nil && !oneof.Desc.IsSynthetic() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", setterName, "(v ", goType, ") {")
		structPtr := "x"
		if message.isOpaque() && message.isTracked {
			// Add access to zero field for tracking
			g.P(structPtr, ".XXX_ft_", oneof.GoName, " = struct{}{}")
		}
		if field.Desc.Kind() == protoreflect.BytesKind {
			g.P("if v == nil { v = []byte{} }")
		} else if field.Message != nil {
			g.P("if v == nil {")
			g.P(structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), "= nil")
			g.P("return")
			g.P("}")
		}
		g.P(structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), "= &", opaqueFieldOneofType(field, message.isOpaque()), "{v}")
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field for open type message.
	if !message.isOpaque() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", setterName, "(v ", goType, ") {")
		if field.Desc.Cardinality() != protoreflect.Repeated && field.Desc.Kind() == protoreflect.BytesKind {
			g.P("if v == nil { v = []byte{} }")
		}
		amp := ""
		if pointer {
			amp = "&"
		}

		v := "v"
		g.P("x.", field.GoName, " = ", amp, v)
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field for opaque type message.
	g.P(leadingComments, "func (x *", message.GoIdent, ") ", setterName, "(v ", goType, ") {")
	structPtr := "x"
	if message.isTracked {
		// Add access to zero field for tracking
		g.P(structPtr, ".XXX_ft_", field.GoName, " = struct{}{}")
	}
	if field.Desc.Cardinality() != protoreflect.Repeated && field.Desc.Kind() == protoreflect.BytesKind {
		g.P("if v == nil { v = []byte{} }")
	}
	amp := ""
	if pointer {
		amp = "&"
	}
	if usePresence(message, field) {
		pi := opaqueFieldPresenceIndex(field)
		ai := pi / 32

		if field.Message != nil && field.Desc.IsList() {
			g.P("var sv *", goType)
			g.P(protoimplPackage.Ident("X"), ".AtomicLoadPointer(", protoimplPackage.Ident("Pointer"), "(&", structPtr, ".xxx_hidden_", field.GoName, "), ", protoimplPackage.Ident("Pointer"), "(&sv))")
			g.P("if sv == nil {")
			g.P("sv = &", goType, "{}")
			g.P(protoimplPackage.Ident("X"), ".AtomicInitializePointer(", protoimplPackage.Ident("Pointer"), "(&", structPtr, ".xxx_hidden_", field.GoName, "), ", protoimplPackage.Ident("Pointer"), "(&sv))")
			g.P("}")
			g.P("*sv = v")
			g.P(protoimplPackage.Ident("X"), ".SetPresent(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ",", opaqueNumPresenceFields(message), ")")
		} else if field.Message != nil && !field.Desc.IsMap() {
			// Only for lazy messages do we need to set pointers atomically
			if isLazy(field) {
				g.P(protoimplPackage.Ident("X"), ".AtomicSetPointer(&", structPtr, ".xxx_hidden_", field.GoName, ", ", amp, "v)")
			} else {
				g.P(structPtr, ".xxx_hidden_", field.GoName, " = ", amp, "v")
			}
			// When setting a message or slice of messages to a nil
			// value, we must clear the presence bit, else we will
			// later think that this field still needs to be lazily decoded.
			g.P("if v == nil {")
			g.P(protoimplPackage.Ident("X"), ".ClearPresent(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ")")
			g.P("} else {")
			g.P(protoimplPackage.Ident("X"), ".SetPresent(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ",", opaqueNumPresenceFields(message), ")")
			g.P("}")
		} else {
			// Any map or non-message, possibly repeated, field that uses presence (proto2 only)
			g.P(structPtr, ".xxx_hidden_", field.GoName, " = ", amp, "v")
			// For consistent behaviour with lazy fields, non-map repeated fields should be cleared when
			// the last object is removed. Maps are cleared when set to a nil map.
			if field.Desc.Cardinality() == protoreflect.Repeated { // Includes maps.
				g.P("if v == nil {")
				g.P(protoimplPackage.Ident("X"), ".ClearPresent(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ")")
				g.P("} else {")
			}
			g.P(protoimplPackage.Ident("X"), ".SetPresent(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ",", opaqueNumPresenceFields(message), ")")
			if field.Desc.Cardinality() == protoreflect.Repeated {
				g.P("}")
			}
		}
	} else {
		// proto3 non-lazy fields
		g.P(structPtr, ".xxx_hidden_", field.GoName, " = ", amp, "v")
	}
	g.P("}")
	g.P()
}

// usePresence returns true if the presence map should be used for a field. It
// is always true for lazy message types. It is also true for all scalar fields.
// repeated, map or message fields are not using the presence map.
func usePresence(message *messageInfo, field *protogen.Field) bool {
	if !message.isOpaque() || field.Desc.IsWeak() {
		return false
	}
	return opaqueFieldNeedsPresenceArray(message, field)
}

func opaqueFieldNeedsPresenceArray(message *messageInfo, field *protogen.Field) bool {
	// Non optional fields need presence if truly lazy field, i.e. are message fields.
	if isLazy(field) {
		return true
	}
	isNotOneof := field.Desc.ContainingOneof() == nil || field.Desc.ContainingOneof().IsSynthetic()
	return field.Desc.HasPresence() && field.Message == nil && isNotOneof
}

// opaqueGenHas generates a Has method for a field.
func opaqueGenHas(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field) {
	hasserName, _ := field.MethodName("Has")

	leadingComments := appendDeprecationSuffix("",
		field.Desc.ParentFile(),
		field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
	g.AnnotateSymbol(message.GoIdent.GoName+"."+hasserName, protogen.Annotation{Location: field.Location})
	fieldtrackNoInterface(g, message.noInterface)

	// Weak field.
	if field.Desc.IsWeak() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", hasserName, "() bool {")
		g.P("var w ", protoimplPackage.Ident("WeakFields"))
		g.P("if x != nil {")
		g.P("w = x.", genid.WeakFields_goname)
		if message.isTracked {
			g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName)
		}
		g.P("}")
		g.P("return ", protoimplPackage.Ident("X"), ".HasWeak(w, ", field.Desc.Number(), ")")
		g.P("}")
		g.P()
		return
	}

	// Oneof field.
	if oneof := field.Oneof; oneof != nil && !oneof.Desc.IsSynthetic() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", hasserName, "() bool {")
		structPtr := "x"
		g.P("if ", structPtr, " == nil {")
		g.P("return false")
		g.P("}")
		if message.isOpaque() && message.isTracked {
			// Add access to zero field for tracking
			g.P("_ = ", structPtr, ".", "XXX_ft_", oneof.GoName)
		}
		g.P("_, ok := ", structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), ".(*", opaqueFieldOneofType(field, message.isOpaque()), ")")
		g.P("return ok")
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field in open message.
	if !message.isOpaque() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", hasserName, "() bool {")
		g.P("if x == nil {")
		g.P("return false")
		g.P("}")
		g.P("return ", "x.", field.GoName, " != nil")
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field in opaque message.
	g.P(leadingComments, "func (x *", message.GoIdent, ") ", hasserName, "() bool {")
	g.P("if x == nil {")
	g.P("return false")
	g.P("}")
	structPtr := "x"
	if message.isTracked {
		// Add access to zero field for tracking
		g.P("_ = ", structPtr, ".", "XXX_ft_"+field.GoName)
	}
	if usePresence(message, field) {
		pi := opaqueFieldPresenceIndex(field)
		ai := pi / 32
		g.P("return ", protoimplPackage.Ident("X"), ".Present(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ")")
	} else {
		// Has for proto3 message without presence
		g.P("return ", structPtr, ".xxx_hidden_", field.GoName, " != nil")
	}

	g.P("}")
	g.P()
}

// opaqueGenClear generates a Clear method for a field.
func opaqueGenClear(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field) {
	clearerName, _ := field.MethodName("Clear")
	pi := opaqueFieldPresenceIndex(field)
	ai := pi / 32

	leadingComments := appendDeprecationSuffix("",
		field.Desc.ParentFile(),
		field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
	g.AnnotateSymbol(message.GoIdent.GoName+"."+clearerName, protogen.Annotation{
		Location: field.Location,
		Semantic: descriptorpb.GeneratedCodeInfo_Annotation_SET.Enum(),
	})
	fieldtrackNoInterface(g, message.noInterface)

	// Weak field.
	if field.Desc.IsWeak() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", clearerName, "() {")
		g.P("var w *", protoimplPackage.Ident("WeakFields"))
		g.P("if x != nil {")
		g.P("w = &x.", genid.WeakFields_goname)
		if message.isTracked {
			g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName)
		}
		g.P("}")
		g.P(protoimplPackage.Ident("X"), ".ClearWeak(w, ", field.Desc.Number(), ")")
		g.P("}")
		g.P()
		return
	}

	// Oneof field.
	if oneof := field.Oneof; oneof != nil && !oneof.Desc.IsSynthetic() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", clearerName, "() {")
		structPtr := "x"
		if message.isOpaque() && message.isTracked {
			// Add access to zero field for tracking
			g.P(structPtr, ".", "XXX_ft_", oneof.GoName, " = struct{}{}")
		}
		g.P("if _, ok := ", structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), ".(*", opaqueFieldOneofType(field, message.isOpaque()), "); ok {")
		g.P(structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), " = nil")
		g.P("}")
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field in open message.
	if !message.isOpaque() {
		g.P(leadingComments, "func (x *", message.GoIdent, ") ", clearerName, "() {")
		g.P("x.", field.GoName, " = nil")
		g.P("}")
		g.P()
		return
	}

	// Non-oneof field in opaque message.
	g.P(leadingComments, "func (x *", message.GoIdent, ") ", clearerName, "() {")
	structPtr := "x"
	if message.isTracked {
		// Add access to zero field for tracking
		g.P(structPtr, ".", "XXX_ft_", field.GoName, " = struct{}{}")
	}

	if usePresence(message, field) {
		g.P(protoimplPackage.Ident("X"), ".ClearPresent(&(", structPtr, ".XXX_presence[", ai, "]),", pi, ")")
	}

	// Avoid needing to read the presence value in Get by ensuring that we set the
	// right zero value (unless we have an explicit default, in which case we
	// revert to presence checking in Get). Rationale: Get is called far more
	// frequently than Clear, it should be as lean as possible.
	zv := opaqueZeroValueForField(g, field)
	// For lazy, (repeated) message fields are unmarshalled lazily. Hence they are
	// assigned atomically in Getters (which are allowed to be called
	// concurrently). Due to this, historically, the code generator would use
	// atomic operations everywhere.
	//
	// TODO(b/291588964): Stop using atomic operations for non-presence fields in
	//                    write calls (Set/Clear). Concurrent reads are allowed,
	//                    but concurrent read/write or write/write are not, we
	//                    shouldn't cater to it.
	if isLazy(field) {
		goType, _ := opaqueFieldGoType(g, f, message, field)
		g.P(protoimplPackage.Ident("X"), ".AtomicSetPointer(&", structPtr, ".xxx_hidden_", field.GoName, ",(", goType, ")(", zv, "))")
	} else if !field.Desc.HasDefault() {
		g.P(structPtr, ".xxx_hidden_", field.GoName, " = ", zv)
	}
	g.P("}")
	g.P()
}

// Determine what value to set a cleared field to.
func opaqueZeroValueForField(g *protogen.GeneratedFile, field *protogen.Field) string {
	if field.Desc.Cardinality() == protoreflect.Repeated {
		return "nil"
	}
	switch field.Desc.Kind() {
	case protoreflect.StringKind:
		return "nil"
	case protoreflect.MessageKind, protoreflect.GroupKind, protoreflect.BytesKind:
		return "nil"
	case protoreflect.BoolKind:
		return "false"
	case protoreflect.EnumKind:
		return g.QualifiedGoIdent(field.Enum.Values[0].GoIdent)
	default:
		return "0"
	}
}

// opaqueGenGetOneof generates a Get function for a oneof union.
func opaqueGenGetOneof(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, oneof *protogen.Oneof) {
	ifName := opaqueOneofInterfaceName(oneof)
	g.AnnotateSymbol(message.GoIdent.GoName+".Get"+oneof.GoName, protogen.Annotation{Location: oneof.Location})
	fieldtrackNoInterface(g, message.isTracked)
	g.P("func (x *", message.GoIdent.GoName, ") Get", oneof.GoName, "() ", ifName, " {")
	g.P("if x != nil {")
	g.P("return x.", opaqueOneofFieldName(oneof, message.isOpaque()))
	g.P("}")
	g.P("return nil")
	g.P("}")
	g.P()
}

// opaqueGenHasOneof generates a Has function for a oneof union.
func opaqueGenHasOneof(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, oneof *protogen.Oneof) {
	fieldtrackNoInterface(g, message.noInterface)
	hasserName := oneof.MethodName("Has")
	g.P("func (x *", message.GoIdent, ") ", hasserName, "() bool {")
	g.P("if x == nil {")
	g.P("return false")
	g.P("}")
	structPtr := "x"
	if message.isOpaque() && message.isTracked {
		// Add access to zero field for tracking
		g.P("_ = ", structPtr, ".XXX_ft_", oneof.GoName)
	}
	g.P("return ", structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), " != nil")
	g.P("}")
	g.P()
}

// opaqueGenClearOneof generates a Clear function for a oneof union.
func opaqueGenClearOneof(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, oneof *protogen.Oneof) {
	fieldtrackNoInterface(g, message.noInterface)
	clearerName := oneof.MethodName("Clear")
	g.P("func (x *", message.GoIdent, ") ", clearerName, "() {")
	structPtr := "x"
	if message.isOpaque() && message.isTracked {
		// Add access to zero field for tracking
		g.P(structPtr, ".", "XXX_ft_", oneof.GoName, " = struct{}{}")
	}
	g.P(structPtr, ".", opaqueOneofFieldName(oneof, message.isOpaque()), " = nil")
	g.P("}")
	g.P()
}

// opaqueGenWhichOneof generates the Which method for each oneof union, as well as the case values for each member
// of that union.
func opaqueGenWhichOneof(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo) {
	// Go through the message, and for each field that is the first of a oneof field, dig down
	// and generate constants + the actual which method.
	oneofIndex := 0
	for _, field := range message.Fields {
		if oneof := field.Oneof; oneof != nil {
			if !isFirstOneofField(field) {
				continue
			}
			caseType := opaqueOneofCaseTypeName(oneof)
			g.P("const ", message.GoIdent.GoName, "_", oneof.GoName, "_not_set_case ", caseType, " = ", 0)
			for _, f := range oneof.Fields {
				g.P("const ", message.GoIdent.GoName, "_", f.GoName, "_case ", caseType, " = ", f.Desc.Number())
			}
			fieldtrackNoInterface(g, message.noInterface)
			whicherName := oneof.MethodName("Which")
			g.P("func (x *", message.GoIdent, ") ", whicherName, "() ", caseType, " {")
			g.P("if x == nil {")
			g.P("return ", message.GoIdent.GoName, "_", oneof.GoName, "_not_set_case ")
			g.P("}")
			g.P("switch x.", opaqueOneofFieldName(oneof, message.isOpaque()), ".(type) {")
			for _, f := range oneof.Fields {
				g.P("case *", opaqueFieldOneofType(f, message.isOpaque()), ":")
				g.P("return ", message.GoIdent.GoName, "_", f.GoName, "_case")
			}
			g.P("default", ":")
			g.P("return ", message.GoIdent.GoName, "_", oneof.GoName, "_not_set_case ")
			g.P("}")
			g.P("}")
			g.P()
			oneofIndex++
		}
	}
}

func opaqueNeedsPresenceArray(message *messageInfo) bool {
	if !message.isOpaque() {
		return false
	}
	for _, field := range message.Fields {
		if opaqueFieldNeedsPresenceArray(message, field) {
			return true
		}
	}
	return false
}

func opaqueNeedsLazyStruct(message *messageInfo) bool {
	for _, field := range message.Fields {
		if isLazy(field) {
			return true
		}
	}
	return false
}

// opaqueGenMessageBuilder generates a Builder type for a message.
func opaqueGenMessageBuilder(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo) {
	if message.isOpen() {
		return
	}
	// Builder type.
	bName := g.QualifiedGoIdent(message.GoIdent) + genid.BuilderSuffix_goname
	g.AnnotateSymbol(message.GoIdent.GoName+genid.BuilderSuffix_goname, protogen.Annotation{Location: message.Location})

	leadingComments := appendDeprecationSuffix("",
		message.Desc.ParentFile(),
		message.Desc.Options().(*descriptorpb.MessageOptions).GetDeprecated())
	g.P(leadingComments, "type ", bName, " struct {")
	g.P("_ [0]func() // Prevents comparability and use of unkeyed literals for the builder.")
	g.P()
	for _, field := range message.Fields {
		oneof := field.Oneof
		if oneof == nil && field.Desc.IsWeak() {
			continue
		}

		goType, pointer := opaqueBuilderFieldGoType(g, f, message, field)
		if pointer {
			goType = "*" + goType
		} else if oneof != nil && fieldDefaultValue(g, f, message, field) != "nil" {
			goType = "*" + goType
		}
		// Track all non-oneof fields. Note: synthetic oneofs are an
		// implementation detail of proto3 optional fields:
		// go/proto-proposals/proto3-presence.md, which should be tracked.
		tag := ""
		if (oneof == nil || oneof.Desc.IsSynthetic()) && message.isTracked {
			tag = "`go:\"track\"`"
		}
		if oneof != nil && oneof.Fields[0] == field && !oneof.Desc.IsSynthetic() {
			if oneof.Comments.Leading != "" {
				g.P(oneof.Comments.Leading)
				g.P()
			}
			g.P("// Fields of oneof ", opaqueOneofFieldName(oneof, message.isOpaque()), ":")
		}
		g.AnnotateSymbol(field.Parent.GoIdent.GoName+genid.BuilderSuffix_goname+"."+field.BuilderFieldName(), protogen.Annotation{Location: field.Location})
		leadingComments := appendDeprecationSuffix(field.Comments.Leading,
			field.Desc.ParentFile(),
			field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
		g.P(leadingComments,
			field.BuilderFieldName(), " ", goType, " ", tag)
		if oneof != nil && oneof.Fields[len(oneof.Fields)-1] == field && !oneof.Desc.IsSynthetic() {
			g.P("// -- end of ", opaqueOneofFieldName(oneof, message.isOpaque()))
		}
	}
	g.P("}")
	g.P()

	opaqueGenBuildMethod(g, f, message, bName)
}

// opaqueGenBuildMethod generates the actual Build method for the builder
func opaqueGenBuildMethod(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, bName string) {
	// Build method on the builder type.
	fieldtrackNoInterface(g, message.noInterface)
	g.P("func (b0 ", bName, ") Build() *", message.GoIdent, " {")
	g.P("m0 := &", message.GoIdent, "{}")

	if message.isTracked {
		// Redeclare the builder and message types as local
		// defined types, so that field tracking records the
		// field uses against these types instead of the
		// original struct types.
		//
		// TODO: Actually redeclare the struct types
		// without `go:"track"` tags?
		g.P("type (notrackB ", bName, "; notrackM ", message.GoIdent, ")")
		g.P("b, x := (*notrackB)(&b0), (*notrackM)(m0)")
	} else {
		g.P("b, x := &b0, m0")
	}
	g.P("_, _ = b, x")

	for _, field := range message.Fields {
		oneof := field.Oneof
		if oneof == nil && field.Desc.IsWeak() {
			continue
		}
		if oneof != nil && !oneof.Desc.IsSynthetic() {
			qual := ""
			if fieldDefaultValue(g, f, message, field) != "nil" {
				qual = "*"
			}

			g.P("if b.", field.BuilderFieldName(), " != nil {")
			oneofName := opaqueOneofFieldName(oneof, message.isOpaque())
			oneofType := opaqueFieldOneofType(field, message.isOpaque())
			g.P("x.", oneofName, " = &", oneofType, "{", qual, "b.", field.BuilderFieldName(), "}")
			g.P("}")
		} else { // proto3 optional ends up here (synthetic oneof)
			qual := ""
			_, pointer := opaqueBuilderFieldGoType(g, f, message, field)
			if pointer && message.isOpaque() && !field.Desc.IsList() && field.Desc.Kind() != protoreflect.StringKind {
				qual = "*"
			} else if message.isOpaque() && field.Desc.IsList() && field.Desc.Message() != nil {
				qual = "&"
			}
			presence := usePresence(message, field)
			if presence {
				g.P("if b.", field.BuilderFieldName(), " != nil {")
			}
			if presence {
				pi := opaqueFieldPresenceIndex(field)
				g.P(protoimplPackage.Ident("X"), ".SetPresentNonAtomic(&(x.XXX_presence[", pi/32, "]),", pi, ",", opaqueNumPresenceFields(message), ")")
			}
			goName := field.GoName
			if message.isOpaque() {
				goName = "xxx_hidden_" + goName
			}
			g.P("x.", goName, " = ", qual, "b.", field.BuilderFieldName())
			if presence {
				g.P("}")
			}
		}
	}

	g.P("return m0")
	g.P("}")
	g.P()
}

// opaqueBuilderFieldGoType does the same as opaqueFieldGoType, but corrects for
// types that are different in a builder
func opaqueBuilderFieldGoType(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field) (goType string, pointer bool) {
	goType, pointer = opaqueFieldGoType(g, f, message, field)
	kind := field.Desc.Kind()

	// Use []T instead of *[]T for opaque repeated lists.
	if message.isOpaque() && field.Desc.IsList() {
		pointer = false
	}

	// Use *T for optional fields.
	optional := field.Desc.HasPresence()
	if optional &&
		kind != protoreflect.GroupKind &&
		kind != protoreflect.MessageKind &&
		kind != protoreflect.BytesKind &&
		field.Desc.Cardinality() != protoreflect.Repeated {
		pointer = true
	}

	return goType, pointer
}

func opaqueGenOneofWrapperTypes(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo) {
	// TODO: We should avoid generating these wrapper types in pure-opaque mode.
	if !message.isOpen() {
		for _, oneof := range message.Oneofs {
			if oneof.Desc.IsSynthetic() {
				continue
			}
			caseTypeName := opaqueOneofCaseTypeName(oneof)
			g.P("type ", caseTypeName, " ", protoreflectPackage.Ident("FieldNumber"))
			g.P("")

			idx := f.allMessagesByPtr[message]
			typesVar := messageTypesVarName(f)
			g.P("func (x ", caseTypeName, ") String() string {")
			g.P("md := ", typesVar, "[", idx, "].Descriptor()")
			g.P("if x == 0 {")
			g.P(`return "not set"`)
			g.P("}")
			g.P("return ", protoimplPackage.Ident("X"), ".MessageFieldStringOf(md, ", protoreflectPackage.Ident("FieldNumber"), "(x))")
			g.P("}")
			g.P()
		}
	}
	for _, oneof := range message.Oneofs {
		if oneof.Desc.IsSynthetic() {
			continue
		}
		ifName := opaqueOneofInterfaceName(oneof)
		g.P("type ", ifName, " interface {")
		g.P(ifName, "()")
		g.P("}")
		g.P()
		for _, field := range oneof.Fields {
			name := opaqueFieldOneofType(field, message.isOpaque())
			g.AnnotateSymbol(name.GoName, protogen.Annotation{Location: field.Location})
			g.AnnotateSymbol(name.GoName+"."+field.GoName, protogen.Annotation{Location: field.Location})
			g.P("type ", name, " struct {")
			goType, _ := opaqueFieldGoType(g, f, message, field)
			protobufTagValue := fieldProtobufTagValue(field)
			if g.InternalStripForEditionsDiff() {
				protobufTagValue = strings.ReplaceAll(protobufTagValue, ",proto3", "")
			}
			tags := structTags{
				{"protobuf", protobufTagValue},
			}
			leadingComments := appendDeprecationSuffix(field.Comments.Leading,
				field.Desc.ParentFile(),
				field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
			g.P(leadingComments,
				field.GoName, " ", goType, tags,
				trailingComment(field.Comments.Trailing))
			g.P("}")
			g.P()
		}
		for _, field := range oneof.Fields {
			g.P("func (*", opaqueFieldOneofType(field, message.isOpaque()), ") ", ifName, "() {}")
			g.P()
		}
	}
}

// opaqueFieldGoType returns the Go type used for a field.
//
// If it returns pointer=true, the struct field is a pointer to the type.
func opaqueFieldGoType(g *protogen.GeneratedFile, f *fileInfo, message *messageInfo, field *protogen.Field) (goType string, pointer bool) {
	if field.Desc.IsWeak() {
		return "struct{}", false
	}

	pointer = true
	switch field.Desc.Kind() {
	case protoreflect.BoolKind:
		goType = "bool"
	case protoreflect.EnumKind:
		goType = g.QualifiedGoIdent(field.Enum.GoIdent)
	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
		goType = "int32"
	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
		goType = "uint32"
	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
		goType = "int64"
	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
		goType = "uint64"
	case protoreflect.FloatKind:
		goType = "float32"
	case protoreflect.DoubleKind:
		goType = "float64"
	case protoreflect.StringKind:
		goType = "string"
	case protoreflect.BytesKind:
		goType = "[]byte"
		pointer = false
	case protoreflect.MessageKind, protoreflect.GroupKind:
		goType = opaqueMessageFieldGoType(g, f, field, message.isOpaque())
		pointer = false
	}
	switch {
	case field.Desc.IsList():
		goType = "[]" + goType
		pointer = false
	case field.Desc.IsMap():
		keyType, _ := opaqueFieldGoType(g, f, message, field.Message.Fields[0])
		valType, _ := opaqueFieldGoType(g, f, message, field.Message.Fields[1])
		return fmt.Sprintf("map[%v]%v", keyType, valType), false
	}

	// Extension fields always have pointer type, even when defined in a proto3 file.
	if !field.Desc.IsExtension() && !field.Desc.HasPresence() {
		pointer = false
	}

	if message.isOpaque() {
		switch {
		case field.Desc.IsList() && field.Desc.Message() != nil:
			pointer = true
		case !field.Desc.IsList() && field.Desc.Kind() == protoreflect.StringKind:
			switch {
			case field.Desc.HasPresence():
				pointer = true
			default:
				pointer = false
			}
		default:
			pointer = false
		}
	}

	return goType, pointer
}

func opaqueMessageFieldGoType(g *protogen.GeneratedFile, f *fileInfo, field *protogen.Field, isOpaque bool) string {
	return "*" + g.QualifiedGoIdent(field.Message.GoIdent)
}

// opaqueFieldPresenceIndex returns the index to pass to presence functions.
//
// TODO: field.Desc.Index() would be simpler, and would give space to record the presence of oneof fields.
func opaqueFieldPresenceIndex(field *protogen.Field) int {
	structFieldIndex := 0
	for _, f := range field.Parent.Fields {
		if field == f {
			break
		}
		if f.Oneof == nil || isLastOneofField(f) {
			structFieldIndex++
		}
	}
	return structFieldIndex
}

// opaqueNumPresenceFields returns the number of fields that may be passed to presence functions.
//
// Since all fields in a oneof currently share a single entry in the presence bitmap,
// this is not just len(message.Fields).
func opaqueNumPresenceFields(message *messageInfo) int {
	if len(message.Fields) == 0 {
		return 0
	}
	return opaqueFieldPresenceIndex(message.Fields[len(message.Fields)-1]) + 1
}

func fieldtrackNoInterface(g *protogen.GeneratedFile, isTracked bool) {
	if isTracked {
		g.P("//go:nointerface")
	}
}

// opaqueOneofFieldName returns the name of the struct field that holds
// the value of a oneof.
func opaqueOneofFieldName(oneof *protogen.Oneof, isOpaque bool) string {
	if isOpaque {
		return "xxx_hidden_" + oneof.GoName
	}
	return oneof.GoName
}

func opaqueFieldOneofType(field *protogen.Field, isOpaque bool) protogen.GoIdent {
	ident := protogen.GoIdent{
		GoImportPath: field.Parent.GoIdent.GoImportPath,
		GoName:       field.Parent.GoIdent.GoName + "_" + field.GoName,
	}
	// Check for collisions with nested messages or enums.
	//
	// This conflict resolution is incomplete: Among other things, it
	// does not consider collisions with other oneof field types.
Loop:
	for {
		for _, message := range field.Parent.Messages {
			if message.GoIdent == ident {
				ident.GoName += "_"
				continue Loop
			}
		}
		for _, enum := range field.Parent.Enums {
			if enum.GoIdent == ident {
				ident.GoName += "_"
				continue Loop
			}
		}
		return unexportIdent(ident, isOpaque)
	}
}

// unexportIdent turns id into its unexported version (by lower-casing), but
// only if isOpaque is set. This function is used for oneof wrapper types,
// which remain exported in the non-opaque API for now.
func unexportIdent(id protogen.GoIdent, isOpaque bool) protogen.GoIdent {
	if !isOpaque {
		return id
	}
	r, sz := utf8.DecodeRuneInString(id.GoName)
	if r == utf8.RuneError {
		panic(fmt.Sprintf("Go identifier %q contains invalid UTF8?!", id.GoName))
	}
	r = unicode.ToLower(r)
	id.GoName = string(r) + id.GoName[sz:]
	return id
}

func opaqueOneofInterfaceName(oneof *protogen.Oneof) string {
	return fmt.Sprintf("is%s_%s", oneof.Parent.GoIdent.GoName, oneof.GoName)
}
func opaqueOneofCaseTypeName(oneof *protogen.Oneof) string {
	return fmt.Sprintf("case_%s_%s", oneof.Parent.GoIdent.GoName, oneof.GoName)
}

// isFirstOneofField reports whether this is the first field in a oneof.
func isFirstOneofField(field *protogen.Field) bool {
	return field.Oneof != nil && field == field.Oneof.Fields[0] && !field.Oneof.Desc.IsSynthetic()
}

// isLastOneofField returns true if this is the last field in a oneof.
func isLastOneofField(field *protogen.Field) bool {
	return field.Oneof != nil && field == field.Oneof.Fields[len(field.Oneof.Fields)-1]
}
