// Protocol Buffers for Go with Gadgets
//
// Copyright (c) 2013, The GoGo Authors. All rights reserved.
// http://github.com/gogo/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.
//
// 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

import (
	
	
	
	
	
	
	
	
)

type extensionsBytes interface {
	Message
	ExtensionRangeArray() []ExtensionRange
	GetExtensions() *[]byte
}

type slowExtensionAdapter struct {
	extensionsBytes
}

func ( slowExtensionAdapter) () map[int32]Extension {
	panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.")
}

func ( slowExtensionAdapter) () (map[int32]Extension, sync.Locker) {
	 := .GetExtensions()
	,  := BytesToExtensionsMap(*)
	if  != nil {
		panic()
	}
	return , notLocker{}
}

func ( Message,  *ExtensionDesc,  bool) bool {
	if reflect.ValueOf().IsNil() {
		return 
	}
	,  := GetExtension(, )
	if  != nil {
		return 
	}
	if  == nil {
		return 
	}
	if .(*bool) == nil {
		return 
	}
	return *(.(*bool))
}

func ( *Extension) ( *Extension) bool {
	if  := .Encode();  != nil {
		return false
	}
	if  := .Encode();  != nil {
		return false
	}
	return bytes.Equal(.enc, .enc)
}

func ( *Extension) ( *Extension) int {
	if  := .Encode();  != nil {
		return 1
	}
	if  := .Encode();  != nil {
		return -1
	}
	return bytes.Compare(.enc, .enc)
}

func ( extendableProto) ( int) {
	 := getMarshalInfo(reflect.TypeOf())
	return .sizeV1Extensions(.extensionsWrite())
}

type sortableMapElem struct {
	field int32
	ext   Extension
}

func newSortableExtensionsFromMap( map[int32]Extension) sortableExtensions {
	 := make(sortableExtensions, 0, len())
	for ,  := range  {
		 = append(, &sortableMapElem{field: , ext: })
	}
	return 
}

type sortableExtensions []*sortableMapElem

func ( sortableExtensions) () int { return len() }

func ( sortableExtensions) (,  int) { [], [] = [], [] }

func ( sortableExtensions) (,  int) bool { return [].field < [].field }

func ( sortableExtensions) () string {
	sort.Sort()
	 := make([]string, len())
	for  := range  {
		[] = fmt.Sprintf("%d: %v", [].field, [].ext)
	}
	return "map[" + strings.Join(, ",") + "]"
}

func ( extendableProto) string {
	return StringFromExtensionsMap(.extensionsWrite())
}

func ( map[int32]Extension) string {
	return newSortableExtensionsFromMap().String()
}

func ( []byte) string {
	,  := BytesToExtensionsMap()
	if  != nil {
		panic()
	}
	return StringFromExtensionsMap()
}

func ( extendableProto,  []byte) ( int,  error) {
	return EncodeExtensionMap(.extensionsWrite(), )
}

func ( extendableProto,  []byte) ( int,  error) {
	return EncodeExtensionMapBackwards(.extensionsWrite(), )
}

func ( map[int32]Extension,  []byte) ( int,  error) {
	 := 0
	for ,  := range  {
		if  := .Encode();  != nil {
			return 0, 
		}
		 := copy([:], .enc)
		if  != len(.enc) {
			return 0, io.ErrShortBuffer
		}
		 += 
	}
	return , nil
}

func ( map[int32]Extension,  []byte) ( int,  error) {
	 := 0
	 := len()
	for ,  := range  {
		if  := .Encode();  != nil {
			return 0, 
		}
		 := copy([-len(.enc):], .enc)
		if  != len(.enc) {
			return 0, io.ErrShortBuffer
		}
		 -= 
		 += 
	}
	return , nil
}

func ( map[int32]Extension,  int32) ([]byte, error) {
	 := []
	if  := .Encode();  != nil {
		return nil, 
	}
	return .enc, nil
}

func size( []byte,  int) (int, error) {
	switch  {
	case WireVarint:
		,  := DecodeVarint()
		return , nil
	case WireFixed64:
		return 8, nil
	case WireBytes:
		,  := DecodeVarint()
		return int() + , nil
	case WireFixed32:
		return 4, nil
	case WireStartGroup:
		 := 0
		for {
			,  := DecodeVarint([:])
			 := int( & 0x7)
			 += 
			if  == WireEndGroup {
				return , nil
			}
			,  := ([:], )
			if  != nil {
				return 0, 
			}
			 += 
		}
	}
	return 0, fmt.Errorf("proto: can't get size for unknown wire type %d", )
}

func ( []byte) (map[int32]Extension, error) {
	 := make(map[int32]Extension)
	 := 0
	for  < len() {
		,  := DecodeVarint([:])
		if  <= 0 {
			return nil, fmt.Errorf("unable to decode varint")
		}
		 := int32( >> 3)
		 := int( & 0x7)
		,  := size([+:], )
		if  != nil {
			return nil, 
		}
		 :=  + int() + 
		[int32()] = Extension{enc: [:]}
		 = 
	}
	return , nil
}

func ( []byte) Extension {
	 := Extension{enc: make([]byte, len())}
	copy(.enc, )
	return 
}

func ( Message,  int32,  []byte) {
	if ,  := .(extensionsBytes);  {
		 := .GetExtensions()
		* = append(*, ...)
		return
	}
	if ,  := .(extendableProto);  {
		 := .extensionsWrite()
		 := [int32()] // may be missing
		.enc = append(.enc, ...)
		[int32()] = 
	}
}

func encodeExtension( *ExtensionDesc,  interface{}) ([]byte, error) {
	 := getMarshalInfo(reflect.TypeOf(.ExtendedType))
	 := .getExtElemInfo()
	 := 
	 := toAddrPointer(&, .isptr)
	 := .sizer(, SizeVarint(.wiretag))
	 := make([]byte, 0, )
	return .marshaler(, , .wiretag, false)
}

func decodeExtensionFromBytes( *ExtensionDesc,  []byte) (interface{}, error) {
	 := 0
	for  < len() {
		,  := DecodeVarint(()[:])
		 := int32( >> 3)
		 := int( & 0x7)
		if + > len() {
			return nil, fmt.Errorf("unable to decode extension")
		}
		,  := size(()[+:], )
		if  != nil {
			return nil, 
		}
		if int32() == .Field {
			if ++ > len() {
				return nil, fmt.Errorf("unable to decode extension")
			}
			,  := decodeExtension(()[:++], )
			if  != nil {
				return nil, 
			}
			return , nil
		}
		 +=  + 
	}
	return defaultExtensionValue()
}

func ( *Extension) () error {
	if .enc == nil {
		var  error
		.enc,  = encodeExtension(.desc, .value)
		if  != nil {
			return 
		}
	}
	return nil
}

func ( Extension) () string {
	if  := .Encode();  != nil {
		return fmt.Sprintf("error encoding extension: %v", )
	}
	return fmt.Sprintf("proto.NewExtension(%#v)", .enc)
}

func ( Message,  int32,  interface{}) error {
	 := reflect.TypeOf().Elem()
	,  := extensionMaps[]
	if ! {
		return fmt.Errorf("proto: bad extended type; %s is not extendable", .String())
	}
	,  := []
	if ! {
		return errors.New("proto: bad extension number; not in declared ranges")
	}
	return SetExtension(, , )
}

func ( Message,  int32) (interface{}, error) {
	 := reflect.TypeOf().Elem()
	,  := extensionMaps[]
	if ! {
		return nil, fmt.Errorf("proto: bad extended type; %s is not extendable", .String())
	}
	,  := []
	if ! {
		return nil, fmt.Errorf("unregistered field number %d", )
	}
	return GetExtension(, )
}

func ( map[int32]Extension) XXX_InternalExtensions {
	 := &XXX_InternalExtensions{
		p: new(struct {
			           sync.Mutex
			 map[int32]Extension
		}),
	}
	.p.extensionMap = 
	return *
}

func ( Message) map[int32]Extension {
	 := .(extendableProto)
	return .extensionsWrite()
}

func deleteExtension( extensionsBytes,  int32,  int) int {
	 := .GetExtensions()
	for  < len(*) {
		,  := DecodeVarint((*)[:])
		 := int32( >> 3)
		 := int( & 0x7)
		,  := size((*)[+:], )
		if  != nil {
			panic()
		}
		 :=  +  + 
		if  ==  {
			* = append((*)[:], (*)[:]...)
			return 
		}
		 = 
	}
	return -1
}