// Copyright 2018 The Fuchsia 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 codegen

import (
	"fmt"
	"math"
	"sort"
	"strconv"
	"strings"
	"unicode"

	"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

type EncodedCompoundIdentifier = fidlgen.EncodedCompoundIdentifier

type Type struct {
	// TODO(https://fxbug.dev/42156522): Remove Resourceness once stored on fidlgen.Type.
	fidlgen.Resourceness

	// Information extracted from fidlgen.Type.
	Kind             fidlgen.TypeKind
	Nullable         bool
	PrimitiveSubtype fidlgen.PrimitiveSubtype
	ElementType      *Type
	Identifier       EncodedCompoundIdentifier
	DeclType         fidlgen.DeclType

	// The marker type that implements fidl::encoding::Type.
	Fidl string
	// The associated type fidl::encoding::Type::Owned.
	Owned string
	// The type to use when this occurs as a method parameter.
	// TODO(https://fxbug.dev/42073194): Once the transition to the new types if complete,
	// document this as being {Value,Resource}Type::Borrowed.
	Param string
}

type Alias struct {
	fidlgen.Alias
	Name string
	Type Type
}

type Bits struct {
	fidlgen.Bits
	Name           string
	UnderlyingType string
	Members        []BitsMember
}

type BitsMember struct {
	fidlgen.BitsMember
	Name  string
	Value string
}

type Const struct {
	fidlgen.Const
	Name  string
	Type  string
	Value string
}

type Enum struct {
	fidlgen.Enum
	Name           string
	UnderlyingType string
	Members        []EnumMember
	// Member name with the minimum value, used as an arbitrary default value
	// in Decode::new_empty for strict enums.
	MinMember string
}

type EnumMember struct {
	fidlgen.EnumMember
	Name  string
	Value string
}

type Union struct {
	fidlgen.Union
	Derives derives
	ECI     EncodedCompoundIdentifier
	Name    string
	Members []UnionMember
}

type UnionMember struct {
	fidlgen.UnionMember
	Type    Type
	Name    string
	Ordinal int
}

type Struct struct {
	fidlgen.Struct
	ECI                       EncodedCompoundIdentifier
	Derives                   derives
	Name                      string
	Members                   []StructMember
	PaddingMarkersV2          []fidlgen.PaddingMarker
	FlattenedPaddingMarkersV2 []fidlgen.PaddingMarker
	SizeV2                    int
	AlignmentV2               int
	HasPadding                bool
	// True if the struct should be encoded and decoded by memcpy.
	UseFidlStructCopy bool
}

type StructMember struct {
	fidlgen.StructMember
	Type     Type
	Name     string
	OffsetV2 int
}

type Table struct {
	fidlgen.Table
	Derives derives
	ECI     EncodedCompoundIdentifier
	Name    string
	Members []TableMember
}

func (t *Table) ReversedMembers() []TableMember {
	var r []TableMember
	for i := len(t.Members) - 1; i >= 0; i-- {
		r = append(r, t.Members[i])
	}
	return r
}

type TableMember struct {
	fidlgen.TableMember
	Type    Type
	Name    string
	Ordinal int
}

// Protocol is the definition of a protocol in the library being compiled.
type Protocol struct {
	// Raw JSON IR data about this protocol. Embedded to provide access to
	// fields common to all bindings.
	fidlgen.Protocol
	// Compound identifier referring to this protocol.
	ECI EncodedCompoundIdentifier
	// String to use for ProtocolMarker::DEBUG_NAME.
	DebugName string
	// True if the protocol is marked @discoverable.
	Discoverable bool
	// Name of the protocol's Marker struct.
	Marker string
	// Name of the protocol's Proxy struct.
	Proxy string
	// Name of the protocol's ProxyInterface trait.
	ProxyInterface string
	// Name of the protocol's SynchronousProxy struct.
	SynchronousProxy string
	// Name of the protocol's Request enum.
	Request string
	// Name of the protocol's RequestStream struct.
	RequestStream string
	// Name of the protocol's Event enum.
	Event string
	// Name of the protocol's EventStream struct.
	EventStream string
	// Name of the protocol's ControlHandle struct.
	ControlHandle string
	// List of methods that are part of this protocol.
	Methods []Method
}

// Method is a method defined in a protocol.
type Method struct {
	// Raw JSON IR data about this method. Embedded to provide access to fields
	// common to all bindings.
	fidlgen.Method
	// Name of the method converted to snake_case. Used when generating
	// rust-methods associated with this method, such as proxy methods and
	// encoder methods.
	Name string
	// Name of the method converted to CamelCase. Used when generating
	// rust-types associated with this method, such as responders.
	CamelName string
	// Name of the method's Responder struct.
	Responder string
	// Name of the method's ResponseFut type in the protocol's ProxyInterface trait.
	ResponseFut string

	Request  Payload
	Response Payload
}

// DynamicFlags gets rust code for the DynamicFlags value that should be set for
// a call to this method.
func (m *Method) DynamicFlags() string {
	if m.IsStrict() {
		return "fidl::encoding::DynamicFlags::empty()"
	}
	return "fidl::encoding::DynamicFlags::FLEXIBLE"
}

// A method request or response.
type Payload struct {
	// The fidl::encoding::Type type. It can be fidl::encoding::EmptyPayload,
	// a struct, table, or union, or (only for two-way responses) one of
	// fidl::encoding::{Result,Flexible,FlexibleResult}Type.
	FidlType string
	// Equivalent to <FidlType as fidl::encoding::Type>::Owned.
	OwnedType string
	// The user-facing owned type. This is derived from OwnedType by removing
	// flexible wrappers (if any) and flattening structs to tuples.
	TupleType string
	// For methods that use error syntax, TupleType is an alias that refers
	// to TupleTypeAliasRhs. Otherwise, TupleTypeAliasRhs is empty.
	// TODO(https://fxbug.dev/42073194): Remove.
	TupleTypeAliasRhs string
	// Parameters for sending this payload. For an empty payload, this is nil.
	// For a struct without error syntax, it contains one element per struct
	// field. Otherwise, it contains a single element (table, union, or Result).
	Parameters []Parameter
	// Assuming that names from Parameters are in scope, EncodeExpr is an
	// expression of a type implementing fidl::encoding::Encode<FidlType>.
	EncodeExpr string
	// ConvertToTuple converts an expression to TupleType. If OwnedType is
	// fidl::encoding::Flexible or fidl::encoding::FlexibleResult, expects the
	// input variable to be the Ok return value of .into_result(). Otherwise,
	// expects the input variable to be of type OwnedType.
	// TODO(https://fxbug.dev/42073194): Remove.
	ConvertToTuple func(string) string
	// Like ConvertToTuple, but uses names from Parameters for inclusion in a
	// struct. Examples for ConvertToFields("v"):
	//     ""
	//     "param1: v.param1, param2: v.param2,"
	//     "result: v.map(|x| x.param1),"
	// TODO(https://fxbug.dev/42073194): Remove.
	ConvertToFields func(string) string
}

// A parameter in a method request or response.
type Parameter struct {
	// Snake-case parameter name.
	Name string
	// Parameter type.
	Type string
	// Type to use when storing the parameter in an owning data structure.
	OwnedType string
	// Set only if this parameter corresponds to a struct member.
	StructMemberType *Type
}

type Service struct {
	fidlgen.Service
	Name        string
	Members     []ServiceMember
	ServiceName string
}

type ServiceMember struct {
	fidlgen.ServiceMember
	ProtocolType string
	Name         string
	CamelName    string
	SnakeName    string
}

type Root struct {
	Experiments  fidlgen.Experiments
	ExternCrates []string
	Aliases      []Alias
	Bits         []Bits
	Consts       []Const
	Enums        []Enum
	Structs      []Struct
	Unions       []Union
	Tables       []Table
	Protocols    []Protocol
	Services     []Service
}

func (r *Root) findProtocol(eci EncodedCompoundIdentifier) *Protocol {
	for i := range r.Protocols {
		if r.Protocols[i].ECI == eci {
			return &r.Protocols[i]
		}
	}
	return nil
}

func (r *Root) findStruct(eci EncodedCompoundIdentifier) *Struct {
	for i := range r.Structs {
		if r.Structs[i].ECI == eci {
			return &r.Structs[i]
		}
	}
	return nil
}

func (r *Root) findTable(eci EncodedCompoundIdentifier) *Table {
	for i := range r.Tables {
		if r.Tables[i].ECI == eci {
			return &r.Tables[i]
		}
	}
	return nil
}

func (r *Root) findUnion(eci EncodedCompoundIdentifier) *Union {
	for i := range r.Unions {
		if r.Unions[i].ECI == eci {
			return &r.Unions[i]
		}
	}
	return nil
}

var reservedWords = map[string]struct{}{
	"as":       {},
	"box":      {},
	"break":    {},
	"const":    {},
	"continue": {},
	"crate":    {},
	"else":     {},
	"enum":     {},
	"extern":   {},
	"false":    {},
	"fn":       {},
	"for":      {},
	"if":       {},
	"impl":     {},
	"in":       {},
	"let":      {},
	"loop":     {},
	"match":    {},
	"mod":      {},
	"move":     {},
	"mut":      {},
	"pub":      {},
	"ref":      {},
	"return":   {},
	"self":     {},
	"Self":     {},
	"static":   {},
	"struct":   {},
	"super":    {},
	"trait":    {},
	"true":     {},
	"type":     {},
	"unsafe":   {},
	"use":      {},
	"where":    {},
	"while":    {},

	// Keywords reserved for future use (future-proofing...)
	"abstract": {},
	"alignof":  {},
	"await":    {},
	"become":   {},
	"do":       {},
	"final":    {},
	"macro":    {},
	"offsetof": {},
	"override": {},
	"priv":     {},
	"proc":     {},
	"pure":     {},
	"sizeof":   {},
	"typeof":   {},
	"unsized":  {},
	"virtual":  {},
	"yield":    {},

	// Weak keywords (special meaning in specific contexts)
	// These are ok in all contexts of FIDL names.
	//"default":	{},
	//"union":	{},

	// Things that are not keywords, but for which collisions would be very
	// unpleasant
	"Result":  {},
	"Ok":      {},
	"Err":     {},
	"Vec":     {},
	"Option":  {},
	"Some":    {},
	"None":    {},
	"Box":     {},
	"Future":  {},
	"Stream":  {},
	"Never":   {},
	"Send":    {},
	"fidl":    {},
	"futures": {},
	"zx":      {},
	"async":   {},
	"on_open": {},
	"OnOpen":  {},
	// TODO(https://fxbug.dev/42145610): Remove "WaitForEvent".
	"wait_for_event": {},
	"WaitForEvent":   {},
}

var reservedSuffixes = []string{
	"Impl",
	"Marker",
	"Proxy",
	"ProxyProtocol",
	"ControlHandle",
	"Responder",
	"Server",
}

func isReservedWord(str string) bool {
	_, ok := reservedWords[str]
	return ok
}

// hasReservedSuffix checks if a string ends with a suffix commonly used by the
// bindings in generated types
func hasReservedSuffix(str string) bool {
	for _, suffix := range reservedSuffixes {
		if strings.HasSuffix(str, suffix) {
			return true
		}
	}
	return false
}

// changeIfReserved adds an underscore suffix to differentiate an identifier
// from a reserved name
//
// Reserved names include a variety of rust keywords, commonly used rust types
// like Result, Vec, and Future, and any name ending in a suffix used by the
// bindings to identify particular generated types like -Impl, -Marker, and
// -Proxy.
func changeIfReserved(val fidlgen.Identifier) string {
	str := string(val)
	if hasReservedSuffix(str) || isReservedWord(str) {
		return str + "_"
	}
	return str
}

var primitiveTypes = map[fidlgen.PrimitiveSubtype]string{
	fidlgen.Bool:    "bool",
	fidlgen.Int8:    "i8",
	fidlgen.Int16:   "i16",
	fidlgen.Int32:   "i32",
	fidlgen.Int64:   "i64",
	fidlgen.Uint8:   "u8",
	fidlgen.Uint16:  "u16",
	fidlgen.Uint32:  "u32",
	fidlgen.Uint64:  "u64",
	fidlgen.Float32: "f32",
	fidlgen.Float64: "f64",
}

var handleSubtypes = map[fidlgen.HandleSubtype]string{
	fidlgen.HandleSubtypeBti:          "fidl::Bti",
	fidlgen.HandleSubtypeChannel:      "fidl::Channel",
	fidlgen.HandleSubtypeClock:        "fidl::Clock",
	fidlgen.HandleSubtypeDebugLog:     "fidl::DebugLog",
	fidlgen.HandleSubtypeEvent:        "fidl::Event",
	fidlgen.HandleSubtypeEventpair:    "fidl::EventPair",
	fidlgen.HandleSubtypeException:    "fidl::Exception",
	fidlgen.HandleSubtypeFifo:         "fidl::Fifo",
	fidlgen.HandleSubtypeGuest:        "fidl::Guest",
	fidlgen.HandleSubtypeInterrupt:    "fidl::Interrupt",
	fidlgen.HandleSubtypeIommu:        "fidl::Iommu",
	fidlgen.HandleSubtypeJob:          "fidl::Job",
	fidlgen.HandleSubtypeMsi:          "fidl::Msi",
	fidlgen.HandleSubtypeNone:         "fidl::Handle",
	fidlgen.HandleSubtypePager:        "fidl::Pager",
	fidlgen.HandleSubtypePciDevice:    "fidl::PciDevice",
	fidlgen.HandleSubtypePmt:          "fidl::Pmt",
	fidlgen.HandleSubtypePort:         "fidl::Port",
	fidlgen.HandleSubtypeProcess:      "fidl::Process",
	fidlgen.HandleSubtypeProfile:      "fidl::Profile",
	fidlgen.HandleSubtypeResource:     "fidl::Resource",
	fidlgen.HandleSubtypeSocket:       "fidl::Socket",
	fidlgen.HandleSubtypeStream:       "fidl::Stream",
	fidlgen.HandleSubtypeSuspendToken: "fidl::SuspendToken",
	fidlgen.HandleSubtypeThread:       "fidl::Thread",
	fidlgen.HandleSubtypeTimer:        "fidl::Timer",
	fidlgen.HandleSubtypeVcpu:         "fidl::Vcpu",
	fidlgen.HandleSubtypeVmar:         "fidl::Vmar",
	fidlgen.HandleSubtypeVmo:          "fidl::Vmo",
}

var objectTypeConsts = map[fidlgen.HandleSubtype]string{
	fidlgen.HandleSubtypeBti:          "fidl::ObjectType::BTI",
	fidlgen.HandleSubtypeChannel:      "fidl::ObjectType::CHANNEL",
	fidlgen.HandleSubtypeClock:        "fidl::ObjectType::CLOCK",
	fidlgen.HandleSubtypeDebugLog:     "fidl::ObjectType::DEBUGLOG",
	fidlgen.HandleSubtypeEvent:        "fidl::ObjectType::EVENT",
	fidlgen.HandleSubtypeEventpair:    "fidl::ObjectType::EVENTPAIR",
	fidlgen.HandleSubtypeException:    "fidl::ObjectType::EXCEPTION",
	fidlgen.HandleSubtypeFifo:         "fidl::ObjectType::FIFO",
	fidlgen.HandleSubtypeGuest:        "fidl::ObjectType::GUEST",
	fidlgen.HandleSubtypeInterrupt:    "fidl::ObjectType::INTERRUPT",
	fidlgen.HandleSubtypeIommu:        "fidl::ObjectType::IOMMU",
	fidlgen.HandleSubtypeJob:          "fidl::ObjectType::JOB",
	fidlgen.HandleSubtypeMsi:          "fidl::ObjectType::MSI",
	fidlgen.HandleSubtypeNone:         "fidl::ObjectType::NONE",
	fidlgen.HandleSubtypePager:        "fidl::ObjectType::PAGER",
	fidlgen.HandleSubtypePciDevice:    "fidl::ObjectType::PCI_DEVICE",
	fidlgen.HandleSubtypePmt:          "fidl::ObjectType::PMT",
	fidlgen.HandleSubtypePort:         "fidl::ObjectType::PORT",
	fidlgen.HandleSubtypeProcess:      "fidl::ObjectType::PROCESS",
	fidlgen.HandleSubtypeProfile:      "fidl::ObjectType::PROFILE",
	fidlgen.HandleSubtypeResource:     "fidl::ObjectType::RESOURCE",
	fidlgen.HandleSubtypeSocket:       "fidl::ObjectType::SOCKET",
	fidlgen.HandleSubtypeStream:       "fidl::ObjectType::STREAM",
	fidlgen.HandleSubtypeSuspendToken: "fidl::ObjectType::SUSPEND_TOKEN",
	fidlgen.HandleSubtypeThread:       "fidl::ObjectType::THREAD",
	fidlgen.HandleSubtypeTimer:        "fidl::ObjectType::TIMER",
	fidlgen.HandleSubtypeVcpu:         "fidl::ObjectType::VCPU",
	fidlgen.HandleSubtypeVmar:         "fidl::ObjectType::VMAR",
	fidlgen.HandleSubtypeVmo:          "fidl::ObjectType::VMO",
}

type compiler struct {
	decls        fidlgen.DeclInfoMap
	experiments  fidlgen.Experiments
	library      fidlgen.LibraryIdentifier
	externCrates map[string]struct{}
	// Raw structs (including ExternalStructs), needed for
	// flattening parameters and in computeUseFidlStructCopy.
	structs map[fidlgen.EncodedCompoundIdentifier]fidlgen.Struct
}

func (c *compiler) inExternalLibrary(eci fidlgen.EncodedCompoundIdentifier) bool {
	return eci.LibraryName() != c.library.Encode()
}

func (c *compiler) lookupDeclInfo(val fidlgen.EncodedCompoundIdentifier) fidlgen.DeclInfo {
	if info, ok := c.decls[val]; ok {
		return info
	}
	panic(fmt.Sprintf("identifier not in decl map: %s", val))
}

func compileLibraryName(library fidlgen.LibraryIdentifier) string {
	parts := []string{"fidl"}
	for _, part := range library {
		parts = append(parts, string(part))
	}
	return changeIfReserved(fidlgen.Identifier(strings.Join(parts, "_")))
}

// TODO(https://fxbug.dev/42145610): Escaping reserved words should happen *after*
// converting to CamelCase.
func compileCamelIdentifier(val fidlgen.Identifier) string {
	return fidlgen.ToUpperCamelCase(changeIfReserved(val))
}

// TODO(https://fxbug.dev/42145610): Escaping reserved words should happen *after*
// converting to snake_case.
func compileSnakeIdentifier(val fidlgen.Identifier) string {
	return fidlgen.ToSnakeCase(changeIfReserved(val))
}

// TODO(https://fxbug.dev/42145610): Escaping reserved words should happen *after*
// converting to SCREAMING_SNAKE_CASE.
func compileScreamingSnakeIdentifier(val fidlgen.Identifier) string {
	return fidlgen.ConstNameToAllCapsSnake(changeIfReserved(val))
}

func isZirconIdentifier(ci fidlgen.CompoundIdentifier) bool {
	return len(ci.Library) == 1 && ci.Library[0] == fidlgen.Identifier("zx")
}

// We special case references to declarations from //zircon/vdso/zx:zx, since we
// don't generate Rust bindings for that library.
var zirconNames = map[fidlgen.EncodedCompoundIdentifier]string{
	"zx/Rights":                "fidl::Rights",
	"zx/ObjType":               "fidl::ObjectType",
	"zx/CHANNEL_MAX_MSG_BYTES": "fuchsia_zircon_types::ZX_CHANNEL_MAX_MSG_BYTES",
}

// compileDeclIdentifier returns a Rust path expression referring to the given
// declaration. It qualifies the crate name if it is external.
func (c *compiler) compileDeclIdentifier(val fidlgen.EncodedCompoundIdentifier) string {
	ci := val.Parse()
	if ci.Member != "" {
		panic(fmt.Sprintf("unexpected member: %s", val))
	}
	if isZirconIdentifier(ci) {
		name, ok := zirconNames[val]
		if !ok {
			panic(fmt.Sprintf("unexpected zircon identifier: %s", val))
		}
		return name
	}
	var name string
	if c.lookupDeclInfo(val).Type == fidlgen.ConstDeclType {
		name = compileScreamingSnakeIdentifier(ci.Name)
	} else {
		name = compileCamelIdentifier(ci.Name)
	}
	// TODO(https://fxbug.dev/42145610): This is incorrect. We're calling changeIfReserved
	// a second time, after compileScreamingSnakeIdentifier or
	// compileCamelIdentifier already did. We should only call it once.
	name = changeIfReserved(fidlgen.Identifier(name))
	if c.inExternalLibrary(val) {
		crate := compileLibraryName(ci.Library)
		c.externCrates[crate] = struct{}{}
		return fmt.Sprintf("%s::%s", crate, name)
	}
	return name
}

// compileMemberIdentifier returns a Rust path expression referring to the given
// declaration member. It qualifies the crate name if it is external.
func (c *compiler) compileMemberIdentifier(val fidlgen.EncodedCompoundIdentifier) string {
	ci := val.Parse()
	if ci.Member == "" {
		panic(fmt.Sprintf("expected a member: %s", val))
	}
	decl := val.DeclName()
	declType := c.lookupDeclInfo(decl).Type
	var member string
	switch declType {
	case fidlgen.BitsDeclType:
		member = compileScreamingSnakeIdentifier(ci.Member)
	case fidlgen.EnumDeclType:
		if isZirconIdentifier(ci) && ci.Name == "ObjType" {
			member = compileScreamingSnakeIdentifier(ci.Member)
		} else {
			member = compileCamelIdentifier(ci.Member)
		}
	default:
		panic(fmt.Sprintf("unexpected decl type: %s", declType))
	}
	return fmt.Sprintf("%s::%s", c.compileDeclIdentifier(decl), member)
}

func (c *compiler) compileLiteral(val fidlgen.Literal, typ fidlgen.Type) string {
	switch val.Kind {
	case fidlgen.StringLiteral:
		var b strings.Builder
		b.WriteRune('"')
		for _, r := range val.Value {
			switch r {
			case '\\':
				b.WriteString(`\\`)
			case '"':
				b.WriteString(`\"`)
			case '\n':
				b.WriteString(`\n`)
			case '\r':
				b.WriteString(`\r`)
			case '\t':
				b.WriteString(`\t`)
			default:
				if unicode.IsPrint(r) {
					b.WriteRune(r)
				} else {
					b.WriteString(fmt.Sprintf(`\u{%x}`, r))
				}
			}
		}
		b.WriteRune('"')
		return b.String()
	case fidlgen.NumericLiteral:
		if typ.Kind == fidlgen.PrimitiveType &&
			(typ.PrimitiveSubtype == fidlgen.Float32 || typ.PrimitiveSubtype == fidlgen.Float64) &&
			!strings.ContainsRune(val.Value, '.') {
			return fmt.Sprintf("%s.0", val.Value)
		}
		if typ.Kind == fidlgen.IdentifierType && c.lookupDeclInfo(typ.Identifier).Type == fidlgen.BitsDeclType {
			if val.Value != "0" {
				panic(fmt.Sprintf("integer literal for bits const must be 0, got %s", val.Value))
			}
			return fmt.Sprintf("%s::empty()", c.compileDeclIdentifier(typ.Identifier))
		}
		return val.Value
	case fidlgen.BoolLiteral:
		return val.Value
	case fidlgen.DefaultLiteral:
		return "::Default::default()"
	default:
		panic(fmt.Sprintf("unknown literal kind: %v", val.Kind))
	}
}

func (c *compiler) compileConstant(val fidlgen.Constant, typ fidlgen.Type) string {
	switch val.Kind {
	case fidlgen.IdentifierConstant:
		declType := c.lookupDeclInfo(val.Identifier.DeclName()).Type
		var expr string
		switch declType {
		case fidlgen.ConstDeclType:
			expr = c.compileDeclIdentifier(val.Identifier)
		case fidlgen.BitsDeclType:
			expr = c.compileMemberIdentifier(val.Identifier)
			if typ.Kind == fidlgen.PrimitiveType {
				expr += ".bits()"
			}
		case fidlgen.EnumDeclType:
			expr = c.compileMemberIdentifier(val.Identifier)
			if typ.Kind == fidlgen.PrimitiveType {
				expr += ".into_primitive()"
			}
		default:
			panic(fmt.Sprintf("unexpected decl type: %s", declType))
		}
		// TODO(https://fxbug.dev/42140924): fidlc allows conversions between primitive
		// types. Ideally the JSON IR would model these conversions explicitly.
		// In the meantime, just assume that a cast is always necessary.
		if typ.Kind == fidlgen.PrimitiveType {
			expr = fmt.Sprintf("%s as %s", expr, compilePrimitiveSubtype(typ.PrimitiveSubtype))
		}
		return expr
	case fidlgen.LiteralConstant:
		return c.compileLiteral(*val.Literal, typ)
	case fidlgen.BinaryOperator:
		if typ.Kind == fidlgen.PrimitiveType {
			return val.Value
		}
		decl := c.compileDeclIdentifier(typ.Identifier)
		// TODO(https://github.com/rust-lang/rust/issues/67441):
		// Use from_bits(%s).unwrap() once the const_option feature is stable.
		return fmt.Sprintf("%s::from_bits_truncate(%s)", decl, val.Value)
	default:
		panic(fmt.Sprintf("unknown constant kind: %s", val.Kind))
	}
}

func (c *compiler) compileConst(val fidlgen.Const) Const {
	r := Const{
		Const: val,
		Name:  c.compileDeclIdentifier(val.Name),
		Value: c.compileConstant(val.Value, val.Type),
	}
	if val.Type.Kind == fidlgen.StringType {
		r.Type = "&str"
	} else {
		r.Type = c.compileType(val.Type).Owned
	}
	return r
}

func compilePrimitiveSubtype(val fidlgen.PrimitiveSubtype) string {
	if t, ok := primitiveTypes[val]; ok {
		return t
	}
	panic(fmt.Sprintf("unknown primitive type: %v", val))
}

func compileHandleSubtype(val fidlgen.HandleSubtype) string {
	if t, ok := handleSubtypes[val]; ok {
		return t
	}
	panic(fmt.Sprintf("unknown handle type: %v", val))
}

func compileObjectTypeConst(val fidlgen.HandleSubtype) string {
	if t, ok := objectTypeConsts[val]; ok {
		return t
	}
	panic(fmt.Sprintf("unknown handle type: %v", val))
}

func (c *compiler) compileType(val fidlgen.Type) Type {
	t := Type{
		Resourceness:     c.decls.LookupResourceness(val),
		Kind:             val.Kind,
		Nullable:         val.Nullable,
		PrimitiveSubtype: val.PrimitiveSubtype,
		Identifier:       val.Identifier,
	}

	switch val.Kind {
	case fidlgen.PrimitiveType:
		s := compilePrimitiveSubtype(val.PrimitiveSubtype)
		t.Fidl = s
		t.Owned = s
		t.Param = s
	case fidlgen.ArrayType:
		el := c.compileType(*val.ElementType)
		t.ElementType = &el
		t.Fidl = fmt.Sprintf("fidl::encoding::Array<%s, %d>", el.Fidl, *val.ElementCount)
		t.Owned = fmt.Sprintf("[%s; %d]", el.Owned, *val.ElementCount)
		if el.IsResourceType() {
			t.Param = t.Owned
		} else {
			t.Param = "&" + t.Owned
		}
	case fidlgen.VectorType:
		el := c.compileType(*val.ElementType)
		t.ElementType = &el
		if val.ElementCount == nil {
			t.Fidl = fmt.Sprintf("fidl::encoding::UnboundedVector<%s>", el.Fidl)
		} else {
			t.Fidl = fmt.Sprintf("fidl::encoding::Vector<%s, %d>", el.Fidl, *val.ElementCount)
		}
		t.Owned = fmt.Sprintf("Vec<%s>", el.Owned)
		if el.IsResourceType() {
			t.Param = fmt.Sprintf("Vec<%s>", el.Owned)
		} else {
			t.Param = fmt.Sprintf("&[%s]", el.Owned)
		}
		if val.Nullable {
			t.Fidl = fmt.Sprintf("fidl::encoding::Optional<%s>", t.Fidl)
			t.Owned = fmt.Sprintf("Option<%s>", t.Owned)
			t.Param = fmt.Sprintf("Option<%s>", t.Param)
		}
	case fidlgen.StringType:
		if val.ElementCount == nil {
			t.Fidl = "fidl::encoding::UnboundedString"
		} else {
			t.Fidl = fmt.Sprintf("fidl::encoding::BoundedString<%d>", *val.ElementCount)
		}
		t.Owned = "String"
		t.Param = "&str"
		if val.Nullable {
			t.Fidl = fmt.Sprintf("fidl::encoding::Optional<%s>", t.Fidl)
			t.Owned = fmt.Sprintf("Option<%s>", t.Owned)
			t.Param = fmt.Sprintf("Option<%s>", t.Param)
		}
	case fidlgen.HandleType:
		s := compileHandleSubtype(val.HandleSubtype)
		objType := compileObjectTypeConst(val.HandleSubtype)
		t.Fidl = fmt.Sprintf("fidl::encoding::HandleType<%s, { %s.into_raw() }, %d>", s, objType, val.HandleRights)
		t.Owned = s
		t.Param = s
		if val.Nullable {
			t.Fidl = fmt.Sprintf("fidl::encoding::Optional<%s>", t.Fidl)
			t.Owned = fmt.Sprintf("Option<%s>", t.Owned)
			t.Param = fmt.Sprintf("Option<%s>", t.Param)
		}
	case fidlgen.RequestType:
		s := fmt.Sprintf("fidl::endpoints::ServerEnd<%sMarker>", c.compileDeclIdentifier(val.RequestSubtype))
		t.Fidl = fmt.Sprintf("fidl::encoding::Endpoint<%s>", s)
		t.Owned = s
		t.Param = s
		if val.Nullable {
			t.Fidl = fmt.Sprintf("fidl::encoding::Optional<%s>", t.Fidl)
			t.Owned = fmt.Sprintf("Option<%s>", t.Owned)
			t.Param = fmt.Sprintf("Option<%s>", t.Param)
		}
	case fidlgen.IdentifierType:
		name := c.compileDeclIdentifier(val.Identifier)
		declInfo := c.lookupDeclInfo(val.Identifier)
		t.DeclType = declInfo.Type
		switch declInfo.Type {
		case fidlgen.BitsDeclType, fidlgen.EnumDeclType:
			t.Fidl = name
			t.Owned = name
			t.Param = name
		case fidlgen.StructDeclType, fidlgen.TableDeclType, fidlgen.UnionDeclType:
			t.Fidl = name
			t.Owned = name
			if t.IsResourceType() {
				t.Param = name
			} else {
				t.Param = "&" + name
			}
			if val.Nullable {
				switch declInfo.Type {
				case fidlgen.StructDeclType:
					t.Fidl = fmt.Sprintf("fidl::encoding::Boxed<%s>", t.Fidl)
				case fidlgen.UnionDeclType:
					t.Fidl = fmt.Sprintf("fidl::encoding::OptionalUnion<%s>", t.Fidl)
				default:
					panic(fmt.Sprintf("unexpected type: %s", declInfo.Type))
				}
				t.Owned = fmt.Sprintf("Option<Box<%s>>", t.Owned)
				if declInfo.IsResourceType() {
					t.Param = fmt.Sprintf("Option<%s>", name)
				} else {
					t.Param = fmt.Sprintf("Option<&%s>", name)
				}
			}
		case fidlgen.ProtocolDeclType:
			s := fmt.Sprintf("fidl::endpoints::ClientEnd<%sMarker>", name)
			t.Fidl = fmt.Sprintf("fidl::encoding::Endpoint<%s>", s)
			t.Owned = s
			t.Param = s
			if val.Nullable {
				t.Fidl = fmt.Sprintf("fidl::encoding::Optional<%s>", t.Fidl)
				t.Owned = fmt.Sprintf("Option<%s>", t.Owned)
				t.Param = fmt.Sprintf("Option<%s>", t.Param)
			}
		default:
			panic(fmt.Sprintf("unexpected type: %v", declInfo.Type))
		}
	case fidlgen.InternalType:
		switch val.InternalSubtype {
		case fidlgen.FrameworkErr:
			s := "fidl::encoding::FrameworkErr"
			t.Fidl = s
			t.Owned = s
			t.Param = s
		default:
			panic(fmt.Sprintf("unknown internal subtype: %v", val.InternalSubtype))
		}
	default:
		panic(fmt.Sprintf("unknown type kind: %v", val.Kind))
	}

	return t
}

// convertParamToEncodeExpr returns an expression that converts a variable v
// from t.Param to a type implementing fidl::encoding::Encode<t.Fidl>.
//
// TODO(https://fxbug.dev/42073194): Remove this once the transition to the new types is
// complete, since parameter types will be encodable as is.
func convertParamToEncodeExpr(v string, t Type) string {
	switch t.Kind {
	case fidlgen.PrimitiveType, fidlgen.StringType, fidlgen.HandleType, fidlgen.RequestType:
		return v
	case fidlgen.ArrayType:
		if t.IsResourceType() {
			return "&mut " + v
		}
		return v
	case fidlgen.VectorType:
		if t.IsResourceType() {
			return v + ".as_mut()"
		}
		return v
	case fidlgen.IdentifierType:
		switch t.DeclType {
		case fidlgen.BitsDeclType, fidlgen.EnumDeclType, fidlgen.ProtocolDeclType:
			return v
		case fidlgen.StructDeclType, fidlgen.TableDeclType, fidlgen.UnionDeclType:
			if t.IsResourceType() {
				if t.Nullable {
					return v + ".as_mut()"
				}
				return "&mut " + v
			}
			return v
		default:
			panic(fmt.Sprintf("unexpected type: %v", t.DeclType))
		}
	default:
		panic(fmt.Sprintf("unknown type kind: %v", t.Kind))
	}
}

// convertResultToEncodeExpr returns an expression that converts a variable v
// from Result<(p.Params[0].Type, p.Params[1].Type, ...), _> to Result<T, _>
// where p is payloadForType(t) and T implements fidl::encoding::Encode<p.FidlType>.
// If len(p.Params) == 1 then the source type is Result<p.Params[0].Type, _>.
func convertResultToEncodeExpr(v string, t Type, p Payload) string {
	switch t.DeclType {
	case fidlgen.StructDeclType:
		var names []string
		var exprs []string
		transform := false
		for _, param := range p.Parameters {
			t := *param.StructMemberType
			expr := convertParamToEncodeExpr(param.Name, t)
			if expr != param.Name {
				transform = true
			}
			if t.IsResourceType() {
				expr = convertMutRefParamToEncodeExpr(param.Name, t)
			} else {
				expr = "*" + expr
			}
			names = append(names, param.Name)
			exprs = append(exprs, expr)
		}
		if transform {
			return fmt.Sprintf("%s.as_mut().map_err(|e| *e).map(|%s| %s)", v, fmtOneOrTuple(names), fmtTuple(exprs))
		}
		if len(names) == 1 {
			return fmt.Sprintf("%s.map(|%s| (%s,))", v, names[0], names[0])
		}
		return v
	case fidlgen.TableDeclType, fidlgen.UnionDeclType:
		if t.IsResourceType() {
			return v + ".as_mut().map_err(|e| *e)"
		}
		return v
	default:
		panic(fmt.Sprintf("unexpected decl type: %s", t.DeclType))
	}
}

// convertMutRefParamToEncodeExpr returns an expression that converts a variable
// v from &mut t.Param to a type implementing fidl::encoding::Encode<t.Fidl>.
//
// TODO(https://fxbug.dev/42073194): Remove this once the transition to the new types is
// complete. This is only needed for convertResultToEncodeExpr.
func convertMutRefParamToEncodeExpr(v string, t Type) string {
	switch t.Kind {
	case fidlgen.IdentifierType:
		switch t.DeclType {
		case fidlgen.StructDeclType, fidlgen.TableDeclType, fidlgen.UnionDeclType:
			if t.Nullable {
				if t.IsResourceType() {
					return v + ".as_mut()"
				}
				return v + ".as_ref()"
			}
		}
	}
	return convertMutRefOwnedToEncodeExpr(v, t)
}

// convertMutRefOwnedToEncodeExpr returns an expression that converts a variable
// v from &mut t.Owned to a type implementing fidl::encoding::Encode<t.Fidl>.
//
// TODO(https://fxbug.dev/42073194): Remove this once the transition to the new types is
// complete. This is only needed for convertMutRefResultToEncodeExpr.
func convertMutRefOwnedToEncodeExpr(v string, t Type) string {
	switch t.Kind {
	case fidlgen.PrimitiveType:
		return "*" + v
	case fidlgen.HandleType, fidlgen.RequestType:
		if t.Nullable {
			return fmt.Sprintf("%s.as_mut().map(|x| std::mem::replace(x, fidl::Handle::invalid().into()))", v)
		}
		return fmt.Sprintf("std::mem::replace(%s, fidl::Handle::invalid().into())", v)
	case fidlgen.StringType:
		if t.Nullable {
			return v + ".as_deref()"
		}
		return v + ".as_str()"
	case fidlgen.ArrayType:
		if t.IsResourceType() {
			return v
		}
		return "&*" + v
	case fidlgen.VectorType:
		if t.Nullable {
			if t.IsResourceType() {
				return v + ".as_deref_mut()"
			}
			return v + ".as_deref()"
		}
		if t.IsResourceType() {
			return v + ".as_mut_slice()"
		}
		return v + ".as_slice()"
	case fidlgen.IdentifierType:
		switch t.DeclType {
		case fidlgen.BitsDeclType, fidlgen.EnumDeclType:
			return "*" + v
		case fidlgen.StructDeclType, fidlgen.TableDeclType, fidlgen.UnionDeclType:
			if t.Nullable {
				if t.IsResourceType() {
					return v + ".as_deref_mut()"
				}
				return v + ".as_deref()"
			}
			if t.IsResourceType() {
				return v
			}
			return "&*" + v
		case fidlgen.ProtocolDeclType:
			if t.Nullable {
				return fmt.Sprintf("%s.as_mut().map(|x| std::mem::replace(x, fidl::Handle::invalid().into()))", v)
			}
			return fmt.Sprintf("std::mem::replace(%s, fidl::Handle::invalid().into())", v)
		default:
			panic(fmt.Sprintf("unexpected type: %v", t.DeclType))
		}
	default:
		panic(fmt.Sprintf("unknown type kind: %v", t.Kind))
	}
}

func (c *compiler) compileAlias(val fidlgen.Alias) Alias {
	return Alias{
		Alias: val,
		Name:  c.compileDeclIdentifier(val.Name),
		Type:  c.compileType(val.Type),
	}
}

func (c *compiler) compileBits(val fidlgen.Bits) Bits {
	e := Bits{
		Bits:           val,
		Name:           c.compileDeclIdentifier(val.Name),
		UnderlyingType: c.compileType(val.Type).Owned,
		Members:        []BitsMember{},
	}
	for _, v := range val.Members {
		e.Members = append(e.Members, BitsMember{
			BitsMember: v,
			Name:       compileScreamingSnakeIdentifier(v.Name),
			Value:      c.compileConstant(v.Value, val.Type),
		})
	}
	return e
}

func (c *compiler) compileEnum(val fidlgen.Enum) Enum {
	e := Enum{
		Enum:           val,
		Name:           c.compileDeclIdentifier(val.Name),
		UnderlyingType: compilePrimitiveSubtype(val.Type),
		Members:        []EnumMember{},
	}
	for _, v := range val.Members {
		e.Members = append(e.Members, EnumMember{
			EnumMember: v,
			Name:       compileCamelIdentifier(v.Name),
			Value:      v.Value.Value,
		})
	}
	e.MinMember = findMinEnumMember(val.Type, e.Members).Name
	return e
}

func findMinEnumMember(typ fidlgen.PrimitiveSubtype, members []EnumMember) EnumMember {
	var res EnumMember
	if typ.IsSigned() {
		min := int64(math.MaxInt64)
		for _, m := range members {
			v, err := strconv.ParseInt(m.Value, 10, 64)
			if err != nil {
				panic(fmt.Sprintf("invalid enum member value: %s", err))
			}
			if v < min {
				min = v
				res = m
			}
		}
	} else {
		min := uint64(math.MaxUint64)
		for _, m := range members {
			v, err := strconv.ParseUint(m.Value, 10, 64)
			if err != nil {
				panic(fmt.Sprintf("invalid enum member value: %s", err))
			}
			if v < min {
				min = v
				res = m
			}
		}
	}
	return res
}

// fmtTuple formats items (types or expressions) as a Rust tuple.
func fmtTuple(items []string) string {
	if len(items) == 0 {
		panic("expected at least one item")
	}
	return fmt.Sprintf("(%s,)", strings.Join(items, ", "))
}

// fmtOneOrTuple is like fmtTuple but does not create 1-tuples.
func fmtOneOrTuple(items []string) string {
	switch len(items) {
	case 0:
		panic("expected at least one item")
	case 1:
		return items[0]
	default:
		return fmt.Sprintf("(%s)", strings.Join(items, ", "))
	}
}

func emptyPayload(fidlType string) Payload {
	return Payload{
		FidlType:        fidlType,
		OwnedType:       "()",
		TupleType:       "()",
		EncodeExpr:      "()",
		ConvertToTuple:  func(owned string) string { return owned },
		ConvertToFields: func(owned string) string { return "" },
	}
}

func (c *compiler) payloadForType(payloadType Type) Payload {
	typeName := c.compileDeclIdentifier(payloadType.Identifier)
	st, ok := c.structs[payloadType.Identifier]

	// Not a struct: table or union payload.
	if !ok {
		paramName := "payload"
		return Payload{
			FidlType:  typeName,
			OwnedType: typeName,
			TupleType: typeName,
			Parameters: []Parameter{{
				Name:      paramName,
				Type:      payloadType.Param,
				OwnedType: payloadType.Owned,
			}},
			EncodeExpr:      convertParamToEncodeExpr(paramName, payloadType),
			ConvertToTuple:  func(owned string) string { return owned },
			ConvertToFields: func(owned string) string { return fmt.Sprintf("%s: %s,", paramName, owned) },
		}
	}

	// Empty struct with error syntax.
	if len(st.Members) == 0 {
		return emptyPayload("fidl::encoding::EmptyStruct")
	}

	// Struct payload. Flatten it to parameters.
	var parameters []Parameter
	var ownedTypes, encodeExprs []string
	for _, v := range st.Members {
		paramName := compileSnakeIdentifier(v.Name)
		typ := c.compileType(v.Type)
		parameters = append(parameters, Parameter{
			Name:             paramName,
			Type:             typ.Param,
			OwnedType:        typ.Owned,
			StructMemberType: &typ,
		})
		ownedTypes = append(ownedTypes, typ.Owned)
		encodeExprs = append(encodeExprs, convertParamToEncodeExpr(paramName, typ))
	}
	return Payload{
		FidlType:   typeName,
		OwnedType:  typeName,
		TupleType:  fmtOneOrTuple(ownedTypes),
		Parameters: parameters,
		EncodeExpr: fmtTuple(encodeExprs),
		ConvertToTuple: func(owned string) string {
			var exprs []string
			for _, param := range parameters {
				exprs = append(exprs, fmt.Sprintf("%s.%s", owned, param.Name))
			}
			return fmtOneOrTuple(exprs)
		},
		ConvertToFields: func(owned string) string {
			var b strings.Builder
			for _, param := range parameters {
				b.WriteString(fmt.Sprintf("%s: %s.%s,\n", param.Name, owned, param.Name))
			}
			return b.String()
		},
	}
}

func (c *compiler) compileRequest(m fidlgen.Method) Payload {
	if !m.HasRequest {
		// Not applicable (because the method is an event).
		return Payload{}
	}
	if m.RequestPayload == nil {
		// Empty payload, e.g. the request of `Foo();`.
		return emptyPayload("fidl::encoding::EmptyPayload")
	}
	// Struct, table, or union request payload.
	return c.payloadForType(c.compileType(*m.RequestPayload))
}

func (c *compiler) compileResponse(m fidlgen.Method) Payload {
	if !m.HasResponse {
		// Not applicable (because the method is one-way).
		return Payload{}
	}
	if m.ResponsePayload == nil {
		// Empty payload, e.g. the response of `Foo() -> ();` or `-> Foo();`.
		return emptyPayload("fidl::encoding::EmptyPayload")
	}
	if !m.HasResultUnion() {
		// Plain payload with no flexible/error result union.
		return c.payloadForType(c.compileType(*m.ResponsePayload))
	}

	innerType := c.compileType(*m.ValueType)
	inner := c.payloadForType(innerType)
	var errType Type
	if m.HasError {
		errType = c.compileType(*m.ErrorType)
	}

	var p Payload

	// Set FidlType and OwnedType, which are different for each of the 3 cases.
	if m.HasFrameworkError() && m.HasError {
		p.FidlType = fmt.Sprintf("fidl::encoding::FlexibleResultType<%s, %s>", inner.FidlType, errType.Fidl)
		p.OwnedType = fmt.Sprintf("fidl::encoding::FlexibleResult<%s, %s>", inner.OwnedType, errType.Owned)
	} else if m.HasFrameworkError() {
		p.FidlType = fmt.Sprintf("fidl::encoding::FlexibleType<%s>", inner.FidlType)
		p.OwnedType = fmt.Sprintf("fidl::encoding::Flexible<%s>", inner.OwnedType)
	} else if m.HasError {
		p.FidlType = fmt.Sprintf("fidl::encoding::ResultType<%s, %s>", inner.FidlType, errType.Fidl)
		p.OwnedType = fmt.Sprintf("Result<%s, %s>", inner.OwnedType, errType.Owned)
	} else {
		panic("should have returned earlier")
	}

	// Set all the other fields, where all that matters is m.HasError.
	if !m.HasError {
		p.TupleType = inner.TupleType
		p.Parameters = inner.Parameters
		p.EncodeExpr = inner.EncodeExpr
		p.ConvertToTuple = inner.ConvertToTuple
		p.ConvertToFields = inner.ConvertToFields
	} else {
		paramName := "result"
		p.TupleType = c.compileDeclIdentifier(m.ResponsePayload.Identifier)
		p.TupleTypeAliasRhs = fmt.Sprintf("Result<%s, %s>", inner.TupleType, errType.Owned)
		okParamType := "()"
		if len(inner.Parameters) > 0 {
			var paramTypes []string
			for _, param := range inner.Parameters {
				paramTypes = append(paramTypes, param.Type)
			}
			okParamType = fmtOneOrTuple(paramTypes)
		}
		p.Parameters = []Parameter{{
			Name:      paramName,
			Type:      fmt.Sprintf("Result<%s, %s>", okParamType, errType.Param),
			OwnedType: p.TupleType,
		}}
		p.EncodeExpr = convertResultToEncodeExpr(paramName, innerType, inner)
		p.ConvertToTuple = func(owned string) string {
			return fmt.Sprintf("%s.map(|x| %s)", owned, inner.ConvertToTuple("x"))
		}
		p.ConvertToFields = func(owned string) string {
			return fmt.Sprintf("%s: %s.map(|x| %s),", paramName, owned, inner.ConvertToTuple("x"))
		}
	}

	// For FlexibleType and FlexibleResultType, we need to wrap the value before encoding.
	if m.HasFrameworkError() {
		name, _, _ := strings.Cut(p.OwnedType, "<")
		p.EncodeExpr = fmt.Sprintf("%s::new(%s)", name, p.EncodeExpr)
	}

	return p
}

func (c *compiler) compileProtocol(val fidlgen.Protocol) Protocol {
	name := c.compileDeclIdentifier(val.Name)
	r := Protocol{
		Protocol:         val,
		ECI:              val.Name,
		Marker:           name + "Marker",
		Proxy:            name + "Proxy",
		ProxyInterface:   name + "ProxyInterface",
		SynchronousProxy: name + "SynchronousProxy",
		Request:          name + "Request",
		RequestStream:    name + "RequestStream",
		Event:            name + "Event",
		EventStream:      name + "EventStream",
		ControlHandle:    name + "ControlHandle",
	}
	if discoverableName := strings.Trim(val.GetProtocolName(), "\""); discoverableName != "" {
		r.Discoverable = true
		// TODO(https://fxbug.dev/42051517): Currently discoverable protocols get
		// PROTOCOL_NAME set equal to DEBUG_NAME, and we change both to use the
		// "fuchsia.foo.Bar" format. We should instead use distinct formats for
		// DEBUG_NAME and PROTOCOL_NAME.
		r.DebugName = discoverableName
	} else {
		// TODO(https://fxbug.dev/42051517): Include the library name in DEBUG_NAME, i.e.
		// "fuchsia.foo/Bar" rather than just "Bar".
		r.DebugName = "(anonymous) " + name
	}

	for _, v := range val.Methods {
		m := Method{
			Method:    v,
			Name:      compileSnakeIdentifier(v.Name),
			CamelName: compileCamelIdentifier(v.Name),
			Request:   c.compileRequest(v),
			Response:  c.compileResponse(v),
		}
		if v.HasRequest && v.HasResponse {
			m.Responder = name + m.CamelName + "Responder"
			m.ResponseFut = m.CamelName + "ResponseFut"
		}
		r.Methods = append(r.Methods, m)
	}

	return r
}

func (c *compiler) compileService(val fidlgen.Service) Service {
	r := Service{
		Service:     val,
		Name:        c.compileDeclIdentifier(val.Name),
		Members:     []ServiceMember{},
		ServiceName: val.GetServiceName(),
	}

	for _, v := range val.Members {
		m := ServiceMember{
			ServiceMember: v,
			Name:          string(v.Name),
			CamelName:     compileCamelIdentifier(v.Name),
			SnakeName:     compileSnakeIdentifier(v.Name),
			ProtocolType:  c.compileDeclIdentifier(v.Type.Identifier),
		}
		r.Members = append(r.Members, m)
	}

	return r
}

func (c *compiler) compileStructMember(val fidlgen.StructMember) StructMember {
	return StructMember{
		StructMember: val,
		Type:         c.compileType(val.Type),
		Name:         compileSnakeIdentifier(val.Name),
		OffsetV2:     val.FieldShapeV2.Offset,
	}
}

func (c *compiler) computeUseFidlStructCopyForStruct(st fidlgen.Struct) bool {
	if len(st.Members) == 0 {
		// In Rust, structs containing empty structs do not match the C++ struct layout
		// since empty structs have size 0 in Rust -- even in repr(C).
		return false
	}
	for _, member := range st.Members {
		if !c.computeUseFidlStructCopy(member.Type) {
			return false
		}
	}
	return true
}

func (c *compiler) computeUseFidlStructCopy(typ fidlgen.Type) bool {
	if typ.Nullable {
		return false
	}
	switch typ.Kind {
	case fidlgen.ArrayType:
		return c.computeUseFidlStructCopy(*typ.ElementType)
	case fidlgen.VectorType, fidlgen.StringType, fidlgen.HandleType, fidlgen.RequestType:
		return false
	case fidlgen.PrimitiveType:
		switch typ.PrimitiveSubtype {
		case fidlgen.Bool, fidlgen.Float32, fidlgen.Float64:
			return false
		}
		return true
	case fidlgen.IdentifierType:
		if c.inExternalLibrary(typ.Identifier) {
			return false
		}
		declType := c.lookupDeclInfo(typ.Identifier).Type
		switch declType {
		case fidlgen.BitsDeclType, fidlgen.EnumDeclType, fidlgen.TableDeclType, fidlgen.UnionDeclType, fidlgen.ProtocolDeclType:
			return false
		case fidlgen.StructDeclType:
			st, ok := c.structs[typ.Identifier]
			if !ok {
				panic(fmt.Sprintf("struct not found: %v", typ.Identifier))
			}
			return c.computeUseFidlStructCopyForStruct(st)
		default:
			panic(fmt.Sprintf("unknown declaration type: %v", declType))
		}
	default:
		panic(fmt.Sprintf("unknown type kind: %v", typ.Kind))
	}
}

func (c *compiler) resolveStruct(identifier fidlgen.EncodedCompoundIdentifier) *fidlgen.Struct {
	if c.inExternalLibrary(identifier) {
		// This behavior is matched by computeUseFullStructCopy.
		return nil
	}
	if c.lookupDeclInfo(identifier).Type == fidlgen.StructDeclType {
		st, ok := c.structs[identifier]
		if !ok {
			panic(fmt.Sprintf("struct not found: %v", identifier))
		}
		return &st
	}
	return nil
}

func (c *compiler) compileStruct(val fidlgen.Struct) Struct {
	name := c.compileDeclIdentifier(val.Name)
	r := Struct{
		Struct:           val,
		ECI:              val.Name,
		Name:             name,
		Members:          []StructMember{},
		SizeV2:           val.TypeShapeV2.InlineSize,
		AlignmentV2:      val.TypeShapeV2.Alignment,
		PaddingMarkersV2: val.BuildPaddingMarkers(fidlgen.PaddingConfig{}),
		FlattenedPaddingMarkersV2: val.BuildPaddingMarkers(fidlgen.PaddingConfig{
			FlattenStructs: true,
			FlattenArrays:  true,
			ResolveStruct:  c.resolveStruct,
		}),
	}

	for _, v := range val.Members {
		member := c.compileStructMember(v)
		r.Members = append(r.Members, member)
		r.HasPadding = r.HasPadding || (v.FieldShapeV2.Padding != 0)
	}

	r.UseFidlStructCopy = c.computeUseFidlStructCopyForStruct(val)

	return r
}

func (c *compiler) compileUnion(val fidlgen.Union) Union {
	r := Union{
		Union: val,
		ECI:   val.Name,
		Name:  c.compileDeclIdentifier(val.Name),
	}
	for _, v := range val.Members {
		r.Members = append(r.Members, UnionMember{
			UnionMember: v,
			Type:        c.compileType(v.Type),
			Name:        compileCamelIdentifier(v.Name),
			Ordinal:     v.Ordinal,
		})
	}
	return r
}

func (c *compiler) compileTable(table fidlgen.Table) Table {
	r := Table{
		Table: table,
		ECI:   table.Name,
		Name:  c.compileDeclIdentifier(table.Name),
	}
	for _, member := range table.Members {
		r.Members = append(r.Members, TableMember{
			TableMember: member,
			Type:        c.compileType(member.Type),
			Name:        compileSnakeIdentifier(member.Name),
			Ordinal:     member.Ordinal,
		})
	}
	return r
}

type derives uint16

const (
	derivesDebug derives = 1 << iota
	derivesCopy
	derivesClone
	derivesDefault
	derivesEq
	derivesPartialEq
	derivesOrd
	derivesPartialOrd
	derivesHash
	derivesAll derives = (1 << iota) - 1
)

// note: keep this list in the same order as the derives definitions
var derivesNames = []string{
	// [START derived_traits]
	"Debug",
	"Copy",
	"Clone",
	"Default",
	"Eq",
	"PartialEq",
	"Ord",
	"PartialOrd",
	"Hash",
	// [END derived_traits]
}

// Returns the derives that are allowed for a type based on resourceness
func allowedDerives(r fidlgen.Resourceness) derives {
	if r.IsResourceType() {
		return derivesAll &^ (derivesCopy | derivesClone)
	}
	return derivesAll
}

// Returns the minimal derives we can assume a type has based on resourceness.
func minimalDerives(r fidlgen.Resourceness) derives {
	if r.IsValueType() {
		return derivesDebug | derivesPartialEq | derivesClone
	}
	return derivesDebug | derivesPartialEq
}

// RemoveCustom removes traits by name. Templates use it when they are providing
// a custom impl instead of deriving. (We can't just omit the traits in
// fillDerives because it would recursively remove it from containing types.)
func (v derives) RemoveCustom(traits ...string) (derives, error) {
	result := v
	for _, name := range traits {
		found := false
		for i, n := range derivesNames {
			if n == name {
				found = true
				result = result &^ (1 << i)
				break
			}
		}
		if !found {
			return 0, fmt.Errorf("trait '%s' not found", name)
		}
	}
	return result, nil
}

func (v derives) String() string {
	var parts []string
	for i, bit := 0, derives(1); bit&derivesAll != 0; i, bit = i+1, bit<<1 {
		if v&bit != 0 {
			parts = append(parts, derivesNames[i])
		}
	}
	if len(parts) == 0 {
		return ""
	}
	sort.Strings(parts)
	return fmt.Sprintf("#[derive(%s)]", strings.Join(parts, ", "))
}

// The status of derive calculation for a particular type.
type deriveStatus struct {
	// recursing indicates whether or not we've passed through this type already
	// on a recursive descent. This is used to prevent unbounded recursion on
	// mutually-recursive types.
	recursing bool
	// complete indicates whether or not the derive for the given type has
	// already been successfully calculated and stored in the IR.
	complete bool
}

// The state of the current calculation of derives.
type derivesCompiler struct {
	*compiler
	topMostCall                bool
	didShortCircuitOnRecursion bool
	statuses                   map[EncodedCompoundIdentifier]deriveStatus
	root                       *Root
}

// [START fill_derives]
// Calculates what traits should be derived for each output type,
// filling in all `*derives` in the IR.
func (c *compiler) fillDerives(ir *Root) {
	// [END fill_derives]
	dc := &derivesCompiler{
		compiler:                   c,
		topMostCall:                true,
		didShortCircuitOnRecursion: false,
		statuses:                   make(map[EncodedCompoundIdentifier]deriveStatus),
		root:                       ir,
	}

	// Bits derives are controlled by the bitflags crate.
	// Enums derive a constant set of traits hardcoded in enum.tmpl.
	for _, v := range ir.Structs {
		dc.fillDerivesForECI(v.ECI)
	}
	for _, v := range ir.Unions {
		dc.fillDerivesForECI(v.ECI)
	}
	for _, v := range ir.Tables {
		dc.fillDerivesForECI(v.ECI)
	}
}

// Computes derives for a struct, table, or union.
// Also fills in the .Derives field if the type is local to this library.
func (dc *derivesCompiler) fillDerivesForECI(eci EncodedCompoundIdentifier) derives {
	declInfo := dc.lookupDeclInfo(eci)

	// TODO(https://fxbug.dev/42140082): Make external type information available here.
	// Currently, we conservatively assume external structs, tables, and unions
	// only derive a minimal set of traits, which includes Clone for value types
	// (not having Clone is especially annoying, so we put resourceness of
	// external types into the IR as a stopgap solution).
	if dc.inExternalLibrary(eci) {
		return minimalDerives(*declInfo.Resourceness)
	}

	topMostCall := dc.topMostCall
	if dc.topMostCall {
		dc.topMostCall = false
	}
	deriveStatus := dc.statuses[eci]
	if deriveStatus.recursing {
		// If we've already seen the current type while recursing,
		// the algorithm has already explored all of the other fields contained
		// within the cycle, so we can return true for all derives, and the
		// correct results will be bubbled up.
		dc.didShortCircuitOnRecursion = true
		return derivesAll
	}
	deriveStatus.recursing = true
	dc.statuses[eci] = deriveStatus

	var derivesOut derives
	switch declInfo.Type {
	case fidlgen.StructDeclType:
		st := dc.root.findStruct(eci)
		if st == nil {
			panic(fmt.Sprintf("struct not found: %v", eci))
		}
		if deriveStatus.complete {
			derivesOut = st.Derives
			break
		}
		derivesOut = allowedDerives(st.Resourceness)
		for _, member := range st.Members {
			derivesOut &= dc.derivesForType(member.Type)
		}
		derivesOut &^= derivesDefault
		st.Derives = derivesOut
	case fidlgen.TableDeclType:
		table := dc.root.findTable(eci)
		if table == nil {
			panic(fmt.Sprintf("table not found: %v", eci))
		}
		if deriveStatus.complete {
			derivesOut = table.Derives
			break
		}
		derivesOut = minimalDerives(*declInfo.Resourceness)
		// We can always derive Default because table fields are optional.
		derivesOut |= derivesDefault
		table.Derives = derivesOut
	case fidlgen.UnionDeclType:
		union := dc.root.findUnion(eci)
		if union == nil {
			panic(fmt.Sprintf("union not found: %v", eci))
		}
		if deriveStatus.complete {
			derivesOut = union.Derives
			break
		}
		if union.IsFlexible() {
			derivesOut = minimalDerives(union.Resourceness)
		} else {
			derivesOut = allowedDerives(union.Resourceness)
			for _, member := range union.Members {
				derivesOut &= dc.derivesForType(member.Type)
			}
		}
		derivesOut &^= derivesDefault
		union.Derives = derivesOut
	default:
		panic(fmt.Sprintf("unexpected declaration type: %v", declInfo.Type))
	}
	if topMostCall || !dc.didShortCircuitOnRecursion {
		// Our completed result is only valid if it's either at top-level
		// (ensuring we've fully visited all child types in the recursive
		// substructure at least once) or if we performed no recursion-based
		// short-circuiting, in which case results are correct and absolute.
		//
		// Note that non-topMostCalls are invalid if we did short-circuit
		// on recursion, because we might have short-circuited just beneath
		// a type without having explored all of its children at least once
		// beneath it.
		//
		// For example, imagine A -> B -> C -> A.
		// When we start on A, we go to B, then go to C, then go to A, at which
		// point we short-circuit. The intermediate result for C is invalid
		// for anything except the computation of A and B above, as it does
		// not take into account that C contains A and B, only that it contains
		// its top-level fields (other than A). In order to get a correct
		// idea of the shape of C, we have to start with C, following through
		// every branch until we find C again.
		deriveStatus.complete = true
	}
	if topMostCall {
		// Reset intermediate state
		dc.topMostCall = true
		dc.didShortCircuitOnRecursion = false
	}
	deriveStatus.recursing = false
	dc.statuses[eci] = deriveStatus
	return derivesOut
}

func (dc *derivesCompiler) derivesForType(t Type) derives {
	switch t.Kind {
	case fidlgen.ArrayType:
		return dc.derivesForType(*t.ElementType)
	case fidlgen.VectorType:
		return derivesAll &^ derivesCopy & dc.derivesForType(*t.ElementType)
	case fidlgen.StringType:
		return derivesAll &^ derivesCopy
	case fidlgen.HandleType, fidlgen.RequestType:
		return derivesAll &^ (derivesCopy | derivesClone)
	case fidlgen.PrimitiveType:
		switch t.PrimitiveSubtype {
		case fidlgen.Bool:
			return derivesAll
		case fidlgen.Int8, fidlgen.Int16, fidlgen.Int32, fidlgen.Int64,
			fidlgen.Uint8, fidlgen.Uint16, fidlgen.Uint32, fidlgen.Uint64:
			return derivesAll
		case fidlgen.Float32, fidlgen.Float64:
			// Floats don't have a total ordering due to NAN and its multiple representations.
			return derivesAll &^ (derivesEq | derivesOrd | derivesHash)
		default:
			panic(fmt.Sprintf("unknown primitive type: %v", t.PrimitiveSubtype))
		}
	case fidlgen.IdentifierType:
		switch t.DeclType {
		case fidlgen.BitsDeclType, fidlgen.EnumDeclType:
			return derivesAll
		case fidlgen.StructDeclType, fidlgen.UnionDeclType:
			result := dc.fillDerivesForECI(t.Identifier)
			if t.Nullable {
				// Nullable structs and unions gets put in Option<Box<...>>.
				result &^= derivesCopy
			}
			return result
		case fidlgen.TableDeclType:
			return dc.fillDerivesForECI(t.Identifier)
		case fidlgen.ProtocolDeclType:
			// An IdentifierType referring to a Protocol is a client_end.
			return derivesAll &^ (derivesCopy | derivesClone)
		default:
			panic(fmt.Sprintf("unexpected identifier type: %v", t.DeclType))
		}
	default:
		panic(fmt.Sprintf("unknown type kind: %v", t.Kind))
	}
}

func Compile(r fidlgen.Root) Root {
	r = r.ForBindings("rust")
	r = r.ForTransport("Channel")
	root := Root{
		Experiments: r.Experiments,
	}
	thisLibParsed := r.Name.Parse()
	c := compiler{
		decls:        r.DeclInfo(),
		experiments:  r.Experiments,
		library:      thisLibParsed,
		externCrates: map[string]struct{}{},
		structs:      map[fidlgen.EncodedCompoundIdentifier]fidlgen.Struct{},
	}

	for _, s := range r.Structs {
		c.structs[s.Name] = s
	}

	for _, s := range r.ExternalStructs {
		c.structs[s.Name] = s
	}

	for _, v := range r.Aliases {
		root.Aliases = append(root.Aliases, c.compileAlias(v))
	}

	for _, v := range r.Bits {
		root.Bits = append(root.Bits, c.compileBits(v))
	}

	for _, v := range r.Consts {
		root.Consts = append(root.Consts, c.compileConst(v))
	}

	for _, v := range r.Enums {
		root.Enums = append(root.Enums, c.compileEnum(v))
	}

	for _, v := range r.Services {
		root.Services = append(root.Services, c.compileService(v))
	}

	for _, v := range r.Tables {
		root.Tables = append(root.Tables, c.compileTable(v))
	}

	for _, v := range r.Structs {
		if v.IsEmptySuccessStruct {
			continue
		}
		root.Structs = append(root.Structs, c.compileStruct(v))
	}

	for _, v := range r.Unions {
		if v.IsResult {
			continue
		}
		root.Unions = append(root.Unions, c.compileUnion(v))
	}

	for _, v := range r.Protocols {
		root.Protocols = append(root.Protocols, c.compileProtocol(v))
	}

	c.fillDerives(&root)

	thisLibCompiled := compileLibraryName(thisLibParsed)

	// Sort the extern crates to make sure the generated file is
	// consistent across builds.
	var externCrates []string
	for k := range c.externCrates {
		externCrates = append(externCrates, k)
	}
	sort.Strings(externCrates)

	for _, k := range externCrates {
		if k != thisLibCompiled {
			root.ExternCrates = append(root.ExternCrates, k)
		}
	}

	return root
}
