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