// Copyright 2019 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. //go:generate go run . -execute package main import ( "flag" "fmt" "io/ioutil" "os" "os/exec" "path" "path/filepath" "strings" "github.com/golang/protobuf/proto" gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/reflect/protodesc" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/descriptorpb" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/emptypb" "google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/wrapperspb" "google.golang.org/protobuf/types/pluginpb" ) func main() { run := flag.Bool("execute", false, "Write generated files to destination.") flag.Parse() // Set of generated proto packages to forward to v2. files := []struct { goPkg string pbDesc protoreflect.FileDescriptor }{{ goPkg: "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor", pbDesc: descriptorpb.File_google_protobuf_descriptor_proto, }, { goPkg: "github.com/golang/protobuf/protoc-gen-go/plugin;plugin_go", pbDesc: pluginpb.File_google_protobuf_compiler_plugin_proto, }, { goPkg: "github.com/golang/protobuf/ptypes/any;any", pbDesc: anypb.File_google_protobuf_any_proto, }, { goPkg: "github.com/golang/protobuf/ptypes/duration;duration", pbDesc: durationpb.File_google_protobuf_duration_proto, }, { goPkg: "github.com/golang/protobuf/ptypes/timestamp;timestamp", pbDesc: timestamppb.File_google_protobuf_timestamp_proto, }, { goPkg: "github.com/golang/protobuf/ptypes/wrappers;wrappers", pbDesc: wrapperspb.File_google_protobuf_wrappers_proto, }, { goPkg: "github.com/golang/protobuf/ptypes/struct;structpb", pbDesc: structpb.File_google_protobuf_struct_proto, }, { goPkg: "github.com/golang/protobuf/ptypes/empty;empty", pbDesc: emptypb.File_google_protobuf_empty_proto, }} // For each package, construct a proto file that public imports the package. var req pluginpb.CodeGeneratorRequest for _, file := range files { pkgPath := file.goPkg[:strings.IndexByte(file.goPkg, ';')] fd := &descriptorpb.FileDescriptorProto{ Name: proto.String(pkgPath + "/" + path.Base(pkgPath) + ".proto"), Syntax: proto.String(file.pbDesc.Syntax().String()), Dependency: []string{file.pbDesc.Path()}, PublicDependency: []int32{0}, Options: &descriptorpb.FileOptions{GoPackage: proto.String(file.goPkg)}, } req.ProtoFile = append(req.ProtoFile, protodesc.ToFileDescriptorProto(file.pbDesc), fd) req.FileToGenerate = append(req.FileToGenerate, fd.GetName()) } // Use the internal logic of protoc-gen-go to generate the files. gen, err := protogen.New(&req, nil) check(err) for _, file := range gen.Files { if file.Generate { gengo.GenerateVersionMarkers = false gengo.GenerateFile(gen, file) } } // Write the generated files. resp := gen.Response() if resp.Error != nil { panic("gengo error: " + resp.GetError()) } for _, file := range resp.File { relPath, err := filepath.Rel(filepath.FromSlash("github.com/golang/protobuf"), file.GetName()) check(err) check(ioutil.WriteFile(relPath+".bak", []byte(file.GetContent()), 0664)) if *run { fmt.Println("#", relPath) check(os.Rename(relPath+".bak", relPath)) } else { cmd := exec.Command("diff", relPath, relPath+".bak", "-N", "-u") cmd.Stdout = os.Stdout cmd.Run() os.Remove(relPath + ".bak") // best-effort delete } } } func check(err error) { if err != nil { panic(err) } }