Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 37 additions & 20 deletions cmd/protoc-gen-elixir-grpc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ const (
usage = "\n\nFlags:\n -h, --help\tPrint this help and exit.\n --version\tPrint the version and exit.\n --handler_module_prefix\tCustom Elixir module prefix for handler modules instead of protobuf package.\n --http_transcode\tEnable HTTP transcoding support (adds http_transcode: true to use GRPC.Server).\n --codecs\tComma-separated list of codec modules (e.g., 'GRPC.Codec.Proto,GRPC.Codec.WebText,GRPC.Codec.JSON').\n --compressors\tComma-separated list of compressor modules (e.g., 'GRPC.Compressor.Gzip')."
)

// GenerateOptions contains configuration options for generating Elixir gRPC files
type GenerateOptions struct {
PackagePrefix string
HandlerModulePrefix string
HTTPTranscode bool
Codecs []string
Compressors []string
}

func parsePluginParameters(paramStr string, flagSet *flag.FlagSet) error {
if paramStr == "" {
return nil
Expand Down Expand Up @@ -222,6 +231,14 @@ func main() {
codecsList := parseCodecs(*codecs)
compressorsList := parseCodecs(*compressors)

opts := GenerateOptions{
PackagePrefix: *packagePrefix,
HandlerModulePrefix: *handlerModulePrefix,
HTTPTranscode: *httpTranscode,
Codecs: codecsList,
Compressors: compressorsList,
}

for _, fileName := range req.FileToGenerate {
var protoFile *descriptorpb.FileDescriptorProto
for _, file := range req.ProtoFile {
Expand All @@ -238,7 +255,7 @@ func main() {
continue
}

generateElixirFile(resp, protoFile, *packagePrefix, *handlerModulePrefix, *httpTranscode, codecsList, compressorsList)
generateElixirFile(resp, protoFile, opts)
}

output, err := proto.Marshal(resp)
Expand All @@ -253,12 +270,12 @@ func main() {
}
}

func generateElixirFile(resp *pluginpb.CodeGeneratorResponse, file *descriptorpb.FileDescriptorProto, packagePrefix, handlerModulePrefix string, httpTranscode bool, codecs []string, compressors []string) {
func generateElixirFile(resp *pluginpb.CodeGeneratorResponse, file *descriptorpb.FileDescriptorProto, opts GenerateOptions) {
if len(file.Service) == 0 {
return
}

fileName := generateFilePath(file, packagePrefix)
fileName := generateFilePath(file, opts)

var content strings.Builder
content.WriteString("# Code generated by protoc-gen-elixir-grpc. DO NOT EDIT.\n")
Expand All @@ -267,7 +284,7 @@ func generateElixirFile(resp *pluginpb.CodeGeneratorResponse, file *descriptorpb
content.WriteString("\n")

for _, service := range file.Service {
generateServiceModule(&content, file, service, handlerModulePrefix, httpTranscode, codecs, compressors)
generateServiceModule(&content, file, service, opts)
content.WriteString("\n")
}

Expand All @@ -277,29 +294,29 @@ func generateElixirFile(resp *pluginpb.CodeGeneratorResponse, file *descriptorpb
})
}

func generateServiceModule(content *strings.Builder, file *descriptorpb.FileDescriptorProto, service *descriptorpb.ServiceDescriptorProto, handlerModulePrefix string, httpTranscode bool, codecs []string, compressors []string) {
func generateServiceModule(content *strings.Builder, file *descriptorpb.FileDescriptorProto, service *descriptorpb.ServiceDescriptorProto, opts GenerateOptions) {
serverModuleName := generateServerModuleName(file, service)
serviceModuleName := generateServiceModuleName(file, service)

content.WriteString("defmodule " + serverModuleName + " do\n")
content.WriteString(" use GRPC.Server,\n")
content.WriteString(" service: " + serviceModuleName)
if httpTranscode {
if opts.HTTPTranscode {
content.WriteString(",\n http_transcode: true")
}
if len(codecs) > 0 {
if len(opts.Codecs) > 0 {
content.WriteString(",\n codecs: [")
for i, codec := range codecs {
for i, codec := range opts.Codecs {
if i > 0 {
content.WriteString(", ")
}
content.WriteString(codec)
}
content.WriteString("]")
}
if len(compressors) > 0 {
if len(opts.Compressors) > 0 {
content.WriteString(",\n compressors: [")
for i, compressor := range compressors {
for i, compressor := range opts.Compressors {
if i > 0 {
content.WriteString(", ")
}
Expand All @@ -310,15 +327,15 @@ func generateServiceModule(content *strings.Builder, file *descriptorpb.FileDesc
content.WriteString("\n\n")

for _, method := range service.Method {
generateMethodDelegate(content, file, service, method, handlerModulePrefix)
generateMethodDelegate(content, file, service, method, opts)
}

content.WriteString("end")
}

func generateMethodDelegate(content *strings.Builder, file *descriptorpb.FileDescriptorProto, service *descriptorpb.ServiceDescriptorProto, method *descriptorpb.MethodDescriptorProto, handlerModulePrefix string) {
func generateMethodDelegate(content *strings.Builder, file *descriptorpb.FileDescriptorProto, service *descriptorpb.ServiceDescriptorProto, method *descriptorpb.MethodDescriptorProto, opts GenerateOptions) {
methodName := toSnakeCase(method.GetName())
handlerModuleName := generateHandlerModuleName(file, service, method, handlerModulePrefix)
handlerModuleName := generateHandlerModuleName(file, service, method, opts)

isStreamingClient := method.GetClientStreaming()
isStreamingServer := method.GetServerStreaming()
Expand Down Expand Up @@ -376,14 +393,14 @@ func generateServerModuleName(file *descriptorpb.FileDescriptorProto, service *d
return strings.Join(elixirParts, ".")
}

func generateHandlerModuleName(file *descriptorpb.FileDescriptorProto, service *descriptorpb.ServiceDescriptorProto, method *descriptorpb.MethodDescriptorProto, handlerModulePrefix string) string {
func generateHandlerModuleName(file *descriptorpb.FileDescriptorProto, service *descriptorpb.ServiceDescriptorProto, method *descriptorpb.MethodDescriptorProto, opts GenerateOptions) string {
serviceName := service.GetName()
methodName := method.GetName()
pkg := file.GetPackage()

if handlerModulePrefix != "" {
if opts.HandlerModulePrefix != "" {
if pkg == "" {
return fmt.Sprintf("%s.%s.Server.%sHandler", handlerModulePrefix, toPascalCase(serviceName), toPascalCase(methodName))
return fmt.Sprintf("%s.%s.Server.%sHandler", opts.HandlerModulePrefix, toPascalCase(serviceName), toPascalCase(methodName))
}

parts := strings.Split(pkg, ".")
Expand All @@ -392,7 +409,7 @@ func generateHandlerModuleName(file *descriptorpb.FileDescriptorProto, service *
packageParts = append(packageParts, toPascalCase(part))
}

return fmt.Sprintf("%s.%s.%s.Server.%sHandler", handlerModulePrefix, strings.Join(packageParts, "."), toPascalCase(serviceName), toPascalCase(methodName))
return fmt.Sprintf("%s.%s.%s.Server.%sHandler", opts.HandlerModulePrefix, strings.Join(packageParts, "."), toPascalCase(serviceName), toPascalCase(methodName))
}

if pkg == "" {
Expand All @@ -410,14 +427,14 @@ func generateHandlerModuleName(file *descriptorpb.FileDescriptorProto, service *
return strings.Join(elixirParts, ".")
}

func generateFilePath(file *descriptorpb.FileDescriptorProto, packagePrefix string) string {
func generateFilePath(file *descriptorpb.FileDescriptorProto, opts GenerateOptions) string {
pkg := file.GetPackage()
fileName := file.GetName()

var pathParts []string

if packagePrefix != "" {
pathParts = append(pathParts, packagePrefix)
if opts.PackagePrefix != "" {
pathParts = append(pathParts, opts.PackagePrefix)
}

if pkg != "" {
Expand Down