// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/protobuf
//
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// 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

/*
 * Routines for encoding data into the wire format for protocol buffers.
 */

import (
	
	
	
	
	
	
	
)

const debug bool = false

// Constants that identify the encoding of a value on the wire.
const (
	WireVarint     = 0
	WireFixed64    = 1
	WireBytes      = 2
	WireStartGroup = 3
	WireEndGroup   = 4
	WireFixed32    = 5
)

// tagMap is an optimization over map[int]int for typical protocol buffer
// use-cases. Encoded protocol buffers are often in tag order with small tag
// numbers.
type tagMap struct {
	fastTags []int
	slowTags map[int]int
}

// tagMapFastLimit is the upper bound on the tag number that will be stored in
// the tagMap slice rather than its map.
const tagMapFastLimit = 1024

func ( *tagMap) ( int) (int, bool) {
	if  > 0 &&  < tagMapFastLimit {
		if  >= len(.fastTags) {
			return 0, false
		}
		 := .fastTags[]
		return ,  >= 0
	}
	,  := .slowTags[]
	return , 
}

func ( *tagMap) ( int,  int) {
	if  > 0 &&  < tagMapFastLimit {
		for len(.fastTags) < +1 {
			.fastTags = append(.fastTags, -1)
		}
		.fastTags[] = 
		return
	}
	if .slowTags == nil {
		.slowTags = make(map[int]int)
	}
	.slowTags[] = 
}

// StructProperties represents properties for all the fields of a struct.
// decoderTags and decoderOrigNames should only be used by the decoder.
type StructProperties struct {
	Prop             []*Properties  // properties for each field
	reqCount         int            // required count
	decoderTags      tagMap         // map from proto tag to struct field number
	decoderOrigNames map[string]int // map from original name to struct field number
	order            []int          // list of struct field numbers in tag order

	// OneofTypes contains information about the oneof fields in this message.
	// It is keyed by the original name of a field.
	OneofTypes map[string]*OneofProperties
}

// OneofProperties represents information about a specific field in a oneof.
type OneofProperties struct {
	Type  reflect.Type // pointer to generated struct type for this oneof field
	Field int          // struct field number of the containing oneof in the message
	Prop  *Properties
}

// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
// See encode.go, (*Buffer).enc_struct.

func ( *StructProperties) () int { return len(.order) }
func ( *StructProperties) (,  int) bool {
	return .Prop[.order[]].Tag < .Prop[.order[]].Tag
}
func ( *StructProperties) (,  int) { .order[], .order[] = .order[], .order[] }

// Properties represents the protocol-specific behavior of a single struct field.
type Properties struct {
	Name     string // name of the field, for error messages
	OrigName string // original name before protocol compiler (always set)
	JSONName string // name to use for JSON; determined by protoc
	Wire     string
	WireType int
	Tag      int
	Required bool
	Optional bool
	Repeated bool
	Packed   bool   // relevant for repeated primitives only
	Enum     string // set for enum types only
	proto3   bool   // whether this is known to be a proto3 field
	oneof    bool   // whether this is a oneof field

	Default     string // default value
	HasDefault  bool   // whether an explicit default was provided
	CustomType  string
	CastType    string
	StdTime     bool
	StdDuration bool
	WktPointer  bool

	stype reflect.Type      // set for struct types only
	ctype reflect.Type      // set for custom types only
	sprop *StructProperties // set for struct types only

	mtype      reflect.Type // set for map types only
	MapKeyProp *Properties  // set for map types only
	MapValProp *Properties  // set for map types only
}

// String formats the properties in the protobuf struct field tag style.
func ( *Properties) () string {
	 := .Wire
	 += ","
	 += strconv.Itoa(.Tag)
	if .Required {
		 += ",req"
	}
	if .Optional {
		 += ",opt"
	}
	if .Repeated {
		 += ",rep"
	}
	if .Packed {
		 += ",packed"
	}
	 += ",name=" + .OrigName
	if .JSONName != .OrigName {
		 += ",json=" + .JSONName
	}
	if .proto3 {
		 += ",proto3"
	}
	if .oneof {
		 += ",oneof"
	}
	if len(.Enum) > 0 {
		 += ",enum=" + .Enum
	}
	if .HasDefault {
		 += ",def=" + .Default
	}
	return 
}

// Parse populates p by parsing a string in the protobuf struct field tag style.
func ( *Properties) ( string) {
	// "bytes,49,opt,name=foo,def=hello!"
	 := strings.Split(, ",") // breaks def=, but handled below.
	if len() < 2 {
		log.Printf("proto: tag has too few fields: %q", )
		return
	}

	.Wire = [0]
	switch .Wire {
	case "varint":
		.WireType = WireVarint
	case "fixed32":
		.WireType = WireFixed32
	case "fixed64":
		.WireType = WireFixed64
	case "zigzag32":
		.WireType = WireVarint
	case "zigzag64":
		.WireType = WireVarint
	case "bytes", "group":
		.WireType = WireBytes
		// no numeric converter for non-numeric types
	default:
		log.Printf("proto: tag has unknown wire type: %q", )
		return
	}

	var  error
	.Tag,  = strconv.Atoi([1])
	if  != nil {
		return
	}

:
	for  := 2;  < len(); ++ {
		 := []
		switch {
		case  == "req":
			.Required = true
		case  == "opt":
			.Optional = true
		case  == "rep":
			.Repeated = true
		case  == "packed":
			.Packed = true
		case strings.HasPrefix(, "name="):
			.OrigName = [5:]
		case strings.HasPrefix(, "json="):
			.JSONName = [5:]
		case strings.HasPrefix(, "enum="):
			.Enum = [5:]
		case  == "proto3":
			.proto3 = true
		case  == "oneof":
			.oneof = true
		case strings.HasPrefix(, "def="):
			.HasDefault = true
			.Default = [4:] // rest of string
			if +1 < len() {
				// Commas aren't escaped, and def is always last.
				.Default += "," + strings.Join([+1:], ",")
				break 
			}
		case strings.HasPrefix(, "embedded="):
			.OrigName = strings.Split(, "=")[1]
		case strings.HasPrefix(, "customtype="):
			.CustomType = strings.Split(, "=")[1]
		case strings.HasPrefix(, "casttype="):
			.CastType = strings.Split(, "=")[1]
		case  == "stdtime":
			.StdTime = true
		case  == "stdduration":
			.StdDuration = true
		case  == "wktptr":
			.WktPointer = true
		}
	}
}

var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()

// setFieldProps initializes the field properties for submessages and maps.
func ( *Properties) ( reflect.Type,  *reflect.StructField,  bool) {
	 := .Kind() == reflect.Map
	if len(.CustomType) > 0 && ! {
		.ctype = 
		.setTag()
		return
	}
	if .StdTime && ! {
		.setTag()
		return
	}
	if .StdDuration && ! {
		.setTag()
		return
	}
	if .WktPointer && ! {
		.setTag()
		return
	}
	switch  := ; .Kind() {
	case reflect.Struct:
		.stype = 
	case reflect.Ptr:
		if .Elem().Kind() == reflect.Struct {
			.stype = .Elem()
		}
	case reflect.Slice:
		switch  := .Elem(); .Kind() {
		case reflect.Ptr:
			switch  := .Elem(); .Kind() {
			case reflect.Struct:
				.stype = 
			}
		case reflect.Struct:
			.stype = 
		}

	case reflect.Map:

		.mtype = 
		.MapKeyProp = &Properties{}
		.MapKeyProp.init(reflect.PtrTo(.mtype.Key()), "Key", .Tag.Get("protobuf_key"), nil, )
		.MapValProp = &Properties{}
		 := .mtype.Elem()
		if .Kind() != reflect.Ptr && .Kind() != reflect.Slice {
			// The value type is not a message (*T) or bytes ([]byte),
			// so we need encoders for the pointer to this type.
			 = reflect.PtrTo()
		}

		.MapValProp.CustomType = .CustomType
		.MapValProp.StdDuration = .StdDuration
		.MapValProp.StdTime = .StdTime
		.MapValProp.WktPointer = .WktPointer
		.MapValProp.init(, "Value", .Tag.Get("protobuf_val"), nil, )
	}
	.setTag()
}

func ( *Properties) ( bool) {
	if .stype != nil {
		if  {
			.sprop = GetProperties(.stype)
		} else {
			.sprop = getPropertiesLocked(.stype)
		}
	}
}

var (
	marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
)

// Init populates the properties from a protocol buffer struct tag.
func ( *Properties) ( reflect.Type, ,  string,  *reflect.StructField) {
	.init(, , , , true)
}

func ( *Properties) ( reflect.Type, ,  string,  *reflect.StructField,  bool) {
	// "bytes,49,opt,def=hello!"
	.Name = 
	.OrigName = 
	if  == "" {
		return
	}
	.Parse()
	.setFieldProps(, , )
}

var (
	propertiesMu  sync.RWMutex
	propertiesMap = make(map[reflect.Type]*StructProperties)
)

// GetProperties returns the list of properties for the type represented by t.
// t must represent a generated struct type of a protocol message.
func ( reflect.Type) *StructProperties {
	if .Kind() != reflect.Struct {
		panic("proto: type must have kind struct")
	}

	// Most calls to GetProperties in a long-running program will be
	// retrieving details for types we have seen before.
	propertiesMu.RLock()
	,  := propertiesMap[]
	propertiesMu.RUnlock()
	if  {
		return 
	}

	propertiesMu.Lock()
	 = getPropertiesLocked()
	propertiesMu.Unlock()
	return 
}

type (
	oneofFuncsIface interface {
		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
	}
	oneofWrappersIface interface {
		XXX_OneofWrappers() []interface{}
	}
)

// getPropertiesLocked requires that propertiesMu is held.
func getPropertiesLocked( reflect.Type) *StructProperties {
	if ,  := propertiesMap[];  {
		return 
	}

	 := new(StructProperties)
	// in case of recursive protos, fill this in now.
	propertiesMap[] = 

	// build properties
	.Prop = make([]*Properties, .NumField())
	.order = make([]int, .NumField())

	 := false
	for  := 0;  < .NumField(); ++ {
		 := .Field()
		 := new(Properties)
		 := .Name
		.init(.Type, , .Tag.Get("protobuf"), &, false)

		 := .Tag.Get("protobuf_oneof") // special case
		if  != "" {
			 = true
			// Oneof fields don't use the traditional protobuf tag.
			.OrigName = 
		}
		.Prop[] = 
		.order[] = 
		if debug {
			print(, " ", .Name, " ", .String(), " ")
			if .Tag > 0 {
				print(.String())
			}
			print("\n")
		}
	}

	// Re-order prop.order.
	sort.Sort()

	if  {
		var  []interface{}
		switch m := reflect.Zero(reflect.PtrTo()).Interface().(type) {
		case oneofFuncsIface:
			_, _, _,  = .XXX_OneofFuncs()
		case oneofWrappersIface:
			 = .XXX_OneofWrappers()
		}
		if len() > 0 {
			// Interpret oneof metadata.
			.OneofTypes = make(map[string]*OneofProperties)
			for ,  := range  {
				 := &OneofProperties{
					Type: reflect.ValueOf().Type(), // *T
					Prop: new(Properties),
				}
				 := .Type.Elem().Field(0)
				.Prop.Name = .Name
				.Prop.Parse(.Tag.Get("protobuf"))
				// There will be exactly one interface field that
				// this new value is assignable to.
				for  := 0;  < .NumField(); ++ {
					 := .Field()
					if .Type.Kind() != reflect.Interface {
						continue
					}
					if !.Type.AssignableTo(.Type) {
						continue
					}
					.Field = 
					break
				}
				.OneofTypes[.Prop.OrigName] = 
			}
		}
	}

	// build required counts
	// build tags
	 := 0
	.decoderOrigNames = make(map[string]int)
	for ,  := range .Prop {
		if strings.HasPrefix(.Name, "XXX_") {
			// Internal fields should not appear in tags/origNames maps.
			// They are handled specially when encoding and decoding.
			continue
		}
		if .Required {
			++
		}
		.decoderTags.put(.Tag, )
		.decoderOrigNames[.OrigName] = 
	}
	.reqCount = 

	return 
}

// A global registry of enum types.
// The generated code will register the generated maps by calling RegisterEnum.

var enumValueMaps = make(map[string]map[string]int32)
var enumStringMaps = make(map[string]map[int32]string)

// RegisterEnum is called from the generated code to install the enum descriptor
// maps into the global table to aid parsing text format protocol buffers.
func ( string,  map[int32]string,  map[string]int32) {
	if ,  := enumValueMaps[];  {
		panic("proto: duplicate enum registered: " + )
	}
	enumValueMaps[] = 
	if ,  := enumStringMaps[];  {
		panic("proto: duplicate enum registered: " + )
	}
	enumStringMaps[] = 
}

// EnumValueMap returns the mapping from names to integers of the
// enum type enumType, or a nil if not found.
func ( string) map[string]int32 {
	return enumValueMaps[]
}

// A registry of all linked message types.
// The string is a fully-qualified proto name ("pkg.Message").
var (
	protoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers
	protoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types
	revProtoTypes  = make(map[reflect.Type]string)
)

// RegisterType is called from generated code and maps from the fully qualified
// proto name to the type (pointer to struct) of the protocol buffer.
func ( Message,  string) {
	if ,  := protoTypedNils[];  {
		// TODO: Some day, make this a panic.
		log.Printf("proto: duplicate proto type registered: %s", )
		return
	}
	 := reflect.TypeOf()
	if  := reflect.ValueOf(); .Kind() == reflect.Ptr && .Pointer() == 0 {
		// Generated code always calls RegisterType with nil x.
		// This check is just for extra safety.
		protoTypedNils[] = 
	} else {
		protoTypedNils[] = reflect.Zero().Interface().(Message)
	}
	revProtoTypes[] = 
}

// RegisterMapType is called from generated code and maps from the fully qualified
// proto name to the native map type of the proto map definition.
func ( interface{},  string) {
	if reflect.TypeOf().Kind() != reflect.Map {
		panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", , ))
	}
	if ,  := protoMapTypes[];  {
		log.Printf("proto: duplicate proto type registered: %s", )
		return
	}
	 := reflect.TypeOf()
	protoMapTypes[] = 
	revProtoTypes[] = 
}

// MessageName returns the fully-qualified proto name for the given message type.
func ( Message) string {
	type  interface {
		() string
	}
	if ,  := .();  {
		return .()
	}
	return revProtoTypes[reflect.TypeOf()]
}

// MessageType returns the message type (pointer to struct) for a named message.
// The type is not guaranteed to implement proto.Message if the name refers to a
// map entry.
func ( string) reflect.Type {
	if ,  := protoTypedNils[];  {
		return reflect.TypeOf()
	}
	return protoMapTypes[]
}

// A registry of all linked proto files.
var (
	protoFiles = make(map[string][]byte) // file name => fileDescriptor
)

// RegisterFile is called from generated code and maps from the
// full file name of a .proto file to its compressed FileDescriptorProto.
func ( string,  []byte) {
	protoFiles[] = 
}

// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.
func ( string) []byte { return protoFiles[] }