diff --git a/compiler/Makefile b/compiler/Makefile
index ad85973..8da2086 100644
--- a/compiler/Makefile
+++ b/compiler/Makefile
@@ -36,7 +36,7 @@
 GOFILES=\
 	main.go\
 
-DEPS=descriptor plugin
+DEPS=generator descriptor plugin
 
 include $(GOROOT)/src/Make.cmd
 
diff --git a/compiler/descriptor/Makefile b/compiler/descriptor/Makefile
index cd2add9..5c7d716 100644
--- a/compiler/descriptor/Makefile
+++ b/compiler/descriptor/Makefile
@@ -35,6 +35,8 @@
 GOFILES=\
 	descriptor.pb.go\
 
+DEPS=../../proto
+
 include $(GOROOT)/src/Make.pkg
 
 # Not stored here, but descriptor.proto is in http://code.google.com/p/protobuf
diff --git a/compiler/generator/Makefile b/compiler/generator/Makefile
new file mode 100644
index 0000000..2872c83
--- /dev/null
+++ b/compiler/generator/Makefile
@@ -0,0 +1,40 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 Google Inc.  All rights reserved.
+# http://code.google.com/p/goprotobuf/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(GOROOT)/src/Make.$(GOARCH)
+
+TARG=goprotobuf.googlecode.com/hg/compiler/generator
+GOFILES=\
+	generator.go\
+
+DEPS=../descriptor ../plugin ../../proto
+
+include $(GOROOT)/src/Make.pkg
diff --git a/compiler/generator/generator.go b/compiler/generator/generator.go
new file mode 100644
index 0000000..5cef6f5
--- /dev/null
+++ b/compiler/generator/generator.go
@@ -0,0 +1,1030 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 Google Inc.  All rights reserved.
+// http://code.google.com/p/goprotobuf/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+	The code generator for the plugin for the Google protocol buffer compiler.
+	It generates Go code from the protocol buffer description files read by the
+	main routine.
+
+	Not supported yet:
+		services
+		options
+*/
+package generator
+
+import (
+	"bytes"
+	"fmt"
+	"log"
+	"os"
+	"strings"
+	"unicode"
+
+	"goprotobuf.googlecode.com/hg/proto"
+	plugin "goprotobuf.googlecode.com/hg/compiler/plugin"
+	descriptor "goprotobuf.googlecode.com/hg/compiler/descriptor"
+)
+
+// A Plugin provides functionality to add to the output during Go code generation,
+// such as to produce RPC stubs.
+type Plugin interface {
+	// Name identifies the plugin.
+	Name()	string
+	// Generate produces the code generated by the plugin for this file, except for the imports,
+	// by calling the generator's methods P, In, and Out.
+	Generate(g *Generator, file *FileDescriptor)
+	// GenerateImports produces the import declarations for this file.
+	GenerateImports(g *Generator, file *FileDescriptor)
+}
+
+var plugins []Plugin
+
+// RegisterPlugin installs a (second-order) plugin to be run when the Go output is generated.
+// It is typically called during initialization.
+func RegisterPlugin(p Plugin) {
+	n := len(plugins)
+	if cap(plugins) == n {
+		nplugins := make([]Plugin, n, n+10)	// very unlikely to need more than this
+		copy(nplugins, plugins)
+		plugins = nplugins
+	}
+	plugins = plugins[0:n+1]
+	plugins[n] = p
+	log.Stderr("installed plugin:", p.Name())
+}
+
+// Each type we import as a protocol buffer (other than FileDescriptorProto) needs
+// a pointer to the FileDescriptorProto that represents it.  These types achieve that
+// wrapping by placing each Proto inside a struct with the pointer to its File. The
+// structs have the same names as their contents, with "Proto" removed.
+// FileDescriptor is used to store the things that it points to.
+
+// The file and package name method are common to messages and enums.
+type common struct {
+	File *descriptor.FileDescriptorProto // File this object comes from.
+}
+
+// PackageName is name in the package clause in the generated file.
+func (c *common) PackageName() string { return uniquePackageOf(c.File) }
+
+// Descriptor represents a protocol buffer message.
+type Descriptor struct {
+	common
+	*descriptor.DescriptorProto
+	parent   *Descriptor            // The containing message, if any.
+	nested   []*Descriptor          // Inner messages, if any.
+	ext      []*ExtensionDescriptor // Extensions, if any.
+	typename []string               // Cached typename vector.
+}
+
+// TypeName returns the elements of the dotted type name.
+// The package name is not part of this name.
+func (d *Descriptor) TypeName() []string {
+	if d.typename != nil {
+		return d.typename
+	}
+	n := 0
+	for parent := d; parent != nil; parent = parent.parent {
+		n++
+	}
+	s := make([]string, n, n)
+	for parent := d; parent != nil; parent = parent.parent {
+		n--
+		s[n] = proto.GetString(parent.Name)
+	}
+	d.typename = s
+	return s
+}
+
+// EnumDescriptor describes an enum. If it's at top level, its parent will be nil.
+// Otherwise it will be the descriptor of the message in which it is defined.
+type EnumDescriptor struct {
+	common
+	*descriptor.EnumDescriptorProto
+	parent   *Descriptor // The containing message, if any.
+	typename []string    // Cached typename vector.
+}
+
+// TypeName returns the elements of the dotted type name.
+// The package name is not part of this name.
+func (e *EnumDescriptor) TypeName() (s []string) {
+	if e.typename != nil {
+		return e.typename
+	}
+	name := proto.GetString(e.Name)
+	if e.parent == nil {
+		s = make([]string, 1)
+	} else {
+		pname := e.parent.TypeName()
+		s = make([]string, len(pname)+1)
+		copy(s, pname)
+	}
+	s[len(s)-1] = name
+	e.typename = s
+	return s
+}
+
+// Everything but the last element of the full type name, CamelCased.
+// The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... .
+func (e *EnumDescriptor) prefix() string {
+	typeName := e.TypeName()
+	ccPrefix := CamelCaseSlice(typeName[0:len(typeName)-1]) + "_"
+	if e.parent == nil {
+		// If the enum is not part of a message, the prefix is just the type name.
+		ccPrefix = CamelCase(*e.Name) + "_"
+	}
+	return ccPrefix
+}
+
+// The integer value of the named constant in this enumerated type.
+func (e *EnumDescriptor) integerValueAsString(name string) string {
+	for _, c := range e.Value {
+		if proto.GetString(c.Name) == name {
+			return fmt.Sprint(proto.GetInt32(c.Number))
+		}
+	}
+	log.Exit("cannot find value for enum constant")
+	return ""
+}
+
+// ExtensionDescriptor desribes an extension. If it's at top level, its parent will be nil.
+// Otherwise it will be the descriptor of the message in which it is defined.
+type ExtensionDescriptor struct {
+	common
+	*descriptor.FieldDescriptorProto
+	parent   *Descriptor // The containing message, if any.
+}
+
+// TypeName returns the elements of the dotted type name.
+// The package name is not part of this name.
+func (e *ExtensionDescriptor) TypeName() (s []string) {
+	name := proto.GetString(e.Name)
+	if e.parent == nil {
+		// top-level extension
+		s = make([]string, 1)
+	} else {
+		pname := e.parent.TypeName()
+		s = make([]string, len(pname)+1)
+		copy(s, pname)
+	}
+	s[len(s)-1] = name
+	return s
+}
+
+// FileDescriptor describes an protocol buffer descriptor file (.proto).
+// It includes slices of all the messages and enums defined within it.
+// Those slices are constructed by WrapTypes.
+type FileDescriptor struct {
+	*descriptor.FileDescriptorProto
+	desc []*Descriptor           // All the messages defined in this file.
+	enum []*EnumDescriptor       // All the enums defined in this file.
+	ext  []*ExtensionDescriptor  // All the top-level extensions defined in this file.
+}
+
+// PackageName is the package name we'll use in the generated code to refer to this file.
+func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) }
+
+// The package named defined in the input for this file, possibly dotted.
+func (d *FileDescriptor) originalPackageName() string {
+	return proto.GetString(d.Package)
+}
+
+// Whether the proto library needs importing.
+// This will be true if there are any enums, extensions, or messages with extension ranges.
+func (d *FileDescriptor) needProtoImport() bool {
+	if len(d.enum) > 0 || len(d.ext) > 0 {
+		return true
+	}
+	for _, desc := range d.desc {
+		if len(desc.ext) > 0 || len(desc.ExtensionRange) > 0 {
+			return true
+		}
+	}
+	return false
+}
+
+// Object is an interface abstracting the abilities shared by enums and messages.
+type Object interface {
+	PackageName() string // The name we use in our output (a_b_c), possibly renamed for uniqueness.
+	TypeName() []string
+}
+
+// Each package name we generate must be unique. The package we're generating
+// gets its own name but every other package must have a unqiue name that does
+// not conflict in the code we generate.  These names are chosen globally (although
+// they don't have to be, it simplifies things to do them globally).
+func uniquePackageOf(fd *descriptor.FileDescriptorProto) string {
+	s, ok := uniquePackageName[fd]
+	if !ok {
+		log.Exit("internal error: no package name defined for", proto.GetString(fd.Name))
+	}
+	return s
+}
+
+// Generator is the type whose methods generate the output, stored in the associated response structure.
+type Generator struct {
+	bytes.Buffer
+
+	Request  *plugin.CodeGeneratorRequest  // The input.
+	Response *plugin.CodeGeneratorResponse // The output.
+
+	packageName      string            // What we're calling ourselves.
+	allFiles         []*FileDescriptor // All files in the tree
+	genFiles         []*FileDescriptor // Those files we will generate output for.
+	file             *FileDescriptor   // The file we are compiling now.
+	typeNameToObject map[string]Object // Key is a fully-qualified name in input syntax.
+	indent           string
+}
+
+// New creates a new generator and allocates the request and response protobufs.
+func New() *Generator {
+	g := new(Generator)
+	g.Request = plugin.NewCodeGeneratorRequest()
+	g.Response = plugin.NewCodeGeneratorResponse()
+	return g
+}
+
+// Error reports a problem, including an os.Error, and exits the program.
+func (g *Generator) Error(err os.Error, msgs ...string) {
+	s := strings.Join(msgs, " ") + ":" + err.String()
+	log.Stderr("protoc-gen-go: error: ", s)
+	g.Response.Error = proto.String(s)
+	os.Exit(1)
+}
+
+// Fail reports a problem and exits the program.
+func (g *Generator) Fail(msgs ...string) {
+	s := strings.Join(msgs, " ")
+	log.Stderr("protoc-gen-go: error: ", s)
+	g.Response.Error = proto.String(s)
+	os.Exit(1)
+}
+
+// DefaultPackageName returns the package name printed for the object.
+// If its file is in a different package, it returns the package name we're using for this file, plus ".".
+// Otherwise it returns the empty string.
+func (g *Generator) DefaultPackageName(obj Object) string {
+	pkg := obj.PackageName()
+	if pkg == g.packageName {
+		return ""
+	}
+	return pkg + "."
+}
+
+// For each input file, the unique package name to use, underscored.
+var uniquePackageName = make(map[*descriptor.FileDescriptorProto]string)
+
+// SetPackageNames Sets the package name for this run.
+// The package name must agree across all files being generated.
+// It also defines unique package names for all imported files.
+func (g *Generator) SetPackageNames() {
+	inUse := make(map[string]bool)
+	pkg := proto.GetString(g.genFiles[0].Package)
+	g.packageName = strings.Map(DotToUnderscore, pkg)
+	inUse[pkg] = true
+	for _, f := range g.genFiles {
+		thisPkg := proto.GetString(f.Package)
+		if thisPkg != pkg {
+			g.Fail("inconsistent package names:", thisPkg, pkg)
+		}
+	}
+AllFiles:
+	for _, f := range g.allFiles {
+		for _, genf := range g.genFiles {
+			if f == genf {
+				// In this package already.
+				uniquePackageName[f.FileDescriptorProto] = g.packageName
+				continue AllFiles
+			}
+		}
+		truePkg := proto.GetString(f.Package)
+		pkg := truePkg
+		for {
+			_, present := inUse[pkg]
+			if present {
+				// It's a duplicate; must rename.
+				pkg += "X"
+				continue
+			}
+			break
+		}
+		// Install it.
+		inUse[pkg] = true
+		uniquePackageName[f.FileDescriptorProto] = strings.Map(DotToUnderscore, pkg)
+	}
+}
+
+// WrapTypes walks the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos
+// and FileDescriptorProtos into file-referenced objects within the Generator.
+// It also creates the list of files to generate and so should be called before GenerateAllFiles.
+func (g *Generator) WrapTypes() {
+	g.allFiles = make([]*FileDescriptor, len(g.Request.ProtoFile))
+	for i, f := range g.Request.ProtoFile {
+		pkg := proto.GetString(f.Package)
+		if pkg == "" {
+			g.Fail(proto.GetString(f.Name), "is missing a package declaration")
+		}
+		// We must wrap the descriptors before we wrap the enums
+		descs := wrapDescriptors(f)
+		g.buildNestedDescriptors(descs)
+		enums := wrapEnumDescriptors(f, descs)
+		exts := wrapExtensions(f)
+		g.allFiles[i] = &FileDescriptor{
+			FileDescriptorProto: f,
+			desc:                descs,
+			enum:                enums,
+			ext:                 exts,
+		}
+	}
+
+	g.genFiles = make([]*FileDescriptor, len(g.Request.FileToGenerate))
+FindFiles:
+	for i, fileName := range g.Request.FileToGenerate {
+		// Search the list.  This algorithm is n^2 but n is tiny.
+		for _, file := range g.allFiles {
+			if fileName == proto.GetString(file.Name) {
+				g.genFiles[i] = file
+				continue FindFiles
+			}
+		}
+		g.Fail("could not find file named", fileName)
+	}
+	g.Response.File = make([]*plugin.CodeGeneratorResponse_File, len(g.genFiles))
+}
+
+// Scan the descriptors in this file.  For each one, build the slice of nested descriptors
+func (g *Generator) buildNestedDescriptors(descs []*Descriptor) {
+	for _, desc := range descs {
+		if len(desc.NestedType) != 0 {
+			desc.nested = make([]*Descriptor, len(desc.NestedType))
+			n := 0
+			for _, nest := range descs {
+				if nest.parent == desc {
+					desc.nested[n] = nest
+					n++
+				}
+			}
+			if n != len(desc.NestedType) {
+				g.Fail("internal error: nesting failure for", proto.GetString(desc.Name))
+			}
+		}
+	}
+}
+
+// Construct the Descriptor and add it to the slice
+func addDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*Descriptor {
+	d := &Descriptor{common{File: file}, desc, parent, nil, nil, nil}
+
+	d.ext = make([]*ExtensionDescriptor, len(desc.Extension))
+	for i, field := range desc.Extension {
+		d.ext[i] = &ExtensionDescriptor{common{File: file}, field, d}
+	}
+
+	if len(sl) == cap(sl) {
+		nsl := make([]*Descriptor, len(sl), 2*len(sl))
+		copy(nsl, sl)
+		sl = nsl
+	}
+	sl = sl[0 : len(sl)+1]
+	sl[len(sl)-1] = d
+	return sl
+}
+
+// Return a slice of all the Descriptors defined within this file
+func wrapDescriptors(file *descriptor.FileDescriptorProto) []*Descriptor {
+	sl := make([]*Descriptor, 0, len(file.MessageType)+10)
+	for _, desc := range file.MessageType {
+		sl = wrapThisDescriptor(sl, desc, nil, file)
+	}
+	return sl
+}
+
+// Wrap this Descriptor, recursively
+func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*Descriptor {
+	sl = addDescriptor(sl, desc, parent, file)
+	me := sl[len(sl)-1]
+	for _, nested := range desc.NestedType {
+		sl = wrapThisDescriptor(sl, nested, me, file)
+	}
+	return sl
+}
+
+// Construct the EnumDescriptor and add it to the slice
+func addEnumDescriptor(sl []*EnumDescriptor, desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*EnumDescriptor {
+	if len(sl) == cap(sl) {
+		nsl := make([]*EnumDescriptor, len(sl), 2*len(sl))
+		copy(nsl, sl)
+		sl = nsl
+	}
+	sl = sl[0 : len(sl)+1]
+	sl[len(sl)-1] = &EnumDescriptor{common{File: file}, desc, parent, nil}
+	return sl
+}
+
+// Return a slice of all the EnumDescriptors defined within this file
+func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descriptor) []*EnumDescriptor {
+	sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10)
+	for _, enum := range file.EnumType {
+		sl = addEnumDescriptor(sl, enum, nil, file)
+	}
+	for _, nested := range descs {
+		sl = wrapEnumDescriptorsInMessage(sl, nested, file)
+	}
+	return sl
+}
+
+// Wrap this EnumDescriptor, recursively
+func wrapEnumDescriptorsInMessage(sl []*EnumDescriptor, desc *Descriptor, file *descriptor.FileDescriptorProto) []*EnumDescriptor {
+	for _, enum := range desc.EnumType {
+		sl = addEnumDescriptor(sl, enum, desc, file)
+	}
+	for _, nested := range desc.nested {
+		sl = wrapEnumDescriptorsInMessage(sl, nested, file)
+	}
+	return sl
+}
+
+// Return a slice of all the top-level ExtensionDescriptors defined within this file.
+func wrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor {
+	sl := make([]*ExtensionDescriptor, len(file.Extension))
+	for i, field := range file.Extension {
+		sl[i] = &ExtensionDescriptor{common{File: file}, field, nil}
+	}
+	return sl
+}
+
+// BuildTypeNameMap builds the map from fully qualified type names to objects. 
+// The key names for the map come from the input data, which puts a period at the beginning.
+// It should be called after SetPackageNames and before GenerateAllFiles.
+func (g *Generator) BuildTypeNameMap() {
+	g.typeNameToObject = make(map[string]Object)
+	for _, f := range g.allFiles {
+		dottedPkg := "." + f.originalPackageName() + "."
+		for _, enum := range f.enum {
+			name := dottedPkg + dottedSlice(enum.TypeName())
+			g.typeNameToObject[name] = enum
+		}
+		for _, desc := range f.desc {
+			name := dottedPkg + dottedSlice(desc.TypeName())
+			g.typeNameToObject[name] = desc
+		}
+	}
+}
+
+// ObjectNamed, given a fully-qualified input type name as it appears in the input data,
+// returns the descriptor for the message or enum with that name.
+func (g *Generator) ObjectNamed(typeName string) Object {
+	f, ok := g.typeNameToObject[typeName]
+	if !ok {
+		g.Fail("can't find object with type", typeName)
+	}
+	return f
+}
+
+// P prints the arguments to the generated output.  It handles strings and int32s, plus
+// handling indirections because they may be *string, etc.
+func (g *Generator) P(str ...interface{}) {
+	g.WriteString(g.indent)
+	for _, v := range str {
+		switch s := v.(type) {
+		case string:
+			g.WriteString(s)
+		case *string:
+			g.WriteString(*s)
+		case *int32:
+			g.WriteString(fmt.Sprintf("%d", *s))
+		default:
+			g.Fail(fmt.Sprintf("unknown type in printer: %T", v))
+		}
+	}
+	g.WriteByte('\n')
+}
+
+// In Indents the output one tab stop.
+func (g *Generator) In() { g.indent += "\t" }
+
+// Out unindents the output one tab stop.
+func (g *Generator) Out() {
+	if len(g.indent) > 0 {
+		g.indent = g.indent[1:]
+	}
+}
+
+// GenerateAllFiles generates the output for all the files we're outputting.
+func (g *Generator) GenerateAllFiles() {
+	for i, file := range g.genFiles {
+		g.Reset()
+		g.generate(file)
+		g.runPlugins(file)
+		g.Response.File[i] = plugin.NewCodeGeneratorResponse_File()
+		g.Response.File[i].Name = proto.String(goFileName(*file.Name))
+		g.Response.File[i].Content = proto.String(g.String())
+	}
+}
+
+// Run all the plugins associated with the file.
+func (g *Generator) runPlugins(file *FileDescriptor) {
+	for _, p := range plugins {
+		p.Generate(g, file)
+	}
+}
+
+
+// FileOf return the FileDescriptor for this FileDescriptorProto.
+func (g *Generator) FileOf(fd *descriptor.FileDescriptorProto) *FileDescriptor {
+	for _, file := range g.allFiles {
+		if file.FileDescriptorProto == fd {
+			return file
+		}
+	}
+	g.Fail("could not find file in table:", proto.GetString(fd.Name))
+	return nil
+}
+
+// Fill the response protocol buffer with the generated output for all the files we're
+// supposed to generate.
+func (g *Generator) generate(file *FileDescriptor) {
+	g.file = g.FileOf(file.FileDescriptorProto)
+	g.generateHeader()
+	g.generateImports()
+	for _, enum := range g.file.enum {
+		g.generateEnum(enum)
+	}
+	for _, desc := range g.file.desc {
+		g.generateMessage(desc)
+	}
+	for _, ext := range g.file.ext {
+		g.generateExtension(ext)
+	}
+	g.generateInitFunction()
+}
+
+// Generate the header, including package definition and imports
+func (g *Generator) generateHeader() {
+	g.P("// Code generated by protoc-gen-go from ", Quote(*g.file.Name))
+	g.P("// DO NOT EDIT!")
+	g.P()
+	g.P("package ", g.file.PackageName())
+	g.P()
+}
+
+// Generate the header, including package definition and imports
+func (g *Generator) generateImports() {
+	if g.file.needProtoImport() {
+		g.P(`import "goprotobuf.googlecode.com/hg/proto"`)
+	}
+	for _, s := range g.file.Dependency {
+		// Need to find the descriptor for this file
+		for _, fd := range g.allFiles {
+			if proto.GetString(fd.Name) == s {
+				filename := goFileName(s)
+				if strings.HasSuffix(filename, ".go") {
+					filename = filename[0:len(filename)-3]
+				}
+				g.P("import ", fd.PackageName(), " ", Quote(filename))
+				break
+			}
+		}
+	}
+	g.P()
+	// TODO: may need to worry about uniqueness across plugins
+	for _, p := range plugins {
+		p.GenerateImports(g, g.file)
+		g.P()
+	}
+}
+
+// Generate the enum definitions for this EnumDescriptor.
+func (g *Generator) generateEnum(enum *EnumDescriptor) {
+	// The full type name
+	typeName := enum.TypeName()
+	// The full type name, CamelCased.
+	ccTypeName := CamelCaseSlice(typeName)
+	ccPrefix := enum.prefix()
+	g.P("type ", ccTypeName, " int32")
+	g.P("const (")
+	g.In()
+	for _, e := range enum.Value {
+		g.P(ccPrefix+*e.Name, " = ", e.Number)
+	}
+	g.Out()
+	g.P(")")
+	g.P("var ", ccTypeName, "_name = map[int32] string {")
+	g.In()
+	generated := make(map[int32] bool)	// avoid duplicate values
+	for _, e := range enum.Value {
+		duplicate := ""
+		if _, present := generated[*e.Number]; present {
+			duplicate = "// Duplicate value: "
+		}
+		g.P(duplicate, e.Number, ": ", Quote(*e.Name), ",")
+		generated[*e.Number] = true
+	}
+	g.Out()
+	g.P("}")
+	g.P("var ", ccTypeName, "_value = map[string] int32 {")
+	g.In()
+	for _, e := range enum.Value {
+		g.P(Quote(*e.Name), ": ", e.Number, ",")
+	}
+	g.Out()
+	g.P("}")
+	g.P("func New", ccTypeName, "(x int32) *", ccTypeName, " {")
+	g.In()
+	g.P("e := ", ccTypeName, "(x)")
+	g.P("return &e")
+	g.Out()
+	g.P("}")
+	g.P()
+}
+
+// The tag is a string like "PB(varint,2,opt,name=fieldname,def=7)" that
+// identifies details of the field for the protocol buffer marshaling and unmarshaling
+// code.  The fields are:
+//	wire encoding
+//	protocol tag number
+//	opt,req,rep for optional, required, or repeated
+//	name= the original declared name
+//	enum= the name of the enum type if it is an enum-typed field.
+//	def= string representation of the default value, if any.
+// The default value must be in a representation that can be used at run-time
+// to generate the default value. Thus bools become 0 and 1, for instance.
+func (g *Generator) goTag(field *descriptor.FieldDescriptorProto, wiretype string) string {
+	optrepreq := ""
+	switch {
+	case isOptional(field):
+		optrepreq = "opt"
+	case isRequired(field):
+		optrepreq = "req"
+	case isRepeated(field):
+		optrepreq = "rep"
+	}
+	defaultValue := proto.GetString(field.DefaultValue)
+	if defaultValue != "" {
+		switch *field.Type {
+		case descriptor.FieldDescriptorProto_TYPE_BOOL:
+			if defaultValue == "true" {
+				defaultValue = "1"
+			} else {
+				defaultValue = "0"
+			}
+		case descriptor.FieldDescriptorProto_TYPE_STRING,
+			descriptor.FieldDescriptorProto_TYPE_BYTES:
+			// Protect frogs.
+			defaultValue = Quote(defaultValue)
+			// Don't need the quotes
+			defaultValue = defaultValue[1 : len(defaultValue)-1]
+		case descriptor.FieldDescriptorProto_TYPE_ENUM:
+			// For enums we need to provide the integer constant.
+			obj := g.ObjectNamed(proto.GetString(field.TypeName))
+			enum, ok := obj.(*EnumDescriptor)
+			if !ok {
+				g.Fail("enum type inconsistent for", CamelCaseSlice(obj.TypeName()))
+			}
+			defaultValue = enum.integerValueAsString(defaultValue)
+		}
+		defaultValue = ",def=" + defaultValue
+	}
+	enum := ""
+	if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
+		obj := g.ObjectNamed(proto.GetString(field.TypeName))
+		enum = ",enum=" + obj.PackageName() + "." + CamelCaseSlice(obj.TypeName())
+	}
+	name := proto.GetString(field.Name)
+	if name == CamelCase(name) {
+		name = ""
+	} else {
+		name = ",name=" + name
+	}
+	return Quote(fmt.Sprintf("PB(%s,%d,%s%s%s%s)",
+		wiretype,
+		proto.GetInt32(field.Number),
+		optrepreq,
+		name,
+		enum,
+		defaultValue))
+}
+
+func needsStar(typ descriptor.FieldDescriptorProto_Type) bool {
+	switch typ {
+	case descriptor.FieldDescriptorProto_TYPE_GROUP:
+		return false
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		return false
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		return false
+	}
+	return true
+}
+
+// TypeName is the printed name appropriate for an item. If the object is in the current file,
+// TypeName drops the package name and underscores the rest.
+// Otherwise the object is from another package; and the result is  the underscored
+// package name followed by the item name.
+// The result always has an initial capital.
+func (g *Generator) TypeName(obj Object) string {
+	return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName())
+}
+
+// TypeNameWithPackage is like TypeName, but always includes the package
+// name even if the object is in our own package.
+func (g *Generator) TypeNameWithPackage(obj Object) string {
+	return obj.PackageName() + CamelCaseSlice(obj.TypeName())
+}
+
+// GoType returns a string representing the type name, and the wire type
+func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) {
+	// TODO: Options.
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		typ, wire = "float64", "fixed64"
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		typ, wire = "float32", "fixed32"
+	case descriptor.FieldDescriptorProto_TYPE_INT64:
+		typ, wire = "int64", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_UINT64:
+		typ, wire = "uint64", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_INT32:
+		typ, wire = "int32", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_UINT32:
+		typ, wire = "uint32", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
+		typ, wire = "uint64", "fixed64"
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
+		typ, wire = "uint32", "fixed32"
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		typ, wire = "bool", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		typ, wire = "string", "bytes"
+	case descriptor.FieldDescriptorProto_TYPE_GROUP:
+		desc := g.ObjectNamed(proto.GetString(field.TypeName))
+		typ, wire = "*"+g.TypeName(desc), "group"
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		desc := g.ObjectNamed(proto.GetString(field.TypeName))
+		typ, wire = "*"+g.TypeName(desc), "bytes"
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		typ, wire = "[]byte", "bytes"
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		desc := g.ObjectNamed(proto.GetString(field.TypeName))
+		typ, wire = g.TypeName(desc), "varint"
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		typ, wire = "int32", "fixed32"
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		typ, wire = "int64", "fixed64"
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		typ, wire = "int32", "zigzag32"
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		typ, wire = "int64", "zigzag64"
+	default:
+		g.Fail("unknown type for", proto.GetString(field.Name))
+	}
+	if isRepeated(field) {
+		typ = "[]" + typ
+	} else if needsStar(*field.Type) {
+		typ = "*" + typ
+	}
+	return
+}
+
+// Generate the type and default constant definitions for this Descriptor.
+func (g *Generator) generateMessage(message *Descriptor) {
+	// The full type name
+	typeName := message.TypeName()
+	// The full type name, CamelCased.
+	ccTypeName := CamelCaseSlice(typeName)
+
+	g.P("type ", ccTypeName, " struct {")
+	g.In()
+	for _, field := range message.Field {
+		fieldname := CamelCase(*field.Name)
+		typename, wiretype := g.GoType(message, field)
+		tag := g.goTag(field, wiretype)
+		g.P(fieldname, "\t", typename, "\t", tag)
+	}
+	if len(message.ExtensionRange) > 0 {
+		g.P("XXX_extensions\t\tmap[int32][]byte")
+	}
+	g.P("XXX_unrecognized\t[]byte")
+	g.Out()
+	g.P("}")
+
+	// Reset and New functions
+	g.P("func (this *", ccTypeName, ") Reset() {")
+	g.In()
+	g.P("*this = ", ccTypeName, "{}")
+	g.Out()
+	g.P("}")
+	g.P("func New", ccTypeName, "() *", ccTypeName, " {")
+	g.In()
+	g.P("return new(", ccTypeName, ")")
+	g.Out()
+	g.P("}")
+
+	// Extension support methods
+	if len(message.ExtensionRange) > 0 {
+		g.P()
+		g.P("var extRange_", ccTypeName, " = []proto.ExtensionRange{")
+		g.In()
+		for _, r := range message.ExtensionRange {
+			end := fmt.Sprint(*r.End - 1)  // make range inclusive on both ends
+			g.P("proto.ExtensionRange{", r.Start, ", ", end, "},")
+		}
+		g.Out()
+		g.P("}")
+		g.P("func (*", ccTypeName, ") ExtensionRangeArray() []proto.ExtensionRange {")
+		g.In()
+		g.P("return extRange_", ccTypeName)
+		g.Out()
+		g.P("}")
+		g.P("func (this *", ccTypeName, ") ExtensionMap() map[int32][]byte {")
+		g.In()
+		g.P("if this.XXX_extensions == nil {")
+		g.In()
+		g.P("this.XXX_extensions = make(map[int32][]byte)")
+		g.Out()
+		g.P("}")
+		g.P("return this.XXX_extensions")
+		g.Out()
+		g.P("}")
+	}
+
+	// Default constants
+	for _, field := range message.Field {
+		def := proto.GetString(field.DefaultValue)
+		if def == "" {
+			continue
+		}
+		fieldname := "Default_" + ccTypeName + "_" + CamelCase(*field.Name)
+		typename, _ := g.GoType(message, field)
+		if typename[0] == '*' {
+			typename = typename[1:]
+		}
+		kind := "const "
+		switch {
+		case typename == "bool":
+		case typename == "string":
+			def = Quote(def)
+		case typename == "[]byte":
+			def = "[]byte(" + Quote(def) + ")"
+			kind = "var "
+		case *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM:
+			// Must be an enum.  Need to construct the prefixed name.
+			obj := g.ObjectNamed(proto.GetString(field.TypeName))
+			enum, ok := obj.(*EnumDescriptor)
+			if !ok {
+				log.Stderr("don't know how to generate constant for", fieldname)
+				continue
+			}
+			def = enum.prefix() + def
+		}
+		g.P(kind, fieldname, " ", typename, " = ", def)
+	}
+	g.P()
+
+	for _, ext := range message.ext {
+		g.generateExtension(ext)
+	}
+}
+
+func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
+	// The full type name
+	typeName := ext.TypeName()
+	// Each scope of the extension is individually CamelCased, and all are joined with "_" with an "E_" prefix.
+	for i, s := range typeName {
+		typeName[i] = CamelCase(s)
+	}
+	ccTypeName := "E_" + strings.Join(typeName, "_")
+
+	extendedType := "*" + g.TypeName(g.ObjectNamed(*ext.Extendee))
+	field := ext.FieldDescriptorProto
+	fieldType, wireType := g.GoType(ext.parent, field)
+	tag := g.goTag(field, wireType)
+
+	g.P("var ", ccTypeName, " = &proto.ExtensionDesc{")
+	g.In()
+	g.P("ExtendedType: (", extendedType, ")(nil),")
+	g.P("ExtensionType: (", fieldType, ")(nil),")
+	g.P("Field: ", field.Number, ",")
+	g.P("Tag: ", tag, ",")
+
+	g.Out()
+	g.P("}")
+	g.P()
+}
+
+func (g *Generator) generateInitFunction() {
+	g.P("func init() {")
+	g.In()
+	for _, enum := range g.file.enum {
+		g.generateEnumRegistration(enum)
+	}
+	g.Out()
+	g.P("}")
+}
+
+func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) {
+	pkg := g.packageName + "." // We always print the full package name here.
+	// The full type name
+	typeName := enum.TypeName()
+	// The full type name, CamelCased.
+	ccTypeName := CamelCaseSlice(typeName)
+	g.P("proto.RegisterEnum(", Quote(pkg+ccTypeName), ", ", ccTypeName+"_name, ", ccTypeName+"_value)")
+}
+
+// And now lots of helper functions.
+
+// CamelCase returns the CamelCased name.  Given foo_bar_Baz, the result is FooBar_Baz.
+func CamelCase(name string) string {
+	elems := strings.Split(name, "_", 0)
+	for i, e := range elems {
+		if e == "" {
+			elems[i] = "_"
+			continue
+		}
+		runes := []int(e)
+		if unicode.IsLower(runes[0]) {
+			runes[0] = unicode.ToUpper(runes[0])
+			elems[i] = string(runes)
+		} else {
+			if i > 0 {
+				elems[i] = "_" + e
+			}
+		}
+	}
+	s := strings.Join(elems, "")
+	// Name must not begin with an underscore.
+	if len(s) > 0 && s[0] == '_' {
+		s = "X" + s[1:]
+	}
+	return s
+}
+
+// CamelCaseSlice is like CamelCase, but the argument is a slice of strings to
+// be joined with "_".
+func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }
+
+// dottedSlice turns a sliced name into a dotted name.
+func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
+
+// Quote returns a Go-source quoted string representation of s.
+func Quote(s string) string { return fmt.Sprintf("%q", s) }
+
+// Given a .proto file name, return the output name for the generated Go program.
+func goFileName(name string) string {
+	if strings.HasSuffix(name, ".proto") {
+		name = name[0 : len(name)-6]
+	}
+	return name + ".pb.go"
+}
+
+// Is this field optional?
+func isOptional(field *descriptor.FieldDescriptorProto) bool {
+	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
+}
+
+// Is this field required?
+func isRequired(field *descriptor.FieldDescriptorProto) bool {
+	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED
+}
+
+// Is this field repeated?
+func isRepeated(field *descriptor.FieldDescriptorProto) bool {
+	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
+}
+
+// DotToUnderscore is the mapping function used to generate Go names from package names,
+// which can be dotted in the input .proto file.
+func DotToUnderscore(rune int) int {
+	if rune == '.' {
+		return '_'
+	}
+	return rune
+}
diff --git a/compiler/main.go b/compiler/main.go
index c8aaa45..568a62b 100644
--- a/compiler/main.go
+++ b/compiler/main.go
@@ -35,44 +35,35 @@
 	This plugin takes no options and the protocol buffer file syntax does
 	not yet define any options for Go, so program does no option evaluation.
 	That may change.
-
-	Not supported yet:
-		Services
 */
 
 package main
 
 import (
-	"bytes"
-	"fmt"
 	"io/ioutil"
-	"log"
 	"os"
-	"strings"
-	"unicode"
 
 	"goprotobuf.googlecode.com/hg/proto"
-	plugin "goprotobuf.googlecode.com/hg/compiler/plugin"
-	descriptor "goprotobuf.googlecode.com/hg/compiler/descriptor"
+	"goprotobuf.googlecode.com/hg/compiler/generator"
 )
 
 func main() {
 	// Begin by allocating a generator. The request and response structures are stored there
 	// so we can do error handling easily - the response structure contains the field to
 	// report failure.
-	g := NewGenerator()
+	g := generator.New()
 
 	data, err := ioutil.ReadAll(os.Stdin)
 	if err != nil {
-		g.error(err, "reading input")
+		g.Error(err, "reading input")
 	}
 
-	if err := proto.Unmarshal(data, g.request); err != nil {
-		g.error(err, "parsing input proto")
+	if err := proto.Unmarshal(data, g.Request); err != nil {
+		g.Error(err, "parsing input proto")
 	}
 
-	if len(g.request.FileToGenerate) == 0 {
-		g.fail("no files to generate")
+	if len(g.Request.FileToGenerate) == 0 {
+		g.Fail("no files to generate")
 	}
 
 	// Create a wrapped version of the Descriptors and EnumDescriptors that
@@ -85,936 +76,12 @@
 	g.GenerateAllFiles()
 
 	// Send back the results.
-	data, err = proto.Marshal(g.response)
+	data, err = proto.Marshal(g.Response)
 	if err != nil {
-		g.error(err, "failed to marshal output proto")
+		g.Error(err, "failed to marshal output proto")
 	}
 	_, err = os.Stdout.Write(data)
 	if err != nil {
-		g.error(err, "failed to write output proto")
+		g.Error(err, "failed to write output proto")
 	}
 }
-
-// Each type we import as a protocol buffer (other than FileDescriptorProto) needs
-// a pointer to the FileDescriptorProto that represents it.  These types achieve that
-// wrapping by placing each Proto inside a struct with the pointer to its File. The
-// structs have the same names as their contents, with "Proto" removed.
-// FileDescriptor is used to store the things that it points to.
-
-// The file and package name method are common to messages and enums.
-type common struct {
-	file *descriptor.FileDescriptorProto // File this object comes from.
-}
-
-// The package name we will produce in our output.
-func (c *common) packageName() string { return uniquePackageOf(c.file) }
-
-// A message (struct).
-type Descriptor struct {
-	common
-	*descriptor.DescriptorProto
-	parent   *Descriptor            // The containing message, if any.
-	nested   []*Descriptor          // Inner messages, if any.
-	ext      []*ExtensionDescriptor // Extensions, if any.
-	typename []string               // Cached typename vector.
-}
-
-// Return the elements of the dotted type name.  The package name is not part
-// of this name.
-func (d *Descriptor) typeName() []string {
-	if d.typename != nil {
-		return d.typename
-	}
-	n := 0
-	for parent := d; parent != nil; parent = parent.parent {
-		n++
-	}
-	s := make([]string, n, n)
-	for parent := d; parent != nil; parent = parent.parent {
-		n--
-		s[n] = proto.GetString(parent.Name)
-	}
-	d.typename = s
-	return s
-}
-
-// An enum. If it's at top level, its parent will be nil. Otherwise it will be
-// the descriptor of the message in which it is defined.
-type EnumDescriptor struct {
-	common
-	*descriptor.EnumDescriptorProto
-	parent   *Descriptor // The containing message, if any.
-	typename []string    // Cached typename vector.
-}
-
-// Return the elements of the dotted type name.
-func (e *EnumDescriptor) typeName() (s []string) {
-	if e.typename != nil {
-		return e.typename
-	}
-	name := proto.GetString(e.Name)
-	if e.parent == nil {
-		s = make([]string, 1)
-	} else {
-		pname := e.parent.typeName()
-		s = make([]string, len(pname)+1)
-		copy(s, pname)
-	}
-	s[len(s)-1] = name
-	e.typename = s
-	return s
-}
-
-// Everything but the last element of the full type name, CamelCased.
-// The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... .
-func (e *EnumDescriptor) prefix() string {
-	typeName := e.typeName()
-	ccPrefix := CamelCaseSlice(typeName[0:len(typeName)-1]) + "_"
-	if e.parent == nil {
-		// If the enum is not part of a message, the prefix is just the type name.
-		ccPrefix = CamelCase(*e.Name) + "_"
-	}
-	return ccPrefix
-}
-
-// The integer value of the named constant in this enumerated type.
-func (e *EnumDescriptor) integerValueAsString(name string) string {
-	for _, c := range e.Value {
-		if proto.GetString(c.Name) == name {
-			return fmt.Sprint(proto.GetInt32(c.Number))
-		}
-	}
-	log.Exit("cannot find value for enum constant")
-	return ""
-}
-
-// An extension. If it's at top level, its parent will be nil. Otherwise it will be
-// the descriptor of the message in which it is defined.
-type ExtensionDescriptor struct {
-	common
-	*descriptor.FieldDescriptorProto
-	parent   *Descriptor // The containing message, if any.
-}
-
-// Return the elements of the dotted type name.
-func (e *ExtensionDescriptor) typeName() (s []string) {
-	name := proto.GetString(e.Name)
-	if e.parent == nil {
-		// top-level extension
-		s = make([]string, 1)
-	} else {
-		pname := e.parent.typeName()
-		s = make([]string, len(pname)+1)
-		copy(s, pname)
-	}
-	s[len(s)-1] = name
-	return s
-}
-
-// A file. Includes slices of all the messages and enums defined within it.
-// Those slices are constructed by WrapTypes.
-type FileDescriptor struct {
-	*descriptor.FileDescriptorProto
-	desc []*Descriptor           // All the messages defined in this file.
-	enum []*EnumDescriptor       // All the enums defined in this file.
-	ext  []*ExtensionDescriptor  // All the top-level extensions defined in this file.
-}
-
-// The package name we'll use in the generated code to refer to this file.
-func (d *FileDescriptor) packageName() string { return uniquePackageOf(d.FileDescriptorProto) }
-
-// The package named defined in the input for this file, possibly dotted.
-func (d *FileDescriptor) originalPackageName() string {
-	return proto.GetString(d.Package)
-}
-
-// Whether the proto library needs importing.
-// This will be true if there are any enums or any extensions, or any messages with extension ranges.
-func (d *FileDescriptor) needProtoImport() bool {
-	if len(d.enum) > 0 || len(d.ext) > 0 {
-		return true
-	}
-	for _, desc := range d.desc {
-		if len(desc.ext) > 0 || len(desc.ExtensionRange) > 0 {
-			return true
-		}
-	}
-	return false
-}
-
-// Simplify some things by abstracting the abilities shared by enums and messages.
-type Object interface {
-	packageName() string // The name we use in our output (a_b_c), possibly renamed for uniqueness.
-	typeName() []string
-}
-
-// Each package name we generate must be unique. The package we're generating
-// gets its own name but every other package must have a unqiue name that does
-// not conflict in the code we generate.  These names are chosen globally (although
-// they don't have to be, it simplifies things to do them globally).
-func uniquePackageOf(fd *descriptor.FileDescriptorProto) string {
-	s, ok := uniquePackageName[fd]
-	if !ok {
-		log.Exit("internal error: no package name defined for", proto.GetString(fd.Name))
-	}
-	return s
-}
-
-// The type whose methods generate the output, stored in the associated response structure.
-type Generator struct {
-	bytes.Buffer
-
-	request  *plugin.CodeGeneratorRequest  // The input.
-	response *plugin.CodeGeneratorResponse // The output.
-
-	packageName      string            // What we're calling ourselves.
-	allFiles         []*FileDescriptor // All files in the tree
-	genFiles         []*FileDescriptor // Those files we will generate output for.
-	file             *FileDescriptor   // The file we are compiling now.
-	typeNameToObject map[string]Object // Key is a fully-qualified name in input syntax.
-	indent           string
-}
-
-// Create a new generator and allocate the request and response protobufs.
-func NewGenerator() *Generator {
-	g := new(Generator)
-	g.request = plugin.NewCodeGeneratorRequest()
-	g.response = plugin.NewCodeGeneratorResponse()
-	return g
-}
-
-// Report problem, including an os.Error, and fail.
-func (g *Generator) error(err os.Error, msgs ...string) {
-	s := strings.Join(msgs, " ") + ":" + err.String()
-	log.Stderr("protoc-gen-go: error: ", s)
-	g.response.Error = proto.String(s)
-	os.Exit(1)
-}
-
-// Report problem and fail.
-func (g *Generator) fail(msgs ...string) {
-	s := strings.Join(msgs, " ")
-	log.Stderr("protoc-gen-go: error: ", s)
-	g.response.Error = proto.String(s)
-	os.Exit(1)
-}
-
-// If this file is in a different package, return the package name we're using for this file, plus ".".
-// Otherwise return the empty string.
-func (g *Generator) DefaultPackageName(obj Object) string {
-	pkg := obj.packageName()
-	if pkg == g.packageName {
-		return ""
-	}
-	return pkg + "."
-}
-
-// For each input file, the unique package name to use, underscored.
-var uniquePackageName = make(map[*descriptor.FileDescriptorProto]string)
-
-// Set the package name for this run.  It must agree across all files being generated.
-// Also define unique package names for all imported files.
-func (g *Generator) SetPackageNames() {
-	inUse := make(map[string]bool)
-	pkg := proto.GetString(g.genFiles[0].Package)
-	g.packageName = strings.Map(DotToUnderscore, pkg)
-	inUse[pkg] = true
-	for _, f := range g.genFiles {
-		thisPkg := proto.GetString(f.Package)
-		if thisPkg != pkg {
-			g.fail("inconsistent package names:", thisPkg, pkg)
-		}
-	}
-AllFiles:
-	for _, f := range g.allFiles {
-		for _, genf := range g.genFiles {
-			if f == genf {
-				// In this package already.
-				uniquePackageName[f.FileDescriptorProto] = g.packageName
-				continue AllFiles
-			}
-		}
-		truePkg := proto.GetString(f.Package)
-		pkg := truePkg
-		for {
-			_, present := inUse[pkg]
-			if present {
-				// It's a duplicate; must rename.
-				pkg += "X"
-				continue
-			}
-			break
-		}
-		// Install it.
-		inUse[pkg] = true
-		uniquePackageName[f.FileDescriptorProto] = strings.Map(DotToUnderscore, pkg)
-	}
-}
-
-// Walk the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos and FileDescriptorProtos
-// into file-referenced objects within the Generator.  Also create the list of files
-// to generate
-func (g *Generator) WrapTypes() {
-	g.allFiles = make([]*FileDescriptor, len(g.request.ProtoFile))
-	for i, f := range g.request.ProtoFile {
-		pkg := proto.GetString(f.Package)
-		if pkg == "" {
-			g.fail(proto.GetString(f.Name), "is missing a package declaration")
-		}
-		// We must wrap the descriptors before we wrap the enums
-		descs := WrapDescriptors(f)
-		g.BuildNestedDescriptors(descs)
-		enums := WrapEnumDescriptors(f, descs)
-		exts := WrapExtensions(f)
-		g.allFiles[i] = &FileDescriptor{
-			FileDescriptorProto: f,
-			desc:                descs,
-			enum:                enums,
-			ext:                 exts,
-		}
-	}
-
-	g.genFiles = make([]*FileDescriptor, len(g.request.FileToGenerate))
-FindFiles:
-	for i, fileName := range g.request.FileToGenerate {
-		// Search the list.  This algorithm is n^2 but n is tiny.
-		for _, file := range g.allFiles {
-			if fileName == proto.GetString(file.Name) {
-				g.genFiles[i] = file
-				continue FindFiles
-			}
-		}
-		g.fail("could not find file named", fileName)
-	}
-	g.response.File = make([]*plugin.CodeGeneratorResponse_File, len(g.genFiles))
-}
-
-// Scan the descriptors in this file.  For each one, build the slice of nested descriptors
-func (g *Generator) BuildNestedDescriptors(descs []*Descriptor) {
-	for _, desc := range descs {
-		if len(desc.NestedType) != 0 {
-			desc.nested = make([]*Descriptor, len(desc.NestedType))
-			n := 0
-			for _, nest := range descs {
-				if nest.parent == desc {
-					desc.nested[n] = nest
-					n++
-				}
-			}
-			if n != len(desc.NestedType) {
-				g.fail("internal error: nesting failure for", proto.GetString(desc.Name))
-			}
-		}
-	}
-}
-
-// Construct the Descriptor and add it to the slice
-func AddDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*Descriptor {
-	d := &Descriptor{common{file: file}, desc, parent, nil, nil, nil}
-
-	d.ext = make([]*ExtensionDescriptor, len(desc.Extension))
-	for i, field := range desc.Extension {
-		d.ext[i] = &ExtensionDescriptor{common{file: file}, field, d}
-	}
-
-	if len(sl) == cap(sl) {
-		nsl := make([]*Descriptor, len(sl), 2*len(sl))
-		copy(nsl, sl)
-		sl = nsl
-	}
-	sl = sl[0 : len(sl)+1]
-	sl[len(sl)-1] = d
-	return sl
-}
-
-// Return a slice of all the Descriptors defined within this file
-func WrapDescriptors(file *descriptor.FileDescriptorProto) []*Descriptor {
-	sl := make([]*Descriptor, 0, len(file.MessageType)+10)
-	for _, desc := range file.MessageType {
-		sl = WrapThisDescriptor(sl, desc, nil, file)
-	}
-	return sl
-}
-
-// Wrap this Descriptor, recursively
-func WrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*Descriptor {
-	sl = AddDescriptor(sl, desc, parent, file)
-	me := sl[len(sl)-1]
-	for _, nested := range desc.NestedType {
-		sl = WrapThisDescriptor(sl, nested, me, file)
-	}
-	return sl
-}
-
-// Construct the EnumDescriptor and add it to the slice
-func AddEnumDescriptor(sl []*EnumDescriptor, desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto) []*EnumDescriptor {
-	if len(sl) == cap(sl) {
-		nsl := make([]*EnumDescriptor, len(sl), 2*len(sl))
-		copy(nsl, sl)
-		sl = nsl
-	}
-	sl = sl[0 : len(sl)+1]
-	sl[len(sl)-1] = &EnumDescriptor{common{file: file}, desc, parent, nil}
-	return sl
-}
-
-// Return a slice of all the EnumDescriptors defined within this file
-func WrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descriptor) []*EnumDescriptor {
-	sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10)
-	for _, enum := range file.EnumType {
-		sl = AddEnumDescriptor(sl, enum, nil, file)
-	}
-	for _, nested := range descs {
-		sl = WrapEnumDescriptorsInMessage(sl, nested, file)
-	}
-	return sl
-}
-
-// Wrap this EnumDescriptor, recursively
-func WrapEnumDescriptorsInMessage(sl []*EnumDescriptor, desc *Descriptor, file *descriptor.FileDescriptorProto) []*EnumDescriptor {
-	for _, enum := range desc.EnumType {
-		sl = AddEnumDescriptor(sl, enum, desc, file)
-	}
-	for _, nested := range desc.nested {
-		sl = WrapEnumDescriptorsInMessage(sl, nested, file)
-	}
-	return sl
-}
-
-// Return a slice of all the top-level ExtensionDescriptors defined within this file.
-func WrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor {
-	sl := make([]*ExtensionDescriptor, len(file.Extension))
-	for i, field := range file.Extension {
-		sl[i] = &ExtensionDescriptor{common{file: file}, field, nil}
-	}
-	return sl
-}
-
-// Build the map from fully qualified type names to objects.  The key for the map
-// comes from the input data, which puts a period at the beginning.
-func (g *Generator) BuildTypeNameMap() {
-	g.typeNameToObject = make(map[string]Object)
-	for _, f := range g.allFiles {
-		dottedPkg := "." + f.originalPackageName() + "."
-		for _, enum := range f.enum {
-			name := dottedPkg + DottedSlice(enum.typeName())
-			g.typeNameToObject[name] = enum
-		}
-		for _, desc := range f.desc {
-			name := dottedPkg + DottedSlice(desc.typeName())
-			g.typeNameToObject[name] = desc
-		}
-	}
-}
-
-// Given a fully-qualified input type name, return the descriptor for the message or enum with that type.
-func (g *Generator) objectNamed(typeName string) Object {
-	f, ok := g.typeNameToObject[typeName]
-	if !ok {
-		g.fail("can't find object with type", typeName)
-	}
-	return f
-}
-
-// Print the arguments, handling indirections because they may be *string, etc.
-func (g *Generator) p(str ...interface{}) {
-	g.WriteString(g.indent)
-	for _, v := range str {
-		switch s := v.(type) {
-		case string:
-			g.WriteString(s)
-		case *string:
-			g.WriteString(*s)
-		case *int32:
-			g.WriteString(fmt.Sprintf("%d", *s))
-		default:
-			g.fail(fmt.Sprintf("unknown type in printer: %T", v))
-		}
-	}
-	g.WriteByte('\n')
-}
-
-// Indent the output one tab stop.
-func (g *Generator) in() { g.indent += "\t" }
-
-// Unindent the output one tab stop.
-func (g *Generator) out() {
-	if len(g.indent) > 0 {
-		g.indent = g.indent[1:]
-	}
-}
-
-// Generate the output for all the files we're generating output for.
-func (g *Generator) GenerateAllFiles() {
-	for i, file := range g.genFiles {
-		g.Reset()
-		g.Generate(file)
-		g.response.File[i] = plugin.NewCodeGeneratorResponse_File()
-		g.response.File[i].Name = proto.String(GoName(*file.Name))
-		g.response.File[i].Content = proto.String(g.String())
-	}
-}
-
-// Return the FileDescriptor for this FileDescriptorProto
-func (g *Generator) FileOf(fd *descriptor.FileDescriptorProto) *FileDescriptor {
-	for _, file := range g.allFiles {
-		if file.FileDescriptorProto == fd {
-			return file
-		}
-	}
-	g.fail("could not find file in table:", proto.GetString(fd.Name))
-	return nil
-}
-
-// Fill the response protocol buffer with the generated output for all the files we're
-// supposed to generate.
-func (g *Generator) Generate(file *FileDescriptor) {
-	g.file = g.FileOf(file.FileDescriptorProto)
-	g.GenerateHeader()
-	g.GenerateImports()
-	for _, enum := range g.file.enum {
-		g.GenerateEnum(enum)
-	}
-	for _, desc := range g.file.desc {
-		g.GenerateMessage(desc)
-	}
-	for _, ext := range g.file.ext {
-		g.GenerateExtension(ext)
-	}
-	g.GenerateInitFunction()
-}
-
-// Generate the header, including package definition and imports
-func (g *Generator) GenerateHeader() {
-	g.p("// Code generated by protoc-gen-go from ", Quote(*g.file.Name))
-	g.p("// DO NOT EDIT!")
-	g.p()
-	g.p("package ", g.file.packageName())
-	g.p()
-}
-
-// Generate the header, including package definition and imports
-func (g *Generator) GenerateImports() {
-	if g.file.needProtoImport() {
-		g.p(`import "goprotobuf.googlecode.com/hg/proto"`)
-	}
-	for _, s := range g.file.Dependency {
-		// Need to find the descriptor for this file
-		for _, fd := range g.allFiles {
-			if proto.GetString(fd.Name) == s {
-				filename := GoName(s)
-				if strings.HasSuffix(filename, ".go") {
-					filename = filename[0:len(filename)-3]
-				}
-				g.p("import ", fd.packageName(), " ", Quote(filename))
-				break
-			}
-		}
-	}
-	g.p()
-}
-
-// Generate the enum definitions for this EnumDescriptor.
-func (g *Generator) GenerateEnum(enum *EnumDescriptor) {
-	// The full type name
-	typeName := enum.typeName()
-	// The full type name, CamelCased.
-	ccTypeName := CamelCaseSlice(typeName)
-	ccPrefix := enum.prefix()
-	g.p("type ", ccTypeName, " int32")
-	g.p("const (")
-	g.in()
-	for _, e := range enum.Value {
-		g.p(ccPrefix+*e.Name, " = ", e.Number)
-	}
-	g.out()
-	g.p(")")
-	g.p("var ", ccTypeName, "_name = map[int32] string {")
-	g.in()
-	generated := make(map[int32] bool)	// avoid duplicate values
-	for _, e := range enum.Value {
-		duplicate := ""
-		if _, present := generated[*e.Number]; present {
-			duplicate = "// Duplicate value: "
-		}
-		g.p(duplicate, e.Number, ": ", Quote(*e.Name), ",")
-		generated[*e.Number] = true
-	}
-	g.out()
-	g.p("}")
-	g.p("var ", ccTypeName, "_value = map[string] int32 {")
-	g.in()
-	for _, e := range enum.Value {
-		g.p(Quote(*e.Name), ": ", e.Number, ",")
-	}
-	g.out()
-	g.p("}")
-	g.p("func New", ccTypeName, "(x int32) *", ccTypeName, " {")
-	g.in()
-	g.p("e := ", ccTypeName, "(x)")
-	g.p("return &e")
-	g.out()
-	g.p("}")
-	g.p()
-}
-
-// The tag is a string like "PB(varint,2,opt,name=fieldname,def=7)" that
-// identifies details of the field for the protocol buffer marshaling and unmarshaling
-// code.  The fields are:
-//	wire encoding
-//	protocol tag number
-//	opt,req,rep for optional, required, or repeated
-//	name= the original declared name
-//	enum= the name of the enum type if it is an enum-typed field.
-//	def= string representation of the default value, if any.
-// The default value must be in a representation that can be used at run-time
-// to generate the default value. Thus bools become 0 and 1, for instance.
-func (g *Generator) GoTag(field *descriptor.FieldDescriptorProto, wiretype string) string {
-	optrepreq := ""
-	switch {
-	case IsOptional(field):
-		optrepreq = "opt"
-	case IsRequired(field):
-		optrepreq = "req"
-	case IsRepeated(field):
-		optrepreq = "rep"
-	}
-	defaultValue := proto.GetString(field.DefaultValue)
-	if defaultValue != "" {
-		switch *field.Type {
-		case descriptor.FieldDescriptorProto_TYPE_BOOL:
-			if defaultValue == "true" {
-				defaultValue = "1"
-			} else {
-				defaultValue = "0"
-			}
-		case descriptor.FieldDescriptorProto_TYPE_STRING,
-			descriptor.FieldDescriptorProto_TYPE_BYTES:
-			// Protect frogs.
-			defaultValue = Quote(defaultValue)
-			// Don't need the quotes
-			defaultValue = defaultValue[1 : len(defaultValue)-1]
-		case descriptor.FieldDescriptorProto_TYPE_ENUM:
-			// For enums we need to provide the integer constant.
-			obj := g.objectNamed(proto.GetString(field.TypeName))
-			enum, ok := obj.(*EnumDescriptor)
-			if !ok {
-				g.fail("enum type inconsistent for", CamelCaseSlice(obj.typeName()))
-			}
-			defaultValue = enum.integerValueAsString(defaultValue)
-		}
-		defaultValue = ",def=" + defaultValue
-	}
-	enum := ""
-	if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
-		obj := g.objectNamed(proto.GetString(field.TypeName))
-		enum = ",enum=" + obj.packageName() + "." + CamelCaseSlice(obj.typeName())
-	}
-	name := proto.GetString(field.Name)
-	if name == CamelCase(name) {
-		name = ""
-	} else {
-		name = ",name=" + name
-	}
-	return Quote(fmt.Sprintf("PB(%s,%d,%s%s%s%s)",
-		wiretype,
-		proto.GetInt32(field.Number),
-		optrepreq,
-		name,
-		enum,
-		defaultValue))
-}
-
-func NeedsStar(typ descriptor.FieldDescriptorProto_Type) bool {
-	switch typ {
-	case descriptor.FieldDescriptorProto_TYPE_GROUP:
-		return false
-	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
-		return false
-	case descriptor.FieldDescriptorProto_TYPE_BYTES:
-		return false
-	}
-	return true
-}
-
-// The type name appropriate for an item. If it's in the current file,
-// drop the package name and underscore the rest.
-// Otherwise it's from another package; use the underscored package name
-// followed by the field name.  The result has an initial capital.
-func (g *Generator) TypeName(obj Object) string {
-	return g.DefaultPackageName(obj) + CamelCaseSlice(obj.typeName())
-}
-
-// Like TypeName, but always includes the package name even if it's our own package.
-func (g *Generator) TypeNameWithPackage(obj Object) string {
-	return obj.packageName() + CamelCaseSlice(obj.typeName())
-}
-
-// Returns a string representing the type name, and the wire type
-func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) {
-	// TODO: Options.
-	switch *field.Type {
-	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
-		typ, wire = "float64", "fixed64"
-	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
-		typ, wire = "float32", "fixed32"
-	case descriptor.FieldDescriptorProto_TYPE_INT64:
-		typ, wire = "int64", "varint"
-	case descriptor.FieldDescriptorProto_TYPE_UINT64:
-		typ, wire = "uint64", "varint"
-	case descriptor.FieldDescriptorProto_TYPE_INT32:
-		typ, wire = "int32", "varint"
-	case descriptor.FieldDescriptorProto_TYPE_UINT32:
-		typ, wire = "uint32", "varint"
-	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
-		typ, wire = "uint64", "fixed64"
-	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
-		typ, wire = "uint32", "fixed32"
-	case descriptor.FieldDescriptorProto_TYPE_BOOL:
-		typ, wire = "bool", "varint"
-	case descriptor.FieldDescriptorProto_TYPE_STRING:
-		typ, wire = "string", "bytes"
-	case descriptor.FieldDescriptorProto_TYPE_GROUP:
-		desc := g.objectNamed(proto.GetString(field.TypeName))
-		typ, wire = "*"+g.TypeName(desc), "group"
-	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
-		desc := g.objectNamed(proto.GetString(field.TypeName))
-		typ, wire = "*"+g.TypeName(desc), "bytes"
-	case descriptor.FieldDescriptorProto_TYPE_BYTES:
-		typ, wire = "[]byte", "bytes"
-	case descriptor.FieldDescriptorProto_TYPE_ENUM:
-		desc := g.objectNamed(proto.GetString(field.TypeName))
-		typ, wire = g.TypeName(desc), "varint"
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
-		typ, wire = "int32", "fixed32"
-	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
-		typ, wire = "int64", "fixed64"
-	case descriptor.FieldDescriptorProto_TYPE_SINT32:
-		typ, wire = "int32", "zigzag32"
-	case descriptor.FieldDescriptorProto_TYPE_SINT64:
-		typ, wire = "int64", "zigzag64"
-	default:
-		g.fail("unknown type for", proto.GetString(field.Name))
-	}
-	if IsRepeated(field) {
-		typ = "[]" + typ
-	} else if NeedsStar(*field.Type) {
-		typ = "*" + typ
-	}
-	return
-}
-
-// Generate the type and default constant definitions for this Descriptor.
-func (g *Generator) GenerateMessage(message *Descriptor) {
-	// The full type name
-	typeName := message.typeName()
-	// The full type name, CamelCased.
-	ccTypeName := CamelCaseSlice(typeName)
-
-	g.p("type ", ccTypeName, " struct {")
-	g.in()
-	for _, field := range message.Field {
-		fieldname := CamelCase(*field.Name)
-		typename, wiretype := g.GoType(message, field)
-		tag := g.GoTag(field, wiretype)
-		g.p(fieldname, "\t", typename, "\t", tag)
-	}
-	if len(message.ExtensionRange) > 0 {
-		g.p("XXX_extensions\t\tmap[int32][]byte")
-	}
-	g.p("XXX_unrecognized\t[]byte")
-	g.out()
-	g.p("}")
-
-	// Reset and New functions
-	g.p("func (this *", ccTypeName, ") Reset() {")
-	g.in()
-	g.p("*this = ", ccTypeName, "{}")
-	g.out()
-	g.p("}")
-	g.p("func New", ccTypeName, "() *", ccTypeName, " {")
-	g.in()
-	g.p("return new(", ccTypeName, ")")
-	g.out()
-	g.p("}")
-
-	// Extension support methods
-	if len(message.ExtensionRange) > 0 {
-		g.p()
-		g.p("var extRange_", ccTypeName, " = []proto.ExtensionRange{")
-		g.in()
-		for _, r := range message.ExtensionRange {
-			end := fmt.Sprint(*r.End - 1)  // make range inclusive on both ends
-			g.p("proto.ExtensionRange{", r.Start, ", ", end, "},")
-		}
-		g.out()
-		g.p("}")
-		g.p("func (*", ccTypeName, ") ExtensionRangeArray() []proto.ExtensionRange {")
-		g.in()
-		g.p("return extRange_", ccTypeName)
-		g.out()
-		g.p("}")
-		g.p("func (this *", ccTypeName, ") ExtensionMap() map[int32][]byte {")
-		g.in()
-		g.p("if this.XXX_extensions == nil {")
-		g.in()
-		g.p("this.XXX_extensions = make(map[int32][]byte)")
-		g.out()
-		g.p("}")
-		g.p("return this.XXX_extensions")
-		g.out()
-		g.p("}")
-	}
-
-	// Default constants
-	for _, field := range message.Field {
-		def := proto.GetString(field.DefaultValue)
-		if def == "" {
-			continue
-		}
-		fieldname := "Default_" + ccTypeName + "_" + CamelCase(*field.Name)
-		typename, _ := g.GoType(message, field)
-		if typename[0] == '*' {
-			typename = typename[1:]
-		}
-		kind := "const "
-		switch {
-		case typename == "bool":
-		case typename == "string":
-			def = Quote(def)
-		case typename == "[]byte":
-			def = "[]byte(" + Quote(def) + ")"
-			kind = "var "
-		case *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM:
-			// Must be an enum.  Need to construct the prefixed name.
-			obj := g.objectNamed(proto.GetString(field.TypeName))
-			enum, ok := obj.(*EnumDescriptor)
-			if !ok {
-				log.Stderr("don't know how to generate constant for", fieldname)
-				continue
-			}
-			def = enum.prefix() + def
-		}
-		g.p(kind, fieldname, " ", typename, " = ", def)
-	}
-	g.p()
-
-	for _, ext := range message.ext {
-		g.GenerateExtension(ext)
-	}
-}
-
-// Generate the extension descriptor for this ExtensionDescriptor.
-func (g *Generator) GenerateExtension(ext *ExtensionDescriptor) {
-	// The full type name
-	typeName := ext.typeName()
-	// Each scope of the extension is individually CamelCased, and all are joined with "_" with a "E_" prefix.
-	for i, s := range typeName {
-		typeName[i] = CamelCase(s)
-	}
-	ccTypeName := "E_" + strings.Join(typeName, "_")
-
-	extendedType := "*" + g.TypeName(g.objectNamed(*ext.Extendee))
-	field := ext.FieldDescriptorProto
-	fieldType, wireType := g.GoType(ext.parent, field)
-	tag := g.GoTag(field, wireType)
-
-	g.p("var ", ccTypeName, " = &proto.ExtensionDesc{")
-	g.in()
-	g.p("ExtendedType: (", extendedType, ")(nil),")
-	g.p("ExtensionType: (", fieldType, ")(nil),")
-	g.p("Field: ", field.Number, ",")
-	g.p("Tag: ", tag, ",")
-
-	g.out()
-	g.p("}")
-	g.p()
-}
-
-func (g *Generator) GenerateInitFunction() {
-	g.p("func init() {")
-	g.in()
-	for _, enum := range g.file.enum {
-		g.GenerateEnumRegistration(enum)
-	}
-	g.out()
-	g.p("}")
-}
-
-func (g *Generator) GenerateEnumRegistration(enum *EnumDescriptor) {
-	pkg := g.packageName + "." // We always print the full package name here.
-	// The full type name
-	typeName := enum.typeName()
-	// The full type name, CamelCased.
-	ccTypeName := CamelCaseSlice(typeName)
-	g.p("proto.RegisterEnum(", Quote(pkg+ccTypeName), ", ", ccTypeName+"_name, ", ccTypeName+"_value)")
-}
-
-// And now lots of helper functions.
-
-// Return change foo_bar_Baz to FooBar_Baz.
-func CamelCase(name string) string {
-	elems := strings.Split(name, "_", 0)
-	for i, e := range elems {
-		if e == "" {
-			elems[i] = "_"
-			continue
-		}
-		runes := []int(e)
-		if unicode.IsLower(runes[0]) {
-			runes[0] = unicode.ToUpper(runes[0])
-			elems[i] = string(runes)
-		} else {
-			if i > 0 {
-				elems[i] = "_" + e
-			}
-		}
-	}
-	s := strings.Join(elems, "")
-	// Name must not begin with an underscore.
-	if len(s) > 0 && s[0] == '_' {
-		s = "X" + s[1:]
-	}
-	return s
-}
-
-// Like CamelCase, but the argument is a slice of strings to
-// be concatenated with "_"
-func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }
-
-// Turn a sliced name into a dotted name
-func DottedSlice(elem []string) string { return strings.Join(elem, ".") }
-
-// Return a Go-source quoted string representation of s.
-func Quote(s string) string { return fmt.Sprintf("%q", s) }
-
-// Given a .proto file name, return the output name for the generated Go program.
-func GoName(name string) string {
-	if strings.HasSuffix(name, ".proto") {
-		name = name[0 : len(name)-6]
-	}
-	return name + ".pb.go"
-}
-
-// Is this field optional?
-func IsOptional(field *descriptor.FieldDescriptorProto) bool {
-	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
-}
-
-// Is this field required?
-func IsRequired(field *descriptor.FieldDescriptorProto) bool {
-	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED
-}
-
-// Is this field repeated?
-func IsRepeated(field *descriptor.FieldDescriptorProto) bool {
-	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
-}
-
-// Mapping function used to generate Go names from package names, which can be dotted.
-func DotToUnderscore(rune int) int {
-	if rune == '.' {
-		return '_'
-	}
-	return rune
-}
diff --git a/compiler/plugin/Makefile b/compiler/plugin/Makefile
index 08be77f..d2db4a4 100644
--- a/compiler/plugin/Makefile
+++ b/compiler/plugin/Makefile
@@ -35,6 +35,8 @@
 GOFILES=\
 	plugin.pb.go\
 
+DEPS=../../proto ../descriptor
+
 include $(GOROOT)/src/Make.pkg
 
 # Not stored here, but plugin.proto is in http://code.google.com/p/protobuf
