package main import ( "strings" "github.com/go-kratos/kratos/cmd/protoc-gen-go-errors/v2/errors" "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/proto" ) const ( errorsPackage = protogen.GoImportPath("github.com/go-kratos/kratos/v2/errors") fmtPackage = protogen.GoImportPath("fmt") ) // generateFile generates a _http.pb.go file containing kratos errors definitions. func generateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile { var hasCode bool for _, enum := range file.Enums { if code := defaultErrorCode(enum); code > 0 { hasCode = true } } if len(file.Enums) == 0 || !hasCode { return nil } filename := file.GeneratedFilenamePrefix + "_errors.pb.go" g := gen.NewGeneratedFile(filename, file.GoImportPath) g.P("// Code generated by protoc-gen-go-errors. DO NOT EDIT.") g.P() g.P("package ", file.GoPackageName) g.P() g.QualifiedGoIdent(fmtPackage.Ident("")) generateFileContent(gen, file, g) return g } // generateFileContent generates the kratos errors definitions, excluding the package statement. func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) { if len(file.Enums) == 0 { return } g.P("// This is a compile-time assertion to ensure that this generated file") g.P("// is compatible with the kratos package it is being compiled against.") g.P("const _ = ", errorsPackage.Ident("SupportPackageIsVersion1")) g.P() for _, enum := range file.Enums { genErrorsReason(gen, file, g, enum) } } func defaultErrorCode(enum *protogen.Enum) int { defaultCode := proto.GetExtension(enum.Desc.Options(), errors.E_DefaultCode) if code, ok := defaultCode.(int32); ok && code > 0 { return int(code) } return 0 } func genErrorsReason(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, enum *protogen.Enum) { var ew errorWrapper defCode := defaultErrorCode(enum) for _, v := range enum.Values { code := int(proto.GetExtension(v.Desc.Options(), errors.E_Code).(int32)) if code == 0 { code = defCode } if code > 600 || code < 200 { panic("httpstatus code must be greater than or equal to 200 and less than 600") } err := &errorInfo{ Name: string(enum.Desc.Name()), Value: string(v.Desc.Name()), CamelValue: case2Camel(string(v.Desc.Name())), HttpCode: code, } ew.Errors = append(ew.Errors, err) } g.P(ew.execute()) } func case2Camel(name string) string { if !strings.Contains(name, "_") { return name } name = strings.ToLower(name) name = strings.Replace(name, "_", " ", -1) name = strings.Title(name) return strings.Replace(name, " ", "", -1) }