func main()

in lib/proto/cmd/star2proto/star2proto.go [49:135]


func main() {
	log.SetPrefix("star2proto: ")
	log.SetFlags(0)
	flag.Parse()
	if len(flag.Args()) != 1 {
		fatalf("requires a single Starlark file name")
	}
	filename := flag.Args()[0]

	// By default, use the linked-in descriptors
	// (very few in star2proto, e.g. descriptorpb itself).
	pool := protoregistry.GlobalFiles

	// Load a user-provided FileDescriptorSet produced by a command such as:
	// $ protoc --descriptor_set_out=foo.fds foo.proto
	if *descriptors != "" {
		var fdset descriptorpb.FileDescriptorSet
		for i, filename := range strings.Split(*descriptors, ",") {
			data, err := ioutil.ReadFile(filename)
			if err != nil {
				log.Fatalf("--descriptors[%d]: %s", i, err)
			}
			// Accumulate into the repeated field of FileDescriptors.
			if err := (proto.UnmarshalOptions{Merge: true}).Unmarshal(data, &fdset); err != nil {
				log.Fatalf("%s does not contain a proto2.FileDescriptorSet: %v", filename, err)
			}
		}

		files, err := protodesc.NewFiles(&fdset)
		if err != nil {
			log.Fatalf("protodesc.NewFiles: could not build FileDescriptor index: %v", err)
		}
		pool = files
	}

	// Execute the Starlark file.
	thread := &starlark.Thread{
		Print: func(_ *starlark.Thread, msg string) { fmt.Println(msg) },
	}
	starlarkproto.SetPool(thread, pool)
	predeclared := starlark.StringDict{
		"proto": starlarkproto.Module,
		"json":  json.Module,
	}
	globals, err := starlark.ExecFile(thread, filename, nil, predeclared)
	if err != nil {
		if evalErr, ok := err.(*starlark.EvalError); ok {
			fatalf("%s", evalErr.Backtrace())
		} else {
			fatalf("%s", err)
		}
	}

	// Print the output variable as a message.
	// TODO(adonovan): this is clumsy.
	// Let the user call print(), or provide an expression on the command line.
	result, ok := globals[*varFlag]
	if !ok {
		fatalf("%s must define a module-level variable named %q", filename, *varFlag)
	}
	msgwrap, ok := result.(*starlarkproto.Message)
	if !ok {
		fatalf("got %s, want proto.Message, for %q", result.Type(), *varFlag)
	}
	msg := msgwrap.Message()

	// -output
	var marshal func(protoreflect.ProtoMessage) ([]byte, error)
	switch *outputFlag {
	case "wire":
		marshal = proto.Marshal

	case "text":
		marshal = prototext.MarshalOptions{Multiline: true, Indent: "\t"}.Marshal

	case "json":
		marshal = protojson.MarshalOptions{Multiline: true, Indent: "\t"}.Marshal

	default:
		fatalf("unsupported -output format: %s", *outputFlag)
	}
	data, err := marshal(msg)
	if err != nil {
		fatalf("%s", err)
	}
	os.Stdout.Write(data)
}