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

import (
	descriptorV1 "github.com/golang/protobuf/protoc-gen-go/descriptor"
	"github.com/golang/protobuf/v2/internal/errors"
	"github.com/golang/protobuf/v2/reflect/protoreflect"
)

// TODO: Should the constructors take in a value rather than a pointer?
// TODO: Support initializing StandaloneMessage from a google.protobuf.Type?

// StandaloneMessage is a constructor for a protoreflect.MessageDescriptor
// that does not have a parent and has no child declarations.
type StandaloneMessage struct {
	Syntax          protoreflect.Syntax
	FullName        protoreflect.FullName
	Fields          []Field
	Oneofs          []Oneof
	ExtensionRanges [][2]protoreflect.FieldNumber
	Options         *descriptorV1.MessageOptions

	fields fieldsMeta
	oneofs oneofsMeta
	nums   numbersMeta
}

// NewMessage creates a new protoreflect.MessageDescriptor.
// The caller must relinquish full ownership of the input t and must not
// access or mutate any fields.
func NewMessage(t *StandaloneMessage) (protoreflect.MessageDescriptor, error) {
	mt := standaloneMessage{t}
	if err := validateMessage(mt); err != nil {
		return nil, err
	}
	return mt, nil
}

// NewMessages creates a set of new protoreflect.MessageDescriptors.
//
// This constructor permits the creation of cyclic message types that depend
// on each other. For example, message A may have a field of type message B,
// where message B may have a field of type message A. In such a case,
// a placeholder message is used for these cyclic references.
//
// The caller must relinquish full ownership of the input ts and must not
// access or mutate any fields.
func NewMessages(ts []*StandaloneMessage) ([]protoreflect.MessageDescriptor, error) {
	// TODO: Should this be []*T or []T?
	// TODO: NewMessages is a superset of NewMessage. Do we need NewMessage?
	ms := map[protoreflect.FullName]protoreflect.MessageDescriptor{}
	for _, t := range ts {
		if _, ok := ms[t.FullName]; ok {
			return nil, errors.New("duplicate message %v", t.FullName)
		}
		ms[t.FullName] = standaloneMessage{t}
	}

	var mts []protoreflect.MessageDescriptor
	for _, t := range ts {
		for i, f := range t.Fields {
			// Resolve placeholder messages with a concrete standalone message.
			// If this fails, validateMessage will complain about it later.
			if !f.Options.GetWeak() && f.MessageType != nil && f.MessageType.IsPlaceholder() {
				if m, ok := ms[f.MessageType.FullName()]; ok {
					t.Fields[i].MessageType = m
				}
			}
		}
		mt := standaloneMessage{t}
		if err := validateMessage(mt); err != nil {
			return nil, err
		}
		mts = append(mts, mt)
	}
	return mts, nil
}

// StandaloneEnum is a constructor for a protoreflect.EnumDescriptor
// that does not have a parent.
type StandaloneEnum struct {
	Syntax   protoreflect.Syntax
	FullName protoreflect.FullName
	Values   []EnumValue
	Options  *descriptorV1.EnumOptions

	vals enumValuesMeta
}

// NewEnum creates a new protoreflect.EnumDescriptor.
// The caller must relinquish full ownership of the input t and must not
// access or mutate any fields.
func NewEnum(t *StandaloneEnum) (protoreflect.EnumDescriptor, error) {
	et := standaloneEnum{t}
	if err := validateEnum(et); err != nil {
		return nil, err
	}
	return et, nil
}

// StandaloneExtension is a constructor for a protoreflect.ExtensionDescriptor
// that does not have a parent.
type StandaloneExtension struct {
	FullName     protoreflect.FullName
	Number       protoreflect.FieldNumber
	Cardinality  protoreflect.Cardinality
	Kind         protoreflect.Kind
	Default      protoreflect.Value
	MessageType  protoreflect.MessageDescriptor
	EnumType     protoreflect.EnumDescriptor
	ExtendedType protoreflect.MessageDescriptor
	Options      *descriptorV1.FieldOptions

	dv defaultValue
}

// NewExtension creates a new protoreflect.ExtensionDescriptor.
// The caller must relinquish full ownership of the input t and must not
// access or mutate any fields.
func NewExtension(t *StandaloneExtension) (protoreflect.ExtensionDescriptor, error) {
	xt := standaloneExtension{t}
	if err := validateExtension(xt); err != nil {
		return nil, err
	}
	return xt, nil
}
