func (d *FileDescriptor) goPackageName() (name string, explicit bool) {
	if opts := d.Options; opts != nil {
		if pkg := opts.GetGoPackage(); pkg != "" {
			return pkg, true
		}
	}
	if pkg := d.GetPackage(); pkg != "" {
		return pkg, false
	}
	return baseName(d.GetName()), false
}
goPackageName returns the Go package name to use in the
generated Go file.  The result explicit reports whether the name
came from an option go_package statement.  If explicit is false,
the name was derived from the protocol buffer's package statement
or the input file name.
package generator
import (
	"bytes"
	"fmt"
	"go/parser"
	"go/printer"
	"go/token"
	"log"
	"os"
	"path"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"
	"code.google.com/p/goprotobuf/proto"
	descriptor "code.google.com/p/goprotobuf/protoc-gen-go/descriptor"
	plugin "code.google.com/p/goprotobuf/protoc-gen-go/plugin"
)
type Plugin interface {
	Name() string
	Init(g *Generator)
	Generate(file *FileDescriptor)
	GenerateImports(file *FileDescriptor)
}
var plugins []Plugin
func RegisterPlugin(p Plugin) {
	plugins = append(plugins, p)
}
type common struct {
	file *descriptor.FileDescriptorProto  
}
func (c *common) PackageName() string { return uniquePackageOf(c.file) }
func (c *common) File() *descriptor.FileDescriptorProto { return c.file }
type Descriptor struct {
	common
	*descriptor.DescriptorProto
	parent   *Descriptor             
	nested   []*Descriptor           
	ext      []*ExtensionDescriptor  
	typename []string                
	index    int                     
	path     string                  
	group    bool
}
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] = parent.GetName()
	}
	d.typename = s
	return s
}
type EnumDescriptor struct {
	common
	*descriptor.EnumDescriptorProto
	parent   *Descriptor  
	typename []string     
	index    int          
	path     string       
}
func (e *EnumDescriptor) TypeName() (s []string) {
	if e.typename != nil {
		return e.typename
	}
	name := e.GetName()
	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
}
func (e *EnumDescriptor) prefix() string {
	typeName := e.TypeName()
	ccPrefix := CamelCaseSlice(typeName[0:len(typeName)-1]) + "_"
	if e.parent == nil {
		ccPrefix = CamelCase(*e.Name) + "_"
	}
	return ccPrefix
}
func (e *EnumDescriptor) integerValueAsString(name string) string {
	for _, c := range e.Value {
		if c.GetName() == name {
			return fmt.Sprint(c.GetNumber())
		}
	}
	log.Fatal("cannot find value for enum constant")
	return ""
}
type ExtensionDescriptor struct {
	common
	*descriptor.FieldDescriptorProto
	parent *Descriptor  
}
func (e *ExtensionDescriptor) TypeName() (s []string) {
	name := e.GetName()
	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
	return s
}
func (e *ExtensionDescriptor) DescName() string {
	typeName := e.TypeName()
	for i, s := range typeName {
		typeName[i] = CamelCase(s)
	}
	return "E_" + strings.Join(typeName, "_")
}
type ImportedDescriptor struct {
	common
	o Object
}
func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeName() }
type FileDescriptor struct {
	*descriptor.FileDescriptorProto
	desc []*Descriptor           
	enum []*EnumDescriptor       
	ext  []*ExtensionDescriptor  
	imp  []*ImportedDescriptor   
	comments map[string]*descriptor.SourceCodeInfo_Location
	exported map[Object][]symbol
	index int  
}
func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) }