// 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.
	fd := d.(protoreflect.FileDescriptor)
	b, _ := proto.Marshal(protodesc.ToFileDescriptorProto(fd))
	file := protoimpl.X.CompressGZIP(b)

	// 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
}
