// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package impl

import (
	
	

	
)

type mapConverter struct {
	goType           reflect.Type // map[K]V
	keyConv, valConv Converter
}

func ( reflect.Type,  protoreflect.FieldDescriptor) *mapConverter {
	if .Kind() != reflect.Map {
		panic(fmt.Sprintf("invalid Go type %v for field %v", , .FullName()))
	}
	return &mapConverter{
		goType:  ,
		keyConv: newSingularConverter(.Key(), .MapKey()),
		valConv: newSingularConverter(.Elem(), .MapValue()),
	}
}

func ( *mapConverter) ( reflect.Value) protoreflect.Value {
	if .Type() != .goType {
		panic(fmt.Sprintf("invalid type: got %v, want %v", .Type(), .goType))
	}
	return protoreflect.ValueOfMap(&mapReflect{, .keyConv, .valConv})
}

func ( *mapConverter) ( protoreflect.Value) reflect.Value {
	return .Map().(*mapReflect).v
}

func ( *mapConverter) ( protoreflect.Value) bool {
	,  := .Interface().(*mapReflect)
	if ! {
		return false
	}
	return .v.Type() == .goType
}

func ( *mapConverter) ( reflect.Value) bool {
	return .IsValid() && .Type() == .goType
}

func ( *mapConverter) () protoreflect.Value {
	return .PBValueOf(reflect.MakeMap(.goType))
}

func ( *mapConverter) () protoreflect.Value {
	return .PBValueOf(reflect.Zero(.goType))
}

type mapReflect struct {
	v       reflect.Value // map[K]V
	keyConv Converter
	valConv Converter
}

func ( *mapReflect) () int {
	return .v.Len()
}
func ( *mapReflect) ( protoreflect.MapKey) bool {
	 := .keyConv.GoValueOf(.Value())
	 := .v.MapIndex()
	return .IsValid()
}
func ( *mapReflect) ( protoreflect.MapKey) protoreflect.Value {
	 := .keyConv.GoValueOf(.Value())
	 := .v.MapIndex()
	if !.IsValid() {
		return protoreflect.Value{}
	}
	return .valConv.PBValueOf()
}
func ( *mapReflect) ( protoreflect.MapKey,  protoreflect.Value) {
	 := .keyConv.GoValueOf(.Value())
	 := .valConv.GoValueOf()
	.v.SetMapIndex(, )
}
func ( *mapReflect) ( protoreflect.MapKey) {
	 := .keyConv.GoValueOf(.Value())
	.v.SetMapIndex(, reflect.Value{})
}
func ( *mapReflect) ( protoreflect.MapKey) protoreflect.Value {
	if ,  := .valConv.(*messageConverter); ! {
		panic("invalid Mutable on map with non-message value type")
	}
	 := .Get()
	if !.IsValid() {
		 = .NewValue()
		.Set(, )
	}
	return 
}
func ( *mapReflect) ( func(protoreflect.MapKey, protoreflect.Value) bool) {
	 := mapRange(.v)
	for .Next() {
		 := .keyConv.PBValueOf(.Key()).MapKey()
		 := .valConv.PBValueOf(.Value())
		if !(, ) {
			return
		}
	}
}
func ( *mapReflect) () protoreflect.Value {
	return .valConv.New()
}
func ( *mapReflect) () bool {
	return !.v.IsNil()
}
func ( *mapReflect) () interface{} {
	return .v.Interface()
}