// 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"
	"strings"
	"unicode"
	"unicode/utf8"

	"google.golang.org/protobuf/compiler/protogen"
	"google.golang.org/protobuf/internal/filedesc"
	"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 message.isOpaque() {
		name = "xxx_hidden_" + name
	}

	if message.isOpaque() {
		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.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 do not have setters.
		if message.isOpen() {
			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?
	return field.Desc.(interface{ IsLazy() bool }).IsLazy()
}

// 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})

	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)

	// 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() {
		return false
	}
	usePresence, _ := filedesc.UsePresenceForField(field.Desc)
	return usePresence
}

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

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

	// 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 usePresence, _ := filedesc.UsePresenceForField(field.Desc); usePresence {
			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

		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 && !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) {
	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]
}
