Merge "Endian swap the message size parameter."
diff --git a/api/ast/api.go b/api/ast/api.go
new file mode 100644
index 0000000..6135ea8
--- /dev/null
+++ b/api/ast/api.go
@@ -0,0 +1,48 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// package ast holds the set of types used in the abstract syntax tree
+// representation of the api language.
+package ast
+
+import "android.googlesource.com/platform/tools/gpu/parse"
+
+// API is the root of the AST tree, and constitutes one entire parsed file.
+// It holds the set of top level AST nodes, grouped by type.
+type API struct {
+	CST        *parse.Branch // underlying parse structure for this node
+	Macros     []*Function   // functions declared with the "macro" keyword
+	Externs    []*Function   // functions declared with the "extern" keyword
+	Commands   []*Function   // functions declared with the "cmd" keyword
+	Pseudonyms []*Pseudonym  // strong type aliases declared with the "type" keyword
+	Aliases    []*Alias      // weak type aliases declared with the "alias" keyword
+	Enums      []*Enum       // enumerated types, declared with the "enum" keyword
+	Classes    []*Class      // class types, declared with the "class" keyword
+	Fields     []*Field      // variables declared at the global scope
+}
+
+// Annotation is the AST node that represents «@name(arguments) constructs»
+type Annotation struct {
+	CST       *parse.Branch // underlying parse structure for this node
+	Name      *Identifier   // the name part (between the @ and the brackets)
+	Arguments []interface{} // the list of arguments (the bit in brackets)
+}
+
+// Annotations represents the set of Annotation objects that apply to another
+// AST node.
+type Annotations []*Annotation
+
+// Invalid is used when an error was encountered in the parsing, but we want to
+// keep going. If there are no errors, this will never be in the tree.
+type Invalid struct{}
diff --git a/api/ast/expression.go b/api/ast/expression.go
new file mode 100644
index 0000000..400d451
--- /dev/null
+++ b/api/ast/expression.go
@@ -0,0 +1,97 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ast
+
+import "android.googlesource.com/platform/tools/gpu/parse"
+
+// Block represents a linear sequence of statements, most often the contents
+// of a {} pair.
+type Block struct {
+	CST        *parse.Branch // underlying parse structure for this node
+	Docs       *URL          // the url to the documentation for this block
+	Statements []interface{} // The set of statements that make up the block
+}
+
+// If represents an «"if" condition { trueblock } "else" { falseblock }» structure.
+type If struct {
+	CST       *parse.Branch // underlying parse structure for this node
+	Condition interface{}   // the condition to use to select which block is active
+	True      *Block        // the block to use if condition is true
+	False     *Block        // the block to use if condition is false
+}
+
+// Iteration represents a «"for" variable "in" iterable { block }» structure.
+type Iteration struct {
+	CST      *parse.Branch // underlying parse structure for this node
+	Variable *Identifier   // the variable to use for the iteration value
+	Iterable interface{}   // the expression that produces the iterable to loop over
+	Block    *Block        // the block to run once per item in the iterable
+}
+
+// Switch represents a «"switch" value { cases }» structure.
+// The first matching case is selected.
+// If a switch is used as an expression, the case blocks must all be a single
+// expression.
+type Switch struct {
+	CST   *parse.Branch // underlying parse structure for this node
+	Value interface{}   // the value to match against
+	Cases []*Case       // the set of cases to match the value with
+}
+
+// Case represents a «"case" conditions: block» structure within a switch statement.
+// The conditions are a comma separated list of expressions the switch statement
+// value will be compared against.
+type Case struct {
+	CST        *parse.Branch // underlying parse structure for this node.
+	Conditions []interface{} // the set of conditions that would select this case
+	Block      *Block        // the block to run if this case is selected
+}
+
+// Group represents the «(expression)» construct, a single parenthesized expression.
+type Group struct {
+	CST        *parse.Branch // underlying parse structure for this node
+	Expression interface{}   // the expression within the parentheses
+}
+
+// DeclareLocal represents a «name := value» statement that declares a new
+// immutable local variable with the specified value and inferred type.
+type DeclareLocal struct {
+	CST  *parse.Branch // underlying parse structure for this node
+	Name *Identifier   // the name to give the new local
+	RHS  interface{}   // the value to store in that local
+}
+
+// Assign represents a «location = value» statement that assigns a value to an
+// existing mutable location.
+type Assign struct {
+	CST *parse.Branch // underlying parse structure for this node
+	LHS interface{}   // the location to store the value into
+	RHS interface{}   // the value to store
+}
+
+// Assert represents the «"assert" condition» statement.
+// Used mostly to express the pre-conditions of api commands, such as acceptable
+// values for parameters that cannot be expressed in the type system.
+type Assert struct {
+	CST       *parse.Branch // underlying parse structure for this node.
+	Condition interface{}   // the condition to check, should be true
+}
+
+// Length represents the «"len"(value)» construct, were value should be an
+// expresssion that returns an object of array, string or map type.
+type Length struct {
+	CST    *parse.Branch // underlying parse structure for this node.
+	Object interface{}   // the object to query the length of
+}
diff --git a/api/ast/function.go b/api/ast/function.go
new file mode 100644
index 0000000..48352ef
--- /dev/null
+++ b/api/ast/function.go
@@ -0,0 +1,49 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ast
+
+import "android.googlesource.com/platform/tools/gpu/parse"
+
+// Function represents the declaration of a callable entity, any of "cmd", "extern" or "macro".
+// Its structure is «return_type name(parameters) body»
+// where parameters is a comma separated list and body is an optional block.
+type Function struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to this function
+	Name        *Identifier   // the name of the function
+	Parameters  []*Parameter  // the parameters the function takes
+	Block       *Block        // the body of the function if present
+}
+
+// Parameter represents a single parameter in the set of parameters for a Function.
+// It has the structure «["in"|"out"|"inout"|"this"] type name»
+type Parameter struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to this parameter
+	Input       bool          // true if the parameter is an input
+	Output      bool          // true if the parameters is an output
+	This        bool          // true if the parameter is the this pointer of a method
+	Type        interface{}   // the type of the parameter
+	Name        *Identifier   // the name the parameter as exposed to the body
+}
+
+// Call is an expression that invokes a function with a set of arguments.
+// It has the structure «target(arguments)» where target must be a function and
+// arguments is a comma separated list of expressions.
+type Call struct {
+	CST       *parse.Branch // underlying parse structure for this node
+	Target    interface{}   // the function to invoke
+	Arguments []interface{} // the arguments to the function
+}
diff --git a/api/ast/identifier.go b/api/ast/identifier.go
new file mode 100644
index 0000000..94e861d
--- /dev/null
+++ b/api/ast/identifier.go
@@ -0,0 +1,56 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ast
+
+import "android.googlesource.com/platform/tools/gpu/parse"
+
+// Identifier holds a parsed identifier in the parse tree.
+type Identifier struct {
+	CST   *parse.Leaf // underlying parse leaf for this node
+	Value string      // the identifier
+}
+
+const (
+	// Keyword strings represent places in the syntax where a word has special
+	// meaning.
+	KeywordAPI       = "api"
+	KeywordAlias     = "alias"
+	KeywordArray     = "array"
+	KeywordAs        = "as"
+	KeywordAssert    = "assert"
+	KeywordBitfield  = "bitfield"
+	KeywordCase      = "case"
+	KeywordClass     = "class"
+	KeywordCmd       = "cmd"
+	KeywordElse      = "else"
+	KeywordEnum      = "enum"
+	KeywordExtern    = "extern"
+	KeywordFalse     = "false"
+	KeywordFor       = "for"
+	KeywordIf        = "if"
+	KeywordIn        = "in"
+	KeywordInout     = "inout"
+	KeywordLength    = "len"
+	KeywordMacro     = "macro"
+	KeywordMap       = "map"
+	KeywordNew       = "new"
+	KeywordOut       = "out"
+	KeywordPseudonym = "type"
+	KeywordPtr       = "ptr"
+	KeywordSwitch    = "switch"
+	KeywordThis      = "this"
+	KeywordTrue      = "true"
+	KeywordWhen      = "when"
+)
diff --git a/api/ast/literal.go b/api/ast/literal.go
new file mode 100644
index 0000000..fb68994
--- /dev/null
+++ b/api/ast/literal.go
@@ -0,0 +1,51 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ast
+
+import (
+	"net/url"
+
+	"android.googlesource.com/platform/tools/gpu/parse"
+)
+
+// Number represents a typeless numeric constant.
+type Number struct {
+	CST   *parse.Leaf // underlying parse leaf for this node
+	Value string      // the string representation of the constant
+}
+
+// Bool is used for the "true" and "false" keywords.
+type Bool struct {
+	CST   *parse.Leaf // underlying parse leaf for this node
+	Value bool        // The value of the boolean
+}
+
+// String represents a quoted string constant.
+type String struct {
+	CST   *parse.Leaf // underlying parse leaf for this node
+	Value string      // The body of the string, not including the delimiters
+}
+
+// Unknown represents the "?" construct. This is used in places where an
+// expression takes a value that is implementation defined.
+type Unknown struct {
+	CST *parse.Leaf // underlying parse leaf for this node
+}
+
+// URL holds things that start with "http:", used for documentation links in blocks.
+type URL struct {
+	CST *parse.Leaf // underlying parse leaf for this node
+	URL url.URL     // the actual url
+}
diff --git a/api/ast/operator.go b/api/ast/operator.go
new file mode 100644
index 0000000..680cb22
--- /dev/null
+++ b/api/ast/operator.go
@@ -0,0 +1,141 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ast
+
+import (
+	"sort"
+
+	"android.googlesource.com/platform/tools/gpu/parse"
+)
+
+const (
+	// Runes with special meaning to the parser.
+	Quote = '"'
+)
+
+const (
+	// The set of operators understood by the parser.
+	OpUnknown       = "?"
+	OpBlockStart    = "{"
+	OpBlockEnd      = "}"
+	OpIndexStart    = "["
+	OpIndexEnd      = "]"
+	OpListStart     = "("
+	OpListSeparator = ","
+	OpListEnd       = ")"
+	OpMetaStart     = "<"
+	OpMetaEnd       = ">"
+	OpEndStatement  = ";"
+	OpAssign        = "="
+	OpDeclare       = ":="
+	OpMember        = "."
+	OpExtends       = ":"
+	OpAnnotation    = "@"
+	OpInitialise    = ":"
+	OpPointer       = "*"
+	OpEQ            = "=="
+	OpGT            = ">"
+	OpLT            = "<"
+	OpGE            = ">="
+	OpLE            = "<="
+	OpNE            = "!="
+	OpOr            = "||"
+	OpAnd           = "&&"
+	OpPlus          = "+"
+	OpMinus         = "-"
+	OpMultiply      = "*"
+	OpDivide        = "/"
+	OpRange         = ".."
+	OpNot           = "!"
+	OpIn            = "in"
+)
+
+var (
+	Operators       = []string{}            // all valid operator strings, sorted in descending length order
+	UnaryOperators  = map[string]struct{}{} // the map of valid unary operators
+	BinaryOperators = map[string]struct{}{} // the map of valid boolean operators
+)
+
+// UnaryOp represents any unary operation applied to an expression.
+type UnaryOp struct {
+	CST        *parse.Branch // underlying parse structure for this node
+	Operator   string        // the operator being applied
+	Expression interface{}   // the expression the operator is being applied to
+}
+
+// BinaryOp represents any binary operation applied to two expressions.
+type BinaryOp struct {
+	CST      *parse.Branch // underlying parse structure for this node
+	LHS      interface{}   // the expression on the left of the operator
+	Operator string        // the operator being applied
+	RHS      interface{}   // the expression on the right of the operator
+}
+
+func init() {
+	for _, op := range []string{
+		OpUnknown,
+		OpBlockStart,
+		OpBlockEnd,
+		OpIndexStart,
+		OpIndexEnd,
+		OpListStart,
+		OpListSeparator,
+		OpListEnd,
+		OpMetaStart,
+		OpMetaEnd,
+		OpEndStatement,
+		OpAssign,
+		OpDeclare,
+		OpMember,
+		OpExtends,
+		OpAnnotation,
+		OpInitialise,
+		OpPointer,
+	} {
+		Operators = append(Operators, op)
+	}
+	for _, op := range []string{
+		OpEQ,
+		OpGT,
+		OpLT,
+		OpGE,
+		OpLE,
+		OpNE,
+		OpOr,
+		OpAnd,
+		OpPlus,
+		OpMinus,
+		OpMultiply,
+		OpDivide,
+		OpRange,
+		OpIn,
+	} {
+		Operators = append(Operators, op)
+		BinaryOperators[op] = struct{}{}
+	}
+	for _, op := range []string{
+		OpNot,
+	} {
+		Operators = append(Operators, op)
+		UnaryOperators[op] = struct{}{}
+	}
+	sort.Sort(opsByLength(Operators))
+}
+
+type opsByLength []string
+
+func (a opsByLength) Len() int           { return len(a) }
+func (a opsByLength) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a opsByLength) Less(i, j int) bool { return len(a[i]) > len(a[j]) }
diff --git a/api/ast/type.go b/api/ast/type.go
new file mode 100644
index 0000000..56370c6
--- /dev/null
+++ b/api/ast/type.go
@@ -0,0 +1,153 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ast
+
+import "android.googlesource.com/platform/tools/gpu/parse"
+
+// Class represents a class type declaration of the form
+// «"class" name : extension_list { fields }»
+type Class struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to the class
+	Name        *Identifier   // the name of the class
+	Extends     []*Identifier // the set of class names it extends
+	Fields      []*Field      // the fields of the class
+}
+
+// ClassInitializer represents a class literal declaration, of the form
+// «name { field_initializers }»
+type ClassInitializer struct {
+	CST    *parse.Branch       // underlying parse structure for this node
+	Class  *Identifier         // the name of the class instantiate
+	Fields []*FieldInitializer // the initializers for the class fields
+}
+
+// New represents an expression that allocates a new class instance and returns
+// a pointer to it. It takes a class initializer to specify both the type and
+// the initial value for the instance.
+type New struct {
+	CST              *parse.Branch // underlying parse structure for this node
+	ClassInitializer *ClassInitializer
+}
+
+// Field represents a field of a class or api, with the structure
+// «type name = expression»
+type Field struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to the field
+	Type        interface{}   // the type the field holds
+	Name        *Identifier   // the name of the field
+	Default     interface{}   // the default value expression for the field
+}
+
+// FieldInitializer is used as part of a ClassInitializer to specify the value a
+// single field should have.
+type FieldInitializer struct {
+	CST   *parse.Branch // underlying parse structure for this node
+	Name  *Identifier   // the name of the field
+	Value interface{}   // the value the field should be given
+}
+
+// As represents a type coercion expression, of the form «expression "as" type»
+type As struct {
+	CST    *parse.Branch // underlying parse structure for this node
+	Object interface{}   // the value to force the type of
+	Type   interface{}   // the type it should be coerced to
+}
+
+// EnumEntry represents a single value in an enumerated type.
+type EnumEntry struct {
+	CST   *parse.Branch // underlying parse structure for this node
+	Owner *Enum         // the enum this entry is a part of
+	Name  *Identifier   // the name this entry is given
+	Value *Number       // the value of this entry
+}
+
+// Enum represents an enumerated type declaration, of the form
+// «"enum" name { entries }» where entries is a comma separated list of «name = value»
+type Enum struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to the enum
+	Name        *Identifier   // the name of the enum
+	IsBitfield  bool          // whether this enum represents a bitfield form
+	Entries     []*EnumEntry  // the set of valid entries for this enum
+	Extends     []*Identifier // deprecated list of enums this extends
+}
+
+// Member represents an expressions that access members of objects.
+// Always of the form «object.name» where object is an expression.
+type Member struct {
+	CST    *parse.Branch // underlying parse structure for this node
+	Object interface{}   // the object to get a member of
+	Name   *Identifier   // the name of the member to get
+}
+
+// Index represents any expression of the form «object[index]»
+// Used for arrays, maps and bitfields.
+type Index struct {
+	CST    *parse.Branch // underlying parse structure for this node
+	Object interface{}   // the object to index
+	Index  interface{}   // the index to lookup
+}
+
+// ArrayType represents a type declaration for an array, which looks
+// like «"array"<value_type>»
+type ArrayType struct {
+	CST       *parse.Branch // underlying parse structure for this node
+	ValueType interface{}   // the type stored as elements of the array
+}
+
+// StaticArrayType represents a type declaration for a constant size array,
+// which looks like «type[dimensions]»
+// dimensions is a comma separated list of dimensions, for declaring
+// multidimensional arrays, for instance f32[4,4] for a matrix.
+type StaticArrayType struct {
+	CST        *parse.Branch // underlying parse structure for this node
+	ValueType  interface{}   // The type to store in the array
+	Dimensions []interface{} // the dimensions of the array
+}
+
+// MapType represents a type declaration of a map, of the form
+// «map<key_type, value_type>»
+type MapType struct {
+	CST       *parse.Branch // underlying parse structure for this node
+	KeyType   interface{}   // the type used to index the map
+	ValueType interface{}   // the type stored against the index in the map
+}
+
+// PointerType represents a pointer type declaration, of the form «type*»
+type PointerType struct {
+	CST *parse.Branch // underlying parse structure for this node
+	To  interface{}   // the underlying type this pointer points to
+}
+
+// Alias represents a weak type alias, with structure «"alias" type name».
+// An alias does not declare a new type, just a reusable name for a common type.
+type Alias struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to the alias
+	Name        *Identifier   // the name of the alias
+	To          interface{}   // the type it is an alias for
+}
+
+// Pseudonym declares a new type in terms of another type.
+// Has the form «"type" type name»
+// Pseydonyms are proper types, but the underlying type can be discovered.
+type Pseudonym struct {
+	CST         *parse.Branch // underlying parse structure for this node
+	Annotations Annotations   // the annotations applied to the type
+	Name        *Identifier   // the name of the type
+	To          interface{}   // the underlying type
+}
diff --git a/binary/codergen/main.go b/binary/codergen/main.go
new file mode 100644
index 0000000..17132a3
--- /dev/null
+++ b/binary/codergen/main.go
@@ -0,0 +1,100 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Codergen is a tool to parse go code and automatically generate encoders and
+// decoders for the structs it finds.
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"android.googlesource.com/platform/tools/gpu/binary/generate"
+
+	"golang.org/x/tools/go/loader"
+	"golang.org/x/tools/go/types"
+)
+
+var (
+	golang = flag.String("go", "", "the go file to generate")
+	java   = flag.String("java", "", "the java file to generate")
+)
+
+func run() error {
+	flag.Parse()
+	config := loader.Config{SourceImports: true}
+	_, err := config.FromArgs(flag.Args(), false)
+	if err != nil {
+		return err
+	}
+	config.AllowErrors = true
+	info, err := config.Load()
+	if err != nil {
+		return err
+	}
+	file := generate.File{}
+	for _, pkg := range info.Created {
+		file.Package = pkg.Pkg.Name()
+		for _, def := range pkg.Defs {
+			if n, ok := def.(*types.TypeName); ok {
+				if t, ok := n.Type().(*types.Named); ok {
+					if _, ok := t.Underlying().(*types.Struct); ok {
+						file.Structs = append(file.Structs, generate.FromTypename(pkg.Pkg, n))
+					}
+				}
+			}
+		}
+	}
+	generate.Sort(file.Structs)
+	if *golang != "" {
+		file := file
+		file.Generated = fmt.Sprintf("codergen -go=%s", *golang)
+		result, err := generate.GoFile(&file)
+		if err != nil {
+			return err
+		}
+		err = ioutil.WriteFile(*golang, result, os.ModePerm)
+		if err != nil {
+			return err
+		}
+	}
+	if *java != "" {
+		file := file
+		file.Generated = fmt.Sprintf("codergen -java=%s", filepath.Base(*java))
+		// pick off the package part
+		smashed := strings.Split(*java, "/com/")
+		file.Package = "com." + strings.Replace(smashed[len(smashed)-1], "/", ".", -1)
+		filename := filepath.Join(*java, "ObjectFactory.java")
+		result, err := generate.JavaFile(&file)
+		if err != nil {
+			return err
+		}
+		err = ioutil.WriteFile(filename, result, os.ModePerm)
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func main() {
+	if err := run(); err != nil {
+		fmt.Fprintf(os.Stderr, "codergen failed: %v\n", err)
+		os.Exit(1)
+	}
+}
diff --git a/binary/decoder.go b/binary/decoder.go
index c548600..a620e4a 100644
--- a/binary/decoder.go
+++ b/binary/decoder.go
@@ -15,10 +15,8 @@
 package binary
 
 import (
-	"fmt"
 	"io"
 	"math"
-	"reflect"
 )
 
 // Decoder provides methods for decoding values to an io.Reader.
@@ -167,12 +165,6 @@
 	return buf, err
 }
 
-type unknownTypeID TypeID
-
-func (e unknownTypeID) Error() string {
-	return fmt.Sprintf("Unknown type id %x encountered in binary.Decoder", TypeID(e))
-}
-
 // Object decodes and returns an Object from the Decoder's io.Reader. Object instances that were
 // encoded multiple times will be decoded and returned as a shared, single instance.
 // The type id in the stream must have been previously registered with binary.Register.
@@ -194,11 +186,12 @@
 	if err != nil {
 		return nil, err
 	}
-	t, idFound := idToType[id]
-	if !idFound {
-		return nil, unknownTypeID(id)
+
+	obj, err := MakeObject(id)
+	if err != nil {
+		return nil, err
 	}
-	obj := reflect.New(t).Interface().(Decodable)
+
 	if err = obj.Decode(d); err != nil {
 		return nil, err
 	}
diff --git a/binary/encoder.go b/binary/encoder.go
index c36af06..c38875c 100644
--- a/binary/encoder.go
+++ b/binary/encoder.go
@@ -15,10 +15,8 @@
 package binary
 
 import (
-	"fmt"
 	"io"
 	"math"
-	"reflect"
 )
 
 // Encoder provides methods for encoding values to an io.Writer.
@@ -153,14 +151,6 @@
 	return e.write(data)
 }
 
-type unknownType struct {
-	Object Encodable
-}
-
-func (e unknownType) Error() string {
-	return fmt.Sprintf("Unknown type %T encountered in binary.Encoder", e.Object)
-}
-
 // Object encodes an Encodable to the Encoder's io.Writer. If Object is called repeatedly with the
 // same argument (i.e. the argument has identical dynamic types and equal dynamic values), then the
 // argument will only be encoded with the first call, and later encodings will reference the first
@@ -176,9 +166,9 @@
 		return e.Uint16(key)
 	}
 
-	id, idFound := typeToID[reflect.TypeOf(obj)]
-	if !idFound {
-		return unknownType{obj}
+	id, err := TypeOf(obj)
+	if err != nil {
+		return err
 	}
 
 	key = uint16(len(e.objects))
diff --git a/binary/float16.go b/binary/float16.go
index fc1a9e8..6c342ed 100644
--- a/binary/float16.go
+++ b/binary/float16.go
@@ -17,19 +17,29 @@
 import "unsafe"
 
 // Float16 represents a 16-bit floating point number, containing a single sign bit, 5 exponent bits
-// and 10 fractional bits:
+// and 10 fractional bits. This corresponds to IEEE 754-2008 binary16 (or half precision float) type.
 //
 //    MSB                                                                         LSB
 //   ╔════╦════╤════╤════╤════╤════╦════╤════╤════╤════╤════╤════╤════╤════╤════╤════╗
 //   ║Sign║ E₄ │ E₃ │ E₂ │ E₁ │ E₀ ║ F₉ │ F₈ │ F₇ │ F₆ │ F₅ │ F₄ │ F₃ │ F₂ │ F₁ │ F₀ ║
 //   ╚════╩════╧════╧════╧════╧════╩════╧════╧════╧════╧════╧════╧════╧════╧════╧════╝
 //   Where E is the exponent bits and F is the fractional bits.
-//
-// This floating-point number is similar to IEEE 754-2008, but Float16 does not support NaNs nor
-// ±Infs.
 type Float16 uint16
 
-// Float32 returns the Float16 value expanded to a float32
+const (
+	float16ExpMask  Float16 = 0x7c00
+	float16ExpBias  uint32  = 0xf
+	float16ExpShift uint32  = 10
+	float16FracMask Float16 = 0x03ff
+	float16SignMask Float16 = 0x8000
+	float32ExpMask  uint32  = 0x7f800000
+	float32ExpBias  uint32  = 0x7f
+	float32ExpShift uint32  = 23
+	float32FracMask uint32  = 0x007fffff
+)
+
+// Float32 returns the Float16 value expanded to a float32. Infinities and NaNs are expanded as
+// such.
 func (f Float16) Float32() float32 {
 	u32 := expandF16ToF32(f)
 	ptr := unsafe.Pointer(&u32)
@@ -37,16 +47,93 @@
 	return f32
 }
 
-func expandF16ToF32(in Float16) uint32 {
-	sign := uint32(in&0x8000) << 16
-	nonSign := uint32(in&0x7fff) << 13
-	exp := uint32(in & 0x7c00)
+// IsNaN reports whether f is an “not-a-number” value.
+func (f Float16) IsNaN() bool { return (f&float16ExpMask == float16ExpMask) && (f&float16FracMask != 0) }
 
-	nonSign += 0x38000000
+// IsInf reports whether f is an infinity, according to sign. If sign > 0, IsInf reports whether
+// f is positive infinity. If sign < 0, IsInf reports whether f is negative infinity. If sign ==
+// 0, IsInf reports whether f is either infinity.
+func (f Float16) IsInf(sign int) bool {
+	return ((f == float16ExpMask) && sign >= 0) ||
+		(f == (float16SignMask|float16ExpMask) && sign <= 0)
+}
 
-	if exp == 0 {
-		nonSign = 0
+// Float16NaN returns an “not-a-number” value.
+func NewFloat16NaN() Float16 { return float16ExpMask | float16FracMask }
+
+// Float16Inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
+func NewFloat16Inf(sign int) Float16 {
+	if sign >= 0 {
+		return float16ExpMask
+	} else {
+		return float16SignMask | float16ExpMask
+	}
+}
+
+// NewFloat16 returns a Float16 encoding of a 32-bit floating point number. Infinities and NaNs
+// are encoded as such. Very large and very small numbers get rounded to infinity and zero
+// respectively.
+func NewFloat16(f32 float32) Float16 {
+	ptr := unsafe.Pointer(&f32)
+	u32 := *(*uint32)(ptr)
+
+	sign := Float16(u32>>16) & float16SignMask
+	exp := (u32 & float32ExpMask) >> float32ExpShift
+	frac := u32 & 0x7fffff
+
+	if exp == 0xff {
+		// NaN or Infinity
+		if frac != 0 { // NaN
+			frac = 0x3f
+		}
+
+		return sign | float16ExpMask | Float16(frac)
 	}
 
-	return sign | nonSign
+	if exp+float16ExpBias <= float32ExpBias {
+		// Exponent is too small to represent in a Float16 (or a zero). We need to output
+		// denormalized numbers (possibly rounding very small numbers to zero).
+		denorm := float32ExpBias - exp - 1
+		frac += 1 << float32ExpShift
+		frac >>= denorm
+		return sign | Float16(frac)
+	}
+
+	if exp > float32ExpBias+float16ExpBias {
+		// Number too large to represent in a Float16 => round to Infinity.
+		return sign | float16ExpMask
+	}
+
+	// General case.
+	return sign | Float16(((exp+float16ExpBias-float32ExpBias)<<float16ExpShift)|(frac>>13))
+}
+
+func expandF16ToF32(in Float16) uint32 {
+	sign := uint32(in&float16SignMask) << 16
+	frac := uint32(in&float16FracMask) << 13
+	exp := uint32(in&float16ExpMask) >> float16ExpShift
+
+	if exp == 0x1f {
+		// NaN of Infinity
+		return sign | float32ExpMask | frac
+	}
+
+	if exp == 0 {
+		if frac == 0 {
+			// Zero
+			return sign
+		}
+		// Denormalized number. In a float32 it must be stored in a normalized form, so
+		// we normalize it.
+		exp++
+		for frac&float32ExpMask == 0 {
+			frac <<= 1
+			exp--
+		}
+		frac &= float32FracMask
+	}
+
+	exp += (float32ExpBias - float16ExpBias)
+
+	return sign | (exp << float32ExpShift) | frac
 }
diff --git a/binary/float16_test.go b/binary/float16_test.go
index ecb6c2f..f1658f2 100644
--- a/binary/float16_test.go
+++ b/binary/float16_test.go
@@ -14,31 +14,84 @@
 
 package binary
 
-import "testing"
+import (
+	"math"
+	"testing"
+)
+
+var checks = []struct {
+	f16 Float16
+	f32 float32
+}{
+	{0x0000, 0.0},
+	{0x3c00, 1.0},
+	{0x4000, 2.0},
+	{0x4200, 3.0},
+	{0x4400, 4.0},
+	{0x4500, 5.0},
+	{0x3555, 0.333251953125},
+	{0xbc00, -1.0},
+	{0xc000, -2.0},
+	{0xc200, -3.0},
+	{0xc400, -4.0},
+	{0xc500, -5.0},
+	{0xb555, -0.333251953125},
+	{0x0000, 0.0},
+	{0x7a1a, 5e4},
+	{0x068d, 1e-4},
+	{0x0346, 4.995e-5},
+	{0x0053, 4.95e-6},
+	{0x0008, 4.77e-7},
+}
 
 func TestFloat16To32(t *testing.T) {
-	checks := []struct {
-		f16 Float16
-		f32 float32
-	}{
-		{0x0000, 0.0},
-		{0x3c00, 1.0},
-		{0x4000, 2.0},
-		{0x4200, 3.0},
-		{0x4400, 4.0},
-		{0x4500, 5.0},
-		{0x3555, 0.333251953125},
-		{0xbc00, -1.0},
-		{0xc000, -2.0},
-		{0xc200, -3.0},
-		{0xc400, -4.0},
-		{0xc500, -5.0},
-		{0xb555, -0.333251953125},
-	}
 	for _, c := range checks {
-		expected, got := c.f32, c.f16.Float32()
-		if expected != got {
-			t.Errorf("Expansion of float16(0x%x) to float32 gave unexpected value. Expected: %v, got: %v", c.f16, expected, got)
+		expected, got := float64(c.f32), float64(c.f16.Float32())
+		esign, gsign := math.Signbit(expected), math.Signbit(got)
+		expected, got = math.Abs(expected), math.Abs(got)
+		if esign != gsign || got > expected*1.001 || got < expected*0.999 {
+			t.Errorf("Expansion of float16(0x%04x) to float32 gave unexpected value.\n"+
+				"Expected: %g, got: %g", c.f16, expected, got)
 		}
 	}
 }
+
+func TestFloat32To16(t *testing.T) {
+	for _, c := range checks {
+		expected, got := c.f16, NewFloat16(c.f32)
+		if expected != got {
+			t.Errorf("Encoding of float32 %v gave unexpected value. Expected: %04x, got: %04x",
+				c.f32, expected, got)
+		}
+	}
+}
+
+func TestFloat16InfTo32(t *testing.T) {
+	if v := NewFloat16Inf(1).Float32(); !math.IsInf(float64(v), 1) {
+		t.Errorf("Positive infinity did not expand to positive infinity, but %v.", v)
+	}
+	if v := NewFloat16Inf(-1).Float32(); !math.IsInf(float64(v), -1) {
+		t.Errorf("Negative infinity did not expand to negative infinity, but %v.", v)
+	}
+	if v := NewFloat16NaN().Float32(); !math.IsNaN(float64(v)) {
+		t.Errorf("NaN constant did not expand to NaN, but %v.", v)
+	}
+}
+
+func TestFloat32InfTo16(t *testing.T) {
+	if v := NewFloat16(float32(math.Inf(1))); !v.IsInf(1) {
+		t.Errorf("Positive infinity did not encode to positive infinity, but %04x.", v)
+	}
+	if v := NewFloat16(float32(math.Inf(-1))); !v.IsInf(-1) {
+		t.Errorf("Negative infinity did not encode to negative infinity, but %04x.", v)
+	}
+	if v := NewFloat16(float32(math.NaN())); !v.IsNaN() {
+		t.Errorf("NaN did not encode to NaN, but %04x.", v)
+	}
+	if v := NewFloat16(float32(1e5)); !v.IsInf(1) {
+		t.Errorf("1e5 did not encode to positive infinity, but %04x.", v)
+	}
+	if v := NewFloat16(5e-8); v != 0 {
+		t.Errorf("5e-8 did not encode to zero, but %04x.", v)
+	}
+}
diff --git a/binary/generate/generate.go b/binary/generate/generate.go
new file mode 100644
index 0000000..5c0fa6a
--- /dev/null
+++ b/binary/generate/generate.go
@@ -0,0 +1,187 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package generate has support for generating encode and decode methods
+// for the binary package automatically.
+package generate
+
+import (
+	"bytes"
+	"crypto/sha1"
+	"fmt"
+	"path"
+	"sort"
+	"strings"
+	"text/template"
+
+	"android.googlesource.com/platform/tools/gpu/binary"
+	"golang.org/x/tools/go/types"
+)
+
+type File struct {
+	Generated string
+	Package   string
+	Structs   []*Struct
+}
+
+// Struct is a description of an encodable struct.
+// Signature includes the package, name and name and type of all the fields.
+// Any change to the Signature will cause the ID to change.
+type Struct struct {
+	Name      string        // The simple name of the type.
+	Package   string        // The package name the struct belongs to.
+	Fields    []Field       // Descriptions of the fields of the struct.
+	Signature string        // The full string type signature of the Struct.
+	ID        binary.TypeID // The unique type identifier for the Struct.
+}
+
+// Kind describes the basic nature of a type.
+type Kind int
+
+const (
+	// Native is the kind for primitive types with corresponding direct methods on
+	// Encoder and Decoder
+	Native Kind = iota
+	// Remap is the kind for a type declared as alias to a primitive type.
+	// For example: type U32 uint32.
+	Remap
+	// Codeable is the kind for a direct in place struct.
+	Codeable
+	// Pointer is the kind for a pointer to a struct type. If the struct instance
+	// has equality (==) with a previously encoded object, then this struct will
+	// be encoded as a reference to the first encoded object.
+	Pointer
+	// Array is the kind for an in place slice, with a dynamic length.
+	Array
+	// Interface is the kind for an object boxed in an binary.Object interface
+	// (or superset of). If the object has equality (==) with a previously
+	// encoded object, then this object will be encoded as a reference to the
+	// first encoded object.
+	Interface
+)
+
+// Field holds a description of a single Struct member.
+type Field struct {
+	// Name is the true field name.
+	Name string // The name the field was given.
+	Type *Type  // A description of the type of the field.
+}
+
+// Type is used to describe fields of a struct.
+type Type struct {
+	Name    string // The name of the type.
+	Native  string // The go native name of the type.
+	Kind    Kind   // The types basic Kind.
+	SubType *Type  // If the type is an Array, holds the element type.
+	Method  string // The encode/decode method to use.
+}
+
+// FromTypename creates and initializes a Struct from a types.Typename.
+// It assumes that the typename will map to a types.Struct, and adds all the
+// fields of that struct to the Struct information.
+func FromTypename(pkg *types.Package, n *types.TypeName) *Struct {
+	t := n.Type().Underlying().(*types.Struct)
+	s := &Struct{Name: n.Name()}
+	s.Fields = make([]Field, t.NumFields())
+	s.Package = pkg.Name()
+	for i := range s.Fields {
+		decl := t.Field(i)
+		f := &s.Fields[i]
+		f.Name = decl.Name()
+		f.Type = FromType(pkg, decl.Type())
+	}
+	s.updateID()
+	return s
+}
+
+func (s *Struct) updateID() {
+	b := &bytes.Buffer{}
+	fmt.Fprintf(b, "struct %s.%s {", s.Package, s.Name)
+	for i, f := range s.Fields {
+		if i != 0 {
+			fmt.Fprint(b, ",")
+		}
+		fmt.Fprintf(b, " %s:%s", f.Name, f.Type.Name)
+	}
+	fmt.Fprint(b, " }")
+	s.Signature = b.String()
+	s.ID = sha1.Sum([]byte(s.Signature))
+}
+
+// FromType creates a appropriate Type object from a types.Type.
+func FromType(pkg *types.Package, from types.Type) *Type {
+	t := &Type{Name: path.Base(types.TypeString(pkg, from))}
+	if _, isNamed := from.(*types.Named); isNamed {
+		from = from.Underlying()
+	}
+	t.Native = from.String()
+	switch from := from.(type) {
+	case *types.Basic:
+		t.Kind = Native
+		switch from.Kind() {
+		case types.Int:
+			t.Native = "int32"
+		case types.Byte:
+			t.Native = "uint8"
+		}
+		t.Method = strings.Title(t.Native)
+		if t.Native != t.Name {
+			t.Kind = Remap
+		}
+	case *types.Pointer:
+		t.Kind = Pointer
+		t.SubType = FromType(pkg, from.Elem())
+	case *types.Struct:
+		t.Kind = Codeable
+	case *types.Interface:
+		t.Kind = Interface
+	case *types.Slice:
+		t.Kind = Array
+		t.SubType = FromType(pkg, from.Elem())
+	default:
+		panic(fmt.Errorf("Unhandled type %T for field %s", from, t.Name))
+	}
+	return t
+}
+
+// Sort is used to ensure stable ordering of Struct slices.
+// This is to ensure automatically generated code has minimum diffs.
+// The sort order is by Struct name.
+func Sort(structs []*Struct) {
+	sort.Sort(structsByName(structs))
+}
+
+type structsByName []*Struct
+
+func (a structsByName) Len() int           { return len(a) }
+func (a structsByName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a structsByName) Less(i, j int) bool { return a[i].Name < a[j].Name }
+
+func getTemplate(t *template.Template, name string) *template.Template {
+	result := t.Lookup(name)
+	if result == nil {
+		panic(fmt.Errorf("Could not find template %s", name))
+	}
+	return result
+}
+
+type kindToTemplate map[Kind]*template.Template
+
+func kindDispatch(table kindToTemplate, name string, t *Type) string {
+	b := &bytes.Buffer{}
+	if err := table[t.Kind].Execute(b, Field{name, t}); err != nil {
+		panic(err)
+	}
+	return b.String()
+}
diff --git a/binary/generate/generate_test.go b/binary/generate/generate_test.go
new file mode 100644
index 0000000..89202e2
--- /dev/null
+++ b/binary/generate/generate_test.go
@@ -0,0 +1,159 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package generate
+
+import (
+	"bytes"
+	"fmt"
+	"log"
+	"testing"
+
+	"golang.org/x/tools/go/loader"
+	"golang.org/x/tools/go/types"
+)
+
+func parseStructs(source string) []*Struct {
+	config := loader.Config{}
+	fakeFile := fmt.Sprintf("package fake\n%s", source)
+	file, err := config.ParseFile("", fakeFile)
+	if err != nil {
+		log.Fatalf("invalid source: %s", err)
+	}
+	config.CreateFromFiles("", file)
+	info, err := config.Load()
+	if err != nil {
+		log.Fatalf("load failed: %s", err)
+	}
+	result := []*Struct{}
+	for _, pkg := range info.Created {
+		for _, def := range pkg.Defs {
+			if n, ok := def.(*types.TypeName); ok {
+				if t, ok := n.Type().(*types.Named); ok {
+					if _, ok := t.Underlying().(*types.Struct); ok {
+						result = append(result, FromTypename(pkg.Pkg, n))
+					}
+				}
+			}
+		}
+	}
+	return result
+}
+
+func parseStruct(t *testing.T, name string, source string) *Struct {
+	s := parseStructs(source)
+	if len(s) != 1 {
+		log.Fatalf("Parsed %d structs, expected 1", len(s))
+	}
+	if s[0].Name != name {
+		t.Errorf("Got struct %s, expected %s", s[0].Name, name)
+	}
+	return s[0]
+}
+
+func TestEmpty(t *testing.T) {
+	s := parseStruct(t, "MyStruct", "type MyStruct struct {}")
+	if len(s.Fields) != 0 {
+		t.Errorf("Got %d fields, expected none", len(s.Fields))
+	}
+}
+
+func TestStableID(t *testing.T) {
+	source := "type MyStruct struct {}"
+	a := parseStruct(t, "MyStruct", source)
+	b := parseStruct(t, "MyStruct", source)
+	if a.ID != b.ID {
+		t.Errorf("ID was not stable")
+	}
+}
+
+func TestNameAffectsID(t *testing.T) {
+	a := parseStruct(t, "MyStruct", "type MyStruct struct {}")
+	b := parseStruct(t, "YourStruct", "type YourStruct struct {}")
+	if a.ID == b.ID {
+		t.Errorf("Name change did not change ID")
+	}
+}
+
+func TestFieldCountAffectsID(t *testing.T) {
+	a := parseStruct(t, "MyStruct", "type MyStruct struct { a int}")
+	b := parseStruct(t, "MyStruct", "type MyStruct struct {}")
+	if a.ID == b.ID {
+		t.Errorf("Field count did not change ID")
+	}
+}
+
+func TestFieldNameAffectsID(t *testing.T) {
+	a := parseStruct(t, "MyStruct", "type MyStruct struct { a int}")
+	b := parseStruct(t, "MyStruct", "type MyStruct struct { b int}")
+	if a.ID == b.ID {
+		t.Errorf("Field name did not change ID")
+	}
+}
+
+func TestFieldTypeAffectsID(t *testing.T) {
+	a := parseStruct(t, "MyStruct", "type MyStruct struct { a int}")
+	b := parseStruct(t, "MyStruct", "type MyStruct struct { a byte}")
+	if a.ID == b.ID {
+		t.Errorf("Field type did not change ID")
+	}
+}
+
+func TestTypes(t *testing.T) {
+	fields := []Field{
+		{"a", &Type{"uint8", "uint8", Basic, nil, "Uint8"}},
+		{"b", &Type{"uint16", "uint16", Basic, nil, "Uint16"}},
+		{"c", &Type{"uint32", "uint32", Basic, nil, "Uint32"}},
+		{"d", &Type{"uint64", "uint64", Basic, nil, "Uint64"}},
+		{"e", &Type{"int8", "int8", Basic, nil, "Int8"}},
+		{"f", &Type{"int16", "int16", Basic, nil, "Int16"}},
+		{"g", &Type{"int32", "int32", Basic, nil, "Int32"}},
+		{"h", &Type{"int64", "int64", Basic, nil, "Int64"}},
+		{"i", &Type{"float32", "float32", Basic, nil, "Float32"}},
+		{"j", &Type{"float64", "float64", Basic, nil, "Float64"}},
+		{"k", &Type{"byte", "uint8", Basic, nil, "Uint8"}},
+		{"l", &Type{"int", "int32", Basic, nil, "Int32"}},
+		{"m", &Type{"bool", "bool", Basic, nil, "Bool"}},
+		{"n", &Type{"string", "string", Basic, nil, "String"}},
+		{"o", &Type{"struct{}", "struct{}", Codeable, nil, ""}},
+		{"p", &Type{"*struct{}", "*struct{}", Pointer, nil, ""}},
+		{"q", &Type{"[]struct{}", "[]struct{}", Array, nil, ""}},
+		{"r", &Type{"interface{}", "interface{}", Interface, nil, ""}},
+	}
+	source := &bytes.Buffer{}
+	fmt.Fprint(source, "type MyStruct struct {\n")
+	for _, f := range fields {
+		fmt.Fprintf(source, "  %s %s\n", f.Name, f.Type.Name)
+	}
+	fmt.Fprint(source, "}\n")
+	s := parseStruct(t, "MyStruct", source.String())
+	if len(s.Fields) != len(fields) {
+		t.Errorf("Got %d fields, expected %d", len(s.Fields), len(fields))
+	}
+	for i, got := range s.Fields {
+		expected := fields[i]
+		if got.Name != expected.Name {
+			t.Errorf("Got field %s, expected %s", got.Name, expected.Name)
+		}
+		if got.Type.Kind != expected.Type.Kind {
+			t.Errorf("Got field kind %d, expected %d", got.Type.Kind, expected.Type.Kind)
+		}
+		if got.Type.Native != expected.Type.Native {
+			t.Errorf("Got field native type %s, expected %s", got.Type.Native, expected.Type.Native)
+		}
+		if got.Type.Method != expected.Type.Method {
+			t.Errorf("Got field native type %s, expected %s", got.Type.Method, expected.Type.Method)
+		}
+	}
+}
diff --git a/binary/generate/go.go b/binary/generate/go.go
new file mode 100644
index 0000000..ed2ee7c
--- /dev/null
+++ b/binary/generate/go.go
@@ -0,0 +1,196 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package generate
+
+import (
+	"bytes"
+	"io"
+	"text/template"
+
+	"golang.org/x/tools/imports"
+)
+
+var (
+	goTemplates = template.Must(template.New("").Funcs(goFuncs).Parse(`
+{{define "Register"}} //{{.Signature}}
+	binary.Register(binary.TypeID{ {{range .ID}}{{printf "0x%2.2x" .}}, {{end}} }, &{{.Name}}{})
+{{end}}
+
+{{define "Encoder"}}
+	func (o {{.Name}}) Encode(e *binary.Encoder) error {
+		{{range .Fields}}{{encode (print "o." .Name) .Type}}{{end}}
+		return nil
+	}
+{{end}}
+
+{{define "EncodeNative"}}
+		if err := e.{{.Type.Method}}({{.Name}}); err != nil {
+			return err
+}{{end}}
+
+{{define "EncodeRemap"}}
+		if err := e.{{.Type.Method}}({{.Type.Native}}({{.Name}})); err != nil {
+				return err
+}{{end}}
+
+{{define "EncodeCodeable"}}
+		if err := {{.Name}}.Encode(e); err != nil {
+			return err
+}{{end}}
+
+{{define "EncodeObject"}}
+		if {{.Name}} != nil {
+			if err := e.Object({{.Name}}); err != nil {
+				return err
+			}
+		} else if err := e.Object(nil); err != nil {
+			return err
+}{{end}}
+
+{{define "EncodeArray"}}
+		if err := e.Int32(int32(len({{.Name}}))); err != nil {
+			return err
+		}
+		for i := range {{.Name}} {
+			{{encode (print .Name "[i]") .Type.SubType}}
+}{{end}}
+
+{{define "Decoder"}}
+		func (o *{{.Name}}) Decode(d *binary.Decoder) error {
+			{{range .Fields}}{{decode (print "o." .Name) .Type}}{{end}}
+			return nil
+}{{end}}
+
+{{define "DecodeNative"}}
+		if obj, err := d.{{.Type.Method}}(); err != nil {
+			return err
+		} else {
+			{{.Name}} = {{.Type.Name}}(obj)
+}{{end}}
+
+{{define "DecodeCodeable"}}
+		if err := {{.Name}}.Decode(d); err != nil {
+			return err
+}{{end}}
+
+{{define "DecodeObject"}}
+		if obj, err := d.Object(); err != nil {
+			return err
+		} else if obj != nil {
+			{{.Name}} = obj.({{.Type.Name}})
+		} else {
+			{{.Name}} = nil
+}{{end}}
+
+{{define "DecodeArray"}}
+		if count, err := d.Int32(); err != nil {
+			return err
+		} else {
+			{{.Name}} = make({{.Type.Name}}, count)
+			for i := range {{.Name}} {
+				{{decode (print .Name "[i]") .Type.SubType}}
+			}
+}{{end}}
+
+{{define "File"}}
+////////////////////////////////////////////////////////////////////////////////
+// Do not modify!
+// Generated by {{$.Generated}}
+////////////////////////////////////////////////////////////////////////////////
+
+package {{.Package}}
+
+import (
+       "android.googlesource.com/platform/tools/gpu/binary"
+)
+
+func init() {
+	{{range .Structs}}{{template "Register" .}}{{end}}
+}
+
+{{range .Structs}}
+	{{template "Encoder" .}}
+	{{template "Decoder" .}}
+{{end}}
+
+{{end}}
+	`))
+	goFuncs = template.FuncMap{
+		"encode": func(name string, t *Type) string {
+			return kindDispatch(goEncodeMap, name, t)
+		},
+		"decode": func(name string, t *Type) string {
+			return kindDispatch(goDecodeMap, name, t)
+		},
+	}
+	goEncodeMap kindToTemplate
+	goDecodeMap kindToTemplate
+	goFile      *template.Template
+	goRegister  *template.Template
+	goEncoder   *template.Template
+	goDecoder   *template.Template
+)
+
+func init() {
+	goFile = getTemplate(goTemplates, "File")
+	goRegister = getTemplate(goTemplates, "Register")
+	goEncoder = getTemplate(goTemplates, "Encoder")
+	goDecoder = getTemplate(goTemplates, "Decoder")
+	goEncodeMap = kindToTemplate{
+		Native:    getTemplate(goTemplates, "EncodeNative"),
+		Remap:     getTemplate(goTemplates, "EncodeRemap"),
+		Codeable:  getTemplate(goTemplates, "EncodeCodeable"),
+		Pointer:   getTemplate(goTemplates, "EncodeObject"),
+		Interface: getTemplate(goTemplates, "EncodeObject"),
+		Array:     getTemplate(goTemplates, "EncodeArray"),
+	}
+	goDecodeMap = kindToTemplate{
+		Native:    getTemplate(goTemplates, "DecodeNative"),
+		Remap:     getTemplate(goTemplates, "DecodeNative"),
+		Codeable:  getTemplate(goTemplates, "DecodeCodeable"),
+		Pointer:   getTemplate(goTemplates, "DecodeObject"),
+		Interface: getTemplate(goTemplates, "DecodeObject"),
+		Array:     getTemplate(goTemplates, "DecodeArray"),
+	}
+}
+
+// GoFile generates the all the go code for a file with a set of structs.
+func GoFile(file *File) ([]byte, error) {
+	b := &bytes.Buffer{}
+	if err := goFile.Execute(b, file); err != nil {
+		return nil, err
+	}
+	result, err := imports.Process("", b.Bytes(), nil)
+	if err != nil {
+		return b.Bytes(), nil
+	}
+	return result, nil
+}
+
+// GoRegister generates the go code to register a Struct with the system,
+// writing it to an io.Writer.
+func GoRegister(w io.Writer, s *Struct) error {
+	return goRegister.Execute(w, s)
+}
+
+// GoEncoder generates an encoder for a Struct, writing it to an io.Writer.
+func GoEncoder(w io.Writer, s *Struct) error {
+	return goEncoder.Execute(w, s)
+}
+
+// GoEncoder generates a decoder for a Struct, writing it to an io.Writer.
+func GoDecoder(w io.Writer, s *Struct) error {
+	return goDecoder.Execute(w, s)
+}
diff --git a/binary/generate/java.go b/binary/generate/java.go
new file mode 100644
index 0000000..9a2d9f3
--- /dev/null
+++ b/binary/generate/java.go
@@ -0,0 +1,175 @@
+// Copyright (C) 2014 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package generate
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+	"text/template"
+	"unicode"
+	"unicode/utf8"
+)
+
+var (
+	javaTemplates = template.Must(template.New("").Funcs(javaFuncs).Parse(`
+{{define "Enum"}}{{.Name}}Enum{{end}}
+{{define "ID"}}{{.Name}}ID{{end}}
+{{define "IDBytes"}}{{.Name}}IDBytes{{end}}
+
+{{define "Encoder"}}
+	public static void encode(Encoder e, {{class .Name}} o) throws IOException {
+	{{range .Fields}}	{{encode (print "o." .Name) .Type}}
+	{{end}}} {{end}}
+
+{{define "EncodeNative"}}e.{{lower .Type.Method}}({{.Name}});{{end}}
+{{define "EncodeRemap"}}{{.Name}}.encode(e);{{end}}
+{{define "EncodeCodeable"}}{{.Name}}.encode(e);{{end}}
+{{define "EncodeObject"}}e.object({{.Name}});{{end}}
+
+{{define "EncodeArray"}} e.int32({{.Name}}.length);
+		for (int i = 0; i < {{.Name}}.length; i++) {
+			{{encode (print .Name "[i]") .Type.SubType}}
+		}
+{{end}}
+
+{{define "Decoder"}}
+	public static void decode(Decoder d, {{class .Name}} o) throws IOException {
+	{{range .Fields}}	{{decode (print "o." .Name) .Type}}
+	{{end}}} {{end}}
+
+{{define "DecodeNative"}}{{.Name}} = d.{{lower .Type.Method}}();{{end}}
+{{define "DecodeRemap"}}{{.Name}} = {{.Type.Name}}.decode(d);{{end}}
+{{define "DecodeCodeable"}}{{.Name}} = new {{.Type.Name}}(d);{{end}}
+{{define "DecodeObject"}}{{.Name}} = ({{storage .Type}})d.object();{{end}}
+
+{{define "DecodeArray"}} {{.Name}} = new {{storage .Type.SubType}}[d.int32()];
+		for (int i = 0; i < {{.Name}}.length; i++) {
+			{{decode (print .Name "[i]") .Type.SubType}}
+		}
+{{end}}
+
+{{define "File"}}
+////////////////////////////////////////////////////////////////////////////////
+// Do not modify!
+// Generated by {{$.Generated}}
+////////////////////////////////////////////////////////////////////////////////
+package {{.Package}};
+
+import com.android.tools.idea.gfx.binary.BinaryObject;
+import com.android.tools.idea.gfx.binary.ObjectTypeID;
+import com.android.tools.idea.gfx.binary.BinaryObjectCreator;
+import com.android.tools.idea.gfx.binary.Decoder;
+import com.android.tools.idea.gfx.binary.Encoder;
+import java.io.IOException;
+
+class ObjectFactory {
+	public enum Entries implements BinaryObjectCreator { {{range .Structs}}
+		{{template "Enum" .}} {
+			@Override public BinaryObject create() { return new {{class .Name}}(); }
+		}, {{end}}
+	}
+	{{range .Structs}}
+	public static byte[] {{template "IDBytes" .}} = { {{range .ID}}{{toS8 .}}, {{end}} };
+	public static ObjectTypeID {{template "ID" .}} = new ObjectTypeID({{template "IDBytes" .}}); {{end}}
+
+	static { {{range .Structs}}
+		ObjectTypeID.register({{template "ID" .}}, Entries.{{template "Enum" .}});{{end}}
+	}
+
+	{{range .Structs}}
+		{{template "Encoder" .}}
+		{{template "Decoder" .}}
+	{{end}}
+}
+
+{{end}}
+	`))
+	javaFuncs = template.FuncMap{
+		"encode": func(name string, t *Type) string {
+			return kindDispatch(javaEncodeMap, name, t)
+		},
+		"decode": func(name string, t *Type) string {
+			return kindDispatch(javaDecodeMap, name, t)
+		},
+		"lower": strings.ToLower,
+		"fieldname": func(s string) string {
+			r, n := utf8.DecodeRuneInString(s)
+			return string(unicode.ToLower(r)) + s[n:]
+		},
+		"toS8": func(val byte) string { return fmt.Sprint(int8(val)) },
+		"storage": func(t *Type) string {
+			name := t.Name
+			if t.Kind == Pointer {
+				name = t.SubType.Name
+			}
+			if result, ok := javaTypeMap[name]; ok {
+				return result
+			}
+			return name
+		},
+		"class": func(name string) string {
+			if strings.HasPrefix(name, "call") {
+				return fmt.Sprintf("Commands.%s.Call", name[4:])
+			}
+			if strings.HasPrefix(name, "result") {
+				return fmt.Sprintf("Commands.%s.Result", name[6:])
+			}
+			return name
+		},
+	}
+	javaEncodeMap kindToTemplate
+	javaDecodeMap kindToTemplate
+	javaFile      *template.Template
+	javaTypeMap   = map[string]string{
+		"int8":    "byte",
+		"uint8":   "short",
+		"int16":   "short",
+		"uint16":  "int",
+		"int32":   "int",
+		"uint32":  "long",
+		"int64":   "long",
+		"uint64":  "long",
+		"float32": "float",
+		"float64": "double",
+	}
+)
+
+func init() {
+	javaFile = getTemplate(javaTemplates, "File")
+	javaEncodeMap = kindToTemplate{
+		Native:    getTemplate(javaTemplates, "EncodeNative"),
+		Remap:     getTemplate(javaTemplates, "EncodeRemap"),
+		Codeable:  getTemplate(javaTemplates, "EncodeCodeable"),
+		Pointer:   getTemplate(javaTemplates, "EncodeObject"),
+		Interface: getTemplate(javaTemplates, "EncodeObject"),
+		Array:     getTemplate(javaTemplates, "EncodeArray"),
+	}
+	javaDecodeMap = kindToTemplate{
+		Native:    getTemplate(javaTemplates, "DecodeNative"),
+		Remap:     getTemplate(javaTemplates, "DecodeRemap"),
+		Codeable:  getTemplate(javaTemplates, "DecodeCodeable"),
+		Pointer:   getTemplate(javaTemplates, "DecodeObject"),
+		Interface: getTemplate(javaTemplates, "DecodeObject"),
+		Array:     getTemplate(javaTemplates, "DecodeArray"),
+	}
+}
+
+// JavaFile generates the all the java code for a file with a set of structs.
+func JavaFile(file *File) ([]byte, error) {
+	b := &bytes.Buffer{}
+	err := javaFile.Execute(b, file)
+	return b.Bytes(), err
+}
diff --git a/binary/object.go b/binary/object.go
index f99cccc..9234fb6 100644
--- a/binary/object.go
+++ b/binary/object.go
@@ -62,3 +62,37 @@
 	}
 	idToType[id] = t.Elem()
 }
+
+type unknownType struct {
+	Object Encodable
+}
+
+func (e unknownType) Error() string {
+	return fmt.Sprintf("Unknown type %T encountered in binary.TypeOf", e.Object)
+}
+
+// Given an encodable object return the TypeID for that type of object.
+// If there is no TypeID for this type of object, return a non-nil error.
+func TypeOf(obj Encodable) (TypeID, error) {
+	id, idFound := typeToID[reflect.TypeOf(obj)]
+	if !idFound {
+		return TypeID{}, unknownType{obj}
+	}
+	return id, nil
+}
+
+type unknownTypeID TypeID
+
+func (e unknownTypeID) Error() string {
+	return fmt.Sprintf("Unknown type id %x encountered in binary.MakeObject", TypeID(e))
+}
+
+// Given a TypeID return a zero value instance of the object type.
+// If this TypeID is not for a registered type, return a non-nil error.
+func MakeObject(typeId TypeID) (Decodable, error) {
+	t, idFound := idToType[typeId]
+	if !idFound {
+		return nil, unknownTypeID(typeId)
+	}
+	return reflect.New(t).Interface().(Decodable), nil
+}