github.com/cloudwego/kitex@v0.9.0/tool/internal_pkg/pluginmode/protoc/protoc.go (about) 1 // Copyright 2021 CloudWeGo Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package protoc 16 17 import ( 18 "errors" 19 "fmt" 20 "os" 21 "path/filepath" 22 "strings" 23 24 gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo" 25 "google.golang.org/protobuf/compiler/protogen" 26 "google.golang.org/protobuf/proto" 27 "google.golang.org/protobuf/types/pluginpb" 28 29 "github.com/cloudwego/kitex/tool/internal_pkg/log" 30 "github.com/cloudwego/kitex/tool/internal_pkg/util" 31 ) 32 33 // PluginName . 34 const PluginName = "protoc-gen-kitex" 35 36 // Run . 37 func Run() int { 38 opts := protogen.Options{} 39 if err := run(opts); err != nil { 40 fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), err) 41 return 1 42 } 43 return 0 44 } 45 46 func run(opts protogen.Options) error { 47 // unmarshal request from stdin 48 in, err := util.ReadInput() 49 if err != nil { 50 return err 51 } 52 req := &pluginpb.CodeGeneratorRequest{} 53 if err := proto.Unmarshal(in, req); err != nil { 54 return err 55 } 56 57 // init plugin 58 pp := new(protocPlugin) 59 pp.init() 60 args := strings.Split(req.GetParameter(), ",") 61 err = pp.Unpack(args) 62 if err != nil { 63 return fmt.Errorf("%s: unpack args: %w", PluginName, err) 64 } 65 66 pp.parseM() 67 68 // unify go_package 69 pe := &pathElements{ 70 module: pp.ModuleName, 71 prefix: pp.PackagePrefix, 72 } 73 for _, f := range req.ProtoFile { 74 if f == nil { 75 return errors.New("ERROR: got nil ProtoFile") 76 } 77 78 gopkg, ok := pp.importPaths[f.GetName()] 79 if ok { 80 f.Options.GoPackage = &gopkg 81 log.Infof("[INFO] option specified import path for %q: %q\n", f.GetName(), gopkg) 82 } else { 83 if f.Options == nil || f.Options.GoPackage == nil { 84 return fmt.Errorf("ERROR: go_package is missing in proto file %q", f.GetName()) 85 } 86 gopkg = f.GetOptions().GetGoPackage() 87 } 88 if path, ok := pe.getImportPath(gopkg); ok { 89 f.Options.GoPackage = &path 90 log.Infof("[INFO] update import path for %q: %q -> %q\n", f.GetName(), gopkg, path) 91 } 92 } 93 94 // generate files 95 gen, err := opts.New(req) 96 if err != nil { 97 return err 98 } 99 pp.process(gen) 100 gen.SupportedFeatures = gengo.SupportedFeatures 101 102 // construct plugin response 103 resp := gen.Response() 104 out, err := proto.Marshal(resp) 105 if err != nil { 106 return err 107 } 108 if _, err := os.Stdout.Write(out); err != nil { 109 return err 110 } 111 return nil 112 }