// Copyright 2020 The Bazel 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 proto defines a module of utilities for constructing and
// accessing protocol messages within Starlark programs.
//
// THIS PACKAGE IS EXPERIMENTAL AND ITS INTERFACE MAY CHANGE.
//
// This package defines several types of Starlark value:
//
//      Message                 -- a protocol message
//      RepeatedField           -- a repeated field of a message, like a list
//
//      FileDescriptor          -- information about a .proto file
//      FieldDescriptor         -- information about a message field (or extension field)
//      MessageDescriptor       -- information about the type of a message
//      EnumDescriptor          -- information about an enumerated type
//      EnumValueDescriptor     -- a value of an enumerated type
//
// A Message value is a wrapper around a protocol message instance.
// Starlark programs may access and update Messages using dot notation:
//
//      x = msg.field
//      msg.field = x + 1
//      msg.field += 1
//
// Assignments to message fields perform dynamic checks on the type and
// range of the value to ensure that the message is at all times valid.
//
// The value of a repeated field of a message is represented by the
// list-like data type, RepeatedField.  Its elements may be accessed,
// iterated, and updated in the usual ways.  As with assignments to
// message fields, an assignment to an element of a RepeatedField
// performs a dynamic check to ensure that the RepeatedField holds
// only elements of the correct type.
//
//      type(msg.uint32s)       # "proto.repeated<uint32>"
//      msg.uint32s[0] = 1
//      msg.uint32s[0] = -1     # error: invalid uint32: -1
//
// Any iterable may be assigned to a repeated field of a message.  If
// the iterable is itself a value of type RepeatedField, the message
// field holds a reference to it.
//
//      msg2.uint32s = msg.uint32s      # both messages share one RepeatedField
//      msg.uint32s[0] = 123
//      print(msg2.uint32s[0])          # "123"
//
// The RepeatedFields' element types must match.
// It is not enough for the values to be merely valid:
//
//      msg.uint32s = [1, 2, 3]         # makes a copy
//      msg.uint64s = msg.uint32s       # error: repeated field has wrong type
//      msg.uint64s = list(msg.uint32s) # ok; makes a copy
//
// For all other iterables, a new RepeatedField is constructed from the
// elements of the iterable.
//
//      msg.uints32s = [1, 2, 3]
//      print(type(msg.uints32s))       # "proto.repeated<uint32>"
//
//
// To construct a Message from encoded binary or text data, call
// Unmarshal or UnmarshalText.  These two functions are exposed to
// Starlark programs as proto.unmarshal{,_text}.
//
// To construct a Message from an existing Go proto.Message instance,
// you must first encode the Go message to binary, then decode it using
// Unmarshal. This ensures that messages visible to Starlark are
// encapsulated and cannot be mutated once their Starlark wrapper values
// are frozen.
//
// TODO(adonovan): document descriptors, enums, message instantiation.
//
// See proto_test.go for an example of how to use the 'proto'
// module in an application that embeds Starlark.
//
package proto

// TODO(adonovan): Go and Starlark API improvements:
// - Make Message and RepeatedField comparable.
//   (NOTE: proto.Equal works only with generated message types.)
// - Support maps, oneof, any. But not messageset if we can avoid it.
// - Support "well-known types".
// - Defend against cycles in object graph.
// - Test missing required fields in marshalling.

import (
	"bytes"
	"fmt"
	"sort"
	"strings"
	"unsafe"
	_ "unsafe" // for linkname hack

	"google.golang.org/protobuf/encoding/prototext"
	"google.golang.org/protobuf/proto"
	"google.golang.org/protobuf/reflect/protoreflect"
	"google.golang.org/protobuf/reflect/protoregistry"
	"google.golang.org/protobuf/types/dynamicpb"

	"go.starlark.net/starlark"
	"go.starlark.net/starlarkstruct"
	"go.starlark.net/syntax"
)

// SetPool associates with the specified Starlark thread the
// descriptor pool used to find descriptors for .proto files and to
// instantiate messages from descriptors.  Clients must call SetPool
// for a Starlark thread to use this package.
//
// For example:
//	SetPool(thread, protoregistry.GlobalFiles)
//
func SetPool(thread *starlark.Thread, pool DescriptorPool) {
	thread.SetLocal(contextKey, pool)
}

// Pool returns the descriptor pool previously associated with this thread.
func Pool(thread *starlark.Thread) DescriptorPool {
	pool, _ := thread.Local(contextKey).(DescriptorPool)
	return pool
}

const contextKey = "proto.DescriptorPool"

// A DescriptorPool loads FileDescriptors by path name or package name,
// possibly on demand.
//
// It is a superinterface of protodesc.Resolver, so any Resolver
// implementation is a valid pool. For example.
// protoregistry.GlobalFiles, which loads FileDescriptors from the
// compressed binary information in all the *.pb.go files linked into
// the process; and protodesc.NewFiles, which holds a set of
// FileDescriptorSet messages. See star2proto for example usage.
type DescriptorPool interface {
	FindFileByPath(string) (protoreflect.FileDescriptor, error)
}

var Module = &starlarkstruct.Module{
	Name: "proto",
	Members: starlark.StringDict{
		"file":           starlark.NewBuiltin("proto.file", file),
		"has":            starlark.NewBuiltin("proto.has", has),
		"marshal":        starlark.NewBuiltin("proto.marshal", marshal),
		"marshal_text":   starlark.NewBuiltin("proto.marshal_text", marshal),
		"set_field":      starlark.NewBuiltin("proto.set_field", setFieldStarlark),
		"get_field":      starlark.NewBuiltin("proto.get_field", getFieldStarlark),
		"unmarshal":      starlark.NewBuiltin("proto.unmarshal", unmarshal),
		"unmarshal_text": starlark.NewBuiltin("proto.unmarshal_text", unmarshal_text),

		// TODO(adonovan):
		// - merge(msg, msg) -> msg
		// - equals(msg, msg) -> bool
		// - diff(msg, msg) -> string
		// - clone(msg) -> msg
	},
}

// file(filename) loads the FileDescriptor of the given name, or the
// first if the pool contains more than one.
//
// It's unfortunate that renaming a .proto file in effect breaks the
// interface it presents to Starlark. Ideally one would import
// descriptors by package name, but there may be many FileDescriptors
// for the same package name, and there is no "package descriptor".
// (Technically a pool may also have many FileDescriptors with the same
// file name, but this can't happen with a single consistent snapshot.)
func file(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var filename string
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &filename); err != nil {
		return nil, err
	}

	pool := Pool(thread)
	if pool == nil {
		return nil, fmt.Errorf("internal error: SetPool was not called")
	}

	desc, err := pool.FindFileByPath(filename)
	if err != nil {
		return nil, err
	}

	return FileDescriptor{Desc: desc}, nil
}

// has(msg, field) reports whether the specified field of the message is present.
// A field may be specified by name (string) or FieldDescriptor.
// has reports an error if the message type has no such field.
func has(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var x, field starlark.Value
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &x, &field); err != nil {
		return nil, err
	}
	msg, ok := x.(*Message)
	if !ok {
		return nil, fmt.Errorf("%s: got %s, want proto.Message", fn.Name(), x.Type())
	}

	var fdesc protoreflect.FieldDescriptor
	switch field := field.(type) {
	case starlark.String:
		var err error
		fdesc, err = fieldDesc(msg.desc(), string(field))
		if err != nil {
			return nil, err
		}

	case FieldDescriptor:
		if field.Desc.ContainingMessage() != msg.desc() {
			return nil, fmt.Errorf("%s: %v does not have field %v", fn.Name(), msg.desc().FullName(), field)
		}
		fdesc = field.Desc

	default:
		return nil, fmt.Errorf("%s: for field argument, got %s, want string or proto.FieldDescriptor", fn.Name(), field.Type())
	}

	return starlark.Bool(msg.msg.Has(fdesc)), nil
}

// marshal{,_text}(msg) encodes a Message value to binary or text form.
func marshal(_ *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var m *Message
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &m); err != nil {
		return nil, err
	}
	if fn.Name() == "proto.marshal" {
		data, err := proto.Marshal(m.Message())
		if err != nil {
			return nil, fmt.Errorf("%s: %v", fn.Name(), err)
		}
		return starlark.Bytes(data), nil
	} else {
		text, err := prototext.MarshalOptions{Indent: "  "}.Marshal(m.Message())
		if err != nil {
			return nil, fmt.Errorf("%s: %v", fn.Name(), err)
		}
		return starlark.String(text), nil
	}
}

// unmarshal(msg) decodes a binary protocol message to a Message.
func unmarshal(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var desc MessageDescriptor
	var data starlark.Bytes
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &desc, &data); err != nil {
		return nil, err
	}
	return unmarshalData(desc.Desc, []byte(data), true)
}

// unmarshal_text(msg) decodes a text protocol message to a Message.
func unmarshal_text(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var desc MessageDescriptor
	var data string
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &desc, &data); err != nil {
		return nil, err
	}
	return unmarshalData(desc.Desc, []byte(data), false)
}

// set_field(msg, field, value) updates the value of a field.
// It is typically used for extensions, which cannot be updated using msg.field = v notation.
func setFieldStarlark(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	// TODO(adonovan): allow field to be specified by name (for non-extension fields), like has?
	var m *Message
	var field FieldDescriptor
	var v starlark.Value
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 3, &m, &field, &v); err != nil {
		return nil, err
	}

	if *m.frozen {
		return nil, fmt.Errorf("%s: cannot set %v field of frozen %v message", fn.Name(), field, m.desc().FullName())
	}

	if field.Desc.ContainingMessage() != m.desc() {
		return nil, fmt.Errorf("%s: %v does not have field %v", fn.Name(), m.desc().FullName(), field)
	}

	return starlark.None, setField(m.msg, field.Desc, v)
}

// get_field(msg, field) retrieves the value of a field.
// It is typically used for extension fields, which cannot be accessed using msg.field notation.
func getFieldStarlark(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	// TODO(adonovan): allow field to be specified by name (for non-extension fields), like has?
	var msg *Message
	var field FieldDescriptor
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 2, &msg, &field); err != nil {
		return nil, err
	}

	if field.Desc.ContainingMessage() != msg.desc() {
		return nil, fmt.Errorf("%s: %v does not have field %v", fn.Name(), msg.desc().FullName(), field)
	}

	return msg.getField(field.Desc), nil
}

// The Call method implements the starlark.Callable interface.
// When a message descriptor is called, it returns a new instance of the
// protocol message it describes.
//
//      Message(msg)            -- return a shallow copy of an existing message
//      Message(k=v, ...)       -- return a new message with the specified fields
//      Message(dict(...))      -- return a new message with the specified fields
//
func (d MessageDescriptor) CallInternal(thread *starlark.Thread, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	dest := &Message{
		msg:    newMessage(d.Desc),
		frozen: new(bool),
	}

	// Single positional argument?
	if len(args) > 0 {
		if len(kwargs) > 0 {
			return nil, fmt.Errorf("%s: got both positional and named arguments", d.Desc.Name())
		}
		if len(args) > 1 {
			return nil, fmt.Errorf("%s: got %d positional arguments, want at most 1", d.Desc.Name(), len(args))
		}

		// Keep consistent with MessageKind case of toProto.
		// (support the same argument types).
		switch src := args[0].(type) {
		case *Message:
			if dest.desc() != src.desc() {
				return nil, fmt.Errorf("%s: got message of type %s, want type %s", d.Desc.Name(), src.desc().FullName(), dest.desc().FullName())
			}

			// Make shallow copy of message.
			// TODO(adonovan): How does frozen work if we have shallow copy?
			src.msg.Range(func(fdesc protoreflect.FieldDescriptor, v protoreflect.Value) bool {
				dest.msg.Set(fdesc, v)
				return true
			})
			return dest, nil

		case *starlark.Dict:
			kwargs = src.Items()
			// fall through

		default:
			return nil, fmt.Errorf("%s: got %s, want dict or message", d.Desc.Name(), src.Type())
		}
	}

	// Convert named arguments to field values.
	err := setFields(dest.msg, kwargs)
	return dest, err
}

// setFields updates msg as if by msg.name=value for each (name, value) in items.
func setFields(msg protoreflect.Message, items []starlark.Tuple) error {
	for _, item := range items {
		name, ok := starlark.AsString(item[0])
		if !ok {
			return fmt.Errorf("got %s, want string", item[0].Type())
		}
		fdesc, err := fieldDesc(msg.Descriptor(), name)
		if err != nil {
			return err
		}
		if err := setField(msg, fdesc, item[1]); err != nil {
			return err
		}
	}
	return nil
}

// setField validates a Starlark field value, converts it to canonical form,
// and assigns to the field of msg.  If value is None, the field is unset.
func setField(msg protoreflect.Message, fdesc protoreflect.FieldDescriptor, value starlark.Value) error {
	// None unsets a field.
	if value == starlark.None {
		msg.Clear(fdesc)
		return nil
	}

	// Assigning to a repeated field must make a copy,
	// because the fields.Set doesn't specify whether
	// it aliases the list or not, so we cannot assume.
	//
	// This is potentially surprising as
	//  x = []; msg.x = x; y = msg.x
	// causes x and y not to alias.
	if fdesc.IsList() {
		iter := starlark.Iterate(value)
		if iter == nil {
			return fmt.Errorf("got %s for .%s field, want iterable", value.Type(), fdesc.Name())
		}
		defer iter.Done()

		// TODO(adonovan): handle maps
		list := msg.Mutable(fdesc).List()
		var x starlark.Value
		for i := 0; iter.Next(&x); i++ {
			v, err := toProto(fdesc, x)
			if err != nil {
				return fmt.Errorf("index %d: %v", i, err)
			}
			list.Append(v)
		}
		return nil
	}

	v, err := toProto(fdesc, value)
	if err != nil {
		return fmt.Errorf("in field %s: %v", fdesc.Name(), err)
	}

	if fdesc.IsExtension() {
		// The protoreflect.Message.NewField method must be able
		// to return a new instance of the field type. Without
		// having the Go type information available for extensions,
		// the implementation of NewField won't know what to do.
		//
		// Thus we must augment the FieldDescriptor to one that
		// additional holds Go representation type information
		// (based in this case on dynamicpb).
		fdesc = dynamicpb.NewExtensionType(fdesc).TypeDescriptor()
		_ = fdesc.(protoreflect.ExtensionTypeDescriptor)
	}

	msg.Set(fdesc, v)
	return nil
}

// toProto converts a Starlark value for a message field into protoreflect form.
func toProto(fdesc protoreflect.FieldDescriptor, v starlark.Value) (protoreflect.Value, error) {
	switch fdesc.Kind() {
	case protoreflect.BoolKind:
		// To avoid mistakes, we require v be exactly a bool.
		if v, ok := v.(starlark.Bool); ok {
			return protoreflect.ValueOfBool(bool(v)), nil
		}

	case protoreflect.Fixed32Kind,
		protoreflect.Uint32Kind:
		// uint32
		if i, ok := v.(starlark.Int); ok {
			if u, ok := i.Uint64(); ok && uint64(uint32(u)) == u {
				return protoreflect.ValueOfUint32(uint32(u)), nil
			}
			return noValue, fmt.Errorf("invalid %s: %v", typeString(fdesc), i)
		}

	case protoreflect.Int32Kind,
		protoreflect.Sfixed32Kind,
		protoreflect.Sint32Kind:
		// int32
		if i, ok := v.(starlark.Int); ok {
			if i, ok := i.Int64(); ok && int64(int32(i)) == i {
				return protoreflect.ValueOfInt32(int32(i)), nil
			}
			return noValue, fmt.Errorf("invalid %s: %v", typeString(fdesc), i)
		}

	case protoreflect.Uint64Kind,
		protoreflect.Fixed64Kind:
		// uint64
		if i, ok := v.(starlark.Int); ok {
			if u, ok := i.Uint64(); ok {
				return protoreflect.ValueOfUint64(u), nil
			}
			return noValue, fmt.Errorf("invalid %s: %v", typeString(fdesc), i)
		}

	case protoreflect.Int64Kind,
		protoreflect.Sfixed64Kind,
		protoreflect.Sint64Kind:
		// int64
		if i, ok := v.(starlark.Int); ok {
			if i, ok := i.Int64(); ok {
				return protoreflect.ValueOfInt64(i), nil
			}
			return noValue, fmt.Errorf("invalid %s: %v", typeString(fdesc), i)
		}

	case protoreflect.StringKind:
		if s, ok := starlark.AsString(v); ok {
			return protoreflect.ValueOfString(s), nil
		} else if b, ok := v.(starlark.Bytes); ok {
			// TODO(adonovan): allow bytes for string? Not friendly to a Java port.
			return protoreflect.ValueOfBytes([]byte(b)), nil
		}

	case protoreflect.BytesKind:
		if s, ok := starlark.AsString(v); ok {
			// TODO(adonovan): don't allow string for bytes: it's hostile to a Java port.
			// Instead provide b"..." literals in the core
			// and a bytes(str) conversion.
			return protoreflect.ValueOfBytes([]byte(s)), nil
		} else if b, ok := v.(starlark.Bytes); ok {
			return protoreflect.ValueOfBytes([]byte(b)), nil
		}

	case protoreflect.DoubleKind:
		switch v := v.(type) {
		case starlark.Float:
			return protoreflect.ValueOfFloat64(float64(v)), nil
		case starlark.Int:
			return protoreflect.ValueOfFloat64(float64(v.Float())), nil
		}

	case protoreflect.FloatKind:
		switch v := v.(type) {
		case starlark.Float:
			return protoreflect.ValueOfFloat32(float32(v)), nil
		case starlark.Int:
			return protoreflect.ValueOfFloat32(float32(v.Float())), nil
		}

	case protoreflect.GroupKind,
		protoreflect.MessageKind:
		// Keep consistent with MessageDescriptor.CallInternal!
		desc := fdesc.Message()
		switch v := v.(type) {
		case *Message:
			if desc != v.desc() {
				return noValue, fmt.Errorf("got %s, want %s", v.desc().FullName(), desc.FullName())
			}
			return protoreflect.ValueOfMessage(v.msg), nil // alias it directly

		case *starlark.Dict:
			dest := newMessage(desc)
			err := setFields(dest, v.Items())
			return protoreflect.ValueOfMessage(dest), err
		}

	case protoreflect.EnumKind:
		enumval, err := enumValueOf(fdesc.Enum(), v)
		if err != nil {
			return noValue, err
		}
		return protoreflect.ValueOfEnum(enumval.Number()), nil
	}

	return noValue, fmt.Errorf("got %s, want %s", v.Type(), typeString(fdesc))
}

var noValue protoreflect.Value

// toStarlark returns a Starlark value for the value x of a message field.
// If the result is a repeated field or message,
// the result aliases the original and has the specified "frozenness" flag.
//
// fdesc is only used for the type, not other properties of the field.
func toStarlark(typ protoreflect.FieldDescriptor, x protoreflect.Value, frozen *bool) starlark.Value {
	if list, ok := x.Interface().(protoreflect.List); ok {
		return &RepeatedField{
			typ:    typ,
			list:   list,
			frozen: frozen,
		}
	}
	return toStarlark1(typ, x, frozen)
}

// toStarlark1, for scalar (non-repeated) values only.
func toStarlark1(typ protoreflect.FieldDescriptor, x protoreflect.Value, frozen *bool) starlark.Value {

	switch typ.Kind() {
	case protoreflect.BoolKind:
		return starlark.Bool(x.Bool())

	case protoreflect.Fixed32Kind,
		protoreflect.Uint32Kind,
		protoreflect.Uint64Kind,
		protoreflect.Fixed64Kind:
		return starlark.MakeUint64(x.Uint())

	case protoreflect.Int32Kind,
		protoreflect.Sfixed32Kind,
		protoreflect.Sint32Kind,
		protoreflect.Int64Kind,
		protoreflect.Sfixed64Kind,
		protoreflect.Sint64Kind:
		return starlark.MakeInt64(x.Int())

	case protoreflect.StringKind:
		return starlark.String(x.String())

	case protoreflect.BytesKind:
		return starlark.Bytes(x.Bytes())

	case protoreflect.DoubleKind, protoreflect.FloatKind:
		return starlark.Float(x.Float())

	case protoreflect.GroupKind, protoreflect.MessageKind:
		return &Message{
			msg:    x.Message(),
			frozen: frozen,
		}

	case protoreflect.EnumKind:
		// Invariant: only EnumValueDescriptor may appear here.
		enumval := typ.Enum().Values().ByNumber(x.Enum())
		return EnumValueDescriptor{Desc: enumval}
	}

	panic(fmt.Sprintf("got %T, want %s", x, typeString(typ)))
}

// A Message is a Starlark value that wraps a protocol message.
//
// Two Messages are equivalent if and only if they are identical.
//
// When a Message value becomes frozen, a Starlark program may
// not modify the underlying protocol message, nor any Message
// or RepeatedField wrapper values derived from it.
type Message struct {
	msg    protoreflect.Message // any concrete type is allowed
	frozen *bool                // shared by a group of related Message/RepeatedField wrappers
}

// Message returns the wrapped message.
func (m *Message) Message() protoreflect.ProtoMessage { return m.msg.Interface() }

func (m *Message) desc() protoreflect.MessageDescriptor { return m.msg.Descriptor() }

var _ starlark.HasSetField = (*Message)(nil)

// Unmarshal parses the data as a binary protocol message of the specified type,
// and returns it as a new Starlark message value.
func Unmarshal(desc protoreflect.MessageDescriptor, data []byte) (*Message, error) {
	return unmarshalData(desc, data, true)
}

// UnmarshalText parses the data as a text protocol message of the specified type,
// and returns it as a new Starlark message value.
func UnmarshalText(desc protoreflect.MessageDescriptor, data []byte) (*Message, error) {
	return unmarshalData(desc, data, false)
}

// unmarshalData constructs a Starlark proto.Message by decoding binary or text data.
func unmarshalData(desc protoreflect.MessageDescriptor, data []byte, binary bool) (*Message, error) {
	m := &Message{
		msg:    newMessage(desc),
		frozen: new(bool),
	}
	var err error
	if binary {
		err = proto.Unmarshal(data, m.Message())
	} else {
		err = prototext.Unmarshal(data, m.Message())
	}
	if err != nil {
		return nil, fmt.Errorf("unmarshalling %s failed: %v", desc.FullName(), err)
	}
	return m, nil
}

func (m *Message) String() string {
	buf := new(bytes.Buffer)
	buf.WriteString(string(m.desc().FullName()))
	buf.WriteByte('(')

	// Sort fields (including extensions) by number.
	var fields []protoreflect.FieldDescriptor
	m.msg.Range(func(fdesc protoreflect.FieldDescriptor, v protoreflect.Value) bool {
		// TODO(adonovan): opt: save v in table too.
		fields = append(fields, fdesc)
		return true
	})
	sort.Slice(fields, func(i, j int) bool {
		return fields[i].Number() < fields[j].Number()
	})

	for i, fdesc := range fields {
		if i > 0 {
			buf.WriteString(", ")
		}
		if fdesc.IsExtension() {
			// extension field: "[pkg.Msg.field]"
			buf.WriteString(string(fdesc.FullName()))
		} else if fdesc.Kind() != protoreflect.GroupKind {
			// ordinary field: "field"
			buf.WriteString(string(fdesc.Name()))
		} else {
			// group field: "MyGroup"
			//
			// The name of a group is the mangled version,
			// while the true name of a group is the message itself.
			// For example, for a group called "MyGroup",
			// the inlined message will be called "MyGroup",
			// but the field will be named "mygroup".
			// This rule complicates name logic everywhere.
			buf.WriteString(string(fdesc.Message().Name()))
		}
		buf.WriteString("=")
		writeString(buf, fdesc, m.msg.Get(fdesc))
	}
	buf.WriteByte(')')
	return buf.String()
}

func (m *Message) Type() string                { return "proto.Message" }
func (m *Message) Truth() starlark.Bool        { return true }
func (m *Message) Freeze()                     { *m.frozen = true }
func (m *Message) Hash() (h uint32, err error) { return uint32(uintptr(unsafe.Pointer(m))), nil } // identity hash

// Attr returns the value of this message's field of the specified name.
// Extension fields are not accessible this way as their names are not unique.
func (m *Message) Attr(name string) (starlark.Value, error) {
	// The name 'descriptor' is already effectively reserved
	// by the Go API for generated message types.
	if name == "descriptor" {
		return MessageDescriptor{Desc: m.desc()}, nil
	}

	fdesc, err := fieldDesc(m.desc(), name)
	if err != nil {
		return nil, err
	}
	return m.getField(fdesc), nil
}

func (m *Message) getField(fdesc protoreflect.FieldDescriptor) starlark.Value {
	if fdesc.IsExtension() {
		// See explanation in setField.
		fdesc = dynamicpb.NewExtensionType(fdesc).TypeDescriptor()
	}

	if m.msg.Has(fdesc) {
		return toStarlark(fdesc, m.msg.Get(fdesc), m.frozen)
	}
	return defaultValue(fdesc)
}

//go:linkname detrandDisable google.golang.org/protobuf/internal/detrand.Disable
func detrandDisable()

func init() {
	// Nasty hack to disable the randomization of output that occurs in textproto.
	// TODO(adonovan): once go/proto-proposals/canonical-serialization
	// is resolved the need for the hack should go away. See also go/go-proto-stability.
	// If the proposal is rejected, we will need our own text-mode formatter.
	detrandDisable()
}

// defaultValue returns the (frozen) default Starlark value for a given message field.
func defaultValue(fdesc protoreflect.FieldDescriptor) starlark.Value {
	frozen := true

	// The default value of a repeated field is an empty list.
	if fdesc.IsList() {
		return &RepeatedField{typ: fdesc, list: emptyList{}, frozen: &frozen}
	}

	// The zero value for a message type is an empty instance of that message.
	if desc := fdesc.Message(); desc != nil {
		return &Message{msg: newMessage(desc), frozen: &frozen}
	}

	// Convert the default value, which is not necessarily zero, to Starlark.
	// The frozenness isn't used as the remaining types are all immutable.
	return toStarlark1(fdesc, fdesc.Default(), &frozen)
}

// A frozen empty implementation of protoreflect.List.
type emptyList struct{ protoreflect.List }

func (emptyList) Len() int { return 0 }

// newMessage returns a new empty instance of the message type described by desc.
func newMessage(desc protoreflect.MessageDescriptor) protoreflect.Message {
	// If desc refers to a built-in message,
	// use the more efficient generated type descriptor (a Go struct).
	mt, err := protoregistry.GlobalTypes.FindMessageByName(desc.FullName())
	if err == nil && mt.Descriptor() == desc {
		return mt.New()
	}

	// For all others, use the generic dynamicpb representation.
	return dynamicpb.NewMessage(desc).ProtoReflect()
}

// fieldDesc returns the descriptor for the named non-extension field.
func fieldDesc(desc protoreflect.MessageDescriptor, name string) (protoreflect.FieldDescriptor, error) {
	if fdesc := desc.Fields().ByName(protoreflect.Name(name)); fdesc != nil {
		return fdesc, nil
	}
	return nil, starlark.NoSuchAttrError(fmt.Sprintf("%s has no .%s field", desc.FullName(), name))
}

// SetField updates a non-extension field of this message.
// It implements the HasSetField interface.
func (m *Message) SetField(name string, v starlark.Value) error {
	fdesc, err := fieldDesc(m.desc(), name)
	if err != nil {
		return err
	}
	if *m.frozen {
		return fmt.Errorf("cannot set .%s field of frozen %s message",
			name, m.desc().FullName())
	}
	return setField(m.msg, fdesc, v)
}

// AttrNames returns the set of field names defined for this message.
// It satisfies the starlark.HasAttrs interface.
func (m *Message) AttrNames() []string {
	seen := make(map[string]bool)

	// standard fields
	seen["descriptor"] = true

	// non-extension fields
	fields := m.desc().Fields()
	for i := 0; i < fields.Len(); i++ {
		fdesc := fields.Get(i)
		if !fdesc.IsExtension() {
			seen[string(fdesc.Name())] = true
		}
	}

	names := make([]string, 0, len(seen))
	for name := range seen {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}

// typeString returns a user-friendly description of the type of a
// protocol message field (or element of a repeated field).
func typeString(fdesc protoreflect.FieldDescriptor) string {
	switch fdesc.Kind() {
	case protoreflect.GroupKind,
		protoreflect.MessageKind:
		return string(fdesc.Message().FullName())

	case protoreflect.EnumKind:
		return string(fdesc.Enum().FullName())

	default:
		return strings.ToLower(strings.TrimPrefix(fdesc.Kind().String(), "TYPE_"))
	}
}

// A RepeatedField is a Starlark value that wraps a repeated field of a protocol message.
//
// An assignment to an element of a repeated field incurs a dynamic
// check that the new value has (or can be converted to) the correct
// type using conversions similar to those done when calling a
// MessageDescriptor to construct a message.
//
// TODO(adonovan): make RepeatedField implement starlark.Comparable.
// Should the comparison include type, or be defined on the elements alone?
type RepeatedField struct {
	typ       protoreflect.FieldDescriptor // only for type information, not field name
	list      protoreflect.List
	frozen    *bool
	itercount int
}

var _ starlark.HasSetIndex = (*RepeatedField)(nil)

func (rf *RepeatedField) Type() string {
	return fmt.Sprintf("proto.repeated<%s>", typeString(rf.typ))
}

func (rf *RepeatedField) SetIndex(i int, v starlark.Value) error {
	if *rf.frozen {
		return fmt.Errorf("cannot insert value in frozen repeated field")
	}
	if rf.itercount > 0 {
		return fmt.Errorf("cannot insert value in repeated field with active iterators")
	}
	x, err := toProto(rf.typ, v)
	if err != nil {
		// The repeated field value cannot know which field it
		// belongs to---it might be shared by several of the
		// same type---so the error message is suboptimal.
		return fmt.Errorf("setting element of repeated field: %v", err)
	}
	rf.list.Set(i, x)
	return nil
}

func (rf *RepeatedField) Freeze()               { *rf.frozen = true }
func (rf *RepeatedField) Hash() (uint32, error) { return 0, fmt.Errorf("unhashable: %s", rf.Type()) }
func (rf *RepeatedField) Index(i int) starlark.Value {
	return toStarlark1(rf.typ, rf.list.Get(i), rf.frozen)
}
func (rf *RepeatedField) Iterate() starlark.Iterator {
	if !*rf.frozen {
		rf.itercount++
	}
	return &repeatedFieldIterator{rf, 0}
}
func (rf *RepeatedField) Len() int { return rf.list.Len() }
func (rf *RepeatedField) String() string {
	// We use list [...] notation even though it not exactly a list.
	buf := new(bytes.Buffer)
	buf.WriteByte('[')
	for i := 0; i < rf.list.Len(); i++ {
		if i > 0 {
			buf.WriteString(", ")
		}
		writeString(buf, rf.typ, rf.list.Get(i))
	}
	buf.WriteByte(']')
	return buf.String()
}
func (rf *RepeatedField) Truth() starlark.Bool { return rf.list.Len() > 0 }

type repeatedFieldIterator struct {
	rf *RepeatedField
	i  int
}

func (it *repeatedFieldIterator) Next(p *starlark.Value) bool {
	if it.i < it.rf.Len() {
		*p = it.rf.Index(it.i)
		it.i++
		return true
	}
	return false
}

func (it *repeatedFieldIterator) Done() {
	if !*it.rf.frozen {
		it.rf.itercount--
	}
}

func writeString(buf *bytes.Buffer, fdesc protoreflect.FieldDescriptor, v protoreflect.Value) {
	// TODO(adonovan): opt: don't materialize the Starlark value.
	// TODO(adonovan): skip message type when printing submessages? {...}?
	var frozen bool // ignored
	x := toStarlark(fdesc, v, &frozen)
	buf.WriteString(x.String())
}

// -------- descriptor values --------

// A FileDescriptor is an immutable Starlark value that describes a
// .proto file.  It is a reference to a protoreflect.FileDescriptor.
// Two FileDescriptor values compare equal if and only if they refer to
// the same protoreflect.FileDescriptor.
//
// Its fields are the names of the message types (MessageDescriptor) and enum
// types (EnumDescriptor).
type FileDescriptor struct {
	Desc protoreflect.FileDescriptor // TODO(adonovan): hide field, expose method?
}

var _ starlark.HasAttrs = FileDescriptor{}

func (f FileDescriptor) String() string              { return string(f.Desc.Path()) }
func (f FileDescriptor) Type() string                { return "proto.FileDescriptor" }
func (f FileDescriptor) Truth() starlark.Bool        { return true }
func (f FileDescriptor) Freeze()                     {} // immutable
func (f FileDescriptor) Hash() (h uint32, err error) { return starlark.String(f.Desc.Path()).Hash() }
func (f FileDescriptor) Attr(name string) (starlark.Value, error) {
	if desc := f.Desc.Messages().ByName(protoreflect.Name(name)); desc != nil {
		return MessageDescriptor{Desc: desc}, nil
	}
	if desc := f.Desc.Extensions().ByName(protoreflect.Name(name)); desc != nil {
		return FieldDescriptor{desc}, nil
	}
	if enum := f.Desc.Enums().ByName(protoreflect.Name(name)); enum != nil {
		return EnumDescriptor{Desc: enum}, nil
	}
	return nil, nil
}
func (f FileDescriptor) AttrNames() []string {
	var names []string
	messages := f.Desc.Messages()
	for i, n := 0, messages.Len(); i < n; i++ {
		names = append(names, string(messages.Get(i).Name()))
	}
	extensions := f.Desc.Extensions()
	for i, n := 0, extensions.Len(); i < n; i++ {
		names = append(names, string(extensions.Get(i).Name()))
	}
	enums := f.Desc.Enums()
	for i, n := 0, enums.Len(); i < n; i++ {
		names = append(names, string(enums.Get(i).Name()))
	}
	sort.Strings(names)
	return names
}

// A MessageDescriptor is an immutable Starlark value that describes a protocol
// message type.
//
// A MessageDescriptor value contains a reference to a protoreflect.MessageDescriptor.
// Two MessageDescriptor values compare equal if and only if they refer to the
// same protoreflect.MessageDescriptor.
//
// The fields of a MessageDescriptor value are the names of any message types
// (MessageDescriptor), fields or extension fields (FieldDescriptor),
// and enum types (EnumDescriptor) nested within the declaration of this message type.
type MessageDescriptor struct {
	Desc protoreflect.MessageDescriptor
}

var (
	_ starlark.Callable = MessageDescriptor{}
	_ starlark.HasAttrs = MessageDescriptor{}
)

func (d MessageDescriptor) String() string       { return string(d.Desc.FullName()) }
func (d MessageDescriptor) Type() string         { return "proto.MessageDescriptor" }
func (d MessageDescriptor) Truth() starlark.Bool { return true }
func (d MessageDescriptor) Freeze()              {} // immutable
func (d MessageDescriptor) Hash() (h uint32, err error) {
	return starlark.String(d.Desc.FullName()).Hash()
}
func (d MessageDescriptor) Attr(name string) (starlark.Value, error) {
	if desc := d.Desc.Messages().ByName(protoreflect.Name(name)); desc != nil {
		return MessageDescriptor{desc}, nil
	}
	if desc := d.Desc.Extensions().ByName(protoreflect.Name(name)); desc != nil {
		return FieldDescriptor{desc}, nil
	}
	if desc := d.Desc.Fields().ByName(protoreflect.Name(name)); desc != nil {
		return FieldDescriptor{desc}, nil
	}
	if desc := d.Desc.Enums().ByName(protoreflect.Name(name)); desc != nil {
		return EnumDescriptor{desc}, nil
	}
	return nil, nil
}
func (d MessageDescriptor) AttrNames() []string {
	var names []string
	messages := d.Desc.Messages()
	for i, n := 0, messages.Len(); i < n; i++ {
		names = append(names, string(messages.Get(i).Name()))
	}
	enums := d.Desc.Enums()
	for i, n := 0, enums.Len(); i < n; i++ {
		names = append(names, string(enums.Get(i).Name()))
	}
	sort.Strings(names)
	return names
}
func (d MessageDescriptor) Name() string { return string(d.Desc.Name()) } // for Callable

// A FieldDescriptor is an immutable Starlark value that describes
// a field (possibly an extension field) of protocol message.
//
// A FieldDescriptor value contains a reference to a protoreflect.FieldDescriptor.
// Two FieldDescriptor values compare equal if and only if they refer to the
// same protoreflect.FieldDescriptor.
//
// The primary use for FieldDescriptors is to access extension fields of a message.
//
// A FieldDescriptor value has not attributes.
// TODO(adonovan): expose metadata fields (e.g. name, type).
type FieldDescriptor struct {
	Desc protoreflect.FieldDescriptor
}

var (
	_ starlark.HasAttrs = FieldDescriptor{}
)

func (d FieldDescriptor) String() string       { return string(d.Desc.FullName()) }
func (d FieldDescriptor) Type() string         { return "proto.FieldDescriptor" }
func (d FieldDescriptor) Truth() starlark.Bool { return true }
func (d FieldDescriptor) Freeze()              {} // immutable
func (d FieldDescriptor) Hash() (h uint32, err error) {
	return starlark.String(d.Desc.FullName()).Hash()
}
func (d FieldDescriptor) Attr(name string) (starlark.Value, error) {
	// TODO(adonovan): expose metadata fields of Desc?
	return nil, nil
}
func (d FieldDescriptor) AttrNames() []string {
	var names []string
	// TODO(adonovan): expose metadata fields of Desc?
	sort.Strings(names)
	return names
}

// An EnumDescriptor is an immutable Starlark value that describes an
// protocol enum type.
//
// An EnumDescriptor contains a reference to a protoreflect.EnumDescriptor.
// Two EnumDescriptor values compare equal if and only if they
// refer to the same protoreflect.EnumDescriptor.
//
// An EnumDescriptor may be called like a function.  It converts its
// sole argument, which must be an int, string, or EnumValueDescriptor,
// to an EnumValueDescriptor.
//
// The fields of an EnumDescriptor value are the values of the
// enumeration, each of type EnumValueDescriptor.
type EnumDescriptor struct {
	Desc protoreflect.EnumDescriptor
}

var (
	_ starlark.HasAttrs = EnumDescriptor{}
	_ starlark.Callable = EnumDescriptor{}
)

func (e EnumDescriptor) String() string              { return string(e.Desc.FullName()) }
func (e EnumDescriptor) Type() string                { return "proto.EnumDescriptor" }
func (e EnumDescriptor) Truth() starlark.Bool        { return true }
func (e EnumDescriptor) Freeze()                     {}                // immutable
func (e EnumDescriptor) Hash() (h uint32, err error) { return 0, nil } // TODO(adonovan): number?
func (e EnumDescriptor) Attr(name string) (starlark.Value, error) {
	if v := e.Desc.Values().ByName(protoreflect.Name(name)); v != nil {
		return EnumValueDescriptor{v}, nil
	}
	return nil, nil
}
func (e EnumDescriptor) AttrNames() []string {
	var names []string
	values := e.Desc.Values()
	for i, n := 0, values.Len(); i < n; i++ {
		names = append(names, string(values.Get(i).Name()))
	}
	sort.Strings(names)
	return names
}
func (e EnumDescriptor) Name() string { return string(e.Desc.Name()) } // for Callable

// The Call method implements the starlark.Callable interface.
// A call to an enum descriptor converts its argument to a value of that enum type.
func (e EnumDescriptor) CallInternal(_ *starlark.Thread, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var x starlark.Value
	if err := starlark.UnpackPositionalArgs(string(e.Desc.Name()), args, kwargs, 1, &x); err != nil {
		return nil, err
	}
	v, err := enumValueOf(e.Desc, x)
	if err != nil {
		return nil, fmt.Errorf("%s: %v", e.Desc.Name(), err)
	}
	return EnumValueDescriptor{Desc: v}, nil
}

// enumValueOf converts an int, string, or enum value to a value of the specified enum type.
func enumValueOf(enum protoreflect.EnumDescriptor, x starlark.Value) (protoreflect.EnumValueDescriptor, error) {
	switch x := x.(type) {
	case starlark.Int:
		i, err := starlark.AsInt32(x)
		if err != nil {
			return nil, fmt.Errorf("invalid number %s for %s enum", x, enum.Name())
		}
		desc := enum.Values().ByNumber(protoreflect.EnumNumber(i))
		if desc == nil {
			return nil, fmt.Errorf("invalid number %d for %s enum", i, enum.Name())
		}
		return desc, nil

	case starlark.String:
		name := protoreflect.Name(x)
		desc := enum.Values().ByName(name)
		if desc == nil {
			return nil, fmt.Errorf("invalid name %q for %s enum", name, enum.Name())
		}
		return desc, nil

	case EnumValueDescriptor:
		if parent := x.Desc.Parent(); parent != enum {
			return nil, fmt.Errorf("invalid value %s.%s for %s enum",
				parent.Name(), x.Desc.Name(), enum.Name())
		}
		return x.Desc, nil
	}

	return nil, fmt.Errorf("cannot convert %s to %s enum", x.Type(), enum.Name())
}

// An EnumValueDescriptor is an immutable Starlark value that represents one value of an enumeration.
//
// An EnumValueDescriptor contains a reference to a protoreflect.EnumValueDescriptor.
// Two EnumValueDescriptor values compare equal if and only if they
// refer to the same protoreflect.EnumValueDescriptor.
//
// An EnumValueDescriptor has the following fields:
//
//      index   -- int, index of this value within the enum sequence
//      name    -- string, name of this enum value
//      number  -- int, numeric value of this enum value
//      type    -- EnumDescriptor, the enum type to which this value belongs
//
type EnumValueDescriptor struct {
	Desc protoreflect.EnumValueDescriptor
}

var (
	_ starlark.HasAttrs   = EnumValueDescriptor{}
	_ starlark.Comparable = EnumValueDescriptor{}
)

func (e EnumValueDescriptor) String() string {
	enum := e.Desc.Parent()
	return string(enum.Name() + "." + e.Desc.Name()) // "Enum.EnumValue"
}
func (e EnumValueDescriptor) Type() string                { return "proto.EnumValueDescriptor" }
func (e EnumValueDescriptor) Truth() starlark.Bool        { return true }
func (e EnumValueDescriptor) Freeze()                     {} // immutable
func (e EnumValueDescriptor) Hash() (h uint32, err error) { return uint32(e.Desc.Number()), nil }
func (e EnumValueDescriptor) AttrNames() []string {
	return []string{"index", "name", "number", "type"}
}
func (e EnumValueDescriptor) Attr(name string) (starlark.Value, error) {
	switch name {
	case "index":
		return starlark.MakeInt(e.Desc.Index()), nil
	case "name":
		return starlark.String(e.Desc.Name()), nil
	case "number":
		return starlark.MakeInt(int(e.Desc.Number())), nil
	case "type":
		enum := e.Desc.Parent()
		return EnumDescriptor{Desc: enum.(protoreflect.EnumDescriptor)}, nil
	}
	return nil, nil
}
func (x EnumValueDescriptor) CompareSameType(op syntax.Token, y_ starlark.Value, depth int) (bool, error) {
	y := y_.(EnumValueDescriptor)
	switch op {
	case syntax.EQL:
		return x.Desc == y.Desc, nil
	case syntax.NEQ:
		return x.Desc != y.Desc, nil
	default:
		return false, fmt.Errorf("%s %s %s not implemented", x.Type(), op, y_.Type())
	}
}
