Go support for protocol buffers.

Consists of a compiler plugin and the support library, all written in Go.

This is a complete implementation except for:
  - Extensions in the plugin
    - coming soon
    - support is already in the library
  - Services (RPC)
    - needs an external definition to honor before supporting.
  - Insertion points in the plugin
    - may come

R=rsc, dsymonds1, ken2
CC=golang-dev
http://codereview.appspot.com/676041
diff --git a/proto/lib.go b/proto/lib.go
new file mode 100644
index 0000000..8660335
--- /dev/null
+++ b/proto/lib.go
@@ -0,0 +1,537 @@
+// 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 proto package converts data structures to and from the
+	wire format of protocol buffers.  It works in concert with the
+	Go source code generated for .proto files by the protocol compiler.
+
+	A summary of the properties of the protocol buffer interface
+	for a protocol buffer variable v:
+
+	  - Names are turned from camel_case to CamelCase for export.
+	  - There are no methods on v to set and get fields; just treat
+	  	them as structure fields.
+	  - The zero value for a struct is its correct initialization state.
+		All desired fields must be set before marshaling.
+	  - A Reset() method will restore a protobuf struct to its zero state.
+	  - Each type T has a method NewT() to create a new instance. It
+		is equivalent to new(T).
+	  - Non-repeated fields are pointers to the values; nil means unset.
+		That is, optional or required field int32 f becomes F *int32.
+	  - Repeated fields are slices.
+	  - Helper functions are available to simplify the getting and setting of fields:
+	  	foo.String = proto.String("hello") // set field
+	  	s := proto.GetString(foo.String)  // get field
+	  - Constants are defined to hold the default values of all fields that
+		have them.  They have the form Default_StructName_FieldName.
+	  - Enums are given type names and maps between names to values,
+	  	plus a helper function to create values.  Enum values are prefixed
+	  	with the enum's type name.
+	  - Nested groups and enums have type names prefixed with the name of
+	  	the surrounding message type.
+	  - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+	The simplest way to describe this is to see an example.
+	Given file test.proto, containing
+
+		package example;
+
+		enum FOO { X = 17; };
+
+		message Test {
+		  required string label = 1;
+		  optional int32 type = 2 [default=77];
+		  repeated int64 reps = 3;
+		  optional group OptionalGroup = 4 {
+		    required string RequiredField = 5;
+		  };
+		}
+
+	The resulting file, test.pb.go, is:
+
+		package example
+
+		import "goprotobuf.googlecode.com/hg/proto"
+
+		type FOO int32
+		const (
+			FOO_X = 17
+		)
+		var FOO_name = map[int32] string {
+			17: "X",
+		}
+		var FOO_value = map[string] int32 {
+			"X": 17,
+		}
+		func NewFOO(x int32) *FOO {
+			e := FOO(x)
+			return &e
+		}
+
+		type Test struct {
+			Label	*string	"PB(bytes,1,req,name=label)"
+			Type	*int32	"PB(varint,2,opt,name=type,def=77)"
+			Reps	[]int64	"PB(varint,3,rep,name=reps)"
+			Optionalgroup	*Test_OptionalGroup	"PB(group,4,opt,name=optionalgroup)"
+			XXX_unrecognized []byte
+		}
+		func (this *Test) Reset() {
+			*this = Test{}
+		}
+		func NewTest() *Test {
+			return new(Test)
+		}
+		const Default_Test_Type int32 = 77
+
+		type Test_OptionalGroup struct {
+			RequiredField	*string	"PB(bytes,5,req)"
+			XXX_unrecognized []byte
+		}
+		func (this *Test_OptionalGroup) Reset() {
+			*this = Test_OptionalGroup{}
+		}
+		func NewTest_OptionalGroup() *Test_OptionalGroup {
+			return new(Test_OptionalGroup)
+		}
+
+		func init() {
+			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+		}
+
+	To create and play with a Test object:
+
+		package main
+
+		import (
+			"log"
+
+			"goprotobuf.googlecode.com/hg/proto"
+			"./example.pb"
+		)
+
+		func main() {
+			test := &example.Test {
+				Label: proto.String("hello"),
+				Type: proto.Int32(17),
+				Optionalgroup: &example.Test_OptionalGroup {
+					RequiredField: proto.String("good bye"),
+				},
+			}
+			data, err := proto.Marshal(test)
+			if err != nil {
+				log.Exit("marshaling error:", err)
+			}
+			newTest := example.NewTest()
+			err = proto.Unmarshal(data, newTest)
+			if err != nil {
+				log.Exit("unmarshaling error:", err)
+			}
+			// Now test and newTest contain the same data.
+			if proto.GetString(test.Label) != proto.GetString(newTest.Label) {
+				log.Exit("data mismatch %q %q", proto.GetString(test.Label), proto.GetString(newTest.Label))
+			}
+			// etc.
+		}
+*/
+package proto
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// Stats records allocation details about the protocol buffer encoders
+// and decoders.  Useful for tuning the library itself.
+type Stats struct {
+	Emalloc uint64 // mallocs in encode
+	Dmalloc uint64 // mallocs in decode
+	Encode  uint64 // number of encodes
+	Decode  uint64 // number of decodes
+	Chit    uint64 // number of cache hits
+	Cmiss   uint64 // number of cache misses
+}
+
+var stats Stats
+
+// GetStats returns a copy of the global Stats structure.
+func GetStats() Stats { return stats }
+
+// A Buffer is a buffer manager for marshaling and unmarshaling
+// protocol buffers.  It may be reused between invocations to
+// reduce memory usage.  It is not necessary to use a Buffer;
+// the global functions Marshal and Unmarshal create a
+// temporary Buffer and are fine for most applications.
+type Buffer struct {
+	buf       []byte     // encode/decode byte stream
+	index     int        // write point
+	freelist  [10][]byte // list of available buffers
+	nfreelist int        // number of free buffers
+	ptr       uintptr    // scratch area for pointers
+}
+
+// NewBuffer allocates a new Buffer and initializes its internal data to
+// the contents of the argument slice.
+func NewBuffer(e []byte) *Buffer {
+	p := new(Buffer)
+	if e == nil {
+		e = p.bufalloc()
+	}
+	p.buf = e
+	p.index = 0
+	return p
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+	if p.buf == nil {
+		p.buf = p.bufalloc()
+	}
+	p.buf = p.buf[0:0] // for reading/writing
+	p.index = 0        // for reading
+}
+
+// SetBuf replaces the internal buffer with the slice,
+// ready for unmarshaling the contents of the slice.
+func (p *Buffer) SetBuf(s []byte) {
+	p.buf = s
+	p.index = 0
+}
+
+// Bytes returns the contents of the Buffer.
+func (p *Buffer) Bytes() []byte { return p.buf }
+
+// Allocate a buffer for the Buffer.
+func (p *Buffer) bufalloc() []byte {
+	if p.nfreelist > 0 {
+		// reuse an old one
+		p.nfreelist--
+		s := p.freelist[p.nfreelist]
+		return s[0:0]
+	}
+	// make a new one
+	s := make([]byte, 0, 16)
+	return s
+}
+
+// Free (and remember in freelist) a byte buffer for the Buffer.
+func (p *Buffer) buffree(s []byte) {
+	if p.nfreelist < len(p.freelist) {
+		// Take next slot.
+		p.freelist[p.nfreelist] = s
+		p.nfreelist++
+		return
+	}
+
+	// Find the smallest.
+	besti := -1
+	bestl := len(s)
+	for i, b := range p.freelist {
+		if len(b) < bestl {
+			besti = i
+			bestl = len(b)
+		}
+	}
+
+	// Overwrite the smallest.
+	if besti >= 0 {
+		p.freelist[besti] = s
+	}
+}
+
+/*
+ * Helper routines for simplifying the creation of optional fields of basic type.
+ */
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool {
+	p := new(bool)
+	*p = v
+	return p
+}
+
+// Int32 is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it.
+func Int32(v int32) *int32 {
+	p := new(int32)
+	*p = v
+	return p
+}
+
+// Int is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it, but unlike Int32
+// its argument value is an int.
+func Int(v int) *int32 {
+	p := new(int32)
+	*p = int32(v)
+	return p
+}
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 {
+	p := new(int64)
+	*p = v
+	return p
+}
+
+// Float32 is a helper routine that allocates a new float32 value
+// to store v and returns a pointer to it.
+func Float32(v float32) *float32 {
+	p := new(float32)
+	*p = v
+	return p
+}
+
+// Float64 is a helper routine that allocates a new float64 value
+// to store v and returns a pointer to it.
+func Float64(v float64) *float64 {
+	p := new(float64)
+	*p = v
+	return p
+}
+
+// Uint32 is a helper routine that allocates a new uint32 value
+// to store v and returns a pointer to it.
+func Uint32(v uint32) *uint32 {
+	p := new(uint32)
+	*p = v
+	return p
+}
+
+// Uint64 is a helper routine that allocates a new uint64 value
+// to store v and returns a pointer to it.
+func Uint64(v uint64) *uint64 {
+	p := new(uint64)
+	*p = v
+	return p
+}
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string {
+	p := new(string)
+	*p = v
+	return p
+}
+
+/*
+ * Helper routines for simplifying the fetching of optional fields of basic type.
+ * If the field is missing, they return the zero for the type.
+ */
+
+// GetBool is a helper routine that returns an optional bool value.
+func GetBool(p *bool) bool {
+	if p == nil {
+		return false
+	}
+	return *p
+}
+
+// GetInt32 is a helper routine that returns an optional int32 value.
+func GetInt32(p *int32) int32 {
+	if p == nil {
+		return 0
+	}
+	return *p
+}
+
+// GetInt64 is a helper routine that returns an optional int64 value.
+func GetInt64(p *int64) int64 {
+	if p == nil {
+		return 0
+	}
+	return *p
+}
+
+// GetFloat32 is a helper routine that returns an optional float32 value.
+func GetFloat32(p *float32) float32 {
+	if p == nil {
+		return 0
+	}
+	return *p
+}
+
+// GetFloat64 is a helper routine that returns an optional float64 value.
+func GetFloat64(p *float64) float64 {
+	if p == nil {
+		return 0
+	}
+	return *p
+}
+
+// GetUint32 is a helper routine that returns an optional uint32 value.
+func GetUint32(p *uint32) uint32 {
+	if p == nil {
+		return 0
+	}
+	return *p
+}
+
+// GetUint64 is a helper routine that returns an optional uint64 value.
+func GetUint64(p *uint64) uint64 {
+	if p == nil {
+		return 0
+	}
+	return *p
+}
+
+// GetString is a helper routine that returns an optional string value.
+func GetString(p *string) string {
+	if p == nil {
+		return ""
+	}
+	return *p
+}
+
+// EnumName is a helper function to simplify printing protocol buffer enums
+// by name.  Given an enum map and a value, it returns a useful string.
+func EnumName(m map[int32]string, v int32) string {
+	s, ok := m[v]
+	if ok {
+		return s
+	}
+	return "unknown_enum_" + strconv.Itoa(int(v))
+}
+
+// DebugPrint dumps the encoded data in b in a debugging format with a header
+// including the string s. Used in testing but made available for general debugging.
+func (o *Buffer) DebugPrint(s string, b []byte) {
+	var u uint64
+
+	obuf := o.buf
+	index := o.index
+	o.buf = b
+	o.index = 0
+	depth := 0
+
+	fmt.Printf("\n--- %s ---\n", s)
+
+out:
+	for {
+		for i := 0; i < depth; i++ {
+			fmt.Print("  ")
+		}
+
+		index := o.index
+		if index == len(o.buf) {
+			break
+		}
+
+		op, err := o.DecodeVarint()
+		if err != nil {
+			fmt.Printf("%3d: fetching op err %v\n", index, err)
+			break out
+		}
+		tag := op >> 3
+		wire := op & 7
+
+		switch wire {
+		default:
+			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
+				index, tag, wire)
+			break out
+
+		case WireBytes:
+			var r []byte
+
+			r, err = o.DecodeRawBytes(false)
+			if err != nil {
+				break out
+			}
+			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
+			if len(r) <= 6 {
+				for i := 0; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			} else {
+				for i := 0; i < 3; i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+				fmt.Printf(" ..")
+				for i := len(r) - 3; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			}
+			fmt.Printf("\n")
+
+		case WireFixed32:
+			u, err = o.DecodeFixed32()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
+
+		case WireFixed64:
+			u, err = o.DecodeFixed64()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
+			break
+
+		case WireVarint:
+			u, err = o.DecodeVarint()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
+
+		case WireStartGroup:
+			if err != nil {
+				fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d start\n", index, tag)
+			depth++
+
+		case WireEndGroup:
+			depth--
+			if err != nil {
+				fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d end\n", index, tag)
+		}
+	}
+
+	if depth != 0 {
+		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
+	}
+	fmt.Printf("\n")
+
+	o.buf = obuf
+	o.index = index
+}