// 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 protodesc provides functionality for converting
// FileDescriptorProto messages to/from [protoreflect.FileDescriptor] values.
//
// The google.protobuf.FileDescriptorProto is a protobuf message that describes
// the type information for a .proto file in a form that is easily serializable.
// The [protoreflect.FileDescriptor] is a more structured representation of
// the FileDescriptorProto message where references and remote dependencies
// can be directly followed.
package protodesc

import (
	"strings"

	"google.golang.org/protobuf/internal/editionssupport"
	"google.golang.org/protobuf/internal/errors"
	"google.golang.org/protobuf/internal/filedesc"
	"google.golang.org/protobuf/internal/pragma"
	"google.golang.org/protobuf/internal/strs"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"

	"google.golang.org/protobuf/types/descriptorpb"
)

// Resolver is the resolver used by [NewFile] to resolve dependencies.
// The enums and messages provided must belong to some parent file,
// which is also registered.
//
// It is implemented by [protoregistry.Files].
type Resolver interface {
	FindFileByPath(string) (protoreflect.FileDescriptor, error)
	FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error)
}

// FileOptions configures the construction of file descriptors.
type FileOptions struct {
	pragma.NoUnkeyedLiterals

	// AllowUnresolvable configures New to permissively allow unresolvable
	// file, enum, or message dependencies. Unresolved dependencies are replaced
	// by placeholder equivalents.
	//
	// The following dependencies may be left unresolved:
	//	• Resolving an imported file.
	//	• Resolving the type for a message field or extension field.
	//	If the kind of the field is unknown, then a placeholder is used for both
	//	the Enum and Message accessors on the protoreflect.FieldDescriptor.
	//	• Resolving an enum value set as the default for an optional enum field.
	//	If unresolvable, the protoreflect.FieldDescriptor.Default is set to the
	//	first value in the associated enum (or zero if the also enum dependency
	//	is also unresolvable). The protoreflect.FieldDescriptor.DefaultEnumValue
	//	is populated with a placeholder.
	//	• Resolving the extended message type for an extension field.
	//	• Resolving the input or output message type for a service method.
	//
	// If the unresolved dependency uses a relative name,
	// then the placeholder will contain an invalid FullName with a "*." prefix,
	// indicating that the starting prefix of the full name is unknown.
	AllowUnresolvable bool
}

// NewFile creates a new [protoreflect.FileDescriptor] from the provided
// file descriptor message. See [FileOptions.New] for more information.
func NewFile(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
	return FileOptions{}.New(fd, r)
}

// NewFiles creates a new [protoregistry.Files] from the provided
// FileDescriptorSet message. See [FileOptions.NewFiles] for more information.
func NewFiles(fd *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
	return FileOptions{}.NewFiles(fd)
}

// New creates a new [protoreflect.FileDescriptor] from the provided
// file descriptor message. The file must represent a valid proto file according
// to protobuf semantics. The returned descriptor is a deep copy of the input.
//
// Any imported files, enum types, or message types referenced in the file are
// resolved using the provided registry. When looking up an import file path,
// the path must be unique. The newly created file descriptor is not registered
// back into the provided file registry.
func (o FileOptions) New(fd *descriptorpb.FileDescriptorProto, r Resolver) (protoreflect.FileDescriptor, error) {
	if r == nil {
		r = (*protoregistry.Files)(nil) // empty resolver
	}

	// Handle the file descriptor content.
	f := &filedesc.File{L2: &filedesc.FileL2{}}
	switch fd.GetSyntax() {
	case "proto2", "":
		f.L1.Syntax = protoreflect.Proto2
		f.L1.Edition = filedesc.EditionProto2
	case "proto3":
		f.L1.Syntax = protoreflect.Proto3
		f.L1.Edition = filedesc.EditionProto3
	case "editions":
		f.L1.Syntax = protoreflect.Editions
		f.L1.Edition = fromEditionProto(fd.GetEdition())
	default:
		return nil, errors.New("invalid syntax: %q", fd.GetSyntax())
	}
	f.L1.Path = fd.GetName()
	if f.L1.Path == "" {
		return nil, errors.New("file path must be populated")
	}
	if f.L1.Syntax == protoreflect.Editions && (fd.GetEdition() < editionssupport.Minimum || fd.GetEdition() > editionssupport.Maximum) {
		// Allow cmd/protoc-gen-go/testdata to use any edition for easier
		// testing of upcoming edition features.
		if !strings.HasPrefix(fd.GetName(), "cmd/protoc-gen-go/testdata/") {
			return nil, errors.New("use of edition %v not yet supported by the Go Protobuf runtime", fd.GetEdition())
		}
	}
	f.L1.Package = protoreflect.FullName(fd.GetPackage())
	if !f.L1.Package.IsValid() && f.L1.Package != "" {
		return nil, errors.New("invalid package: %q", f.L1.Package)
	}
	if opts := fd.GetOptions(); opts != nil {
		opts = proto.Clone(opts).(*descriptorpb.FileOptions)
		f.L2.Options = func() protoreflect.ProtoMessage { return opts }
	}
	initFileDescFromFeatureSet(f, fd.GetOptions().GetFeatures())

	f.L2.Imports = make(filedesc.FileImports, len(fd.GetDependency()))
	for _, i := range fd.GetPublicDependency() {
		if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsPublic {
			return nil, errors.New("invalid or duplicate public import index: %d", i)
		}
		f.L2.Imports[i].IsPublic = true
	}
	for _, i := range fd.GetWeakDependency() {
		if !(0 <= i && int(i) < len(f.L2.Imports)) || f.L2.Imports[i].IsWeak {
			return nil, errors.New("invalid or duplicate weak import index: %d", i)
		}
		f.L2.Imports[i].IsWeak = true
	}
	imps := importSet{f.Path(): true}
	for i, path := range fd.GetDependency() {
		imp := &f.L2.Imports[i]
		f, err := r.FindFileByPath(path)
		if err == protoregistry.NotFound && (o.AllowUnresolvable || imp.IsWeak) {
			f = filedesc.PlaceholderFile(path)
		} else if err != nil {
			return nil, errors.New("could not resolve import %q: %v", path, err)
		}
		imp.FileDescriptor = f

		if imps[imp.Path()] {
			return nil, errors.New("already imported %q", path)
		}
		imps[imp.Path()] = true
	}
	for i := range fd.GetDependency() {
		imp := &f.L2.Imports[i]
		imps.importPublic(imp.Imports())
	}

	// Handle source locations.
	f.L2.Locations.File = f
	for _, loc := range fd.GetSourceCodeInfo().GetLocation() {
		var l protoreflect.SourceLocation
		// TODO: Validate that the path points to an actual declaration?
		l.Path = protoreflect.SourcePath(loc.GetPath())
		s := loc.GetSpan()
		switch len(s) {
		case 3:
			l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[0]), int(s[2])
		case 4:
			l.StartLine, l.StartColumn, l.EndLine, l.EndColumn = int(s[0]), int(s[1]), int(s[2]), int(s[3])
		default:
			return nil, errors.New("invalid span: %v", s)
		}
		// TODO: Validate that the span information is sensible?
		// See https://github.com/protocolbuffers/protobuf/issues/6378.
		if false && (l.EndLine < l.StartLine || l.StartLine < 0 || l.StartColumn < 0 || l.EndColumn < 0 ||
			(l.StartLine == l.EndLine && l.EndColumn <= l.StartColumn)) {
			return nil, errors.New("invalid span: %v", s)
		}
		l.LeadingDetachedComments = loc.GetLeadingDetachedComments()
		l.LeadingComments = loc.GetLeadingComments()
		l.TrailingComments = loc.GetTrailingComments()
		f.L2.Locations.List = append(f.L2.Locations.List, l)
	}

	// Step 1: Allocate and derive the names for all declarations.
	// This copies all fields from the descriptor proto except:
	//	google.protobuf.FieldDescriptorProto.type_name
	//	google.protobuf.FieldDescriptorProto.default_value
	//	google.protobuf.FieldDescriptorProto.oneof_index
	//	google.protobuf.FieldDescriptorProto.extendee
	//	google.protobuf.MethodDescriptorProto.input
	//	google.protobuf.MethodDescriptorProto.output
	var err error
	sb := new(strs.Builder)
	r1 := make(descsByName)
	if f.L1.Enums.List, err = r1.initEnumDeclarations(fd.GetEnumType(), f, sb); err != nil {
		return nil, err
	}
	if f.L1.Messages.List, err = r1.initMessagesDeclarations(fd.GetMessageType(), f, sb); err != nil {
		return nil, err
	}
	if f.L1.Extensions.List, err = r1.initExtensionDeclarations(fd.GetExtension(), f, sb); err != nil {
		return nil, err
	}
	if f.L1.Services.List, err = r1.initServiceDeclarations(fd.GetService(), f, sb); err != nil {
		return nil, err
	}

	// Step 2: Resolve every dependency reference not handled by step 1.
	r2 := &resolver{local: r1, remote: r, imports: imps, allowUnresolvable: o.AllowUnresolvable}
	if err := r2.resolveMessageDependencies(f.L1.Messages.List, fd.GetMessageType()); err != nil {
		return nil, err
	}
	if err := r2.resolveExtensionDependencies(f.L1.Extensions.List, fd.GetExtension()); err != nil {
		return nil, err
	}
	if err := r2.resolveServiceDependencies(f.L1.Services.List, fd.GetService()); err != nil {
		return nil, err
	}

	// Step 3: Validate every enum, message, and extension declaration.
	if err := validateEnumDeclarations(f.L1.Enums.List, fd.GetEnumType()); err != nil {
		return nil, err
	}
	if err := validateMessageDeclarations(f, f.L1.Messages.List, fd.GetMessageType()); err != nil {
		return nil, err
	}
	if err := validateExtensionDeclarations(f, f.L1.Extensions.List, fd.GetExtension()); err != nil {
		return nil, err
	}

	return f, nil
}

type importSet map[string]bool

func (is importSet) importPublic(imps protoreflect.FileImports) {
	for i := 0; i < imps.Len(); i++ {
		if imp := imps.Get(i); imp.IsPublic {
			is[imp.Path()] = true
			is.importPublic(imp.Imports())
		}
	}
}

// NewFiles creates a new [protoregistry.Files] from the provided
// FileDescriptorSet message. The descriptor set must include only
// valid files according to protobuf semantics. The returned descriptors
// are a deep copy of the input.
func (o FileOptions) NewFiles(fds *descriptorpb.FileDescriptorSet) (*protoregistry.Files, error) {
	files := make(map[string]*descriptorpb.FileDescriptorProto)
	for _, fd := range fds.File {
		if _, ok := files[fd.GetName()]; ok {
			return nil, errors.New("file appears multiple times: %q", fd.GetName())
		}
		files[fd.GetName()] = fd
	}
	r := &protoregistry.Files{}
	for _, fd := range files {
		if err := o.addFileDeps(r, fd, files); err != nil {
			return nil, err
		}
	}
	return r, nil
}
func (o FileOptions) addFileDeps(r *protoregistry.Files, fd *descriptorpb.FileDescriptorProto, files map[string]*descriptorpb.FileDescriptorProto) error {
	// Set the entry to nil while descending into a file's dependencies to detect cycles.
	files[fd.GetName()] = nil
	for _, dep := range fd.Dependency {
		depfd, ok := files[dep]
		if depfd == nil {
			if ok {
				return errors.New("import cycle in file: %q", dep)
			}
			continue
		}
		if err := o.addFileDeps(r, depfd, files); err != nil {
			return err
		}
	}
	// Delete the entry once dependencies are processed.
	delete(files, fd.GetName())
	f, err := o.New(fd, r)
	if err != nil {
		return err
	}
	return r.RegisterFile(f)
}
