// Copyright 2019 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 dynamicpb creates protocol buffer messages using runtime type information.
package dynamicpb

import (
	"math"
	"reflect"

	"google.golang.org/protobuf/internal/errors"
	pref "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
)

// A Message is a dynamically constructed protocol buffer message.
//
// Message implements the proto.Message interface, and may be used with all
// standard proto package functions such as Marshal, Unmarshal, and so forth.
//
// Message also implements the protoreflect.Message interface. See the protoreflect
// package documentation for that interface for how to get and set fields and
// otherwise interact with the contents of a Message.
//
// Reflection API functions which construct messages, such as NewField,
// return new dynamic messages of the appropriate type. Functions which take
// messages, such as Set for a message-value field, will accept any message
// with a compatible type.
//
// Operations which modify a Message are not safe for concurrent use.
type Message struct {
	typ     messageType
	known   map[pref.FieldNumber]pref.Value
	ext     map[pref.FieldNumber]pref.FieldDescriptor
	unknown pref.RawFields
}

// NewMessage creates a new message with the provided descriptor.
func NewMessage(desc pref.MessageDescriptor) *Message {
	return &Message{
		typ:   messageType{desc},
		known: make(map[pref.FieldNumber]pref.Value),
		ext:   make(map[pref.FieldNumber]pref.FieldDescriptor),
	}
}

// ProtoReflect implements the protoreflect.ProtoMessage interface.
func (m *Message) ProtoReflect() pref.Message {
	return m
}

// String returns a string representation of a message.
func (m *Message) String() string {
	return protoimpl.X.MessageStringOf(m)
}

// Descriptor returns the message descriptor.
func (m *Message) Descriptor() pref.MessageDescriptor {
	return m.typ.desc
}

// Type returns the message type.
func (m *Message) Type() pref.MessageType {
	return m.typ
}

// New returns a newly allocated empty message with the same descriptor.
// See protoreflect.Message for details.
func (m *Message) New() pref.Message {
	return m.Type().New()
}

// Interface returns the message.
// See protoreflect.Message for details.
func (m *Message) Interface() pref.ProtoMessage {
	return m
}

// Range visits every populated field in undefined order.
// See protoreflect.Message for details.
func (m *Message) Range(f func(pref.FieldDescriptor, pref.Value) bool) {
	for num, v := range m.known {
		fd := m.ext[num]
		if fd == nil {
			fd = m.Descriptor().Fields().ByNumber(num)
			if !isSet(fd, v) {
				continue
			}
		}
		if !f(fd, v) {
			return
		}
	}
}

// Range reports whether a field is populated.
// See protoreflect.Message for details.
func (m *Message) Has(fd pref.FieldDescriptor) bool {
	m.checkField(fd)
	if fd.IsExtension() {
		return m.ext[fd.Number()] == fd
	}
	v, ok := m.known[fd.Number()]
	if !ok {
		return false
	}
	return isSet(fd, v)
}

// Clear clears a field.
// See protoreflect.Message for details.
func (m *Message) Clear(fd pref.FieldDescriptor) {
	m.checkField(fd)
	num := fd.Number()
	delete(m.known, num)
	delete(m.ext, num)
}

// Get returns the value of a field.
// See protoreflect.Message for details.
func (m *Message) Get(fd pref.FieldDescriptor) pref.Value {
	m.checkField(fd)
	num := fd.Number()
	if fd.IsExtension() {
		if fd != m.ext[num] {
			return fd.(pref.ExtensionTypeDescriptor).Type().Zero()
		}
		return m.known[num]
	}
	if v, ok := m.known[num]; ok {
		return v
	}
	switch {
	case fd.IsMap():
		return pref.ValueOf(&dynamicMap{desc: fd})
	case fd.IsList():
		return pref.ValueOf(emptyList{desc: fd})
	case fd.Message() != nil:
		return pref.ValueOf(&Message{typ: messageType{fd.Message()}})
	case fd.Kind() == pref.BytesKind:
		return pref.ValueOf(append([]byte(nil), fd.Default().Bytes()...))
	default:
		return fd.Default()
	}
}

// Mutable returns a mutable reference to a repeated, map, or message field.
// See protoreflect.Message for details.
func (m *Message) Mutable(fd pref.FieldDescriptor) pref.Value {
	m.checkField(fd)
	if !fd.IsMap() && !fd.IsList() && fd.Message() == nil {
		panic(errors.New("%v: getting mutable reference to non-composite type", fd.FullName()))
	}
	if m.known == nil {
		panic(errors.New("%v: modification of read-only message", fd.FullName()))
	}
	num := fd.Number()
	if fd.IsExtension() {
		if fd != m.ext[num] {
			m.ext[num] = fd
			m.known[num] = fd.(pref.ExtensionTypeDescriptor).Type().New()
		}
		return m.known[num]
	}
	if v, ok := m.known[num]; ok {
		return v
	}
	m.clearOtherOneofFields(fd)
	m.known[num] = m.NewField(fd)
	if fd.IsExtension() {
		m.ext[num] = fd
	}
	return m.known[num]
}

// Set stores a value in a field.
// See protoreflect.Message for details.
func (m *Message) Set(fd pref.FieldDescriptor, v pref.Value) {
	m.checkField(fd)
	if m.known == nil {
		panic(errors.New("%v: modification of read-only message", fd.FullName()))
	}
	if fd.IsExtension() {
		if !fd.(pref.ExtensionTypeDescriptor).Type().IsValidValue(v) {
			panic(errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface()))
		}
		m.ext[fd.Number()] = fd
	} else {
		typecheck(fd, v)
	}
	m.clearOtherOneofFields(fd)
	m.known[fd.Number()] = v
}

func (m *Message) clearOtherOneofFields(fd pref.FieldDescriptor) {
	od := fd.ContainingOneof()
	if od == nil {
		return
	}
	num := fd.Number()
	for i := 0; i < od.Fields().Len(); i++ {
		if n := od.Fields().Get(i).Number(); n != num {
			delete(m.known, n)
		}
	}
}

// NewMessage returns a newly-allocated message assignable to a field.
// See protoreflect.Message for details.
func (m *Message) NewMessage(fd pref.FieldDescriptor) pref.Message {
	m.checkField(fd)
	md := fd.Message()
	if fd.Cardinality() == pref.Repeated || md == nil {
		panic(errors.New("%v: field is not of non-repeated message type", fd.FullName()))
	}
	return NewMessage(md).ProtoReflect()
}

// NewField returns a new value for assignable to the field of a given descriptor.
// See protoreflect.Message for details.
func (m *Message) NewField(fd pref.FieldDescriptor) pref.Value {
	m.checkField(fd)
	switch {
	case fd.IsExtension():
		return fd.(pref.ExtensionTypeDescriptor).Type().New()
	case fd.IsMap():
		return pref.ValueOf(&dynamicMap{
			desc: fd,
			mapv: make(map[interface{}]pref.Value),
		})
	case fd.IsList():
		return pref.ValueOf(&dynamicList{desc: fd})
	case fd.Message() != nil:
		return pref.ValueOf(NewMessage(fd.Message()).ProtoReflect())
	default:
		return fd.Default()
	}
}

// WhichOneof reports which field in a oneof is populated, returning nil if none are populated.
// See protoreflect.Message for details.
func (m *Message) WhichOneof(od pref.OneofDescriptor) pref.FieldDescriptor {
	for i := 0; i < od.Fields().Len(); i++ {
		fd := od.Fields().Get(i)
		if m.Has(fd) {
			return fd
		}
	}
	return nil
}

// GetUnknown returns the raw unknown fields.
// See protoreflect.Message for details.
func (m *Message) GetUnknown() pref.RawFields {
	return m.unknown
}

// SetUnknown sets the raw unknown fields.
// See protoreflect.Message for details.
func (m *Message) SetUnknown(r pref.RawFields) {
	if m.known == nil {
		panic(errors.New("%v: modification of read-only message", m.typ.desc.FullName()))
	}
	m.unknown = r
}

func (m *Message) checkField(fd pref.FieldDescriptor) {
	if fd.IsExtension() && fd.ContainingMessage().FullName() == m.Descriptor().FullName() {
		if _, ok := fd.(pref.ExtensionTypeDescriptor); !ok {
			panic(errors.New("%v: extension field descriptor does not implement ExtensionTypeDescriptor", fd.FullName()))
		}
		return
	}
	if fd.Parent() == m.Descriptor() {
		return
	}
	fields := m.Descriptor().Fields()
	index := fd.Index()
	if index >= fields.Len() || fields.Get(index) != fd {
		panic(errors.New("%v: field descriptor does not belong to this message", fd.FullName()))
	}
}

type messageType struct {
	desc pref.MessageDescriptor
}

// NewMessageType creates a new MessageType with the provided descriptor.
//
// MessageTypes created by this package are equal if their descriptors are equal.
// That is, if md1 == md2, then NewMessageType(md1) == NewMessageType(md2).
func NewMessageType(desc pref.MessageDescriptor) pref.MessageType {
	return messageType{desc}
}

func (mt messageType) New() pref.Message                  { return NewMessage(mt.desc) }
func (mt messageType) Zero() pref.Message                 { return NewMessage(mt.desc) }
func (mt messageType) GoType() reflect.Type               { return reflect.TypeOf((*Message)(nil)) }
func (mt messageType) Descriptor() pref.MessageDescriptor { return mt.desc }

type emptyList struct {
	desc pref.FieldDescriptor
}

func (x emptyList) Len() int                { return 0 }
func (x emptyList) Get(n int) pref.Value    { panic(errors.New("out of range")) }
func (x emptyList) Set(n int, v pref.Value) { panic(errors.New("modification of immutable list")) }
func (x emptyList) Append(v pref.Value)     { panic(errors.New("modification of immutable list")) }
func (x emptyList) Truncate(n int)          { panic(errors.New("modification of immutable list")) }
func (x emptyList) NewMessage() pref.Message {
	md := x.desc.Message()
	if md == nil {
		panic(errors.New("list is not of message type"))
	}
	return NewMessage(md).ProtoReflect()
}
func (x emptyList) NewElement() pref.Value {
	return newListEntry(x.desc)
}

type dynamicList struct {
	desc pref.FieldDescriptor
	list []pref.Value
}

func (x *dynamicList) Len() int {
	return len(x.list)
}

func (x *dynamicList) Get(n int) pref.Value {
	return x.list[n]
}

func (x *dynamicList) Set(n int, v pref.Value) {
	typecheckSingular(x.desc, v)
	x.list[n] = v
}

func (x *dynamicList) Append(v pref.Value) {
	typecheckSingular(x.desc, v)
	x.list = append(x.list, v)
}

func (x *dynamicList) Truncate(n int) {
	// Zero truncated elements to avoid keeping data live.
	for i := n; i < len(x.list); i++ {
		x.list[i] = pref.Value{}
	}
	x.list = x.list[:n]
}

func (x *dynamicList) NewMessage() pref.Message {
	md := x.desc.Message()
	if md == nil {
		panic(errors.New("list is not of message type"))
	}
	return NewMessage(md).ProtoReflect()
}

func (x *dynamicList) NewElement() pref.Value {
	return newListEntry(x.desc)
}

type dynamicMap struct {
	desc pref.FieldDescriptor
	mapv map[interface{}]pref.Value
}

func (x *dynamicMap) Get(k pref.MapKey) pref.Value { return x.mapv[k.Interface()] }
func (x *dynamicMap) Set(k pref.MapKey, v pref.Value) {
	typecheckSingular(x.desc.MapKey(), k.Value())
	typecheckSingular(x.desc.MapValue(), v)
	x.mapv[k.Interface()] = v
}
func (x *dynamicMap) Has(k pref.MapKey) bool { return x.Get(k).IsValid() }
func (x *dynamicMap) Clear(k pref.MapKey)    { delete(x.mapv, k.Interface()) }
func (x *dynamicMap) Len() int               { return len(x.mapv) }
func (x *dynamicMap) NewMessage() pref.Message {
	md := x.desc.MapValue().Message()
	if md == nil {
		panic(errors.New("map value is not of message type"))
	}
	return NewMessage(md).ProtoReflect()
}
func (x *dynamicMap) NewValue() pref.Value {
	if md := x.desc.MapValue().Message(); md != nil {
		return pref.ValueOf(NewMessage(md).ProtoReflect())
	}
	return x.desc.MapValue().Default()
}

func (x *dynamicMap) Range(f func(pref.MapKey, pref.Value) bool) {
	for k, v := range x.mapv {
		if !f(pref.ValueOf(k).MapKey(), v) {
			return
		}
	}
}

func isSet(fd pref.FieldDescriptor, v pref.Value) bool {
	switch {
	case fd.IsMap():
		return v.Map().Len() > 0
	case fd.IsList():
		return v.List().Len() > 0
	case fd.ContainingOneof() != nil:
		return true
	case fd.Syntax() == pref.Proto3:
		switch fd.Kind() {
		case pref.BoolKind:
			return v.Bool()
		case pref.EnumKind:
			return v.Enum() != 0
		case pref.Int32Kind, pref.Sint32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed32Kind, pref.Sfixed64Kind:
			return v.Int() != 0
		case pref.Uint32Kind, pref.Uint64Kind, pref.Fixed32Kind, pref.Fixed64Kind:
			return v.Uint() != 0
		case pref.FloatKind, pref.DoubleKind:
			return v.Float() != 0 || math.Signbit(v.Float())
		case pref.StringKind:
			return v.String() != ""
		case pref.BytesKind:
			return len(v.Bytes()) > 0
		}
	}
	return true
}

func typecheck(fd pref.FieldDescriptor, v pref.Value) {
	if err := typeIsValid(fd, v); err != nil {
		panic(err)
	}
}

func typeIsValid(fd pref.FieldDescriptor, v pref.Value) error {
	switch {
	case fd.IsMap():
		if mapv, ok := v.Interface().(*dynamicMap); !ok || mapv.desc != fd {
			return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
		}
		return nil
	case fd.IsList():
		switch list := v.Interface().(type) {
		case *dynamicList:
			if list.desc == fd {
				return nil
			}
		case emptyList:
			if list.desc == fd {
				return nil
			}
		}
		return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
	default:
		return singularTypeIsValid(fd, v)
	}
}

func typecheckSingular(fd pref.FieldDescriptor, v pref.Value) {
	if err := singularTypeIsValid(fd, v); err != nil {
		panic(err)
	}
}

func singularTypeIsValid(fd pref.FieldDescriptor, v pref.Value) error {
	vi := v.Interface()
	var ok bool
	switch fd.Kind() {
	case pref.BoolKind:
		_, ok = vi.(bool)
	case pref.EnumKind:
		// We could check against the valid set of enum values, but do not.
		_, ok = vi.(pref.EnumNumber)
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
		_, ok = vi.(int32)
	case pref.Uint32Kind, pref.Fixed32Kind:
		_, ok = vi.(uint32)
	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		_, ok = vi.(int64)
	case pref.Uint64Kind, pref.Fixed64Kind:
		_, ok = vi.(uint64)
	case pref.FloatKind:
		_, ok = vi.(float32)
	case pref.DoubleKind:
		_, ok = vi.(float64)
	case pref.StringKind:
		_, ok = vi.(string)
	case pref.BytesKind:
		_, ok = vi.([]byte)
	case pref.MessageKind, pref.GroupKind:
		var m pref.Message
		m, ok = vi.(pref.Message)
		if ok && m.Descriptor().FullName() != fd.Message().FullName() {
			return errors.New("%v: assigning invalid message type %v", fd.FullName(), m.Descriptor().FullName())
		}
		if dm, ok := vi.(*Message); ok && dm.known == nil {
			return errors.New("%v: assigning invalid zero-value message", fd.FullName())
		}
	}
	if !ok {
		return errors.New("%v: assigning invalid type %T", fd.FullName(), v.Interface())
	}
	return nil
}

func newListEntry(fd pref.FieldDescriptor) pref.Value {
	switch fd.Kind() {
	case pref.BoolKind:
		return pref.ValueOf(false)
	case pref.EnumKind:
		return pref.ValueOf(fd.Enum().Values().Get(0).Number())
	case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind:
		return pref.ValueOf(int32(0))
	case pref.Uint32Kind, pref.Fixed32Kind:
		return pref.ValueOf(uint32(0))
	case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind:
		return pref.ValueOf(int64(0))
	case pref.Uint64Kind, pref.Fixed64Kind:
		return pref.ValueOf(uint64(0))
	case pref.FloatKind:
		return pref.ValueOf(float32(0))
	case pref.DoubleKind:
		return pref.ValueOf(float64(0))
	case pref.StringKind:
		return pref.ValueOf("")
	case pref.BytesKind:
		return pref.ValueOf(([]byte)(nil))
	case pref.MessageKind, pref.GroupKind:
		return pref.ValueOf(NewMessage(fd.Message()).ProtoReflect())
	}
	panic(errors.New("%v: unknown kind %v", fd.FullName(), fd.Kind()))
}

// extensionType is a dynamic protoreflect.ExtensionType.
type extensionType struct {
	desc extensionTypeDescriptor
}

// NewExtensionType creates a new ExtensionType with the provided descriptor.
//
// Dynamic ExtensionTypes with the same descriptor compare as equal. That is,
// if xd1 == xd2, then NewExtensionType(xd1) == NewExtensionType(xd2).
//
// The InterfaceOf and ValueOf methods of the extension type are defined as:
//
//	func (xt extensionType) ValueOf(iv interface{}) protoreflect.Value {
//		return protoreflect.ValueOf(iv)
//	}
//
//	func (xt extensionType) InterfaceOf(v protoreflect.Value) interface{} {
//		return v.Interface()
//	}
//
// The Go type used by the proto.GetExtension and proto.SetExtension functions
// is determined by these methods, and is therefore equivalent to the Go type
// used to represent a protoreflect.Value. See the protoreflect.Value
// documentation for more details.
func NewExtensionType(desc pref.ExtensionDescriptor) pref.ExtensionType {
	if xt, ok := desc.(pref.ExtensionTypeDescriptor); ok {
		desc = xt.Descriptor()
	}
	return extensionType{extensionTypeDescriptor{desc}}
}

func (xt extensionType) New() pref.Value {
	switch {
	case xt.desc.IsMap():
		return pref.ValueOf(&dynamicMap{
			desc: xt.desc,
			mapv: make(map[interface{}]pref.Value),
		})
	case xt.desc.IsList():
		return pref.ValueOf(&dynamicList{desc: xt.desc})
	case xt.desc.Message() != nil:
		return pref.ValueOf(NewMessage(xt.desc.Message()))
	default:
		return xt.desc.Default()
	}
}

func (xt extensionType) Zero() pref.Value {
	switch {
	case xt.desc.IsMap():
		return pref.ValueOf(&dynamicMap{desc: xt.desc})
	case xt.desc.Cardinality() == pref.Repeated:
		return pref.ValueOf(emptyList{desc: xt.desc})
	case xt.desc.Message() != nil:
		return pref.ValueOf(&Message{typ: messageType{xt.desc.Message()}})
	default:
		return xt.desc.Default()
	}
}

func (xt extensionType) GoType() reflect.Type {
	return reflect.TypeOf(xt.InterfaceOf(xt.New()))
}

func (xt extensionType) TypeDescriptor() pref.ExtensionTypeDescriptor {
	return xt.desc
}

func (xt extensionType) ValueOf(iv interface{}) pref.Value {
	v := pref.ValueOf(iv)
	typecheck(xt.desc, v)
	return v
}

func (xt extensionType) InterfaceOf(v pref.Value) interface{} {
	typecheck(xt.desc, v)
	return v.Interface()
}

func (xt extensionType) IsValidInterface(iv interface{}) bool {
	return typeIsValid(xt.desc, pref.ValueOf(iv)) == nil
}

func (xt extensionType) IsValidValue(v pref.Value) bool {
	return typeIsValid(xt.desc, v) == nil
}

type extensionTypeDescriptor struct {
	pref.ExtensionDescriptor
}

func (xt extensionTypeDescriptor) Type() pref.ExtensionType {
	return extensionType{xt}
}

func (xt extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor {
	return xt.ExtensionDescriptor
}
