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:
		enumval := typ.Enum().Values().ByNumber(x.Enum())
		return EnumValueDescriptor{Desc: enumval}
	}
	panic(fmt.Sprintf("got %T, want %s", x, typeString(typ)))
}
toStarlark1, for scalar (non-repeated) values only.
package proto
import (
	"bytes"
	"fmt"
	"sort"
	"strings"
	"unsafe"
	_ "unsafe"  
	"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"
)
func SetPool(thread *starlark.Thread, pool DescriptorPool) {
	thread.SetLocal(contextKey, pool)
}
func Pool(thread *starlark.Thread) DescriptorPool {
	pool, _ := thread.Local(contextKey).(DescriptorPool)
	return pool
}
const contextKey = "proto.DescriptorPool"
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),
	},
}
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
}
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
}
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
	}
}
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)
}
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)
}
func setFieldStarlark(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	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)
}
func getFieldStarlark(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	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
}
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),
	}
	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))
		}
		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())
			}
			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()
		default:
			return nil, fmt.Errorf("%s: got %s, want dict or message", d.Desc.Name(), src.Type())
		}
	}
	err := setFields(dest.msg, kwargs)
	return dest, err
}
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
}
func setField(msg protoreflect.Message, fdesc protoreflect.FieldDescriptor, value starlark.Value) error {
	if value == starlark.None {
		msg.Clear(fdesc)
		return nil
	}
	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()
		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() {
		fdesc = dynamicpb.NewExtensionType(fdesc).TypeDescriptor()
		_ = fdesc.(protoreflect.ExtensionTypeDescriptor)
	}
	msg.Set(fdesc, v)
	return nil
}
func toProto(fdesc protoreflect.FieldDescriptor, v starlark.Value) (protoreflect.Value, error) {
	switch fdesc.Kind() {
	case protoreflect.BoolKind:
		if v, ok := v.(starlark.Bool); ok {
			return protoreflect.ValueOfBool(bool(v)), nil
		}
	case protoreflect.Fixed32Kind,
		protoreflect.Uint32Kind:
		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:
		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:
		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:
		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 {
			return protoreflect.ValueOfBytes([]byte(b)), nil
		}
	case protoreflect.BytesKind:
		if s, ok := starlark.AsString(v); ok {
			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:
		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  
		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
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)
}