// 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 (
	"reflect"
	"strconv"

	"google.golang.org/protobuf/encoding/prototext"
	pref "google.golang.org/protobuf/reflect/protoreflect"
	piface "google.golang.org/protobuf/runtime/protoiface"
)

// Export is a zero-length named type that exists only to export a set of
// functions that we do not want to appear in godoc.
type Export struct{}

// enum is any enum type generated by protoc-gen-go
// and must be a named int32 type.
type enum = interface{}

// EnumOf returns the protoreflect.Enum interface over e.
func (Export) EnumOf(e enum) pref.Enum {
	if ev, ok := e.(pref.Enum); ok {
		return ev
	}
	return legacyWrapEnum(reflect.ValueOf(e))
}

// EnumTypeOf returns the protoreflect.EnumType for e.
func (Export) EnumTypeOf(e enum) pref.EnumType {
	if ev, ok := e.(pref.Enum); ok {
		return ev.Type()
	}
	return legacyLoadEnumType(reflect.TypeOf(e))
}

// EnumDescriptorOf returns the protoreflect.EnumDescriptor for e.
func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor {
	if ev, ok := e.(pref.Enum); ok {
		return ev.Descriptor()
	}
	return LegacyLoadEnumDesc(reflect.TypeOf(e))
}

// EnumStringOf returns the enum value as a string, either as the name if
// the number is resolvable, or the number formatted as a string.
func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string {
	ev := ed.Values().ByNumber(n)
	if ev != nil {
		return string(ev.Name())
	}
	return strconv.Itoa(int(n))
}

// message is any message type generated by protoc-gen-go
// and must be a pointer to a named struct type.
type message = interface{}

// MessageOf returns the protoreflect.Message interface over m.
func (Export) MessageOf(m message) pref.Message {
	if mv, ok := m.(pref.ProtoMessage); ok {
		return mv.ProtoReflect()
	}
	return legacyWrapMessage(reflect.ValueOf(m)).ProtoReflect()
}

// MessageTypeOf returns the protoreflect.MessageType for m.
func (Export) MessageTypeOf(m message) pref.MessageType {
	if mv, ok := m.(pref.ProtoMessage); ok {
		return mv.ProtoReflect().Type()
	}
	return legacyLoadMessageInfo(reflect.TypeOf(m))
}

// MessageDescriptorOf returns the protoreflect.MessageDescriptor for m.
func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor {
	if mv, ok := m.(pref.ProtoMessage); ok {
		return mv.ProtoReflect().Descriptor()
	}
	return LegacyLoadMessageDesc(reflect.TypeOf(m))
}

// MessageStringOf returns the message value as a string,
// which is the message serialized in the protobuf text format.
func (Export) MessageStringOf(m pref.ProtoMessage) string {
	b, _ := prototext.MarshalOptions{AllowPartial: true}.Marshal(m)
	return string(b)
}

// ExtensionDescFromType returns the legacy protoiface.ExtensionDescV1 for t.
func (Export) ExtensionDescFromType(t pref.ExtensionType) *piface.ExtensionDescV1 {
	return legacyExtensionDescFromType(t)
}

// ExtensionTypeFromDesc returns the v2 protoreflect.ExtensionType for d.
func (Export) ExtensionTypeFromDesc(d *piface.ExtensionDescV1) pref.ExtensionType {
	return legacyExtensionTypeFromDesc(d)
}
