// Copyright 2016 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 descriptor provides functions for obtaining the protocol buffer
// descriptors of generated Go types.
//
// Deprecated: See the "google.golang.org/protobuf/reflect/protoreflect" package
// for how to obtain an EnumDescriptor or MessageDescriptor in order to
// programatically interact with the protobuf type system.
package descriptor

import (
	"bytes"
	"compress/gzip"
	"io/ioutil"
	"sync"

	"github.com/golang/protobuf/proto"
	"google.golang.org/protobuf/reflect/protodesc"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/runtime/protoimpl"

	descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
)

// Message is proto.Message with a method to return its descriptor.
//
// Deprecated: The Descriptor method may not be generated by future
// versions of protoc-gen-go, meaning that this interface may not
// be implemented by many concrete message types.
type Message interface {
	proto.Message
	Descriptor() ([]byte, []int)
}

// ForMessage returns the file descriptor proto containing
// the message and the message descriptor proto for the message itself.
// The returned proto messages must not be mutated.
//
// Deprecated: Not all concrete message types satisfy the Message interface.
// Use MessageDescriptorProto instead. If possible, the calling code should
// be rewritten to use protobuf reflection instead.
// See package "google.golang.org/protobuf/reflect/protoreflect" for details.
func ForMessage(m Message) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) {
	return MessageDescriptorProto(m)
}

type rawDesc struct {
	fileDesc []byte
	indexes  []int
}

var rawDescCache sync.Map // map[protoreflect.Descriptor]*rawDesc

func deriveRawDescriptor(d protoreflect.Descriptor) ([]byte, []int) {
	// Fast-path: check whether raw descriptors are already cached.
	origDesc := d
	if v, ok := rawDescCache.Load(origDesc); ok {
		return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes
	}

	// Slow-path: derive the raw descriptor from the v2 descriptor.

	// Start with the leaf (a given enum or message declaration) and
	// ascend upwards until we hit the parent file descriptor.
	var idxs []int
	for {
		idxs = append(idxs, d.Index())
		d = d.Parent()
		if d == nil {
			// TODO: We could construct a FileDescriptor stub for standalone
			// descriptors to satisfy the API.
			return nil, nil
		}
		if _, ok := d.(protoreflect.FileDescriptor); ok {
			break
		}
	}

	// Obtain the raw file descriptor.
	var raw []byte
	switch fd := d.(type) {
	case interface{ ProtoLegacyRawDesc() []byte }:
		raw = fd.ProtoLegacyRawDesc()
	case protoreflect.FileDescriptor:
		raw, _ = proto.Marshal(protodesc.ToFileDescriptorProto(fd))
	}
	file := protoimpl.X.CompressGZIP(raw)

	// Reverse the indexes, since we populated it in reverse.
	for i, j := 0, len(idxs)-1; i < j; i, j = i+1, j-1 {
		idxs[i], idxs[j] = idxs[j], idxs[i]
	}

	if v, ok := rawDescCache.LoadOrStore(origDesc, &rawDesc{file, idxs}); ok {
		return v.(*rawDesc).fileDesc, v.(*rawDesc).indexes
	}
	return file, idxs
}

// EnumRawDescriptor returns the GZIP'd raw file descriptor representing
// the enum and the index path to reach the enum declaration.
// The returned slices must not be mutated.
func EnumRawDescriptor(e proto.GeneratedEnum) ([]byte, []int) {
	if ev, ok := e.(interface{ EnumDescriptor() ([]byte, []int) }); ok {
		return ev.EnumDescriptor()
	}
	ed := protoimpl.X.EnumTypeOf(e)
	return deriveRawDescriptor(ed.Descriptor())
}

// MessageRawDescriptor returns the GZIP'd raw file descriptor representing
// the message and the index path to reach the message declaration.
// The returned slices must not be mutated.
func MessageRawDescriptor(m proto.GeneratedMessage) ([]byte, []int) {
	if mv, ok := m.(interface{ Descriptor() ([]byte, []int) }); ok {
		return mv.Descriptor()
	}
	md := protoimpl.X.MessageTypeOf(m)
	return deriveRawDescriptor(md.Descriptor())
}

var fileDescCache sync.Map // map[*byte]*descriptorpb.FileDescriptorProto

func deriveFileDescriptor(rawDesc []byte) *descriptorpb.FileDescriptorProto {
	// Fast-path: check whether descriptor protos are already cached.
	if v, ok := fileDescCache.Load(&rawDesc[0]); ok {
		return v.(*descriptorpb.FileDescriptorProto)
	}

	// Slow-path: derive the descriptor proto from the GZIP'd message.
	zr, err := gzip.NewReader(bytes.NewReader(rawDesc))
	if err != nil {
		panic(err)
	}
	b, err := ioutil.ReadAll(zr)
	if err != nil {
		panic(err)
	}
	fd := new(descriptorpb.FileDescriptorProto)
	if err := proto.Unmarshal(b, fd); err != nil {
		panic(err)
	}
	if v, ok := fileDescCache.LoadOrStore(&rawDesc[0], fd); ok {
		return v.(*descriptorpb.FileDescriptorProto)
	}
	return fd
}

// EnumDescriptorProto returns the file descriptor proto representing
// the enum and the enum descriptor proto for the enum itself.
// The returned proto messages must not be mutated.
func EnumDescriptorProto(e proto.GeneratedEnum) (*descriptorpb.FileDescriptorProto, *descriptorpb.EnumDescriptorProto) {
	rawDesc, idxs := EnumRawDescriptor(e)
	if rawDesc == nil || idxs == nil {
		return nil, nil
	}
	fd := deriveFileDescriptor(rawDesc)
	if len(idxs) == 1 {
		return fd, fd.EnumType[idxs[0]]
	}
	md := fd.MessageType[idxs[0]]
	for _, i := range idxs[1 : len(idxs)-1] {
		md = md.NestedType[i]
	}
	ed := md.EnumType[idxs[len(idxs)-1]]
	return fd, ed
}

// MessageDescriptorProto returns the file descriptor proto representing
// the message and the message descriptor proto for the message itself.
// The returned proto messages must not be mutated.
func MessageDescriptorProto(m proto.GeneratedMessage) (*descriptorpb.FileDescriptorProto, *descriptorpb.DescriptorProto) {
	rawDesc, idxs := MessageRawDescriptor(m)
	if rawDesc == nil || idxs == nil {
		return nil, nil
	}
	fd := deriveFileDescriptor(rawDesc)
	md := fd.MessageType[idxs[0]]
	for _, i := range idxs[1:] {
		md = md.NestedType[i]
	}
	return fd, md
}
