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/extensions.go b/proto/extensions.go
new file mode 100644
index 0000000..480e8d3
--- /dev/null
+++ b/proto/extensions.go
@@ -0,0 +1,153 @@
+// 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.
+
+package proto
+
+
+/*
+ * Types and routines for supporting protocol buffer extensions.
+ */
+
+import (
+	"os"
+	"reflect"
+	"unsafe"
+)
+
+// ExtensionRange represents a range of message extensions for a protocol buffer.
+// Used in code generated by the protocol compiler.
+type ExtensionRange struct {
+	Start, End int32 // both inclusive
+}
+
+// extendableProto is an interface implemented by any protocol buffer that may be extended.
+type extendableProto interface {
+	ExtensionRangeArray() []ExtensionRange
+	ExtensionMap() map[int32][]byte
+}
+
+// ExtensionDesc represents an extension specification.
+// Used in generated code from the protocol compiler.
+type ExtensionDesc struct {
+	ExtendedType  interface{} // nil pointer to the type that is being extended
+	ExtensionType interface{} // nil pointer to the extension type
+	Field         int32       // field number
+	Tag           string      // PB(...) tag style
+}
+
+// Return true iff the given field number is in an extension range.
+func isExtensionField(extended extendableProto, field int32) bool {
+	for _, er := range extended.ExtensionRangeArray() {
+		if er.Start <= field && field <= er.End {
+			return true
+		}
+	}
+	return false
+}
+
+func checkExtensionTypes(extended extendableProto, extension *ExtensionDesc) os.Error {
+	// Check the extended type.
+	if a, b := reflect.Typeof(extended), reflect.Typeof(extension.ExtendedType); a != b {
+		return os.NewError("bad extended type; " + b.String() + " does not extend " + a.String())
+	}
+	// Check the range.
+	if !isExtensionField(extended, extension.Field) {
+		return os.NewError("bad extension number; not in declared ranges")
+	}
+	return nil
+}
+
+func HasExtension(extended extendableProto, extension *ExtensionDesc) bool {
+	// TODO: Check types, field numbers, etc.?
+	_, ok := extended.ExtensionMap()[extension.Field]
+	return ok
+}
+
+func ClearExtension(extended extendableProto, extension *ExtensionDesc) {
+	// TODO: Check types, field numbers, etc.?
+	extended.ExtensionMap()[extension.Field] = nil, false
+}
+
+func GetExtension(extended extendableProto, extension *ExtensionDesc) (interface{}, os.Error) {
+	if err := checkExtensionTypes(extended, extension); err != nil {
+		return nil, err
+	}
+
+	b, ok := extended.ExtensionMap()[extension.Field]
+	if !ok {
+		return nil, nil // not an error
+	}
+
+	// Discard wire type and field number varint. It isn't needed.
+	_, n := DecodeVarint(b)
+	o := NewBuffer(b[n:])
+
+	t := reflect.Typeof(extension.ExtensionType).(*reflect.PtrType)
+	props := &Properties{}
+	props.Init(t, "irrelevant_name", extension.Tag, 0)
+
+	base := unsafe.New(t)
+	var sbase uintptr
+	if _, ok := t.Elem().(*reflect.StructType); ok {
+		// props.dec will be dec_struct_message, which does not refer to sbase.
+		*(*unsafe.Pointer)(base) = unsafe.New(t.Elem())
+	} else {
+		sbase = uintptr(unsafe.New(t.Elem()))
+	}
+	if err := props.dec(o, props, uintptr(base), sbase); err != nil {
+		return nil, err
+	}
+	return unsafe.Unreflect(t, base), nil
+}
+
+// TODO(: (needed for repeated extensions)
+//   - ExtensionSize
+//   - AddExtension
+
+func SetExtension(extended extendableProto, extension *ExtensionDesc, value interface{}) os.Error {
+	if err := checkExtensionTypes(extended, extension); err != nil {
+		return err
+	}
+	if reflect.Typeof(extension.ExtensionType) != reflect.Typeof(value) {
+		return os.NewError("bad extension value type")
+	}
+
+	props := new(Properties)
+	props.Init(reflect.Typeof(extension.ExtensionType), "unknown_name", extension.Tag, 0)
+
+	p := NewBuffer(nil)
+	v := reflect.NewValue(value)
+	if err := props.enc(p, props, v.Addr()); err != nil {
+		return err
+	}
+	extended.ExtensionMap()[extension.Field] = p.buf
+	return nil
+}