package gen import ( "path" "strings" "google.golang.org/protobuf/reflect/protoreflect" ) // luaPackagePath returns the dotted Lua require path for a generated file. // // Resolution order: // 1. file option (tarantool.lua_package), used as-is // 2. proto package + file basename + "_pb" // e.g. package=foo.bar, file=baz.proto -> "foo.bar.baz_pb" // 3. file basename only (when proto package is empty) // e.g. file=baz.proto -> "baz_pb" func luaPackagePath(f protoreflect.FileDescriptor, prefix string) string { var p string if v := luaPackageOption(f); v != "" { p = v } else { base := strings.TrimSuffix(path.Base(f.Path()), ".proto") + "_pb" if pkg := string(f.Package()); pkg != "" { p = pkg + "." + base } else { p = base } } if prefix != "" { return prefix + "." + p } return p } // outputFilename returns the on-disk path (relative to the protoc out dir) // for a generated file. Mirrors the dotted Lua require path with `/`-separators // and a `.lua` extension. // // For example, lua package "myapp.proto.foo" -> "myapp/proto/foo.lua". func outputFilename(f protoreflect.FileDescriptor, prefix string) string { return strings.ReplaceAll(luaPackagePath(f, prefix), ".", "/") + ".lua" } // luaTypeName returns the underscore-flattened type name used in generated // Lua module tables. Strips the leading proto-package prefix. // // Examples (assuming file package = "foo.bar"): // foo.bar.Person -> "Person" // foo.bar.Outer.Inner -> "Outer_Inner" // foo.bar.Color -> "Color" func luaTypeName(fullName protoreflect.FullName, filePkg protoreflect.FullName) string { s := string(fullName) if filePkg != "" { prefix := string(filePkg) + "." s = strings.TrimPrefix(s, prefix) } return strings.ReplaceAll(s, ".", "_") } // importAlias produces a stable Lua local-variable name for a required module. // It dot-separates the module path and joins with underscores, prefixed with // "_imp_" to avoid clashing with user identifiers. // // "myapp.proto.foo" -> "_imp_myapp_proto_foo" func importAlias(luaPath string) string { return "_imp_" + strings.ReplaceAll(luaPath, ".", "_") } // isWellKnownTypeFile reports whether the file declares Google's // google.protobuf.* well-known types. Those are fulfilled by `pb.wkt` // at runtime and don't need a separate generated module. func isWellKnownTypeFile(fd protoreflect.FileDescriptor) bool { return string(fd.Package()) == "google.protobuf" } // wktTypeName strips the `google.protobuf.` prefix from a WKT type's full // name. Example: "google.protobuf.Timestamp" -> "Timestamp". func wktTypeName(full protoreflect.FullName) string { return strings.TrimPrefix(string(full), "google.protobuf.") }