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

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

	"fidl/compiler/backend/common"
	"fidl/compiler/backend/types"
)

const (
	ProxySuffix            = "Interface"
	StubSuffix             = "Stub"
	EventProxySuffix       = "EventProxy"
	ServiceSuffix          = "Service"
	TransitionalBaseSuffix = "TransitionalBase"
	ServiceNameSuffix      = "Name"
	RequestSuffix          = "InterfaceRequest"
	TagSuffix              = "Tag"

	MessageHeaderSize = 16

	SyscallZxPackage = "syscall/zx"
	SyscallZxAlias   = "_zx"

	BindingsPackage = "syscall/zx/fidl"
	BindingsAlias   = "_bindings"
)

// Type represents a golang type.
type Type string

// Const represents the idiomatic representation of a constant in golang.
type Const struct {
	types.Attributes

	// Name is the name of the constant.
	Name string

	// Type is the constant's type.
	Type Type

	// Value is the constant's value.
	Value string
}

// Enum represents the idiomatic representation of an enum in golang.
//
// That is, something like:
// type MyEnum int32
// const (
//    MyEnumMember1 MyEnum = 1
//    MyEnumMember2        = 2
//    ...
// )
type Enum struct {
	types.Attributes

	// Name is the name of the enum type alias.
	Name string

	// Type is the underlying primitive type for the enum.
	Type Type

	// Members is the list of enum variants that are a part of this enum.
	// The values of the Members must not overlap.
	Members []EnumMember
}

// EnumMember represents a single enum variant. See Enum for more details.
type EnumMember struct {
	types.Attributes

	// Name is the name of the enum variant without any prefix.
	Name string

	// Value is the raw value of the enum variant, represented as a string
	// to support many types.
	Value string
}

// Struct represents a golang struct.
type Struct struct {
	types.Attributes

	// Name is the name of the golang struct.
	Name string

	// Members is a list of the golang struct members.
	Members []StructMember

	// Size is the FIDL-encoded size of the struct.
	Size int

	// Alignment is the alignment of the FIDL-encoded struct.
	Alignment int
}

// TODO(pascallouis): document, see `readTag` function in
// https://fuchsia.googlesource.com/third_party/go/+/master/src/syscall/zx/fidl/encoding_new.go#211
type tagNew struct {
	reverseOfBounds []int
}

func (t tagNew) String() string {
	var (
		elems    []string
		allEmpty = true
	)
	for i := len(t.reverseOfBounds) - 1; 0 <= i; i-- {
		bound := t.reverseOfBounds[i]
		if bound == math.MaxInt32 {
			elems = append(elems, "")
		} else {
			elems = append(elems, strconv.Itoa(bound))
			allEmpty = false
		}
	}
	if allEmpty {
		return ""
	}
	return fmt.Sprintf(`fidl2:"%s"`, strings.Join(elems, ","))
}

// Tag loosely represents a golang struct member tag for maximum elements e.g.
// `fidl:"3,4,5"`. For a type like vector<vector<int>:3>:4, the tag would
// look like `fidl:"3,4"`, such that the commas separate nesting. Note that if
// a nested type that doesn't specify a max size is used, it is encoded as the
// empty string. For example, vector<vector<vector<int>:3>>:5 would have tag
// `fidl:"3,,5"`. Note that this makes a maximum length of 0 distinct.
// Fundamentally, this Tag exists to provide type metadata for nested FIDL2
// container types to the encoder/decoder in the bindings.
//
// Note that arrays are not included because their maximum sizes are encoded in
// the golang type system. Because of this, FIDL types such as
// vector<array<int>:10>:10 will have a tag that looks like `fidl:"10"`.
//
// Rather than representing handle nullability using a pointer indirection, we
// include it as part of the struct tag. For example, vector<handle?>:2 will
// have tag `fidl:"*,2"`.
//
// Lastly, when a field is on table, its ordinal is stored in `Ordinal`, and
// appears in the struct tag as the rightmost element.
type Tag struct {
	// MaxElems is the maximum number of elements a type is annotated with.
	MaxElems []*int

	// Nullable is whether the innermost type is nullable. This only applies
	// for handle types.
	Nullable bool

	// Ordinal is the table ordinal of the field this type is annotated with.
	Ordinal int
}

// String generates a string representation for the tag.
func (t *Tag) String() string {
	var elemsTag []string
	anyData := false
	if t.Nullable {
		elemsTag = append(elemsTag, "*")
		anyData = true
	}
	for _, elems := range t.MaxElems {
		if elems == nil {
			elemsTag = append(elemsTag, "")
			continue
		}
		anyData = true
		elemsTag = append(elemsTag, strconv.Itoa(*elems))
	}
	if 0 < t.Ordinal {
		anyData = true
		elemsTag = append(elemsTag, strconv.Itoa(t.Ordinal))
	}
	if !anyData {
		return ""
	}
	return fmt.Sprintf(`fidl:"%s"`, strings.Join(elemsTag, ","))
}

func tagsfmt(t Tag, t2 tagNew) string {
	var tags []string
	if t_str := t.String(); len(t_str) != 0 {
		tags = append(tags, t_str)
	}
	if t2_str := t2.String(); len(t2_str) != 0 {
		tags = append(tags, t2_str)
	}
	if len(tags) == 0 {
		return ""
	}
	return fmt.Sprintf("`%s`", strings.Join(tags, " "))
}

// StructMember represents the member of a golang struct.
type StructMember struct {
	types.Attributes

	// Name is the name of the golang struct member.
	Name string

	// PrivateName is the unexported version of the name of the struct member.
	PrivateName string

	// Type is the type of the golang struct member.
	Type Type

	// Tags are the golang struct member tag which holds additional metadata
	// about the struct field.
	Tags string
}

// Union represents a FIDL union as a golang struct.
type Union struct {
	types.Attributes

	// Name is the name of the FIDL union as a golang struct.
	Name string

	// TagName is the name of the golang enum type for the tag of the FIDL enum.
	TagName string

	// Members is a list of FIDL union members represented as golang struct members.
	Members []UnionMember

	// Size is the size of the FIDL union on the wire in bytes.
	Size int

	// Alignment is the alignment factor of the FIDL union on the wire in bytes.
	Alignment int
}

// UnionMember represents a FIDL union member as a golang struct member.
type UnionMember struct {
	types.Attributes

	// Name is the exported name of the FIDL union member.
	Name string

	// PrivateName is the unexported name of the FIDL union member.
	PrivateName string

	// Type is the golang type of the union member.
	Type Type

	// Tag are the golang struct member tag which holds additional metadata
	// about the union member.
	Tags string
}

// Table represents a FIDL table as a golang struct.
type Table struct {
	types.Attributes
	Name      string
	Members   []TableMember
	Size      int
	Alignment int
}

// TableMember represents a FIDL table member as two golang struct members, one
// for the member itself, and one to indicate presence or absence.
type TableMember struct {
	types.Attributes

	// DataField is the exported name of the FIDL table member.
	DataField string

	// PrivateDataField is an unexported name of the FIDL table member, used as
	// argument.
	PrivateDataField string

	// PresenceField is the exported name of boolean indicating presence of
	// the FIDL table member.
	PresenceField string

	// Setter is the exported name of the FIDL table member setter.
	Setter string

	// Getter is the exported name of the FIDL table member getter.
	Getter string

	// Clearer is the exported name of the FIDL table member clearer.
	Clearer string

	// Haser is the exported name of the presence checker of the FIDL table
	// member.
	Haser string

	// Type is the golang type of the table member.
	Type Type

	// Tag are the golang struct member tag which holds additional metadata
	// about the table member.
	Tags string
}

// Interface represents a FIDL interface in terms of golang structures.
type Interface struct {
	types.Attributes

	// Name is the Golang name of the interface.
	Name string

	// ProxyName is the name of the proxy type for this FIDL interface.
	ProxyName string

	// ProxyType is concrete type of proxy used for this FIDL interface.
	ProxyType string

	// StubName is the name of the stub type for this FIDL interface.
	StubName string

	// EventProxyName is the name of the event proxy type for this FIDL interface.
	EventProxyName string

	// TransitionalBaseName is the name of the base implementation for transitional methods
	// for this FIDL interface.
	TransitionalBaseName string

	// RequestName is the name of the interface request type for this FIDL interface.
	RequestName string

	// ServerName is the name of the server type for this FIDL interface.
	ServerName string

	// ServiceNameString is the string service name for this FIDL interface.
	ServiceNameString string

	// ServiceNameConstant is the name of the service name constant for this FIDL interface.
	ServiceNameConstant string

	// Methods is a list of methods for this FIDL interface.
	Methods []Method
}

// Method represents a method of a FIDL interface in terms of golang structures.
type Method struct {
	types.Attributes

	// Ordinal is the ordinal for this method.
	Ordinal types.Ordinal

	// OrdinalName is the name of the ordinal for this method, including the interface
	// name as a prefix.
	OrdinalName string

	// GenOrdinal is the generated ordinal for this method.
	GenOrdinal types.Ordinal

	// GenOrdinalName is the name of the generated ordinal for this method,
	// including the interface name as a prefix.
	GenOrdinalName string

	// Name is the name of the Method, including the interface name as a prefix.
	Name string

	// Request represents a goland struct containing the request parameters.
	Request *Struct

	// Response represents an optional golang struct containing the response parameters.
	Response *Struct

	// EventExpectName is the name of the method for the client-side event proxy.
	// Only relevant if the method is an event.
	EventExpectName string

	// IsEvent is set to true if the method is an event. In this case, Response will always be
	// non-nil while Request will always be nil. EventExpectName will also be non-empty.
	IsEvent bool

	// IsTransitional is set to true if the method has the Transitional attribute.
	IsTransitional bool
}

// Library represents a FIDL library as a golang package.
type Library struct {
	// Alias is the alias of the golang package referring to a FIDL library.
	Alias string

	// Path is the path to the golang package referring to a FIDL library.
	Path string
}

// Root is the root of the golang backend IR structure.
//
// The golang backend IR structure is loosely modeled after an abstract syntax
// tree, and is used to generate golang code from templates.
type Root struct {
	// Name is the name of the library.
	Name string

	// PackageName is the name of the golang package as other Go programs would
	// import it.
	PackageName string

	// Consts represents a list of FIDL constants represented as Go constants.
	Consts []Const

	// Enums represents a list of FIDL enums represented as Go enums.
	Enums []Enum

	// Structs represents the list of FIDL structs represented as Go structs.
	Structs []Struct

	// Unions represents the list of FIDL unions represented as Go structs.
	Unions []Union

	// Table represents the list of FIDL tables represented as Go structs.
	Tables []Table

	// Interfaces represents the list of FIDL interfaces represented as Go types.
	Interfaces []Interface

	// Libraries represents the set of library dependencies for this FIDL library.
	Libraries []Library
}

// compiler contains the state necessary for recursive compilation.
type compiler struct {
	// decls contains all top-level declarations for the FIDL source.
	decls types.DeclMap

	// library is the identifier for the current library.
	library types.LibraryIdentifier

	// libraryDeps is a mapping of compiled library identifiers (go package paths)
	// to aliases, which is used to resolve references to types outside of the current
	// FIDL library.
	libraryDeps map[string]string

	// usedLibraryDeps is identical to libraryDeps except it is built up as references
	// are made into libraryDeps. Thus, after Compile is run, it contains the subset of
	// libraryDeps that's actually being used. The purpose is to figure out which
	// dependencies need to be imported.
	usedLibraryDeps map[string]string
}

// Contains the full set of reserved golang keywords, in addition to a set of
// primitive named types. Note that this will result in potentially unnecessary
// identifier renaming, but this isn't a big deal for generated code.
var reservedWords = map[string]bool{
	// Officially reserved keywords.
	"break":       true,
	"case":        true,
	"chan":        true,
	"const":       true,
	"continue":    true,
	"default":     true,
	"defer":       true,
	"else":        true,
	"fallthrough": true,
	"for":         true,
	"func":        true,
	"go":          true,
	"goto":        true,
	"if":          true,
	"int":         true,
	"interface":   true,
	"map":         true,
	"package":     true,
	"range":       true,
	"return":      true,
	"select":      true,
	"struct":      true,
	"switch":      true,
	"try":         true,
	"type":        true,
	"var":         true,

	// Reserved types.
	"bool":   true,
	"byte":   true,
	"int8":   true,
	"int16":  true,
	"int32":  true,
	"int64":  true,
	"rune":   true,
	"string": true,
	"uint8":  true,
	"uint16": true,
	"uint32": true,
	"uint64": true,

	// Reserved values.
	"false": true,
	"true":  true,
}

var primitiveTypes = map[types.PrimitiveSubtype]string{
	types.Bool:    "bool",
	types.Int8:    "int8",
	types.Int16:   "int16",
	types.Int32:   "int32",
	types.Int64:   "int64",
	types.Uint8:   "uint8",
	types.Uint16:  "uint16",
	types.Uint32:  "uint32",
	types.Uint64:  "uint64",
	types.Float32: "float32",
	types.Float64: "float64",
}

var handleTypes = map[types.HandleSubtype]string{
	// TODO(mknyszek): Add support here for process, thread, job, resource,
	// interrupt, eventpair, fifo, guest, and time once these are actually
	// supported in the Go runtime.
	types.Handle:  "_zx.Handle",
	types.Vmo:     "_zx.VMO",
	types.Channel: "_zx.Channel",
	types.Event:   "_zx.Event",
	types.Port:    "_zx.Port",
	types.Log:     "_zx.Log",
	types.Socket:  "_zx.Socket",
	types.Vmar:    "_zx.VMAR",
}

func exportIdentifier(name types.EncodedCompoundIdentifier) types.CompoundIdentifier {
	ci := types.ParseCompoundIdentifier(name)
	ci.Name = types.Identifier(common.ToUpperCamelCase(string(ci.Name)))
	return ci
}

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

func changeIfReserved(val types.Identifier, ext string) string {
	// TODO(mknyszek): Detect name collision within a scope as a result of transforming.
	str := string(val) + ext
	if isReservedWord(str) {
		return str + "_"
	}
	return str
}

func (c *compiler) inExternalLibrary(ci types.CompoundIdentifier) bool {
	if len(ci.Library) != len(c.library) {
		return true
	}
	for i, part := range c.library {
		if ci.Library[i] != part {
			return true
		}
	}
	return false
}

func (_ *compiler) compileIdentifier(id types.Identifier, export bool, ext string) string {
	str := string(id)
	if export {
		str = common.ToUpperCamelCase(str)
	} else {
		str = common.ToLowerCamelCase(str)
	}
	return changeIfReserved(types.Identifier(str), ext)
}

func (c *compiler) compileCompoundIdentifier(eci types.EncodedCompoundIdentifier, ext string) string {
	ci := exportIdentifier(eci)
	pkg := compileLibraryIdentifier(ci.Library)
	strs := []string{}
	if c.inExternalLibrary(ci) {
		pkgAlias := c.libraryDeps[pkg]
		strs = append(strs, pkgAlias)
		c.usedLibraryDeps[pkg] = pkgAlias
	}
	strs = append(strs, changeIfReserved(ci.Name, ext))
	return strings.Join(strs, ".")
}

func (_ *compiler) compileLiteral(val types.Literal) string {
	switch val.Kind {
	// TODO(mknyszek): Support string and default literals.
	case types.NumericLiteral:
		return val.Value
	case types.TrueLiteral:
		return "true"
	case types.FalseLiteral:
		return "false"
	default:
		log.Fatal("Unknown literal kind: ", val.Kind)
		return ""
	}
}

func (c *compiler) compileConstant(val types.Constant) string {
	switch val.Kind {
	// TODO(mknyszek): Support identifiers.
	case types.LiteralConstant:
		return c.compileLiteral(val.Literal)
	default:
		log.Fatal("Unknown constant kind: ", val.Kind)
		return ""
	}
}

func (c *compiler) compilePrimitiveSubtype(val types.PrimitiveSubtype) Type {
	t, ok := primitiveTypes[val]
	if !ok {
		log.Fatal("Unknown primitive type: ", val)
	}
	return Type(t)
}

func (c *compiler) compileType(val types.Type) (r Type, t Tag, t2 tagNew) {
	switch val.Kind {
	case types.ArrayType:
		e, et, et2 := c.compileType(*val.ElementType)
		r = Type(fmt.Sprintf("[%s]%s", strconv.Itoa(*val.ElementCount), e))
		t = et
		t2 = et2
	case types.StringType:
		t.MaxElems = append(t.MaxElems, val.ElementCount)
		if val.ElementCount == nil {
			t2.reverseOfBounds = append(t2.reverseOfBounds, math.MaxInt32)
		} else {
			t2.reverseOfBounds = append(t2.reverseOfBounds, *val.ElementCount)
		}
		if val.Nullable {
			r = Type("*string")
		} else {
			r = Type("string")
		}
	case types.HandleType:
		// Note here that we require the SyscallZx package.
		c.usedLibraryDeps[SyscallZxPackage] = SyscallZxAlias
		e, ok := handleTypes[val.HandleSubtype]
		if !ok {
			// Fall back onto a generic handle if we don't support that particular
			// handle subtype.
			e = handleTypes[types.Handle]
		}
		var nullability int
		if val.Nullable {
			t.Nullable = true
			nullability = 1
		}
		t2.reverseOfBounds = append(t2.reverseOfBounds, nullability)
		r = Type(e)
	case types.RequestType:
		e := c.compileCompoundIdentifier(val.RequestSubtype, RequestSuffix)
		var nullability int
		if val.Nullable {
			t.Nullable = true
			nullability = 1
		}
		t2.reverseOfBounds = append(t2.reverseOfBounds, nullability)
		r = Type(e)
	case types.VectorType:
		e, et, et2 := c.compileType(*val.ElementType)
		et.MaxElems = append(et.MaxElems, val.ElementCount)
		if val.ElementCount == nil {
			et2.reverseOfBounds = append(et2.reverseOfBounds, math.MaxInt32)
		} else {
			et2.reverseOfBounds = append(et2.reverseOfBounds, *val.ElementCount)
		}
		if val.Nullable {
			r = Type(fmt.Sprintf("*[]%s", e))
		} else {
			r = Type(fmt.Sprintf("[]%s", e))
		}
		t = et
		t2 = et2
	case types.PrimitiveType:
		r = c.compilePrimitiveSubtype(val.PrimitiveSubtype)
	case types.IdentifierType:
		e := c.compileCompoundIdentifier(val.Identifier, "")
		declType, ok := c.decls[val.Identifier]
		if !ok {
			log.Fatal("Unknown identifier: ", val.Identifier)
		}
		switch declType {
		case types.EnumDeclType:
			r = Type(e)
		case types.InterfaceDeclType:
			if val.Nullable {
				t.Nullable = true
			}
			r = Type(e + ProxySuffix)
		case types.StructDeclType:
			fallthrough
		case types.UnionDeclType:
			fallthrough
		case types.TableDeclType:
			if val.Nullable {
				r = Type("*" + e)
			} else {
				r = Type(e)
			}
		default:
			log.Fatal("Unknown declaration type: ", declType)
		}
	default:
		log.Fatal("Unknown type kind: ", val.Kind)
	}
	return
}

func (c *compiler) compileConst(val types.Const) Const {
	// It's OK to ignore the tag because this type is guaranteed by the frontend
	// to be either an enum, a primitive, or a string.
	t, _, _ := c.compileType(val.Type)
	return Const{
		Attributes: val.Attributes,
		Name:       c.compileCompoundIdentifier(val.Name, ""),
		Type:       t,
		Value:      c.compileConstant(val.Value),
	}
}

func (c *compiler) compileEnumMember(val types.EnumMember) EnumMember {
	return EnumMember{
		Attributes: val.Attributes,
		Name:       c.compileIdentifier(val.Name, true, ""),
		Value:      c.compileConstant(val.Value),
	}
}

func (c *compiler) compileEnum(val types.Enum) Enum {
	r := Enum{
		Attributes: val.Attributes,
		Name:       c.compileCompoundIdentifier(val.Name, ""),
		Type:       c.compilePrimitiveSubtype(val.Type),
	}
	for _, v := range val.Members {
		r.Members = append(r.Members, c.compileEnumMember(v))
	}
	return r
}

func (c *compiler) compileStructMember(val types.StructMember) StructMember {
	ty, tag, tag2 := c.compileType(val.Type)
	return StructMember{
		Attributes:  val.Attributes,
		Type:        ty,
		Name:        c.compileIdentifier(val.Name, true, ""),
		PrivateName: c.compileIdentifier(val.Name, false, ""),
		Tags:        tagsfmt(tag, tag2),
	}
}

func (c *compiler) compileStruct(val types.Struct) Struct {
	r := Struct{
		Attributes: val.Attributes,
		Name:       c.compileCompoundIdentifier(val.Name, ""),
		Size:       val.Size,
		Alignment:  val.Alignment,
	}

	for _, v := range val.Members {
		r.Members = append(r.Members, c.compileStructMember(v))
	}

	return r
}

func (c *compiler) compileUnionMember(unionName string, val types.UnionMember) UnionMember {
	ty, tag, tag2 := c.compileType(val.Type)
	return UnionMember{
		Attributes:  val.Attributes,
		Type:        ty,
		Name:        c.compileIdentifier(val.Name, true, ""),
		PrivateName: c.compileIdentifier(val.Name, false, ""),
		Tags:        tagsfmt(tag, tag2),
	}
}

func (c *compiler) compileUnion(val types.Union) Union {
	r := Union{
		Attributes: val.Attributes,
		Name:       c.compileCompoundIdentifier(val.Name, ""),
		TagName:    c.compileCompoundIdentifier(val.Name, TagSuffix),
		Size:       val.Size,
		Alignment:  val.Alignment,
	}
	for _, v := range val.Members {
		r.Members = append(r.Members, c.compileUnionMember(r.Name, v))
	}
	return r
}

func (c *compiler) compileTable(val types.Table) Table {
	var members []TableMember
	for _, member := range val.Members {
		if member.Reserved {
			continue
		}
		var (
			ty, tag, tag2 = c.compileType(member.Type)
			name          = c.compileIdentifier(member.Name, true, "")
			privateName   = c.compileIdentifier(member.Name, false, "")
		)
		tag.Ordinal = member.Ordinal
		tag2.reverseOfBounds = append(tag2.reverseOfBounds, member.Ordinal)
		members = append(members, TableMember{
			Attributes:       member.Attributes,
			DataField:        name,
			PrivateDataField: privateName,
			PresenceField:    name + "Present",
			Setter:           "Set" + name,
			Getter:           "Get" + name,
			Haser:            "Has" + name,
			Clearer:          "Clear" + name,
			Type:             ty,
			Tags:             tagsfmt(tag, tag2),
		})
	}
	return Table{
		Attributes: val.Attributes,
		Name:       c.compileCompoundIdentifier(val.Name, ""),
		Size:       val.Size,
		Alignment:  val.Alignment,
		Members:    members,
	}
}

func (c *compiler) compileParameter(p types.Parameter) StructMember {
	ty, tag, tag2 := c.compileType(p.Type)
	return StructMember{
		Type:        ty,
		Name:        c.compileIdentifier(p.Name, true, ""),
		PrivateName: c.compileIdentifier(p.Name, false, ""),
		Tags:        tagsfmt(tag, tag2),
	}
}

func (c *compiler) compileMethod(ifaceName types.EncodedCompoundIdentifier, val types.Method) Method {
	methodName := c.compileIdentifier(val.Name, true, "")
	r := Method{
		Attributes:      val.Attributes,
		Name:            methodName,
		Ordinal:         val.Ordinal,
		OrdinalName:     c.compileCompoundIdentifier(ifaceName, methodName+"Ordinal"),
		GenOrdinal:      val.GenOrdinal,
		GenOrdinalName:  c.compileCompoundIdentifier(ifaceName, methodName+"GenOrdinal"),
		EventExpectName: "Expect" + methodName,
		IsEvent:         !val.HasRequest && val.HasResponse,
		IsTransitional:  val.IsTransitional(),
	}
	if val.HasRequest {
		req := Struct{
			Name: c.compileCompoundIdentifier(ifaceName, methodName+"Request"),
			// We want just the size of the parameter array as a struct, not
			// including the message header size.
			Size: val.RequestSize - MessageHeaderSize,
		}
		for _, p := range val.Request {
			req.Members = append(req.Members, c.compileParameter(p))
		}
		r.Request = &req
	}
	if val.HasResponse {
		resp := Struct{
			Name: c.compileCompoundIdentifier(ifaceName, methodName+"Response"),
			// We want just the size of the parameter array as a struct, not
			// including the message header size.
			Size: val.ResponseSize - MessageHeaderSize,
		}
		for _, p := range val.Response {
			resp.Members = append(resp.Members, c.compileParameter(p))
		}
		r.Response = &resp
	}
	return r
}

func (c *compiler) compileInterface(val types.Interface) Interface {
	proxyType := "ChannelProxy"
	if val.Attributes.GetAttribute("Transport").Value == "SocketControl" {
		proxyType = "SocketControlProxy"
	}
	r := Interface{
		Attributes:           val.Attributes,
		Name:                 c.compileCompoundIdentifier(val.Name, ""),
		TransitionalBaseName: c.compileCompoundIdentifier(val.Name, TransitionalBaseSuffix),
		ProxyName:            c.compileCompoundIdentifier(val.Name, ProxySuffix),
		ProxyType:            proxyType,
		StubName:             c.compileCompoundIdentifier(val.Name, StubSuffix),
		RequestName:          c.compileCompoundIdentifier(val.Name, RequestSuffix),
		EventProxyName:       c.compileCompoundIdentifier(val.Name, EventProxySuffix),
		ServerName:           c.compileCompoundIdentifier(val.Name, ServiceSuffix),
		ServiceNameConstant:  c.compileCompoundIdentifier(val.Name, ServiceNameSuffix),
		ServiceNameString:    val.GetServiceName(),
	}
	for _, v := range val.Methods {
		r.Methods = append(r.Methods, c.compileMethod(val.Name, v))
	}
	return r
}

func compileLibraryIdentifier(lib types.LibraryIdentifier) string {
	return "fidl/" + joinLibraryIdentifier(lib, "/")
}

func joinLibraryIdentifier(lib types.LibraryIdentifier, sep string) string {
	str := make([]string, len([]types.Identifier(lib)))
	for i, id := range lib {
		str[i] = string(id)
	}
	return strings.Join(str, sep)
}

// Compile translates parsed FIDL IR into golang backend IR for code generation.
func Compile(fidlData types.Root) Root {
	libraryName := types.ParseLibraryName(fidlData.Name)
	libraryPath := compileLibraryIdentifier(libraryName)

	// Collect all libraries.
	godeps := make(map[string]string)
	for _, v := range fidlData.Libraries {
		// Don't try to import yourself.
		if v.Name == fidlData.Name {
			continue
		}
		libComponents := types.ParseLibraryName(v.Name)
		path := compileLibraryIdentifier(libComponents)
		alias := changeIfReserved(
			types.Identifier(common.ToLowerCamelCase(
				joinLibraryIdentifier(libComponents, ""),
			)),
			"",
		)
		godeps[path] = alias
	}

	// Instantiate a compiler context.
	c := compiler{
		decls:           fidlData.Decls,
		library:         libraryName,
		libraryDeps:     godeps,
		usedLibraryDeps: make(map[string]string),
	}

	// Compile fidlData into r.
	r := Root{
		Name:        string(libraryName[len(libraryName)-1]),
		PackageName: libraryPath,
	}
	for _, v := range fidlData.Consts {
		r.Consts = append(r.Consts, c.compileConst(v))
	}
	for _, v := range fidlData.Enums {
		r.Enums = append(r.Enums, c.compileEnum(v))
	}
	for _, v := range fidlData.Structs {
		r.Structs = append(r.Structs, c.compileStruct(v))
	}
	for _, v := range fidlData.Unions {
		r.Unions = append(r.Unions, c.compileUnion(v))
	}
	for _, v := range fidlData.Tables {
		r.Tables = append(r.Tables, c.compileTable(v))
	}
	if len(fidlData.Structs) != 0 || len(fidlData.Interfaces) != 0 {
		c.usedLibraryDeps[BindingsPackage] = BindingsAlias
	}
	if len(fidlData.Interfaces) != 0 {
		c.usedLibraryDeps[SyscallZxPackage] = SyscallZxAlias
	}
	for _, v := range fidlData.Interfaces {
		r.Interfaces = append(r.Interfaces, c.compileInterface(v))
	}
	for path, alias := range c.usedLibraryDeps {
		r.Libraries = append(r.Libraries, Library{
			Path:  path,
			Alias: alias,
		})
	}
	// Sort the libraries according to Path.
	sort.Slice(r.Libraries, func(i, j int) bool {
		return strings.Compare(r.Libraries[i].Path, r.Libraries[j].Path) == -1
	})
	return r
}
