goprotobuf: make the generator a package, with the main
program a separate file.  also introduce the hooks for a plugin
(really a plugin for this plugin) to enable add-on generators for
things like RPC.

R=rsc
CC=golang-dev
http://codereview.appspot.com/970046
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
-}