{"owner":"zeromicro","repo":"go-zero","hasSkills":true,"totalSkillsCount":20,"totalTokensCount":37319,"categories":["copilot-instructions","plugin-manifest","anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":[".github/copilot-instructions.md","tools/goctl/api/parser/readme.md","tools/goctl/api/swagger/example/example.swagger.json","tools/goctl/api/swagger/example/example_cn.swagger.json","tools/goctl/config/readme.md","tools/goctl/model/mongo/readme.md","tools/goctl/model/sql/README.MD","tools/goctl/readme.md","tools/goctl/rpc/README.md","tools/goctl/rpc/example/01-basic/README.md","tools/goctl/rpc/example/02-import-sibling/README.md","tools/goctl/rpc/example/03-import-subdir/README.md","tools/goctl/rpc/example/04-transitive-import/README.md","tools/goctl/rpc/example/05-multiple-services/README.md","tools/goctl/rpc/example/06-wellknown-types/README.md","tools/goctl/rpc/example/07-external-proto-same-pkg/README.md","tools/goctl/rpc/example/08-external-proto-diff-pkg/README.md","tools/goctl/rpc/example/09-google-types-as-rpc/README.md","tools/goctl/rpc/example/10-streaming/README.md","tools/goctl/rpc/example/README.md"],"skills":{".github/copilot-instructions.md":"# GitHub Copilot Instructions for go-zero\n\nThis document provides guidelines for GitHub Copilot when assisting with development in the go-zero project.\n\n## Project Overview\n\ngo-zero is a web and RPC framework with lots of built-in engineering practices designed to ensure the stability of busy services with resilience design. It has been serving sites with tens of millions of users for years.\n\n### Key Architecture Components\n\n- **REST API framework** (`rest/`) - HTTP service framework with middleware chain support\n- **RPC framework** (`zrpc/`) - gRPC-based RPC framework with etcd service discovery and p2c_ewma load balancing\n- **Gateway** (`gateway/`) - API gateway supporting both HTTP and gRPC upstreams with proto-based routing\n- **MCP Server** (`mcp/`) - Model Context Protocol server for AI agent integration via SSE\n- **Core utilities** (`core/`) - Production-grade components:\n  - Resilience: circuit breakers (`breaker/`), rate limiters (`limit/`), adaptive load shedding (`load/`)\n  - Storage: SQL with cache (`stores/sqlc/`), Redis (`stores/redis/`), MongoDB (`stores/mongo/`)\n  - Concurrency: MapReduce (`mr/`), worker pools (`executors/`), sync primitives (`syncx/`)\n  - Observability: metrics (`metric/`), tracing (`trace/`), structured logging (`logx/`)\n- **Code generation tool** (`tools/goctl/`) - CLI tool for generating Go code from `.api` and `.proto` files\n\n## Coding Standards and Conventions\n\n### Code Style\n\n1. **Follow Go conventions**: Use `gofmt` for formatting, follow effective Go practices\n2. **Package naming**: Use lowercase, single-word package names when possible\n3. **Error handling**: Always handle errors explicitly, use `errorx.BatchError` for multiple errors\n4. **Context propagation**: Always pass `context.Context` as the first parameter for functions that may block\n5. **Configuration structures**: Use struct tags with JSON annotations, defaults, and validation\n\n**Pattern**: All service configs embed `service.ServiceConf` for common fields (Name, Log, Mode, Telemetry)\n```go\ntype Config struct {\n    service.ServiceConf              // Always embed for services\n    Host     string `json:\",default=0.0.0.0\"`\n    Port     int    // Required field (no default)\n    Timeout  int64  `json:\",default=3000\"`  // Timeouts in milliseconds\n    Optional string `json:\",optional\"`      // Optional field\n    Mode     string `json:\",default=pro,options=dev|test|rt|pre|pro\"`  // Validated options\n}\n```\n\n**Service modes**: `dev`/`test`/`rt` disable load shedding and stats; `pre`/`pro` enable all resilience features\n\n### Interface Design\n\n1. **Small interfaces**: Follow Go's preference for small, focused interfaces\n2. **Context methods**: Provide both context and non-context versions of methods\n3. **Options pattern**: Use functional options for complex configuration\n\nExample:\n```go\nfunc (c *Client) Get(key string, val any) error {\n    return c.GetCtx(context.Background(), key, val)\n}\n\nfunc (c *Client) GetCtx(ctx context.Context, key string, val any) error {\n    // implementation\n}\n```\n\n### Testing Patterns\n\n1. **Test file naming**: Use `*_test.go` suffix\n2. **Test function naming**: Use `TestFunctionName` pattern\n3. **Use testify/assert**: Prefer `assert` package for assertions\n4. **Table-driven tests**: Use table-driven tests for multiple scenarios\n5. **Mock interfaces**: Use `go.uber.org/mock` for mocking\n6. **Test helpers**: Use `redistest`, `mongtest` helpers for database testing\n\nExample test pattern:\n```go\nfunc TestSomething(t *testing.T) {\n    tests := []struct {\n        name     string\n        input    string\n        expected string\n        wantErr  bool\n    }{\n        {\"valid case\", \"input\", \"output\", false},\n        {\"error case\", \"bad\", \"\", true},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            result, err := SomeFunction(tt.input)\n            if tt.wantErr {\n                assert.Error(t, err)\n                return\n            }\n            assert.NoError(t, err)\n            assert.Equal(t, tt.expected, result)\n        })\n    }\n}\n```\n\n## Framework-Specific Guidelines\n\n### REST API Development\n\n1. **API Definition**: Use `.api` files to define REST APIs with goctl codegen\n2. **Handler pattern**: Separate business logic into logic packages (handlers call logic layer)\n3. **Middleware chain**: Middlewares wrap via `chain.Chain` interface - use `Append()` or `Prepend()` to control order\n   - Built-in middlewares (all in `rest/handler/`): tracing, logging, metrics, recovery, breaker, shedding, timeout, maxconns, maxbytes, gunzip\n   - Custom middleware: `func(http.Handler) http.Handler` - call `next.ServeHTTP(w, r)` to continue chain\n4. **Response handling**: Use `httpx.WriteJson(w, code, v)` for JSON responses\n5. **Error handling**: Use `httpx.Error(w, err)` or `httpx.ErrorCtx(ctx, w, err)` for HTTP error responses\n6. **Route registration**: Routes defined with `Method`, `Path`, and `Handler` - wildcards use `:param` syntax\n\n### RPC Development\n\n1. **Protocol Buffers**: Use protobuf for service definitions, generate code with goctl\n2. **Service discovery**: Use etcd for dynamic service registration/discovery, or direct endpoints for static routing\n3. **Load balancing**: Default is `p2c_ewma` (power of 2 choices with EWMA), configurable via `BalancerName`\n4. **Client configuration**: Support `Etcd`, `Endpoints`, or `Target` - use `BuildTarget()` to construct connection string\n5. **Interceptors**: Implement gRPC interceptors for cross-cutting concerns (auth, logging, metrics)\n6. **Health checks**: gRPC health checks enabled by default (`Health: true`)\n\n### Database Operations\n\n1. **SQL operations**: Use `sqlx.SqlConn` interface - methods always end with `Ctx` for context support\n2. **Caching pattern**: `stores/sqlc` provides `CachedConn` for automatic cache-aside pattern\n   - `QueryRowCtx`: Query with cache key, auto-populate on cache miss\n   - `ExecCtx`: Execute and delete cache keys\n3. **Transactions**: Use `sqlx.SqlConn.TransactCtx()` to get transaction session\n4. **Connection pooling**: Managed automatically (64 max idle/open, 1min lifetime)\n5. **Test helpers**: Use `redistest.CreateRedis(t)` for Redis, SQL mocks for DB testing\n\nExample cache pattern:\n```go\nerr := c.QueryRowCtx(ctx, &dest, key, func(ctx context.Context, conn sqlx.SqlConn) error {\n    return conn.QueryRowCtx(ctx, &dest, query, args...)\n})\n```\n\n### Configuration Management\n\n1. **YAML configuration**: Use YAML for configuration files\n2. **Environment variables**: Support environment variable overrides\n3. **Validation**: Include proper validation for configuration parameters\n4. **Sensible defaults**: Provide reasonable default values\n\n## Error Handling Best Practices\n\n1. **Wrap errors**: Use `fmt.Errorf` with `%w` verb to wrap errors\n2. **Custom errors**: Define custom error types when needed\n3. **Error logging**: Log errors appropriately with context\n4. **Graceful degradation**: Implement fallback mechanisms\n\n## Performance Considerations\n\n1. **Resource pools**: Use connection pools and worker pools\n2. **Circuit breakers**: Implement circuit breaker patterns for external calls\n3. **Rate limiting**: Apply rate limiting to protect services\n4. **Load shedding**: Implement adaptive load shedding\n5. **Metrics**: Add appropriate metrics and monitoring\n\n## Security Guidelines\n\n1. **Input validation**: Validate all input parameters\n2. **SQL injection prevention**: Use parameterized queries\n3. **Authentication**: Implement proper JWT token handling\n4. **HTTPS**: Support TLS/HTTPS configurations\n5. **CORS**: Configure CORS appropriately for web APIs\n\n## Documentation Standards\n\n1. **Package documentation**: Include package-level documentation\n2. **Function documentation**: Document exported functions with examples\n3. **API documentation**: Maintain API documentation in sync\n4. **README updates**: Update README for significant changes\n\n## GitHub Issue Management\n\n### Understanding and Categorizing Issues\n\nWhen analyzing GitHub issues, consider these common categories:\n\n1. **Bug Reports**: Stack traces, version info, reproduction steps\n2. **Feature Requests**: Use case, proposed solution, alternatives\n3. **Questions**: Usage, configuration, or architecture\n4. **Documentation Issues**: Missing, unclear, or incorrect docs\n5. **Performance Issues**: Benchmarks, profiling data, resource usage\n\n### Issue Analysis Checklist\n\n- Identify affected component (REST, RPC, Gateway, MCP, Core utilities, goctl)\n- Check versions (go-zero, Go)\n- Look for reproduction steps or code examples\n- Review code snippets, logs, or stack traces\n- Check if related to resilience features (breaker, load shedding, rate limiting)\n- Determine production impact\n\n### Responding to Issues\n\nBe helpful and professional. Ask clarifying questions when needed. Reference relevant documentation and code files. Provide code examples following project conventions. Suggest workarounds when applicable.\n\n### Chinese to English Translation\n\ngo-zero has an international user base. When encountering issues or comments written in Chinese, translate them to English to ensure all contributors can participate in discussions.\n\n#### Translation Guidelines\n\n1. **Update issue titles**: Edit the issue title to include English translation only\n2. **Translate comments in place**: Add a comment with the English translation, followed by the original Chinese text\n3. **Keep original Chinese**: After translating, include the original Chinese text in a blockquote for verification\n4. **Encourage English communication**: Politely suggest users write in English for better collaboration\n5. **Maintain technical accuracy**: Preserve technical terms, component names, and code exactly\n6. **Translate naturally**: Avoid literal word-by-word translation; use idiomatic English\n7. **Preserve formatting**: Keep markdown formatting, code blocks, and links intact\n8. **Keep URLs unchanged**: Don't translate URLs or file paths\n\n#### Common Technical Terms (Chinese → English)\n\n- 框架 → **Framework** | 中间件 → **Middleware** | 负载均衡 → **Load Balancing**\n- 熔断器 → **Circuit Breaker** | 限流 → **Rate Limiting** | 降载/过载保护 → **Load Shedding**\n- 服务发现 → **Service Discovery** | 配置 → **Configuration** | 弹性/容错 → **Resilience** | 微服务 → **Microservices**\n\n#### Translation Example\n\n**Original Chinese Title:** `goctl 执行环境问题`\n**Updated Title:** `goctl Execution Environment Issue`\n\n**Original Chinese Comment:** `我在项目中遇到熔断器配置问题`\n**Translation in Comment:**\n```markdown\nI encountered a circuit breaker configuration issue in my project.\n\n> Original (原文): 我在项目中遇到熔断器配置问题\n```\n\n### Common Issue Patterns and Solutions\n\n#### Configuration Issues\n- Check `service.ServiceConf` embedding and struct tags\n- Verify YAML syntax, defaults, and validation rules\n- Reference: [rest/config.go](rest/config.go), [zrpc/config.go](zrpc/config.go)\n\n#### Code Generation (goctl) Issues\n- Verify `.api` or `.proto` file syntax and goctl version\n- Reference: `tools/goctl/` directory\n\n#### RPC Connection Issues\n- Check etcd configuration, service discovery, and endpoints\n- Verify load balancing settings (p2c_ewma)\n\n#### Database/Cache Issues\n- Verify `sqlx.SqlConn` usage with context\n- Check cache key generation, invalidation, and connection pools\n- Use test helpers (`redistest`, `mongtest`)\n\n#### Performance Issues\n- Check if load shedding is enabled (mode: `pre`/`pro`)\n- Review circuit breaker thresholds, rate limiting, and context timeouts\n\n### Referencing Codebase\n\nWhen explaining issues, reference specific files and patterns:\n- REST API: `rest/`, `rest/handler/`, `rest/httpx/`\n- RPC: `zrpc/`, `zrpc/internal/`\n- Core utilities: `core/breaker/`, `core/limit/`, `core/load/`, etc.\n- Gateway: `gateway/`\n- MCP: `mcp/`\n- Code generation: `tools/goctl/`\n- Examples: `adhoc/` directory contains various examples\n\n### Encouraging Best Practices\n\nWhen responding to issues, gently guide users toward:\n- Proper error handling with context\n- Using resilience features (breakers, rate limiters)\n- Following testing patterns with table-driven tests\n- Implementing proper resource cleanup\n- Reading existing documentation in `docs/` and `readme.md`\n\n## Common Patterns to Follow\n\n### Service Configuration\n```go\ntype ServiceConf struct {\n    Name string\n    Log  logx.LogConf\n    Mode string `json:\",default=pro,options=[dev,test,pre,pro]\"`\n    // ... other common fields\n}\n```\n\n### Middleware Implementation\n```go\nfunc SomeMiddleware() rest.Middleware {\n    return func(next http.HandlerFunc) http.HandlerFunc {\n        return func(w http.ResponseWriter, r *http.Request) {\n            // Pre-processing\n            next.ServeHTTP(w, r)\n            // Post-processing\n        }\n    }\n}\n```\n\n### Resource Management\nAlways implement proper resource cleanup using defer and context cancellation.\n\n## Build and Test Commands\n\n- Build: `go build ./...`\n- Test: `go test ./...`\n- Test with race detection: `go test -race ./...`\n- Format: `gofmt -w .`\n- Code generation:\n  - REST API: `goctl api go -api *.api -dir .`\n  - RPC: `goctl rpc protoc *.proto --go_out=. --go-grpc_out=. --zrpc_out=.`\n  - Model from SQL: `goctl model mysql datasource -url=\"user:pass@tcp(host:port)/db\" -table=\"*\" -dir=\"./model\"`\n\n## Critical Architecture Patterns\n\n### Resilience Design Philosophy\ngo-zero implements defense-in-depth with multiple protection layers:\n1. **Circuit Breaker** (`core/breaker`): Google SRE breaker - tracks success/failure, opens on error threshold\n2. **Adaptive Load Shedding** (`core/load`): CPU-based auto-rejection when system overloaded (disabled in dev/test/rt modes)\n3. **Rate Limiting** (`core/limit`): Token bucket (Redis-based) and period limiters\n4. **Timeout Control**: Cascading timeouts via context - set at multiple levels (client, server, handler)\n\n### Middleware Chain Architecture\n`rest/chain` provides middleware composition:\n```go\n// Middleware signature\ntype Middleware func(http.Handler) http.Handler\n\n// Chain operations\nchain := chain.New(m1, m2)\nchain.Append(m3)    // Adds to end: m1 -> m2 -> m3\nchain.Prepend(m0)   // Adds to start: m0 -> m1 -> m2 -> m3\nhandler := chain.Then(finalHandler)\n```\n\n### Concurrency Patterns\n- **MapReduce** (`core/mr`): Parallel processing with worker pools - use for batch operations\n- **Executors** (`core/executors`): Bulk/period executors for batching operations\n- **SingleFlight** (`core/syncx`): Deduplicates concurrent identical requests\n\nRemember to run tests and ensure all checks pass before submitting changes. The project emphasizes high quality, performance, and reliability, so these should be primary considerations in all development work.","tools/goctl/api/parser/readme.md":"# Api语法描述\n\n## api示例\n\n``` golang\n/**\n * api语法示例及语法说明\n */\n\n// api语法版本\nsyntax = \"v1\"\n\n// import literal\nimport \"foo.api\"\n\n// import group\nimport (\n    \"bar.api\"\n    \"foo/bar.api\"\n)\ninfo(\n    author: \"songmeizi\"\n    date:   \"2020-01-08\"\n    desc:   \"api语法示例及语法说明\"\n)\n\n// type literal\n\ntype Foo{\n    Foo int `json:\"foo\"`\n}\n\n// type group\n\ntype(\n    Bar{\n        Bar int `json:\"bar\"`\n    }\n)\n\n// service block\n@server(\n    jwt:   Auth\n    group: foo\n)\nservice foo-api{\n    @doc \"foo\"\n    @handler foo\n    post /foo (Foo) returns (Bar)\n}\n```\n\n## api语法结构\n\n* syntax语法声明\n* import语法块\n* info语法块\n* type语法块\n* service语法块\n* 隐藏通道\n\n> ### 温馨提示️\n> 在以上语法结构中，各个语法块从语法上来说，按照语法块为单位，可以在.api文件中任意位置声明，\n> 但是为了提高阅读效率，我们建议按照以上顺序进行声明，因为在将来可能会通过严格模式来控制语法块的顺序。\n\n### syntax语法声明\n\nsyntax是新加入的语法结构，该语法的引入可以解决：\n\n* 快速针对api版本定位存在问题的语法结构\n* 针对版本做语法解析\n* 防止api语法大版本升级导致前后不能向前兼容\n\n> ### 警告 ⚠️\n> 被import的api必须要和main api的syntax版本一致。\n\n**语法定义**\n\n``` antlrv4\n'syntax'={checkVersion(p)}STRING\n```\n\n**语法说明**\n> syntax：固定token，标志一个syntax语法结构的开始\n>\n> checkVersion：自定义go方法，检测`STRING`是否为一个合法的版本号，目前检测逻辑为，STRING必须是满足`(?m)\"v[1-9][0-9]*\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"v1\"\n>\n> 一个api语法文件只能有0或者1个syntax语法声明，如果没有syntax，则默认为v1版本\n>\n\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\nsyntax=\"v1\"\n```\n\neg2：规范写法(推荐)\n\n``` api\nsyntax = \"v2\"\n```\n\n**错误语法示例** ❌\n\neg1：\n\n``` api\nsyntax = \"v0\"\n```\n\neg2：\n\n``` api\nsyntax = v1\n```\n\neg3：\n\n``` api\nsyntax = \"V1\"\n```\n\n## import语法块\n\n随着业务规模增大，api中定义的结构体和服务越来越多，所有的语法描述均为一个api文件，这是多么糟糕的一个问题， 其会大大增加了阅读难度和维护难度，import语法块可以帮助我们解决这个问题，通过拆分api文件，\n不同的api文件按照一定规则声明，可以降低阅读难度和维护难度。\n\n> ### 警告 ⚠️\n> 这里import不像golang那样包含package声明，仅仅是一个文件路径的引入，最终解析后会把所有的声明都汇聚到一个spec.Spec中。\n> 不能import多个相同路径，否则会解析错误。\n\n**语法定义**\n\n``` antlrv4\n'import' {checkImportValue(p)}STRING  \n|'import' '(' ({checkImportValue(p)}STRING)+ ')'\n```\n\n**语法说明**\n> import：固定token，标志一个import语法的开始\n>\n> checkImportValue：自定义go方法，检测`STRING`是否为一个合法的文件路径，目前检测逻辑为，STRING必须是满足`(?m)\"(/?[a-zA-Z0-9_#-])+\\.api\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"foo.api\"\n>\n\n\n**正确语法示例** ✅\n\neg：\n\n``` api\nimport \"foo.api\"\nimport \"foo/bar.api\"\n\nimport(\n    \"bar.api\"\n    \"foo/bar/foo.api\"\n)\n```\n\n**错误语法示例** ❌\n\neg：\n\n``` api\nimport foo.api\nimport \"foo.txt\"\nimport (\n    bar.api\n    bar.api\n)\n```\n\n## info语法块\n\ninfo语法块是一个包含了多个键值对的语法体，其作用相当于一个api服务的描述，解析器会将其映射到spec.Spec中， 以备用于翻译成其他语言(golang、java等)\n时需要携带的meta元素。如果仅仅是对当前api的一个说明，而不考虑其翻译 时传递到其他语言，则使用简单的多行注释或者java风格的文档注释即可，关于注释说明请参考下文的 **隐藏通道**。\n\n> ### 警告 ⚠️\n> 不能使用重复的key，每个api文件只能有0或者1个info语法块\n\n**语法定义**\n\n``` antlrv4\n'info' '(' (ID {checkKeyValue(p)}VALUE)+ ')'\n```\n\n**语法说明**\n> info：固定token，标志一个info语法块的开始\n>\n> checkKeyValue：自定义go方法，检测`VALUE`是否为一个合法值。\n>\n> VALUE：key对应的值，可以为单行的除'\\r','\\n','/'后的任意字符，多行请以\"\"包裹，不过强烈建议所有都以\"\"包裹\n>\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ninfo(\nfoo: foo value\nbar:\"bar value\"\n    desc:\"long long long long\nlong long text\"\n)\n```\n\neg2：规范写法(推荐)\n\n``` api\ninfo(\n    foo: \"foo value\"\n    bar: \"bar value\"\n    desc: \"long long long long long long text\"\n)\n```\n\n**错误语法示例** ❌\n\neg1：没有key-value内容\n\n``` api\ninfo()\n```\n\neg2：不包含冒号\n\n``` api\ninfo(\n    foo value\n)\n```\n\neg3：key-value没有换行\n\n``` api\ninfo(foo:\"value\")\n```\n\neg4：没有key\n\n``` api\ninfo(\n    : \"value\"\n)\n```\n\neg5：非法的key\n\n``` api\ninfo(\n    12: \"value\"\n)\n```\n\neg6：移除旧版本多行语法\n\n``` api\ninfo(\n    foo: >\n    some text\n    <\n)\n```\n\n## type语法块\n\n在api服务中，我们需要用到一个结构体(类)来作为请求体，响应体的载体，因此我们需要声明一些结构体来完成这件事情， type语法块由golang的type演变而来，当然也保留着一些golang type的特性，沿用golang特性有：\n\n* 保留了golang内置数据类型`bool`,`int`,`int8`,`int16`,`int32`,`int64`,`uint`,`uint8`,`uint16`,`uint32`,`uint64`,`uintptr`\n  ,`float32`,`float64`,`complex64`,`complex128`,`string`,`byte`,`rune`,\n* 兼容golang struct风格声明\n* 保留golang关键字\n\n> ### 警告 ⚠️\n> * 不支持alias\n> * 不支持time.Time数据类型\n> * 结构体名称、字段名称、不能为golang关键字\n\n**语法定义**\n> 由于其和golang相似，因此不做详细说明，具体语法定义请在[ApiParser.g4](g4/ApiParser.g4)中查看typeSpec定义。\n\n**语法说明**\n\n> 参考golang写法\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ntype Foo struct{\n    Id int `path:\"id\"` // ①\n    Foo int `json:\"foo\"`\n}\n\ntype Bar struct{\n    // 非导出型字段\n    bar int `form:\"bar\"`\n}\n\ntype(\n    // 非导出型结构体\n    fooBar struct{\n        FooBar int\n    }\n)\n```\n\neg2：规范写法（推荐）\n\n``` api\ntype Foo{\n    Id int `path:\"id\"`\n    Foo int `json:\"foo\"`\n}\n\ntype Bar{\n    Bar int `form:\"bar\"`\n}\n\ntype(\n    FooBar{\n        FooBar int\n    }\n)\n```\n\n**错误语法示例** ❌\n\neg\n\n``` api\ntype Gender int // 不支持\n\n// 非struct token\ntype Foo structure{ \n  CreateTime time.Time // 不支持time.Time\n}\n\n// golang关键字 var\ntype var{} \n\ntype Foo{\n  // golang关键字 interface\n  Foo interface \n}\n\n\ntype Foo{\n  foo int \n  // map key必须要golang内置数据类型\n  m map[Bar]string\n}\n```\n\n**① tag说明**\n> tag定义和golang中json tag语法一样，除了json tag外，go-zero还提供了另外一些tag来实现对字段的描述，\n> 详情见下表。\n\n* tag表\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |json|json序列化tag|golang|request、response|`json:\"fooo\"`|\n  |path|路由path，如`/foo/:id`|go-zero|request|`path:\"id\"`|\n  |form|标志请求体是一个form（POST方法时）或者一个query(GET方法时`/search?name=keyword`)|go-zero|request|`form:\"name\"`|\n\n* tag修饰符\n  > 常见参数校验描述\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |optional|定义当前字段为可选参数|go-zero|request|`json:\"name,optional\"`|\n  |options|定义当前字段的枚举值,多个以竖线②隔开|go-zero|request|`json:\"gender,options=male\"`|\n  |default|定义当前字段默认值|go-zero|request|`json:\"gender,default=male\"`|\n  |range|定义当前字段数值范围|go-zero|request|`json:\"age,range=[0:120]\"`|\n\n  ② 竖线：|\n  > ### 温馨提示\n  > tag修饰符需要在tag value后以引文逗号,隔开\n\n## service语法块\n\nservice语法块用于定义api服务，包含服务名称，服务metadata，中间件声明，路由，handler等。\n\n> ### 警告 ⚠️\n> * main api和被import的api服务名称必须一致，不能出现服务名称歧义。\n> * handler名称不能重复\n> * 路由（请求方法+请求path）名称不能重复\n> * 请求体必须声明为普通（非指针）struct，响应体做了一些向前兼容处理，详请见下文说明\n>\n\n**语法定义**\n\n``` antlrv4\nserviceSpec:    atServer? serviceApi;\natServer:       '@server' lp='(' kvLit+ rp=')';\nserviceApi:     {match(p,\"service\")}serviceToken=ID serviceName lbrace='{' serviceRoute* rbrace='}';\nserviceRoute:   atDoc? (atServer|atHandler) route;\natDoc:          '@doc' lp='('? ((kvLit+)|STRING) rp=')'?;\natHandler:      '@handler' ID;\nroute:          {checkHttpMethod(p)}httpMethod=ID path request=body? returnToken=ID? response=replybody?;\nbody:           lp='(' (ID)? rp=')';\nreplybody:      lp='(' dataType? rp=')';\n// kv\nkvLit:          key=ID {checkKeyValue(p)}value=LINE_VALUE;\n\nserviceName:    (ID '-'?)+;\npath:           (('/' (ID ('-' ID)*))|('/:' (ID ('-' ID)?)))+;\n```\n\n**语法说明**\n\n> serviceSpec：包含了一个可选语法块`atServer`和`serviceApi`语法块，其遵循序列模式（编写service必须要按照顺序，否则会解析出错）\n>\n> atServer： 可选语法块，定义key-value结构的server metadata，'@server'表示这一个server语法块的开始，其可以用于描述serviceApi或者route语法块，其用于描述不同语法块时有一些特殊关键key\n> 需要值得注意，见 **atServer关键key描述说明**。\n>\n> serviceApi：包含了1到多个`serviceRoute`语法块\n>\n> serviceRoute：按照序列模式包含了`atDoc`,handler和`route`\n>\n> atDoc：可选语法块，一个路由的key-value描述，其在解析后会传递到spec.Spec结构体，如果不关心传递到spec.Spec,\n> 推荐用单行注释替代。\n>\n> handler：是对路由的handler层描述，可以通过atServer指定`handler` key来指定handler名称，\n> 也可以直接用atHandler语法块来定义handler名称\n>\n> atHandler：'@handler' 固定token，后接一个遵循正则`[_a-zA-Z][a-zA-Z_-]*`)的值，用于声明一个handler名称\n>\n> route：路由，有`httpMethod`、`path`、可选`request`、可选`response`组成，`httpMethod`是必须是小写。\n>\n> body：api请求体语法定义，必须要由()包裹的可选的ID值\n>\n> replyBody：api响应体语法定义，必须由()包裹的struct、~~array(向前兼容处理，后续可能会废弃，强烈推荐以struct包裹，不要直接用array作为响应体)~~\n>\n> kvLit： 同info key-value\n>\n> serviceName: 可以有多个'-'join的ID值\n>\n> path：api请求路径，必须以'/'或者'/:'开头，切不能以'/'结尾，中间可包含ID或者多个以'-'join的ID字符串\n\n**atServer关键key描述说明**\n\n修饰service时\n\n|key|描述|示例|\n|:---|:---|:---|\n|jwt|声明当前service下所有路由需要jwt鉴权，且会自动生成包含jwt逻辑的代码|`jwt: Auth`|\n|group|声明当前service或者路由文件分组|`group: login`|\n|middleware|声明当前service需要开启中间件|`middleware: AuthMiddleware`|\n\n修饰route时\n\n|key|描述|示例|\n|:---|:---|:---|\n|handler|声明一个handler|-|\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc(\n    summary: foo\n  )\n  @server(\n    handler: foo\n  )\n  // 非导出型body\n  post /foo/:id (foo) returns (bar)\n  \n  @doc \"bar\"\n  @handler bar\n  post /bar returns ([]int)// 不推荐数组作为响应体\n  \n  @handler fooBar\n  post /foo/bar (Foo) returns // 可以省略'returns'\n}\n```\n\neg2：规范写法（推荐）\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc \"foo\"\n  @handler: foo\n  post /foo/:id (Foo) returns (Bar)\n}\n\nservice foo-api{\n  @handler ping\n  get /ping\n  \n  @doc \"foo\"\n  @handler: bar\n  post /bar/:id (Foo)\n}\n\n```\n\n**错误语法示例** ❌\n\n``` api\n// 不支持空的server语法块\n@server(\n)\n// 不支持空的service语法块\nservice foo-api{\n}\n\nservice foo-api{\n  @doc kkkk // 简版doc必须用英文双引号引起来\n  @handler foo\n  post /foo\n  \n  @handler foo // 重复的handler\n  post /bar\n  \n  @handler fooBar\n  post /bar // 重复的路由\n  \n  // @handler和@doc顺序错误\n  @handler someHandler\n  @doc \"some doc\"\n  post /some/path\n  \n  // handler缺失\n  post /some/path/:id\n  \n  @handler reqTest\n  post /foo/req (*Foo) // 不支持除普通结构体外的其他数据类型作为请求体\n  \n  @handler replyTest\n  post /foo/reply returns (*Foo) // 不支持除普通结构体、数组(向前兼容，后续考虑废弃)外的其他数据类型作为响应体\n}\n```\n\n## 隐藏通道\n\n隐藏通道目前主要为空白符号，换行符号以及注释，这里我们只说注释，因为空白符号和换行符号我们目前拿来也无用。\n\n### 单行注释\n\n**语法定义**\n\n``` antlrv4\n'//' ~[\\r\\n]*\n```\n\n**语法说明**\n由语法定义可知道，单行注释必须要以`//`开头，内容为不能包含换行符\n\n**正确语法示例** ✅\n\n``` api\n// doc\n// comment\n```\n\n**错误语法示例** ❌\n\n``` api\n// break\nline comments\n```\n\n### java风格文档注释\n\n**语法定义**\n\n``` antlrv4\n'/*' .*? '*/'\n```\n\n**语法说明**\n\n由语法定义可知道，单行注释必须要以`/*`开头，`*/`结尾的任意字符。\n\n**正确语法示例** ✅\n\n``` api\n/**\n * java-style doc\n */\n```\n\n**错误语法示例** ❌\n\n``` api\n/*\n * java-style doc */\n */\n```\n\n## Doc&Comment\n\n如果想获取某一个元素的doc或者comment开发人员需要怎么定义？\n\n**Doc**\n> 我们规定上一个语法块（非隐藏通道内容）的行数line+1到当前语法块第一个元素前的所有注释(当行，或者多行)均为doc， 且保留了`//`、`/*`、`*/`原始标记。\n\n**Comment**\n> 我们规定当前语法块最后一个元素所在行开始的一个注释块(当行，或者多行)为comment 且保留了`//`、`/*`、`*/`原始标记。\n\n语法块Doc和Comment的支持情况\n\n|语法块|parent语法块|Doc|Comment|\n|:---|:---|:---|:---|\n|syntaxLit|api|✅|✅|\n|kvLit|infoSpec|✅|✅|\n|importLit|importSpec|✅|✅|\n|typeLit|api|✅|❌|\n|typeLit|typeBlock|✅|❌|\n|field|typeLit|✅|✅|\n|key-value|atServer|✅|✅|\n|atHandler|serviceRoute|✅|✅|\n|route|serviceRoute|✅|✅|\n\n以下为对应语法块解析后细带doc和comment的写法\n``` api\n// syntaxLit doc\nsyntax = \"v1\" // syntaxLit comment\n\ninfo(\n  // kvLit doc\n  author: songmeizi // kvLit comment\n)\n\n// typeLit doc\ntype Foo {}\n\ntype(\n  // typeLit doc\n  Bar{}\n  \n  FooBar{\n    // filed doc\n    Name int // filed comment\n  }\n)\n\n@server(\n  /**\n   * kvLit doc\n   * 开启jwt鉴权\n   */\n  jwt: Auth /**kvLit comment*/\n)\nservice foo-api{\n  // atHandler doc\n  @handler foo //atHandler comment\n  \n  /*\n   * route doc\n   * post请求\n   * path为 /foo\n   * 请求体：Foo\n   * 响应体：Foo\n   */\n  post /foo (Foo) returns (Foo) // route comment\n}\n```\n","tools/goctl/api/swagger/example/example.swagger.json":"{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"Generating Swagger files using the API demo.\",\n    \"title\": \"Demo API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form demo\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-User not login\\u003cbr\\u003e1002-User permission denied\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"complex json request body API\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"postJson\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"number\": {\n                  \"type\": \"number\",\n                  \"example\": 1.1\n                },\n                \"object\": {\n                  \"type\": \"object\",\n                  \"required\": [\n                    \"integer\",\n                    \"number\",\n                    \"boolean\",\n                    \"string\",\n                    \"object\",\n                    \"pointerObject\"\n                  ],\n                  \"properties\": {\n                    \"boolean\": {\n                      \"type\": \"boolean\",\n                      \"enum\": [\n                        \"true\",\n                        \"false\"\n                      ],\n                      \"example\": true\n                    },\n                    \"integer\": {\n                      \"type\": \"integer\",\n                      \"example\": 1\n                    },\n                    \"number\": {\n                      \"type\": \"number\",\n                      \"example\": 1.1\n                    },\n                    \"object\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      },\n                      \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                    },\n                    \"pointerObject\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        }\n\n<!-- [TRUNCATED AT 50KB] -->","tools/goctl/api/swagger/example/example_cn.swagger.json":"{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"演示 api 生成 swagger 文件的 api 完整写法\",\n    \"title\": \"演示 API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form 接口\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form 表单 api 演示\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-未登录\\u003cbr\\u003e1002-无权限操作\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"复杂的 json 请求体接口\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"post json api 演示\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"mapMapObject\",\n                \"mapMapPointerObject\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"objec\n\n<!-- [TRUNCATED AT 50KB] -->","tools/goctl/config/readme.md":"# 配置项管理\n\n| 名称              | 是否可选 | 说明                                          |\n|-------------------|----------|-----------------------------------------------|\n| namingFormat      | YES      | 文件名称格式化符                      |\n\n# naming-format\n`namingFormat`可以用于对生成代码的文件名称进行格式化，和日期格式化符（yyyy-MM-dd）类似，在代码生成时可以根据这些配置项的格式化符进行格式化。\n\n## 格式化符(gozero)\n格式化符由`go`,`zero`组成，如常见的三种格式化风格你可以这样编写：\n* lower: `gozero`\n* camel: `goZero`\n* snake: `go_zero`\n\n常见格式化符生成示例\n源字符：welcome_to_go_zero\n\n| 格式化符   | 格式化结果            | 说明                      |\n|------------|-----------------------|---------------------------|\n| gozero     | welcometogozero       | 小写                      |\n| goZero     | welcomeToGoZero       | 驼峰                      |\n| go_zero    | welcome_to_go_zero    | snake                     |\n| Go#zero    | Welcome#to#go#zero    | #号分割Title类型          |\n| GOZERO     | WELCOMETOGOZERO       | 大写                      |\n| \\_go#zero_ | \\_welcome#to#go#zero_ | 下划线做前后缀，并且#分割 |\n\n错误格式化符示例\n* go\n* gOZero\n* zero\n* goZEro\n* goZERo\n* goZeRo\n* tal\n\n# 使用方法\n目前可通过在生成api、rpc、model时通过`--style`参数指定format格式，如：\n```shell script\ngoctl api go test.api -dir . -style gozero\n```\n```shell script\n goctl rpc proto -src test.proto -dir . -style go_zero\n```\n```shell script\ngoctl model mysql datasource -url=\"\" -table=\"*\" -dir ./snake -style GoZero\n```\n\n# 默认值\n当不指定-style时默认值为`gozero`\n","tools/goctl/model/mongo/readme.md":"# mongo生成model\n\n## 背景\n\n在业务务开发中，model(dao)数据访问层是一个服务必不可缺的一层，因此数据库访问的CURD也是必须要对外提供的访问方法， 而CURD在go-zero中就仅存在两种情况\n\n* 带缓存model\n* 不带缓存model\n\n从代码结构上来看，C-U-R-D四个方法就是固定的结构，因此我们可以将其交给goctl工具去完成，帮助我们提升开发效率。\n\n## 方案设计\n\nmongo的生成不同于mysql，mysql可以从scheme_information库中读取到一张表的信息（字段名称，数据类型，索引等），\n而mongo是文档型数据库，我们暂时无法从db中读取某一条记录来实现字段信息获取，就算有也不一定是完整信息（某些字段可能是omitempty修饰，可有可无）， 这里采用type自己编写+代码生成方式实现\n\n## 使用示例\n为 User 生成 mongo model\n```bash\n$ goctl model mongo -t User -c --dir .\n```\n\n### 生成示例代码\n\n#### usermodel.go\n```go\npackage model\n\nimport (\n\t\"github.com/zeromicro/go-zero/core/stores/cache\"\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n)\n\nvar _ UserModel = (*customUserModel)(nil)\n\ntype (\n\t// UserModel is an interface to be customized, add more methods here,\n\t// and implement the added methods in customUserModel.\n\tUserModel interface {\n\t\tuserModel\n\t}\n\n\tcustomUserModel struct {\n\t\t*defaultUserModel\n\t}\n)\n\n// NewUserModel returns a model for the mongo.\nfunc NewUserModel(url, db, collection string, c cache.CacheConf) UserModel {\n\tconn := monc.MustNewModel(url, db, collection, c)\n\treturn &customUserModel{\n\t\tdefaultUserModel: newDefaultUserModel(conn),\n\t}\n}\n\n```\n\n#### usermodelgen.go\n```go\n// Code generated by goctl. DO NOT EDIT.\npackage model\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n\t\"go.mongodb.org/mongo-driver/bson\"\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n\t\"go.mongodb.org/mongo-driver/mongo\"\n)\n\nvar prefixUserCacheKey = \"cache:user:\"\n\ntype userModel interface {\n\tInsert(ctx context.Context, data *User) error\n\tFindOne(ctx context.Context, id string) (*User, error)\n\tUpdate(ctx context.Context, data *User) (*mongo.UpdateResult, error)\n\tDelete(ctx context.Context, id string) (int64, error)\n}\n\ntype defaultUserModel struct {\n\tconn *monc.Model\n}\n\nfunc newDefaultUserModel(conn *monc.Model) *defaultUserModel {\n\treturn &defaultUserModel{conn: conn}\n}\n\nfunc (m *defaultUserModel) Insert(ctx context.Context, data *User) error {\n\tif !data.ID.IsZero() {\n\t\tdata.ID = primitive.NewObjectID()\n\t\tdata.CreateAt = time.Now()\n\t\tdata.UpdateAt = time.Now()\n\t}\n\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\t_, err := m.conn.InsertOne(ctx, key, data)\n\treturn err\n}\n\nfunc (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn nil, ErrInvalidObjectId\n\t}\n\n\tvar data User\n\tkey := prefixUserCacheKey + id\n\terr = m.conn.FindOne(ctx, key, &data, bson.M{\"_id\": oid})\n\tswitch err {\n\tcase nil:\n\t\treturn &data, nil\n\tcase monc.ErrNotFound:\n\t\treturn nil, ErrNotFound\n\tdefault:\n\t\treturn nil, err\n\t}\n}\n\nfunc (m *defaultUserModel) Update(ctx context.Context, data *User) (*mongo.UpdateResult, error) {\n\tdata.UpdateAt = time.Now()\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\tres, err := m.conn.ReplaceOne(ctx, key, bson.M{\"_id\": data.ID}, bson.M{\"$set\": data})\n\treturn res, err\n}\n\nfunc (m *defaultUserModel) Delete(ctx context.Context, id string) (int64, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn 0, ErrInvalidObjectId\n\t}\n\tkey := prefixUserCacheKey + id\n\tres, err := m.conn.DeleteOne(ctx, key, bson.M{\"_id\": oid})\n\treturn res, err\n}\n\n```\n\n#### usertypes.go\n```go\npackage model\n\nimport (\n\t\"time\"\n\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n)\n\ntype User struct {\n\tID primitive.ObjectID `bson:\"_id,omitempty\" json:\"id,omitempty\"`\n\t// TODO: Fill your own fields\n\tUpdateAt time.Time `bson:\"updateAt,omitempty\" json:\"updateAt,omitempty\"`\n\tCreateAt time.Time `bson:\"createAt,omitempty\" json:\"createAt,omitempty\"`\n}\n\n```\n\n#### error.go\n```go\npackage model\n\nimport (\n\t\"errors\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/mon\"\n)\n\nvar (\n\tErrNotFound        = mon.ErrNotFound\n\tErrInvalidObjectId = errors.New(\"invalid objectId\")\n)\n```\n\n### 文件目录预览\n\n```text\n.\n├── error.go\n├── usermodel.go\n├── usermodelgen.go\n└── usertypes.go\n```\n\n## 命令预览\n\n```text\nGenerate mongo model\n\nUsage:\n  goctl model mongo [flags]\n\nFlags:\n      --branch string   The branch of the remote repo, it does work with --remote\n  -c, --cache           Generate code with cache [optional]\n  -d, --dir string      The target dir\n  -h, --help            help for mongo\n      --home string     The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n      --remote string   The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n                                The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure\n      --style string    The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n  -t, --type strings    Specified model type name\n\n```\n\n> 温馨提示\n> \n> `--type` 支持slice传值，示例 `goctl model mongo -t=User -t=Class`\n\n","tools/goctl/model/sql/README.MD":"# Goctl Model\n\ngoctl model 为go-zero下的工具模块中的组件之一，目前支持识别mysql ddl进行model层代码生成，通过命令行或者idea插件（即将支持）可以有选择地生成带redis cache或者不带redis cache的代码逻辑。\n\n## 快速开始\n\n* 通过ddl生成\n\n    ```shell script\n    goctl model mysql ddl -src=\"./*.sql\" -dir=\"./sql/model\" -c\n    ```\n\n    执行上述命令后即可快速生成CURD代码。\n\n    ```Plain Text\n    model\n    │   ├── error.go\n    │   └── usermodel.go\n    ```\n\n* 通过datasource生成\n\n    ```shell script\n    goctl model mysql datasource -url=\"user:password@tcp(127.0.0.1:3306)/database\" -table=\"*\"  -dir=\"./model\"\n    ```\n\n* 生成代码示例\n  \n\t```go\n\n\tpackage model\n    \n    import (\n    \t\"database/sql\"\n    \t\"fmt\"\n    \t\"strings\"\n    \t\"time\"\n        \n        \"github.com/zeromicro/go-zero/core/stores/builder\"\n    \t\"github.com/zeromicro/go-zero/core/stores/cache\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlc\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlx\"\n    \t\"github.com/zeromicro/go-zero/core/stringx\"\n    )\n    \n    var (\n    \tuserFieldNames          = builder.FieldNames(&User{})\n    \tuserRows                = strings.Join(userFieldNames, \",\")\n    \tuserRowsExpectAutoSet   = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \",\")\n    \tuserRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \"=?,\") + \"=?\"\n    \n    \tcacheUserPrefix       = \"cache:User:user:\"\n    \tcacheUserNamePrefix   = \"cache:User:name:\"\n    \tcacheUserMobilePrefix = \"cache:User:mobile:\"\n    \tcacheUserIdPrefix     = \"cache:User:id:\"\n    )\n    \n    type (\n    \tUserModel interface {\n    \t\tInsert(data User) (sql.Result, error)\n    \t\tFindOne(id int64) (*User, error)\n    \t\tFindOneByUser(user string) (*User, error)\n    \t\tFindOneByName(name string) (*User, error)\n    \t\tFindOneByMobile(mobile string) (*User, error)\n    \t\tUpdate(data User) error\n    \t\tDelete(id int64) error\n    \t}\n    \n    \tdefaultUserModel struct {\n    \t\tsqlc.CachedConn\n    \t\ttable string\n    \t}\n    \n    \tUser struct {\n    \t\tId         int64     `db:\"id\"`\n    \t\tUser       string    `db:\"user\"`     // 用户\n    \t\tName       string    `db:\"name\"`     // 用户名称\n    \t\tPassword   string    `db:\"password\"` // 用户密码\n    \t\tMobile     string    `db:\"mobile\"`   // 手机号\n    \t\tGender     string    `db:\"gender\"`   // 男｜女｜未公开\n    \t\tNickname   sql.NullString    `db:\"nickname\"` // 用户昵称\n    \t\tCreateTime sql.NullTime `db:\"create_time\"`\n    \t\tUpdateTime time.Time `db:\"update_time\"`\n    \t}\n    )\n    \n    func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {\n    \treturn &defaultUserModel{\n    \t\tCachedConn: sqlc.NewConn(conn, c),\n    \t\ttable:      \"user\",\n    \t}\n    }\n    \n    func (m *defaultUserModel) Insert(data User) (sql.Result, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \tret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"insert into %s (%s) values (?, ?, ?, ?, ?, ?)\", m.table, userRowsExpectAutoSet)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname)\n    \t}, userMobileKey, userKey, userNameKey)\n    \treturn ret, err\n    }\n    \n    func (m *defaultUserModel) FindOne(id int64) (*User, error) {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tvar resp User\n    \terr := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v any) error {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \t\treturn conn.QueryRow(v, query, id)\n    \t})\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByUser(user string) (*User, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, user)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where user = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, user); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByName(name string) (*User, error) {\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, name)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userNameKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where name = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, name); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByMobile(mobile string) (*User, error) {\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, mobile)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userMobileKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where mobile = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, mobile); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) Update(data User) error {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, data.Id)\n    \t_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"update %s set %s where id = ?\", m.table, userRowsWithPlaceHolder)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id)\n    \t}, userIdKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) Delete(id int64) error {\n    \tdata, err := m.FindOne(id)\n    \tif err != nil {\n    \t\treturn err\n    \t}\n    \n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \t_, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"delete from %s where id = ?\", m.table)\n    \t\treturn conn.Exec(query, id)\n    \t}, userIdKey, userKey, userNameKey, userMobileKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) formatPrimary(primary any) string {\n    \treturn fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, primary)\n    }\n    \n    func (m *defaultUserModel) queryPrimary(conn sqlx.SqlConn, v, primary any) error {\n    \tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \treturn conn.QueryRow(v, query, primary)\n    }\n\n\t```\n\n## 用法\n\n```Plain Text\ngoctl model mysql -h\n```\n\n```Plain Text\nNAME:\n   goctl model mysql - generate mysql model\"\n\nUSAGE:\n   goctl model mysql command [command options] [arguments...]\n\nCOMMANDS:\n   ddl         generate mysql model from ddl\"\n   datasource  generate model from datasource\"\n\nOPTIONS:\n   --help, -h  show help\n```\n\n## 生成规则\n\n* 默认规则\n  \n  我们默认用户在建表时会创建createTime、updateTime字段(忽略大小写、下划线命名风格)且默认值均为`CURRENT_TIMESTAMP`，而updateTime支持`ON UPDATE CURRENT_TIMESTAMP`，对于这两个字段生成`insert`、`update`时会被移除，不在赋值范畴内，当然，如果你不需要这两个字段那也无大碍。\n* 带缓存模式\n  * ddl\n\n\t```shell script\n\tgoctl model mysql -src={patterns} -dir={dir} -cache\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql ddl - generate mysql model from ddl\n    \n    USAGE:\n       goctl model mysql ddl [command options] [arguments...]\n    \n    OPTIONS:\n       --src value, -s value  the path or path globbing patterns of the ddl\n       --dir value, -d value  the target dir\n       --style value          the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --cache, -c            generate code with cache [optional]\n       --idea                 for idea plugin [optional]\n       --database, -db        the name of database [optional]\n\t```\n\n  * datasource\n\n\t```shell script\n\tgoctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir} -cache=true\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql datasource - generate model from datasource\n    \n    USAGE:\n       goctl model mysql datasource [command options] [arguments...]\n    \n    OPTIONS:\n       --url value              the data source of database,like \"root:password@tcp(127.0.0.1:3306)/database\n       --table value, -t value  the table or table globbing patterns in the database\n       --cache, -c              generate code with cache [optional]\n       --dir value, -d value    the target dir\n       --style value            the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --idea                   for idea plugin [optional]\n\n\n\t```\n\n\t示例用法请参考[用法](./example/makefile)\n  \n\t> NOTE: goctl model mysql ddl/datasource 均新增了一个`--style`参数，用于标记文件命名风格。\n\n  目前仅支持redis缓存，如果选择带缓存模式，即生成的`FindOne(ByXxx)`&`Delete`代码会生成带缓存逻辑的代码，目前仅支持单索引字段（除全文索引外），对于联合索引我们默认认为不需要带缓存，且不属于通用型代码，因此没有放在代码生成行列，如example中user表中的`id`、`name`、`mobile`字段均属于单字段索引。\n\n* 不带缓存模式\n\n  * ddl\n  \n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n\n  or\n  * ddl\n\n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n  \n生成代码仅基本的CURD结构。\n\n## 缓存\n\n  对于缓存这一块我选择用一问一答的形式进行罗列。我想这样能够更清晰的描述model中缓存的功能。\n\n* 缓存会缓存哪些信息？\n\n  对于主键字段缓存，会缓存整个结构体信息，而对于单索引字段（除全文索引）则缓存主键字段值。\n\n* 数据有更新（`update`）操作会清空缓存吗？\n  \n  会，但仅清空主键缓存的信息，why？这里就不做详细赘述了。\n\n* 为什么不按照单索引字段生成`updateByXxx`和`deleteByXxx`的代码？\n  \n  理论上是没任何问题，但是我们认为，对于model层的数据操作均是以整个结构体为单位，包括查询，我不建议只查询某部分字段（不反对），否则我们的缓存就没有意义了。\n\n* 为什么不支持`findPageLimit`、`findAll`这种模型代码生成？\n  \n  目前，我认为除了基本的CURD外，其他的代码均属于<i>业务型</i>代码，这个我觉得开发人员根据业务需要进行编写更好。\n\n# 类型转换规则\n\n| mysql dataType | golang dataType | golang Null dataType |\n|----------------|-----------------|----------------------------------------|\n| bool           | int64           | sql.NullInt64                          |\n| boolean        | int64           | sql.NullInt64                          |\n| tinyint        | int64           | sql.NullInt64                          |\n| smallint       | int64           | sql.NullInt64                          |\n| mediumint      | int64           | sql.NullInt64                          |\n| int            | int64           | sql.NullInt64                          |\n| integer        | int64           | sql.NullInt64                          |\n| bigint         | int64           | sql.NullInt64                          |\n| float          | float64         | sql.NullFloat64                        |\n| double         | float64         | sql.NullFloat64                        |\n| decimal        | float64         | sql.NullFloat64                        |\n| date           | time.Time       | sql.NullTime                           |\n| datetime       | time.Time       | sql.NullTime                           |\n| timestamp      | time.Time       | sql.NullTime                           |\n| time           | string          | sql.NullString                         |\n| year           | time.Time       | sql.NullInt64                          |\n| char           | string          | sql.NullString                         |\n| varchar        | string          | sql.NullString                         |\n| binary         | string          | sql.NullString                         |\n| varbinary      | string          | sql.NullString                         |\n| tinytext       | string          | sql.NullString                         |\n| text           | string          | sql.NullString                         |\n| mediumtext     | string          | sql.NullString                         |\n| longtext       | string          | sql.NullString                         |\n| enum           | string          | sql.NullString                         |\n| set            | string          | sql.NullString                         |\n| json           | string          | sql.NullString                         |\n\n","tools/goctl/readme.md":"# goctl\n\nEnglish | [简体中文](readme-cn.md) | [한국어](readme-ko.md)\n\nRead document at https://go-zero.dev/docs/tutorials/cli/overview\n","tools/goctl/rpc/README.md":"# goctl rpc — RPC Code Generation\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\ngoctl rpc is the RPC service code generation module of the `goctl` scaffold. It generates a complete zRPC service from `.proto` files. You only need to write the proto definition and business logic — all boilerplate code is generated automatically.\n\n## Features\n\n- **protoc compatible**: Fully compatible with protoc, all protoc arguments are passed through\n- **External proto imports**: Cross-directory and cross-package proto imports with automatic transitive dependency resolution\n- **Multiple services**: Define multiple services in a single proto file, auto-grouped by service name\n- **Streaming support**: Server streaming, client streaming, and bidirectional streaming\n- **Google well-known types**: Automatic recognition of supported `google.protobuf.*` types with correct Go imports\n- **Client generation**: Auto-generated RPC client wrapper code\n\n## Prerequisites\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n```\n\n## Quick Start\n\n### Method 1: Create a Service Instantly\n\n```bash\ngoctl rpc new greeter\n```\n\nGenerates a complete project structure:\n\n```\ngreeter/\n├── etc/\n│   └── greeter.yaml\n├── greeter/\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient/\n│   └── greeter.go\n└── internal/\n    ├── config/\n    │   └── config.go\n    ├── logic/\n    │   └── pinglogic.go\n    ├── server/\n    │   └── greeterserver.go\n    └── svc/\n        └── servicecontext.go\n```\n\n### Method 2: Generate from a Proto File\n\n1. Generate a proto template:\n\n```bash\ngoctl rpc template -o=user.proto\n```\n\n2. Initialize the output directory and generate service code:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n---\n\n## Command Reference\n\n### `goctl rpc protoc`\n\nGenerate zRPC service code from a `.proto` file.\n\n```bash\ngoctl rpc protoc <proto_file> [flags]\n```\n\n**Examples:**\n\n```bash\n# Basic usage\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n\n# Multiple services mode\ngoctl rpc protoc multi.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -m\n\n# Import external protos\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -I ./shared_protos\n\n# Use Google well-known types\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--zrpc_out` | | string | **required** | Output directory for zRPC service code |\n| `--go_out` | | string | **required** | Output directory for protoc Go code |\n| `--go-grpc_out` | | string | **required** | Output directory for protoc gRPC code |\n| `--go_opt` | | string | | Options for protoc-gen-go (e.g., `module=example.com/demo`) |\n| `--go-grpc_opt` | | string | | Options for protoc-gen-go-grpc (e.g., `module=example.com/demo`) |\n| `--proto_path` | `-I` | string[] | | Proto import search directories (repeatable) |\n| `--multiple` | `-m` | bool | `false` | Multiple services mode |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--style` | | string | `gozero` | File naming style |\n| `--module` | | string | | Custom Go module name |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc new`\n\nQuickly create a complete RPC service project.\n\n```bash\ngoctl rpc new <service_name> [flags]\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--style` | | string | `gozero` | File naming style |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--module` | | string | | Custom Go module name |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--idea` | | bool | `false` | Generate IDE project marker |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc template`\n\nGenerate a proto file template.\n\n```bash\ngoctl rpc template -o=<output_file> [flags]\n```\n\n**Flags:**\n\n| Flag | Type | Description |\n|------|------|-------------|\n| `-o` | string | Output file path (required) |\n| `--home` | string | goctl template directory |\n| `--remote` | string | Remote template Git repository URL |\n| `--branch` | string | Remote template branch |\n\n---\n\n## Feature Details\n\n### Multiple Services Mode (`--multiple`)\n\nWhen a proto file contains multiple `service` definitions, the `--multiple` flag is required.\n\n```protobuf\nservice SearchService {\n  rpc Search(SearchReq) returns (SearchReply);\n}\n\nservice NotifyService {\n  rpc Notify(NotifyReq) returns (NotifyReply);\n}\n```\n\n**Directory differences with `--multiple`:**\n\n| Feature | Default mode | `--multiple` mode |\n|---------|-------------|-------------------|\n| Services per proto | Exactly 1 | 1 or more |\n| Client directory | Named after service | Fixed `client/` directory |\n| Code organization | Flat structure | Grouped by service name |\n\n**`--multiple=false` (default) directory structure:**\n\n```\noutput/\n├── greeterclient/\n│   └── greeter.go\n├── internal/\n│   ├── logic/\n│   │   └── sayhellologic.go\n│   └── server/\n│       └── greeterserver.go\n└── ...\n```\n\n**`--multiple=true` directory structure:**\n\n```\noutput/\n├── client/\n│   ├── searchservice/\n│   │   └── searchservice.go\n│   └── notifyservice/\n│       └── notifyservice.go\n├── internal/\n│   ├── logic/\n│   │   ├── searchservice/\n│   │   │   └── searchlogic.go\n│   │   └── notifyservice/\n│   │       └── notifylogic.go\n│   └── server/\n│       ├── searchservice/\n│       │   └── searchserviceserver.go\n│       └── notifyservice/\n│           └── notifyserviceserver.go\n└── ...\n```\n\n### External Proto Imports (`--proto_path`)\n\nUse `-I` / `--proto_path` to specify additional proto search directories. Supported scenarios:\n\n- **Same-directory import**: `import \"types.proto\";`\n- **Subdirectory import**: `import \"common/types.proto\";`\n- **External directory import**: Proto files outside the project\n- **Transitive imports**: A imports B, B imports C — goctl resolves recursively\n- **Cross-package imports**: Different `go_package` values generate correct Go imports automatically\n\n```bash\n# Search multiple directories for proto files\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./shared_protos -I /path/to/external_protos\n```\n\n### Service Naming\n\nBy default, the service name is derived from the proto **package name** (e.g., `package user;` → service name `user`). This allows multiple proto files to share the same package:\n\n```\nprotos/\n├── user_base.proto      # package user;\n├── user_auth.proto      # package user;\n└── user_profile.proto   # package user;\n```\n\nAll three files generate into a single `user` service.\n\nTo use the proto filename for naming (legacy behavior), add the `--name-from-filename` flag.\n\n### Streaming RPC\n\nAll three gRPC streaming patterns are supported:\n\n```protobuf\nservice StreamService {\n  rpc ServerStream(Req) returns (stream Reply);       // Server streaming\n  rpc ClientStream(stream Req) returns (Reply);       // Client streaming\n  rpc BidiStream(stream Req) returns (stream Reply);  // Bidirectional streaming\n}\n```\n\n### Google Well-Known Types\n\ngoctl automatically recognizes and handles Google protobuf well-known types:\n\n| Proto Type | Go Type |\n|-----------|---------|\n| `google.protobuf.Empty` | `emptypb.Empty` |\n| `google.protobuf.Timestamp` | `timestamppb.Timestamp` |\n| `google.protobuf.Duration` | `durationpb.Duration` |\n| `google.protobuf.Any` | `anypb.Any` |\n| `google.protobuf.Struct` | `structpb.Struct` |\n| `google.protobuf.FieldMask` | `fieldmaskpb.FieldMask` |\n| `google.protobuf.*Value` | `wrapperspb.*Value` |\n\nThese types can be used directly as RPC parameter types — goctl generates the correct imports automatically.\n\n---\n\n## Examples\n\nSee the [example/](example/) directory for 10 complete examples covering all generation scenarios.\n\n| # | Example | Scenario |\n|---|---------|----------|\n| 01 | [Basic service](example/01-basic/) | Single service, no imports |\n| 02 | [Sibling import](example/02-import-sibling/) | Import from same directory |\n| 03 | [Subdirectory import](example/03-import-subdir/) | Import from subdirectory |\n| 04 | [Transitive import](example/04-transitive-import/) | A → B → C dependency chain |\n| 05 | [Multiple services](example/05-multiple-services/) | `--multiple` mode |\n| 06 | [Well-known types](example/06-wellknown-types/) | Timestamp etc. in messages |\n| 07 | [External proto (same pkg)](example/07-external-proto-same-pkg/) | External proto, same go_package |\n| 08 | [External proto (diff pkg)](example/08-external-proto-diff-pkg/) | External proto, different go_package |\n| 09 | [Google well-known types as params](example/09-google-types-as-rpc/) | Empty/Timestamp as RPC parameters |\n| 10 | [Streaming](example/10-streaming/) | Server/client/bidirectional streaming |\n","tools/goctl/rpc/example/01-basic/README.md":"# Example 01: Basic RPC Service\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis is the simplest example of generating an RPC service with goctl.\n\n## Proto Definition\n\nA single `greeter.proto` file with one service and one RPC method, no external imports.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/greeter\";\n```\n\n## Generation Commands\n\n### Method 1: Quick Start with `goctl rpc new`\n\n```bash\n# Create a complete RPC project with one command\ngoctl rpc new greeter\n```\n\nThis generates the proto file and service code together:\n\n```\ngreeter/\n├── etc\n│   └── greeter.yaml\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── pinglogic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n### Method 2: Generate from an Existing Proto\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc greeter.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── greeter.yaml\n├── go.mod\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── sayhellologic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n## Key Points\n\n- This is the simplest scenario: one proto file, one service, one RPC method.\n- The `go_package` uses a full module path (`example.com/demo/greeter`), not a relative path.\n- The `--module` flag tells goctl the Go module name; `--go_opt=module=...` and `--go-grpc_opt=module=...` tell protoc to strip the module prefix from output paths.\n- The `--zrpc_out` flag specifies where the goctl-generated service code goes.\n- The `--go_out` and `--go-grpc_out` flags specify where protoc-generated code goes.\n- Edit the logic file (`internal/logic/sayhellologic.go`) to implement your business logic.\n","tools/goctl/rpc/example/02-import-sibling/README.md":"# Example 02: Importing a Sibling Proto File\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from the same directory.\n\n## Proto Definition\n\nTwo proto files in the same directory share the same `go_package`:\n\n- `types.proto` — Defines shared message types (`User`).\n- `user.proto` — Defines the RPC service, importing `types.proto`.\n\nBoth files use the same `go_package` with a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n`user.proto` imports `types.proto` via:\n\n```protobuf\nimport \"types.proto\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc user.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── usersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createuserlogic.go\n│   │   └── getuserlogic.go\n│   ├── server\n│   │   └── userserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── types.pb.go\n│   ├── user.pb.go\n│   └── user_grpc.pb.go\n├── userservice\n│   └── userservice.go\n└── usersvc.go\n```\n\n## Key Points\n\n- Two proto files (`user.proto` and `types.proto`) share the same `go_package = \"example.com/demo/pb\"`, compiled into a single Go package.\n- `user.proto` imports `types.proto` via `import \"types.proto\"`.\n- When multiple proto files share the same `go_package`, they compile into a single Go package.\n- Only the proto file containing `service` definitions needs to be passed to `goctl rpc protoc`.\n- The imported proto is automatically compiled by protoc and resolved by goctl.\n","tools/goctl/rpc/example/03-import-subdir/README.md":"# Example 03: Importing Proto from a Subdirectory\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from a subdirectory.\n\n## Proto Definition\n\nTwo proto files with **different** `go_package` values:\n\n- `order.proto` — Defines the `OrderService`, imports `common/types.proto`.\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `common/types.proto` — Defines reusable pagination and sorting messages.\n\n```protobuf\noption go_package = \"example.com/demo/pb/common\";\n```\n\n`order.proto` imports `common/types.proto` from a subdirectory:\n\n```protobuf\nimport \"common/types.proto\";\n```\n\nNote that the two files have **different** `go_package` values, so they compile into separate Go packages.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc order.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── ordersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── getorderlogic.go\n│   │   └── listorderslogic.go\n│   ├── server\n│   │   └── orderserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── orderservice\n│   └── orderservice.go\n├── ordersvc.go\n└── pb\n    ├── common\n    │   └── types.pb.go\n    ├── order.pb.go\n    └── order_grpc.pb.go\n```\n\n## Key Points\n\n- Two proto files have **different** `go_package` values, so they compile into separate Go packages (`pb/` and `pb/common/`).\n- `order.proto` imports `common/types.proto` from a subdirectory.\n- When imported protos have a different `go_package`, goctl automatically generates cross-package imports.\n- The `-I .` flag tells protoc to search from the current directory, enabling it to find `common/types.proto`.\n","tools/goctl/rpc/example/04-transitive-import/README.md":"# Example 04: Transitive Imports\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates transitive proto imports, where A imports B and B imports C.\n\n## Proto Definition\n\nThree proto files form a transitive import chain, all sharing the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `base.proto` — Layer C: defines base types (`BaseResp`).\n- `middleware.proto` — Layer B: imports `base.proto`, defines `RequestMeta`.\n- `main.proto` — Layer A: imports `middleware.proto`, defines the `PingService` (entry point).\n\nImport chain: `main.proto` → `middleware.proto` → `base.proto`\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc main.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── pingsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── pingserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── base.pb.go\n│   ├── main.pb.go\n│   ├── main_grpc.pb.go\n│   └── middleware.pb.go\n├── pingservice\n│   └── pingservice.go\n└── pingsvc.go\n```\n\n## Key Points\n\n- Three proto files (`main.proto` → `middleware.proto` → `base.proto`) form a transitive import chain.\n- goctl recursively resolves all transitive imports automatically.\n- All three files share the same `go_package = \"example.com/demo/pb\"`.\n- You only need to specify the entry proto file — goctl and protoc handle the rest.\n- Circular imports are detected and will cause an error (same as protoc behavior).\n","tools/goctl/rpc/example/05-multiple-services/README.md":"# Example 05: Multiple Services (`--multiple`)\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates generating multiple RPC services from a single proto file.\n\n## Proto Definition\n\nTwo proto files share the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `shared.proto` — Defines shared message types (`Meta`).\n- `multi.proto` — Defines **two** services: `SearchService` and `NotifyService`.\n\nThe `-m` (or `--multiple`) flag is required when a proto file contains more than one `service` block.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code with the `-m` flag:\n\n```bash\ngoctl rpc protoc multi.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . \\\n  -m\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── client\n│   ├── notifyservice\n│   │   └── notifyservice.go\n│   └── searchservice\n│       └── searchservice.go\n├── etc\n│   └── multisvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── notifyservice\n│   │   │   └── notifylogic.go\n│   │   └── searchservice\n│   │       └── searchlogic.go\n│   ├── server\n│   │   ├── notifyservice\n│   │   │   └── notifyserviceserver.go\n│   │   └── searchservice\n│   │       └── searchserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── multisvc.go\n└── pb\n    ├── multi.pb.go\n    ├── multi_grpc.pb.go\n    └── shared.pb.go\n```\n\n## Key Points\n\n- The `-m` (or `--multiple`) flag enables multiple-service mode.\n- In multiple mode, `client/` contains per-service subdirectories; `logic/` and `server/` are also grouped by service name.\n- Both services share a single entry point (`multisvc.go`) and config.\n- Without `--multiple`, goctl only allows one `service` block per proto file.\n- All services share the same `config.go` and `servicecontext.go`.\n","tools/goctl/rpc/example/06-wellknown-types/README.md":"# Example 06: Well-Known Types\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using a Google protobuf well-known type (`Timestamp`) as a message field.\n\n## Proto Definition\n\n`events.proto` uses `google.protobuf.Timestamp` as a message field type.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc events.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── eventsvc.yaml\n├── eventservice\n│   └── eventservice.go\n├── eventsvc.go\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createeventlogic.go\n│   │   └── listeventslogic.go\n│   ├── server\n│   │   └── eventserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── events.pb.go\n    └── events_grpc.pb.go\n```\n\n## Key Points\n\n- Uses the Google well-known type `google.protobuf.Timestamp` as a message field.\n- goctl automatically maps well-known types to Go imports; in this example, `Timestamp` maps to `timestamppb`.\n- No extra `--proto_path` needed for well-known types if protoc is properly installed.\n","tools/goctl/rpc/example/07-external-proto-same-pkg/README.md":"# Example 07: External Proto — Same `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where both files share the **same** `go_package`.\n\n## Proto Definition\n\nBoth `service.proto` and `ext.proto` use the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\nSource layout:\n\n```\n07-external-proto-same-pkg/\n├── ext_protos\n│   └── ext.proto        # External proto (go_package = \"example.com/demo/pb\")\n├── service.proto        # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- `service.proto` imports `ext.proto` and uses `ext.ExtReq` / `ext.ExtReply` as RPC types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── querylogic.go\n│   ├── server\n│   │   └── queryserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── ext.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n├── queryservice\n│   └── queryservice.go\n└── svc.go\n```\n\n## Key Points\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- Use `-I ./ext_protos` to add the external directory to the proto search path.\n- When the external proto has the **same** `go_package`, all types merge into one Go package — no cross-package imports are needed.\n","tools/goctl/rpc/example/08-external-proto-diff-pkg/README.md":"# Example 08: External Proto — Different `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where the files have **different** `go_package` values, requiring cross-package imports in the generated Go code.\n\n## Proto Definition\n\nThe proto files use different `go_package` values:\n\n- `service.proto`: `go_package = \"example.com/demo/pb\"`\n- `ext_protos/common/types.proto`: `go_package = \"example.com/demo/pb/common\"`\n\nSource layout:\n\n```\n08-external-proto-diff-pkg/\n├── ext_protos\n│   └── common\n│       └── types.proto    # External proto (go_package = \"example.com/demo/pb/common\")\n├── service.proto          # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `types.proto` has `go_package = \"example.com/demo/pb/common\"` — a **different** Go package.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── dataservice\n│   └── dataservice.go\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── fetchlogic.go\n│   ├── server\n│   │   └── dataserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── common\n│   │   └── types.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n└── svc.go\n```\n\n## Key Points\n\n- When the external proto has a **different** `go_package`, goctl generates cross-package Go imports automatically.\n- goctl resolves the proto package name (e.g., `common`) to the correct Go import path by parsing the imported proto's `go_package` option.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n","tools/goctl/rpc/example/09-google-types-as-rpc/README.md":"# Example 09: Google Well-Known Types as RPC Parameters\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using Google protobuf well-known types **directly** as RPC request or response types (not just as message fields).\n\n## Proto Definition\n\n`service.proto` uses `google.protobuf.Empty` and `google.protobuf.Timestamp` directly as RPC request/response types.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── healthsvc.yaml\n├── go.mod\n├── healthservice\n│   └── healthservice.go\n├── healthsvc.go\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── gettimelogic.go\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── healthserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── service.pb.go\n    └── service_grpc.pb.go\n```\n\n## Key Points\n\n- Uses Google well-known types (`google.protobuf.Empty`, `google.protobuf.Timestamp`) directly as RPC request/response types (not just message fields).\n- goctl correctly maps these to Go types (`emptypb.Empty`, `timestamppb.Timestamp`) and generates proper imports.\n- This differs from Example 06 where well-known types are used as message fields.\n","tools/goctl/rpc/example/10-streaming/README.md":"# Example 10: Streaming RPC\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates all three gRPC streaming patterns: server streaming, client streaming, and bidirectional streaming.\n\n## Proto Definition\n\n`stream.proto` defines three RPC methods demonstrating each streaming pattern.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc stream.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── streamsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── bidistreamlogic.go\n│   │   ├── clientstreamlogic.go\n│   │   └── serverstreamlogic.go\n│   ├── server\n│   │   └── streamserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── stream.pb.go\n│   └── stream_grpc.pb.go\n├── streamservice\n│   └── streamservice.go\n└── streamsvc.go\n```\n\n## Key Points\n\n- Supports three streaming patterns: server streaming (`stream` on response), client streaming (`stream` on request), and bidirectional streaming (`stream` on both).\n- goctl generates separate logic files for each streaming RPC method.\n- goctl generates streaming client wrapper methods; use the returned gRPC stream to send and receive messages.\n","tools/goctl/rpc/example/README.md":"# RPC Examples\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis directory contains complete examples for all `goctl rpc` code generation scenarios.\n\nEach example includes:\n- `.proto` source files\n- `README.md` (English), `README-cn.md` (中文), and `README-ko.md` (한국어) documentation\n\n## Examples\n\n| # | Directory | Scenario | Key Flags |\n|---|-----------|----------|-----------|\n| 01 | [01-basic](01-basic/) | Basic single service, no imports | — |\n| 02 | [02-import-sibling](02-import-sibling/) | Import sibling proto file | `--proto_path=.` |\n| 03 | [03-import-subdir](03-import-subdir/) | Import proto from subdirectory | `--proto_path=.` |\n| 04 | [04-transitive-import](04-transitive-import/) | Transitive imports (A → B → C) | `--proto_path=.` |\n| 05 | [05-multiple-services](05-multiple-services/) | Multiple services in one proto | `--multiple` |\n| 06 | [06-wellknown-types](06-wellknown-types/) | Google well-known types in messages | — |\n| 07 | [07-external-proto-same-pkg](07-external-proto-same-pkg/) | External proto, same `go_package` | `-I ./ext_protos` |\n| 08 | [08-external-proto-diff-pkg](08-external-proto-diff-pkg/) | External proto, different `go_package` | `-I ./ext_protos` |\n| 09 | [09-google-types-as-rpc](09-google-types-as-rpc/) | Google well-known types as RPC parameters | — |\n| 10 | [10-streaming](10-streaming/) | Server/client/bidirectional streaming | — |\n\n## Prerequisites\n\n- [Go](https://go.dev/) 1.22+\n- [protoc](https://github.com/protocolbuffers/protobuf/releases) (Protocol Buffers compiler)\n- [protoc-gen-go](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go) and [protoc-gen-go-grpc](https://pkg.go.dev/google.golang.org/grpc/cmd/protoc-gen-go-grpc)\n- [goctl](https://github.com/zeromicro/go-zero/tree/master/tools/goctl)\n\n## Quick Start\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n\n# Try the basic example\ncd 01-basic\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc greeter.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n"},"files":{".github/copilot-instructions.md":"# GitHub Copilot Instructions for go-zero\n\nThis document provides guidelines for GitHub Copilot when assisting with development in the go-zero project.\n\n## Project Overview\n\ngo-zero is a web and RPC framework with lots of built-in engineering practices designed to ensure the stability of busy services with resilience design. It has been serving sites with tens of millions of users for years.\n\n### Key Architecture Components\n\n- **REST API framework** (`rest/`) - HTTP service framework with middleware chain support\n- **RPC framework** (`zrpc/`) - gRPC-based RPC framework with etcd service discovery and p2c_ewma load balancing\n- **Gateway** (`gateway/`) - API gateway supporting both HTTP and gRPC upstreams with proto-based routing\n- **MCP Server** (`mcp/`) - Model Context Protocol server for AI agent integration via SSE\n- **Core utilities** (`core/`) - Production-grade components:\n  - Resilience: circuit breakers (`breaker/`), rate limiters (`limit/`), adaptive load shedding (`load/`)\n  - Storage: SQL with cache (`stores/sqlc/`), Redis (`stores/redis/`), MongoDB (`stores/mongo/`)\n  - Concurrency: MapReduce (`mr/`), worker pools (`executors/`), sync primitives (`syncx/`)\n  - Observability: metrics (`metric/`), tracing (`trace/`), structured logging (`logx/`)\n- **Code generation tool** (`tools/goctl/`) - CLI tool for generating Go code from `.api` and `.proto` files\n\n## Coding Standards and Conventions\n\n### Code Style\n\n1. **Follow Go conventions**: Use `gofmt` for formatting, follow effective Go practices\n2. **Package naming**: Use lowercase, single-word package names when possible\n3. **Error handling**: Always handle errors explicitly, use `errorx.BatchError` for multiple errors\n4. **Context propagation**: Always pass `context.Context` as the first parameter for functions that may block\n5. **Configuration structures**: Use struct tags with JSON annotations, defaults, and validation\n\n**Pattern**: All service configs embed `service.ServiceConf` for common fields (Name, Log, Mode, Telemetry)\n```go\ntype Config struct {\n    service.ServiceConf              // Always embed for services\n    Host     string `json:\",default=0.0.0.0\"`\n    Port     int    // Required field (no default)\n    Timeout  int64  `json:\",default=3000\"`  // Timeouts in milliseconds\n    Optional string `json:\",optional\"`      // Optional field\n    Mode     string `json:\",default=pro,options=dev|test|rt|pre|pro\"`  // Validated options\n}\n```\n\n**Service modes**: `dev`/`test`/`rt` disable load shedding and stats; `pre`/`pro` enable all resilience features\n\n### Interface Design\n\n1. **Small interfaces**: Follow Go's preference for small, focused interfaces\n2. **Context methods**: Provide both context and non-context versions of methods\n3. **Options pattern**: Use functional options for complex configuration\n\nExample:\n```go\nfunc (c *Client) Get(key string, val any) error {\n    return c.GetCtx(context.Background(), key, val)\n}\n\nfunc (c *Client) GetCtx(ctx context.Context, key string, val any) error {\n    // implementation\n}\n```\n\n### Testing Patterns\n\n1. **Test file naming**: Use `*_test.go` suffix\n2. **Test function naming**: Use `TestFunctionName` pattern\n3. **Use testify/assert**: Prefer `assert` package for assertions\n4. **Table-driven tests**: Use table-driven tests for multiple scenarios\n5. **Mock interfaces**: Use `go.uber.org/mock` for mocking\n6. **Test helpers**: Use `redistest`, `mongtest` helpers for database testing\n\nExample test pattern:\n```go\nfunc TestSomething(t *testing.T) {\n    tests := []struct {\n        name     string\n        input    string\n        expected string\n        wantErr  bool\n    }{\n        {\"valid case\", \"input\", \"output\", false},\n        {\"error case\", \"bad\", \"\", true},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            result, err := SomeFunction(tt.input)\n            if tt.wantErr {\n                assert.Error(t, err)\n                return\n            }\n            assert.NoError(t, err)\n            assert.Equal(t, tt.expected, result)\n        })\n    }\n}\n```\n\n## Framework-Specific Guidelines\n\n### REST API Development\n\n1. **API Definition**: Use `.api` files to define REST APIs with goctl codegen\n2. **Handler pattern**: Separate business logic into logic packages (handlers call logic layer)\n3. **Middleware chain**: Middlewares wrap via `chain.Chain` interface - use `Append()` or `Prepend()` to control order\n   - Built-in middlewares (all in `rest/handler/`): tracing, logging, metrics, recovery, breaker, shedding, timeout, maxconns, maxbytes, gunzip\n   - Custom middleware: `func(http.Handler) http.Handler` - call `next.ServeHTTP(w, r)` to continue chain\n4. **Response handling**: Use `httpx.WriteJson(w, code, v)` for JSON responses\n5. **Error handling**: Use `httpx.Error(w, err)` or `httpx.ErrorCtx(ctx, w, err)` for HTTP error responses\n6. **Route registration**: Routes defined with `Method`, `Path`, and `Handler` - wildcards use `:param` syntax\n\n### RPC Development\n\n1. **Protocol Buffers**: Use protobuf for service definitions, generate code with goctl\n2. **Service discovery**: Use etcd for dynamic service registration/discovery, or direct endpoints for static routing\n3. **Load balancing**: Default is `p2c_ewma` (power of 2 choices with EWMA), configurable via `BalancerName`\n4. **Client configuration**: Support `Etcd`, `Endpoints`, or `Target` - use `BuildTarget()` to construct connection string\n5. **Interceptors**: Implement gRPC interceptors for cross-cutting concerns (auth, logging, metrics)\n6. **Health checks**: gRPC health checks enabled by default (`Health: true`)\n\n### Database Operations\n\n1. **SQL operations**: Use `sqlx.SqlConn` interface - methods always end with `Ctx` for context support\n2. **Caching pattern**: `stores/sqlc` provides `CachedConn` for automatic cache-aside pattern\n   - `QueryRowCtx`: Query with cache key, auto-populate on cache miss\n   - `ExecCtx`: Execute and delete cache keys\n3. **Transactions**: Use `sqlx.SqlConn.TransactCtx()` to get transaction session\n4. **Connection pooling**: Managed automatically (64 max idle/open, 1min lifetime)\n5. **Test helpers**: Use `redistest.CreateRedis(t)` for Redis, SQL mocks for DB testing\n\nExample cache pattern:\n```go\nerr := c.QueryRowCtx(ctx, &dest, key, func(ctx context.Context, conn sqlx.SqlConn) error {\n    return conn.QueryRowCtx(ctx, &dest, query, args...)\n})\n```\n\n### Configuration Management\n\n1. **YAML configuration**: Use YAML for configuration files\n2. **Environment variables**: Support environment variable overrides\n3. **Validation**: Include proper validation for configuration parameters\n4. **Sensible defaults**: Provide reasonable default values\n\n## Error Handling Best Practices\n\n1. **Wrap errors**: Use `fmt.Errorf` with `%w` verb to wrap errors\n2. **Custom errors**: Define custom error types when needed\n3. **Error logging**: Log errors appropriately with context\n4. **Graceful degradation**: Implement fallback mechanisms\n\n## Performance Considerations\n\n1. **Resource pools**: Use connection pools and worker pools\n2. **Circuit breakers**: Implement circuit breaker patterns for external calls\n3. **Rate limiting**: Apply rate limiting to protect services\n4. **Load shedding**: Implement adaptive load shedding\n5. **Metrics**: Add appropriate metrics and monitoring\n\n## Security Guidelines\n\n1. **Input validation**: Validate all input parameters\n2. **SQL injection prevention**: Use parameterized queries\n3. **Authentication**: Implement proper JWT token handling\n4. **HTTPS**: Support TLS/HTTPS configurations\n5. **CORS**: Configure CORS appropriately for web APIs\n\n## Documentation Standards\n\n1. **Package documentation**: Include package-level documentation\n2. **Function documentation**: Document exported functions with examples\n3. **API documentation**: Maintain API documentation in sync\n4. **README updates**: Update README for significant changes\n\n## GitHub Issue Management\n\n### Understanding and Categorizing Issues\n\nWhen analyzing GitHub issues, consider these common categories:\n\n1. **Bug Reports**: Stack traces, version info, reproduction steps\n2. **Feature Requests**: Use case, proposed solution, alternatives\n3. **Questions**: Usage, configuration, or architecture\n4. **Documentation Issues**: Missing, unclear, or incorrect docs\n5. **Performance Issues**: Benchmarks, profiling data, resource usage\n\n### Issue Analysis Checklist\n\n- Identify affected component (REST, RPC, Gateway, MCP, Core utilities, goctl)\n- Check versions (go-zero, Go)\n- Look for reproduction steps or code examples\n- Review code snippets, logs, or stack traces\n- Check if related to resilience features (breaker, load shedding, rate limiting)\n- Determine production impact\n\n### Responding to Issues\n\nBe helpful and professional. Ask clarifying questions when needed. Reference relevant documentation and code files. Provide code examples following project conventions. Suggest workarounds when applicable.\n\n### Chinese to English Translation\n\ngo-zero has an international user base. When encountering issues or comments written in Chinese, translate them to English to ensure all contributors can participate in discussions.\n\n#### Translation Guidelines\n\n1. **Update issue titles**: Edit the issue title to include English translation only\n2. **Translate comments in place**: Add a comment with the English translation, followed by the original Chinese text\n3. **Keep original Chinese**: After translating, include the original Chinese text in a blockquote for verification\n4. **Encourage English communication**: Politely suggest users write in English for better collaboration\n5. **Maintain technical accuracy**: Preserve technical terms, component names, and code exactly\n6. **Translate naturally**: Avoid literal word-by-word translation; use idiomatic English\n7. **Preserve formatting**: Keep markdown formatting, code blocks, and links intact\n8. **Keep URLs unchanged**: Don't translate URLs or file paths\n\n#### Common Technical Terms (Chinese → English)\n\n- 框架 → **Framework** | 中间件 → **Middleware** | 负载均衡 → **Load Balancing**\n- 熔断器 → **Circuit Breaker** | 限流 → **Rate Limiting** | 降载/过载保护 → **Load Shedding**\n- 服务发现 → **Service Discovery** | 配置 → **Configuration** | 弹性/容错 → **Resilience** | 微服务 → **Microservices**\n\n#### Translation Example\n\n**Original Chinese Title:** `goctl 执行环境问题`\n**Updated Title:** `goctl Execution Environment Issue`\n\n**Original Chinese Comment:** `我在项目中遇到熔断器配置问题`\n**Translation in Comment:**\n```markdown\nI encountered a circuit breaker configuration issue in my project.\n\n> Original (原文): 我在项目中遇到熔断器配置问题\n```\n\n### Common Issue Patterns and Solutions\n\n#### Configuration Issues\n- Check `service.ServiceConf` embedding and struct tags\n- Verify YAML syntax, defaults, and validation rules\n- Reference: [rest/config.go](rest/config.go), [zrpc/config.go](zrpc/config.go)\n\n#### Code Generation (goctl) Issues\n- Verify `.api` or `.proto` file syntax and goctl version\n- Reference: `tools/goctl/` directory\n\n#### RPC Connection Issues\n- Check etcd configuration, service discovery, and endpoints\n- Verify load balancing settings (p2c_ewma)\n\n#### Database/Cache Issues\n- Verify `sqlx.SqlConn` usage with context\n- Check cache key generation, invalidation, and connection pools\n- Use test helpers (`redistest`, `mongtest`)\n\n#### Performance Issues\n- Check if load shedding is enabled (mode: `pre`/`pro`)\n- Review circuit breaker thresholds, rate limiting, and context timeouts\n\n### Referencing Codebase\n\nWhen explaining issues, reference specific files and patterns:\n- REST API: `rest/`, `rest/handler/`, `rest/httpx/`\n- RPC: `zrpc/`, `zrpc/internal/`\n- Core utilities: `core/breaker/`, `core/limit/`, `core/load/`, etc.\n- Gateway: `gateway/`\n- MCP: `mcp/`\n- Code generation: `tools/goctl/`\n- Examples: `adhoc/` directory contains various examples\n\n### Encouraging Best Practices\n\nWhen responding to issues, gently guide users toward:\n- Proper error handling with context\n- Using resilience features (breakers, rate limiters)\n- Following testing patterns with table-driven tests\n- Implementing proper resource cleanup\n- Reading existing documentation in `docs/` and `readme.md`\n\n## Common Patterns to Follow\n\n### Service Configuration\n```go\ntype ServiceConf struct {\n    Name string\n    Log  logx.LogConf\n    Mode string `json:\",default=pro,options=[dev,test,pre,pro]\"`\n    // ... other common fields\n}\n```\n\n### Middleware Implementation\n```go\nfunc SomeMiddleware() rest.Middleware {\n    return func(next http.HandlerFunc) http.HandlerFunc {\n        return func(w http.ResponseWriter, r *http.Request) {\n            // Pre-processing\n            next.ServeHTTP(w, r)\n            // Post-processing\n        }\n    }\n}\n```\n\n### Resource Management\nAlways implement proper resource cleanup using defer and context cancellation.\n\n## Build and Test Commands\n\n- Build: `go build ./...`\n- Test: `go test ./...`\n- Test with race detection: `go test -race ./...`\n- Format: `gofmt -w .`\n- Code generation:\n  - REST API: `goctl api go -api *.api -dir .`\n  - RPC: `goctl rpc protoc *.proto --go_out=. --go-grpc_out=. --zrpc_out=.`\n  - Model from SQL: `goctl model mysql datasource -url=\"user:pass@tcp(host:port)/db\" -table=\"*\" -dir=\"./model\"`\n\n## Critical Architecture Patterns\n\n### Resilience Design Philosophy\ngo-zero implements defense-in-depth with multiple protection layers:\n1. **Circuit Breaker** (`core/breaker`): Google SRE breaker - tracks success/failure, opens on error threshold\n2. **Adaptive Load Shedding** (`core/load`): CPU-based auto-rejection when system overloaded (disabled in dev/test/rt modes)\n3. **Rate Limiting** (`core/limit`): Token bucket (Redis-based) and period limiters\n4. **Timeout Control**: Cascading timeouts via context - set at multiple levels (client, server, handler)\n\n### Middleware Chain Architecture\n`rest/chain` provides middleware composition:\n```go\n// Middleware signature\ntype Middleware func(http.Handler) http.Handler\n\n// Chain operations\nchain := chain.New(m1, m2)\nchain.Append(m3)    // Adds to end: m1 -> m2 -> m3\nchain.Prepend(m0)   // Adds to start: m0 -> m1 -> m2 -> m3\nhandler := chain.Then(finalHandler)\n```\n\n### Concurrency Patterns\n- **MapReduce** (`core/mr`): Parallel processing with worker pools - use for batch operations\n- **Executors** (`core/executors`): Bulk/period executors for batching operations\n- **SingleFlight** (`core/syncx`): Deduplicates concurrent identical requests\n\nRemember to run tests and ensure all checks pass before submitting changes. The project emphasizes high quality, performance, and reliability, so these should be primary considerations in all development work.","tools/goctl/api/parser/readme.md":"# Api语法描述\n\n## api示例\n\n``` golang\n/**\n * api语法示例及语法说明\n */\n\n// api语法版本\nsyntax = \"v1\"\n\n// import literal\nimport \"foo.api\"\n\n// import group\nimport (\n    \"bar.api\"\n    \"foo/bar.api\"\n)\ninfo(\n    author: \"songmeizi\"\n    date:   \"2020-01-08\"\n    desc:   \"api语法示例及语法说明\"\n)\n\n// type literal\n\ntype Foo{\n    Foo int `json:\"foo\"`\n}\n\n// type group\n\ntype(\n    Bar{\n        Bar int `json:\"bar\"`\n    }\n)\n\n// service block\n@server(\n    jwt:   Auth\n    group: foo\n)\nservice foo-api{\n    @doc \"foo\"\n    @handler foo\n    post /foo (Foo) returns (Bar)\n}\n```\n\n## api语法结构\n\n* syntax语法声明\n* import语法块\n* info语法块\n* type语法块\n* service语法块\n* 隐藏通道\n\n> ### 温馨提示️\n> 在以上语法结构中，各个语法块从语法上来说，按照语法块为单位，可以在.api文件中任意位置声明，\n> 但是为了提高阅读效率，我们建议按照以上顺序进行声明，因为在将来可能会通过严格模式来控制语法块的顺序。\n\n### syntax语法声明\n\nsyntax是新加入的语法结构，该语法的引入可以解决：\n\n* 快速针对api版本定位存在问题的语法结构\n* 针对版本做语法解析\n* 防止api语法大版本升级导致前后不能向前兼容\n\n> ### 警告 ⚠️\n> 被import的api必须要和main api的syntax版本一致。\n\n**语法定义**\n\n``` antlrv4\n'syntax'={checkVersion(p)}STRING\n```\n\n**语法说明**\n> syntax：固定token，标志一个syntax语法结构的开始\n>\n> checkVersion：自定义go方法，检测`STRING`是否为一个合法的版本号，目前检测逻辑为，STRING必须是满足`(?m)\"v[1-9][0-9]*\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"v1\"\n>\n> 一个api语法文件只能有0或者1个syntax语法声明，如果没有syntax，则默认为v1版本\n>\n\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\nsyntax=\"v1\"\n```\n\neg2：规范写法(推荐)\n\n``` api\nsyntax = \"v2\"\n```\n\n**错误语法示例** ❌\n\neg1：\n\n``` api\nsyntax = \"v0\"\n```\n\neg2：\n\n``` api\nsyntax = v1\n```\n\neg3：\n\n``` api\nsyntax = \"V1\"\n```\n\n## import语法块\n\n随着业务规模增大，api中定义的结构体和服务越来越多，所有的语法描述均为一个api文件，这是多么糟糕的一个问题， 其会大大增加了阅读难度和维护难度，import语法块可以帮助我们解决这个问题，通过拆分api文件，\n不同的api文件按照一定规则声明，可以降低阅读难度和维护难度。\n\n> ### 警告 ⚠️\n> 这里import不像golang那样包含package声明，仅仅是一个文件路径的引入，最终解析后会把所有的声明都汇聚到一个spec.Spec中。\n> 不能import多个相同路径，否则会解析错误。\n\n**语法定义**\n\n``` antlrv4\n'import' {checkImportValue(p)}STRING  \n|'import' '(' ({checkImportValue(p)}STRING)+ ')'\n```\n\n**语法说明**\n> import：固定token，标志一个import语法的开始\n>\n> checkImportValue：自定义go方法，检测`STRING`是否为一个合法的文件路径，目前检测逻辑为，STRING必须是满足`(?m)\"(/?[a-zA-Z0-9_#-])+\\.api\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"foo.api\"\n>\n\n\n**正确语法示例** ✅\n\neg：\n\n``` api\nimport \"foo.api\"\nimport \"foo/bar.api\"\n\nimport(\n    \"bar.api\"\n    \"foo/bar/foo.api\"\n)\n```\n\n**错误语法示例** ❌\n\neg：\n\n``` api\nimport foo.api\nimport \"foo.txt\"\nimport (\n    bar.api\n    bar.api\n)\n```\n\n## info语法块\n\ninfo语法块是一个包含了多个键值对的语法体，其作用相当于一个api服务的描述，解析器会将其映射到spec.Spec中， 以备用于翻译成其他语言(golang、java等)\n时需要携带的meta元素。如果仅仅是对当前api的一个说明，而不考虑其翻译 时传递到其他语言，则使用简单的多行注释或者java风格的文档注释即可，关于注释说明请参考下文的 **隐藏通道**。\n\n> ### 警告 ⚠️\n> 不能使用重复的key，每个api文件只能有0或者1个info语法块\n\n**语法定义**\n\n``` antlrv4\n'info' '(' (ID {checkKeyValue(p)}VALUE)+ ')'\n```\n\n**语法说明**\n> info：固定token，标志一个info语法块的开始\n>\n> checkKeyValue：自定义go方法，检测`VALUE`是否为一个合法值。\n>\n> VALUE：key对应的值，可以为单行的除'\\r','\\n','/'后的任意字符，多行请以\"\"包裹，不过强烈建议所有都以\"\"包裹\n>\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ninfo(\nfoo: foo value\nbar:\"bar value\"\n    desc:\"long long long long\nlong long text\"\n)\n```\n\neg2：规范写法(推荐)\n\n``` api\ninfo(\n    foo: \"foo value\"\n    bar: \"bar value\"\n    desc: \"long long long long long long text\"\n)\n```\n\n**错误语法示例** ❌\n\neg1：没有key-value内容\n\n``` api\ninfo()\n```\n\neg2：不包含冒号\n\n``` api\ninfo(\n    foo value\n)\n```\n\neg3：key-value没有换行\n\n``` api\ninfo(foo:\"value\")\n```\n\neg4：没有key\n\n``` api\ninfo(\n    : \"value\"\n)\n```\n\neg5：非法的key\n\n``` api\ninfo(\n    12: \"value\"\n)\n```\n\neg6：移除旧版本多行语法\n\n``` api\ninfo(\n    foo: >\n    some text\n    <\n)\n```\n\n## type语法块\n\n在api服务中，我们需要用到一个结构体(类)来作为请求体，响应体的载体，因此我们需要声明一些结构体来完成这件事情， type语法块由golang的type演变而来，当然也保留着一些golang type的特性，沿用golang特性有：\n\n* 保留了golang内置数据类型`bool`,`int`,`int8`,`int16`,`int32`,`int64`,`uint`,`uint8`,`uint16`,`uint32`,`uint64`,`uintptr`\n  ,`float32`,`float64`,`complex64`,`complex128`,`string`,`byte`,`rune`,\n* 兼容golang struct风格声明\n* 保留golang关键字\n\n> ### 警告 ⚠️\n> * 不支持alias\n> * 不支持time.Time数据类型\n> * 结构体名称、字段名称、不能为golang关键字\n\n**语法定义**\n> 由于其和golang相似，因此不做详细说明，具体语法定义请在[ApiParser.g4](g4/ApiParser.g4)中查看typeSpec定义。\n\n**语法说明**\n\n> 参考golang写法\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ntype Foo struct{\n    Id int `path:\"id\"` // ①\n    Foo int `json:\"foo\"`\n}\n\ntype Bar struct{\n    // 非导出型字段\n    bar int `form:\"bar\"`\n}\n\ntype(\n    // 非导出型结构体\n    fooBar struct{\n        FooBar int\n    }\n)\n```\n\neg2：规范写法（推荐）\n\n``` api\ntype Foo{\n    Id int `path:\"id\"`\n    Foo int `json:\"foo\"`\n}\n\ntype Bar{\n    Bar int `form:\"bar\"`\n}\n\ntype(\n    FooBar{\n        FooBar int\n    }\n)\n```\n\n**错误语法示例** ❌\n\neg\n\n``` api\ntype Gender int // 不支持\n\n// 非struct token\ntype Foo structure{ \n  CreateTime time.Time // 不支持time.Time\n}\n\n// golang关键字 var\ntype var{} \n\ntype Foo{\n  // golang关键字 interface\n  Foo interface \n}\n\n\ntype Foo{\n  foo int \n  // map key必须要golang内置数据类型\n  m map[Bar]string\n}\n```\n\n**① tag说明**\n> tag定义和golang中json tag语法一样，除了json tag外，go-zero还提供了另外一些tag来实现对字段的描述，\n> 详情见下表。\n\n* tag表\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |json|json序列化tag|golang|request、response|`json:\"fooo\"`|\n  |path|路由path，如`/foo/:id`|go-zero|request|`path:\"id\"`|\n  |form|标志请求体是一个form（POST方法时）或者一个query(GET方法时`/search?name=keyword`)|go-zero|request|`form:\"name\"`|\n\n* tag修饰符\n  > 常见参数校验描述\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |optional|定义当前字段为可选参数|go-zero|request|`json:\"name,optional\"`|\n  |options|定义当前字段的枚举值,多个以竖线②隔开|go-zero|request|`json:\"gender,options=male\"`|\n  |default|定义当前字段默认值|go-zero|request|`json:\"gender,default=male\"`|\n  |range|定义当前字段数值范围|go-zero|request|`json:\"age,range=[0:120]\"`|\n\n  ② 竖线：|\n  > ### 温馨提示\n  > tag修饰符需要在tag value后以引文逗号,隔开\n\n## service语法块\n\nservice语法块用于定义api服务，包含服务名称，服务metadata，中间件声明，路由，handler等。\n\n> ### 警告 ⚠️\n> * main api和被import的api服务名称必须一致，不能出现服务名称歧义。\n> * handler名称不能重复\n> * 路由（请求方法+请求path）名称不能重复\n> * 请求体必须声明为普通（非指针）struct，响应体做了一些向前兼容处理，详请见下文说明\n>\n\n**语法定义**\n\n``` antlrv4\nserviceSpec:    atServer? serviceApi;\natServer:       '@server' lp='(' kvLit+ rp=')';\nserviceApi:     {match(p,\"service\")}serviceToken=ID serviceName lbrace='{' serviceRoute* rbrace='}';\nserviceRoute:   atDoc? (atServer|atHandler) route;\natDoc:          '@doc' lp='('? ((kvLit+)|STRING) rp=')'?;\natHandler:      '@handler' ID;\nroute:          {checkHttpMethod(p)}httpMethod=ID path request=body? returnToken=ID? response=replybody?;\nbody:           lp='(' (ID)? rp=')';\nreplybody:      lp='(' dataType? rp=')';\n// kv\nkvLit:          key=ID {checkKeyValue(p)}value=LINE_VALUE;\n\nserviceName:    (ID '-'?)+;\npath:           (('/' (ID ('-' ID)*))|('/:' (ID ('-' ID)?)))+;\n```\n\n**语法说明**\n\n> serviceSpec：包含了一个可选语法块`atServer`和`serviceApi`语法块，其遵循序列模式（编写service必须要按照顺序，否则会解析出错）\n>\n> atServer： 可选语法块，定义key-value结构的server metadata，'@server'表示这一个server语法块的开始，其可以用于描述serviceApi或者route语法块，其用于描述不同语法块时有一些特殊关键key\n> 需要值得注意，见 **atServer关键key描述说明**。\n>\n> serviceApi：包含了1到多个`serviceRoute`语法块\n>\n> serviceRoute：按照序列模式包含了`atDoc`,handler和`route`\n>\n> atDoc：可选语法块，一个路由的key-value描述，其在解析后会传递到spec.Spec结构体，如果不关心传递到spec.Spec,\n> 推荐用单行注释替代。\n>\n> handler：是对路由的handler层描述，可以通过atServer指定`handler` key来指定handler名称，\n> 也可以直接用atHandler语法块来定义handler名称\n>\n> atHandler：'@handler' 固定token，后接一个遵循正则`[_a-zA-Z][a-zA-Z_-]*`)的值，用于声明一个handler名称\n>\n> route：路由，有`httpMethod`、`path`、可选`request`、可选`response`组成，`httpMethod`是必须是小写。\n>\n> body：api请求体语法定义，必须要由()包裹的可选的ID值\n>\n> replyBody：api响应体语法定义，必须由()包裹的struct、~~array(向前兼容处理，后续可能会废弃，强烈推荐以struct包裹，不要直接用array作为响应体)~~\n>\n> kvLit： 同info key-value\n>\n> serviceName: 可以有多个'-'join的ID值\n>\n> path：api请求路径，必须以'/'或者'/:'开头，切不能以'/'结尾，中间可包含ID或者多个以'-'join的ID字符串\n\n**atServer关键key描述说明**\n\n修饰service时\n\n|key|描述|示例|\n|:---|:---|:---|\n|jwt|声明当前service下所有路由需要jwt鉴权，且会自动生成包含jwt逻辑的代码|`jwt: Auth`|\n|group|声明当前service或者路由文件分组|`group: login`|\n|middleware|声明当前service需要开启中间件|`middleware: AuthMiddleware`|\n\n修饰route时\n\n|key|描述|示例|\n|:---|:---|:---|\n|handler|声明一个handler|-|\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc(\n    summary: foo\n  )\n  @server(\n    handler: foo\n  )\n  // 非导出型body\n  post /foo/:id (foo) returns (bar)\n  \n  @doc \"bar\"\n  @handler bar\n  post /bar returns ([]int)// 不推荐数组作为响应体\n  \n  @handler fooBar\n  post /foo/bar (Foo) returns // 可以省略'returns'\n}\n```\n\neg2：规范写法（推荐）\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc \"foo\"\n  @handler: foo\n  post /foo/:id (Foo) returns (Bar)\n}\n\nservice foo-api{\n  @handler ping\n  get /ping\n  \n  @doc \"foo\"\n  @handler: bar\n  post /bar/:id (Foo)\n}\n\n```\n\n**错误语法示例** ❌\n\n``` api\n// 不支持空的server语法块\n@server(\n)\n// 不支持空的service语法块\nservice foo-api{\n}\n\nservice foo-api{\n  @doc kkkk // 简版doc必须用英文双引号引起来\n  @handler foo\n  post /foo\n  \n  @handler foo // 重复的handler\n  post /bar\n  \n  @handler fooBar\n  post /bar // 重复的路由\n  \n  // @handler和@doc顺序错误\n  @handler someHandler\n  @doc \"some doc\"\n  post /some/path\n  \n  // handler缺失\n  post /some/path/:id\n  \n  @handler reqTest\n  post /foo/req (*Foo) // 不支持除普通结构体外的其他数据类型作为请求体\n  \n  @handler replyTest\n  post /foo/reply returns (*Foo) // 不支持除普通结构体、数组(向前兼容，后续考虑废弃)外的其他数据类型作为响应体\n}\n```\n\n## 隐藏通道\n\n隐藏通道目前主要为空白符号，换行符号以及注释，这里我们只说注释，因为空白符号和换行符号我们目前拿来也无用。\n\n### 单行注释\n\n**语法定义**\n\n``` antlrv4\n'//' ~[\\r\\n]*\n```\n\n**语法说明**\n由语法定义可知道，单行注释必须要以`//`开头，内容为不能包含换行符\n\n**正确语法示例** ✅\n\n``` api\n// doc\n// comment\n```\n\n**错误语法示例** ❌\n\n``` api\n// break\nline comments\n```\n\n### java风格文档注释\n\n**语法定义**\n\n``` antlrv4\n'/*' .*? '*/'\n```\n\n**语法说明**\n\n由语法定义可知道，单行注释必须要以`/*`开头，`*/`结尾的任意字符。\n\n**正确语法示例** ✅\n\n``` api\n/**\n * java-style doc\n */\n```\n\n**错误语法示例** ❌\n\n``` api\n/*\n * java-style doc */\n */\n```\n\n## Doc&Comment\n\n如果想获取某一个元素的doc或者comment开发人员需要怎么定义？\n\n**Doc**\n> 我们规定上一个语法块（非隐藏通道内容）的行数line+1到当前语法块第一个元素前的所有注释(当行，或者多行)均为doc， 且保留了`//`、`/*`、`*/`原始标记。\n\n**Comment**\n> 我们规定当前语法块最后一个元素所在行开始的一个注释块(当行，或者多行)为comment 且保留了`//`、`/*`、`*/`原始标记。\n\n语法块Doc和Comment的支持情况\n\n|语法块|parent语法块|Doc|Comment|\n|:---|:---|:---|:---|\n|syntaxLit|api|✅|✅|\n|kvLit|infoSpec|✅|✅|\n|importLit|importSpec|✅|✅|\n|typeLit|api|✅|❌|\n|typeLit|typeBlock|✅|❌|\n|field|typeLit|✅|✅|\n|key-value|atServer|✅|✅|\n|atHandler|serviceRoute|✅|✅|\n|route|serviceRoute|✅|✅|\n\n以下为对应语法块解析后细带doc和comment的写法\n``` api\n// syntaxLit doc\nsyntax = \"v1\" // syntaxLit comment\n\ninfo(\n  // kvLit doc\n  author: songmeizi // kvLit comment\n)\n\n// typeLit doc\ntype Foo {}\n\ntype(\n  // typeLit doc\n  Bar{}\n  \n  FooBar{\n    // filed doc\n    Name int // filed comment\n  }\n)\n\n@server(\n  /**\n   * kvLit doc\n   * 开启jwt鉴权\n   */\n  jwt: Auth /**kvLit comment*/\n)\nservice foo-api{\n  // atHandler doc\n  @handler foo //atHandler comment\n  \n  /*\n   * route doc\n   * post请求\n   * path为 /foo\n   * 请求体：Foo\n   * 响应体：Foo\n   */\n  post /foo (Foo) returns (Foo) // route comment\n}\n```\n","tools/goctl/api/swagger/example/example.swagger.json":"{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"Generating Swagger files using the API demo.\",\n    \"title\": \"Demo API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form demo\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-User not login\\u003cbr\\u003e1002-User permission denied\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"complex json request body API\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"postJson\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"number\": {\n                  \"type\": \"number\",\n                  \"example\": 1.1\n                },\n                \"object\": {\n                  \"type\": \"object\",\n                  \"required\": [\n                    \"integer\",\n                    \"number\",\n                    \"boolean\",\n                    \"string\",\n                    \"object\",\n                    \"pointerObject\"\n                  ],\n                  \"properties\": {\n                    \"boolean\": {\n                      \"type\": \"boolean\",\n                      \"enum\": [\n                        \"true\",\n                        \"false\"\n                      ],\n                      \"example\": true\n                    },\n                    \"integer\": {\n                      \"type\": \"integer\",\n                      \"example\": 1\n                    },\n                    \"number\": {\n                      \"type\": \"number\",\n                      \"example\": 1.1\n                    },\n                    \"object\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      },\n                      \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                    },\n                    \"pointerObject\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        }\n\n<!-- [TRUNCATED AT 50KB] -->","tools/goctl/api/swagger/example/example_cn.swagger.json":"{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"演示 api 生成 swagger 文件的 api 完整写法\",\n    \"title\": \"演示 API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form 接口\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form 表单 api 演示\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-未登录\\u003cbr\\u003e1002-无权限操作\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"复杂的 json 请求体接口\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"post json api 演示\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"mapMapObject\",\n                \"mapMapPointerObject\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"objec\n\n<!-- [TRUNCATED AT 50KB] -->","tools/goctl/config/readme.md":"# 配置项管理\n\n| 名称              | 是否可选 | 说明                                          |\n|-------------------|----------|-----------------------------------------------|\n| namingFormat      | YES      | 文件名称格式化符                      |\n\n# naming-format\n`namingFormat`可以用于对生成代码的文件名称进行格式化，和日期格式化符（yyyy-MM-dd）类似，在代码生成时可以根据这些配置项的格式化符进行格式化。\n\n## 格式化符(gozero)\n格式化符由`go`,`zero`组成，如常见的三种格式化风格你可以这样编写：\n* lower: `gozero`\n* camel: `goZero`\n* snake: `go_zero`\n\n常见格式化符生成示例\n源字符：welcome_to_go_zero\n\n| 格式化符   | 格式化结果            | 说明                      |\n|------------|-----------------------|---------------------------|\n| gozero     | welcometogozero       | 小写                      |\n| goZero     | welcomeToGoZero       | 驼峰                      |\n| go_zero    | welcome_to_go_zero    | snake                     |\n| Go#zero    | Welcome#to#go#zero    | #号分割Title类型          |\n| GOZERO     | WELCOMETOGOZERO       | 大写                      |\n| \\_go#zero_ | \\_welcome#to#go#zero_ | 下划线做前后缀，并且#分割 |\n\n错误格式化符示例\n* go\n* gOZero\n* zero\n* goZEro\n* goZERo\n* goZeRo\n* tal\n\n# 使用方法\n目前可通过在生成api、rpc、model时通过`--style`参数指定format格式，如：\n```shell script\ngoctl api go test.api -dir . -style gozero\n```\n```shell script\n goctl rpc proto -src test.proto -dir . -style go_zero\n```\n```shell script\ngoctl model mysql datasource -url=\"\" -table=\"*\" -dir ./snake -style GoZero\n```\n\n# 默认值\n当不指定-style时默认值为`gozero`\n","tools/goctl/model/mongo/readme.md":"# mongo生成model\n\n## 背景\n\n在业务务开发中，model(dao)数据访问层是一个服务必不可缺的一层，因此数据库访问的CURD也是必须要对外提供的访问方法， 而CURD在go-zero中就仅存在两种情况\n\n* 带缓存model\n* 不带缓存model\n\n从代码结构上来看，C-U-R-D四个方法就是固定的结构，因此我们可以将其交给goctl工具去完成，帮助我们提升开发效率。\n\n## 方案设计\n\nmongo的生成不同于mysql，mysql可以从scheme_information库中读取到一张表的信息（字段名称，数据类型，索引等），\n而mongo是文档型数据库，我们暂时无法从db中读取某一条记录来实现字段信息获取，就算有也不一定是完整信息（某些字段可能是omitempty修饰，可有可无）， 这里采用type自己编写+代码生成方式实现\n\n## 使用示例\n为 User 生成 mongo model\n```bash\n$ goctl model mongo -t User -c --dir .\n```\n\n### 生成示例代码\n\n#### usermodel.go\n```go\npackage model\n\nimport (\n\t\"github.com/zeromicro/go-zero/core/stores/cache\"\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n)\n\nvar _ UserModel = (*customUserModel)(nil)\n\ntype (\n\t// UserModel is an interface to be customized, add more methods here,\n\t// and implement the added methods in customUserModel.\n\tUserModel interface {\n\t\tuserModel\n\t}\n\n\tcustomUserModel struct {\n\t\t*defaultUserModel\n\t}\n)\n\n// NewUserModel returns a model for the mongo.\nfunc NewUserModel(url, db, collection string, c cache.CacheConf) UserModel {\n\tconn := monc.MustNewModel(url, db, collection, c)\n\treturn &customUserModel{\n\t\tdefaultUserModel: newDefaultUserModel(conn),\n\t}\n}\n\n```\n\n#### usermodelgen.go\n```go\n// Code generated by goctl. DO NOT EDIT.\npackage model\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n\t\"go.mongodb.org/mongo-driver/bson\"\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n\t\"go.mongodb.org/mongo-driver/mongo\"\n)\n\nvar prefixUserCacheKey = \"cache:user:\"\n\ntype userModel interface {\n\tInsert(ctx context.Context, data *User) error\n\tFindOne(ctx context.Context, id string) (*User, error)\n\tUpdate(ctx context.Context, data *User) (*mongo.UpdateResult, error)\n\tDelete(ctx context.Context, id string) (int64, error)\n}\n\ntype defaultUserModel struct {\n\tconn *monc.Model\n}\n\nfunc newDefaultUserModel(conn *monc.Model) *defaultUserModel {\n\treturn &defaultUserModel{conn: conn}\n}\n\nfunc (m *defaultUserModel) Insert(ctx context.Context, data *User) error {\n\tif !data.ID.IsZero() {\n\t\tdata.ID = primitive.NewObjectID()\n\t\tdata.CreateAt = time.Now()\n\t\tdata.UpdateAt = time.Now()\n\t}\n\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\t_, err := m.conn.InsertOne(ctx, key, data)\n\treturn err\n}\n\nfunc (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn nil, ErrInvalidObjectId\n\t}\n\n\tvar data User\n\tkey := prefixUserCacheKey + id\n\terr = m.conn.FindOne(ctx, key, &data, bson.M{\"_id\": oid})\n\tswitch err {\n\tcase nil:\n\t\treturn &data, nil\n\tcase monc.ErrNotFound:\n\t\treturn nil, ErrNotFound\n\tdefault:\n\t\treturn nil, err\n\t}\n}\n\nfunc (m *defaultUserModel) Update(ctx context.Context, data *User) (*mongo.UpdateResult, error) {\n\tdata.UpdateAt = time.Now()\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\tres, err := m.conn.ReplaceOne(ctx, key, bson.M{\"_id\": data.ID}, bson.M{\"$set\": data})\n\treturn res, err\n}\n\nfunc (m *defaultUserModel) Delete(ctx context.Context, id string) (int64, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn 0, ErrInvalidObjectId\n\t}\n\tkey := prefixUserCacheKey + id\n\tres, err := m.conn.DeleteOne(ctx, key, bson.M{\"_id\": oid})\n\treturn res, err\n}\n\n```\n\n#### usertypes.go\n```go\npackage model\n\nimport (\n\t\"time\"\n\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n)\n\ntype User struct {\n\tID primitive.ObjectID `bson:\"_id,omitempty\" json:\"id,omitempty\"`\n\t// TODO: Fill your own fields\n\tUpdateAt time.Time `bson:\"updateAt,omitempty\" json:\"updateAt,omitempty\"`\n\tCreateAt time.Time `bson:\"createAt,omitempty\" json:\"createAt,omitempty\"`\n}\n\n```\n\n#### error.go\n```go\npackage model\n\nimport (\n\t\"errors\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/mon\"\n)\n\nvar (\n\tErrNotFound        = mon.ErrNotFound\n\tErrInvalidObjectId = errors.New(\"invalid objectId\")\n)\n```\n\n### 文件目录预览\n\n```text\n.\n├── error.go\n├── usermodel.go\n├── usermodelgen.go\n└── usertypes.go\n```\n\n## 命令预览\n\n```text\nGenerate mongo model\n\nUsage:\n  goctl model mongo [flags]\n\nFlags:\n      --branch string   The branch of the remote repo, it does work with --remote\n  -c, --cache           Generate code with cache [optional]\n  -d, --dir string      The target dir\n  -h, --help            help for mongo\n      --home string     The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n      --remote string   The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n                                The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure\n      --style string    The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n  -t, --type strings    Specified model type name\n\n```\n\n> 温馨提示\n> \n> `--type` 支持slice传值，示例 `goctl model mongo -t=User -t=Class`\n\n","tools/goctl/model/sql/README.MD":"# Goctl Model\n\ngoctl model 为go-zero下的工具模块中的组件之一，目前支持识别mysql ddl进行model层代码生成，通过命令行或者idea插件（即将支持）可以有选择地生成带redis cache或者不带redis cache的代码逻辑。\n\n## 快速开始\n\n* 通过ddl生成\n\n    ```shell script\n    goctl model mysql ddl -src=\"./*.sql\" -dir=\"./sql/model\" -c\n    ```\n\n    执行上述命令后即可快速生成CURD代码。\n\n    ```Plain Text\n    model\n    │   ├── error.go\n    │   └── usermodel.go\n    ```\n\n* 通过datasource生成\n\n    ```shell script\n    goctl model mysql datasource -url=\"user:password@tcp(127.0.0.1:3306)/database\" -table=\"*\"  -dir=\"./model\"\n    ```\n\n* 生成代码示例\n  \n\t```go\n\n\tpackage model\n    \n    import (\n    \t\"database/sql\"\n    \t\"fmt\"\n    \t\"strings\"\n    \t\"time\"\n        \n        \"github.com/zeromicro/go-zero/core/stores/builder\"\n    \t\"github.com/zeromicro/go-zero/core/stores/cache\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlc\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlx\"\n    \t\"github.com/zeromicro/go-zero/core/stringx\"\n    )\n    \n    var (\n    \tuserFieldNames          = builder.FieldNames(&User{})\n    \tuserRows                = strings.Join(userFieldNames, \",\")\n    \tuserRowsExpectAutoSet   = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \",\")\n    \tuserRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \"=?,\") + \"=?\"\n    \n    \tcacheUserPrefix       = \"cache:User:user:\"\n    \tcacheUserNamePrefix   = \"cache:User:name:\"\n    \tcacheUserMobilePrefix = \"cache:User:mobile:\"\n    \tcacheUserIdPrefix     = \"cache:User:id:\"\n    )\n    \n    type (\n    \tUserModel interface {\n    \t\tInsert(data User) (sql.Result, error)\n    \t\tFindOne(id int64) (*User, error)\n    \t\tFindOneByUser(user string) (*User, error)\n    \t\tFindOneByName(name string) (*User, error)\n    \t\tFindOneByMobile(mobile string) (*User, error)\n    \t\tUpdate(data User) error\n    \t\tDelete(id int64) error\n    \t}\n    \n    \tdefaultUserModel struct {\n    \t\tsqlc.CachedConn\n    \t\ttable string\n    \t}\n    \n    \tUser struct {\n    \t\tId         int64     `db:\"id\"`\n    \t\tUser       string    `db:\"user\"`     // 用户\n    \t\tName       string    `db:\"name\"`     // 用户名称\n    \t\tPassword   string    `db:\"password\"` // 用户密码\n    \t\tMobile     string    `db:\"mobile\"`   // 手机号\n    \t\tGender     string    `db:\"gender\"`   // 男｜女｜未公开\n    \t\tNickname   sql.NullString    `db:\"nickname\"` // 用户昵称\n    \t\tCreateTime sql.NullTime `db:\"create_time\"`\n    \t\tUpdateTime time.Time `db:\"update_time\"`\n    \t}\n    )\n    \n    func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {\n    \treturn &defaultUserModel{\n    \t\tCachedConn: sqlc.NewConn(conn, c),\n    \t\ttable:      \"user\",\n    \t}\n    }\n    \n    func (m *defaultUserModel) Insert(data User) (sql.Result, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \tret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"insert into %s (%s) values (?, ?, ?, ?, ?, ?)\", m.table, userRowsExpectAutoSet)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname)\n    \t}, userMobileKey, userKey, userNameKey)\n    \treturn ret, err\n    }\n    \n    func (m *defaultUserModel) FindOne(id int64) (*User, error) {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tvar resp User\n    \terr := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v any) error {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \t\treturn conn.QueryRow(v, query, id)\n    \t})\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByUser(user string) (*User, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, user)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where user = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, user); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByName(name string) (*User, error) {\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, name)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userNameKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where name = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, name); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByMobile(mobile string) (*User, error) {\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, mobile)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userMobileKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where mobile = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, mobile); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) Update(data User) error {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, data.Id)\n    \t_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"update %s set %s where id = ?\", m.table, userRowsWithPlaceHolder)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id)\n    \t}, userIdKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) Delete(id int64) error {\n    \tdata, err := m.FindOne(id)\n    \tif err != nil {\n    \t\treturn err\n    \t}\n    \n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \t_, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"delete from %s where id = ?\", m.table)\n    \t\treturn conn.Exec(query, id)\n    \t}, userIdKey, userKey, userNameKey, userMobileKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) formatPrimary(primary any) string {\n    \treturn fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, primary)\n    }\n    \n    func (m *defaultUserModel) queryPrimary(conn sqlx.SqlConn, v, primary any) error {\n    \tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \treturn conn.QueryRow(v, query, primary)\n    }\n\n\t```\n\n## 用法\n\n```Plain Text\ngoctl model mysql -h\n```\n\n```Plain Text\nNAME:\n   goctl model mysql - generate mysql model\"\n\nUSAGE:\n   goctl model mysql command [command options] [arguments...]\n\nCOMMANDS:\n   ddl         generate mysql model from ddl\"\n   datasource  generate model from datasource\"\n\nOPTIONS:\n   --help, -h  show help\n```\n\n## 生成规则\n\n* 默认规则\n  \n  我们默认用户在建表时会创建createTime、updateTime字段(忽略大小写、下划线命名风格)且默认值均为`CURRENT_TIMESTAMP`，而updateTime支持`ON UPDATE CURRENT_TIMESTAMP`，对于这两个字段生成`insert`、`update`时会被移除，不在赋值范畴内，当然，如果你不需要这两个字段那也无大碍。\n* 带缓存模式\n  * ddl\n\n\t```shell script\n\tgoctl model mysql -src={patterns} -dir={dir} -cache\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql ddl - generate mysql model from ddl\n    \n    USAGE:\n       goctl model mysql ddl [command options] [arguments...]\n    \n    OPTIONS:\n       --src value, -s value  the path or path globbing patterns of the ddl\n       --dir value, -d value  the target dir\n       --style value          the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --cache, -c            generate code with cache [optional]\n       --idea                 for idea plugin [optional]\n       --database, -db        the name of database [optional]\n\t```\n\n  * datasource\n\n\t```shell script\n\tgoctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir} -cache=true\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql datasource - generate model from datasource\n    \n    USAGE:\n       goctl model mysql datasource [command options] [arguments...]\n    \n    OPTIONS:\n       --url value              the data source of database,like \"root:password@tcp(127.0.0.1:3306)/database\n       --table value, -t value  the table or table globbing patterns in the database\n       --cache, -c              generate code with cache [optional]\n       --dir value, -d value    the target dir\n       --style value            the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --idea                   for idea plugin [optional]\n\n\n\t```\n\n\t示例用法请参考[用法](./example/makefile)\n  \n\t> NOTE: goctl model mysql ddl/datasource 均新增了一个`--style`参数，用于标记文件命名风格。\n\n  目前仅支持redis缓存，如果选择带缓存模式，即生成的`FindOne(ByXxx)`&`Delete`代码会生成带缓存逻辑的代码，目前仅支持单索引字段（除全文索引外），对于联合索引我们默认认为不需要带缓存，且不属于通用型代码，因此没有放在代码生成行列，如example中user表中的`id`、`name`、`mobile`字段均属于单字段索引。\n\n* 不带缓存模式\n\n  * ddl\n  \n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n\n  or\n  * ddl\n\n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n  \n生成代码仅基本的CURD结构。\n\n## 缓存\n\n  对于缓存这一块我选择用一问一答的形式进行罗列。我想这样能够更清晰的描述model中缓存的功能。\n\n* 缓存会缓存哪些信息？\n\n  对于主键字段缓存，会缓存整个结构体信息，而对于单索引字段（除全文索引）则缓存主键字段值。\n\n* 数据有更新（`update`）操作会清空缓存吗？\n  \n  会，但仅清空主键缓存的信息，why？这里就不做详细赘述了。\n\n* 为什么不按照单索引字段生成`updateByXxx`和`deleteByXxx`的代码？\n  \n  理论上是没任何问题，但是我们认为，对于model层的数据操作均是以整个结构体为单位，包括查询，我不建议只查询某部分字段（不反对），否则我们的缓存就没有意义了。\n\n* 为什么不支持`findPageLimit`、`findAll`这种模型代码生成？\n  \n  目前，我认为除了基本的CURD外，其他的代码均属于<i>业务型</i>代码，这个我觉得开发人员根据业务需要进行编写更好。\n\n# 类型转换规则\n\n| mysql dataType | golang dataType | golang Null dataType |\n|----------------|-----------------|----------------------------------------|\n| bool           | int64           | sql.NullInt64                          |\n| boolean        | int64           | sql.NullInt64                          |\n| tinyint        | int64           | sql.NullInt64                          |\n| smallint       | int64           | sql.NullInt64                          |\n| mediumint      | int64           | sql.NullInt64                          |\n| int            | int64           | sql.NullInt64                          |\n| integer        | int64           | sql.NullInt64                          |\n| bigint         | int64           | sql.NullInt64                          |\n| float          | float64         | sql.NullFloat64                        |\n| double         | float64         | sql.NullFloat64                        |\n| decimal        | float64         | sql.NullFloat64                        |\n| date           | time.Time       | sql.NullTime                           |\n| datetime       | time.Time       | sql.NullTime                           |\n| timestamp      | time.Time       | sql.NullTime                           |\n| time           | string          | sql.NullString                         |\n| year           | time.Time       | sql.NullInt64                          |\n| char           | string          | sql.NullString                         |\n| varchar        | string          | sql.NullString                         |\n| binary         | string          | sql.NullString                         |\n| varbinary      | string          | sql.NullString                         |\n| tinytext       | string          | sql.NullString                         |\n| text           | string          | sql.NullString                         |\n| mediumtext     | string          | sql.NullString                         |\n| longtext       | string          | sql.NullString                         |\n| enum           | string          | sql.NullString                         |\n| set            | string          | sql.NullString                         |\n| json           | string          | sql.NullString                         |\n\n","tools/goctl/readme.md":"# goctl\n\nEnglish | [简体中文](readme-cn.md) | [한국어](readme-ko.md)\n\nRead document at https://go-zero.dev/docs/tutorials/cli/overview\n","tools/goctl/rpc/README.md":"# goctl rpc — RPC Code Generation\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\ngoctl rpc is the RPC service code generation module of the `goctl` scaffold. It generates a complete zRPC service from `.proto` files. You only need to write the proto definition and business logic — all boilerplate code is generated automatically.\n\n## Features\n\n- **protoc compatible**: Fully compatible with protoc, all protoc arguments are passed through\n- **External proto imports**: Cross-directory and cross-package proto imports with automatic transitive dependency resolution\n- **Multiple services**: Define multiple services in a single proto file, auto-grouped by service name\n- **Streaming support**: Server streaming, client streaming, and bidirectional streaming\n- **Google well-known types**: Automatic recognition of supported `google.protobuf.*` types with correct Go imports\n- **Client generation**: Auto-generated RPC client wrapper code\n\n## Prerequisites\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n```\n\n## Quick Start\n\n### Method 1: Create a Service Instantly\n\n```bash\ngoctl rpc new greeter\n```\n\nGenerates a complete project structure:\n\n```\ngreeter/\n├── etc/\n│   └── greeter.yaml\n├── greeter/\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient/\n│   └── greeter.go\n└── internal/\n    ├── config/\n    │   └── config.go\n    ├── logic/\n    │   └── pinglogic.go\n    ├── server/\n    │   └── greeterserver.go\n    └── svc/\n        └── servicecontext.go\n```\n\n### Method 2: Generate from a Proto File\n\n1. Generate a proto template:\n\n```bash\ngoctl rpc template -o=user.proto\n```\n\n2. Initialize the output directory and generate service code:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n---\n\n## Command Reference\n\n### `goctl rpc protoc`\n\nGenerate zRPC service code from a `.proto` file.\n\n```bash\ngoctl rpc protoc <proto_file> [flags]\n```\n\n**Examples:**\n\n```bash\n# Basic usage\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n\n# Multiple services mode\ngoctl rpc protoc multi.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -m\n\n# Import external protos\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -I ./shared_protos\n\n# Use Google well-known types\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--zrpc_out` | | string | **required** | Output directory for zRPC service code |\n| `--go_out` | | string | **required** | Output directory for protoc Go code |\n| `--go-grpc_out` | | string | **required** | Output directory for protoc gRPC code |\n| `--go_opt` | | string | | Options for protoc-gen-go (e.g., `module=example.com/demo`) |\n| `--go-grpc_opt` | | string | | Options for protoc-gen-go-grpc (e.g., `module=example.com/demo`) |\n| `--proto_path` | `-I` | string[] | | Proto import search directories (repeatable) |\n| `--multiple` | `-m` | bool | `false` | Multiple services mode |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--style` | | string | `gozero` | File naming style |\n| `--module` | | string | | Custom Go module name |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc new`\n\nQuickly create a complete RPC service project.\n\n```bash\ngoctl rpc new <service_name> [flags]\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--style` | | string | `gozero` | File naming style |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--module` | | string | | Custom Go module name |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--idea` | | bool | `false` | Generate IDE project marker |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc template`\n\nGenerate a proto file template.\n\n```bash\ngoctl rpc template -o=<output_file> [flags]\n```\n\n**Flags:**\n\n| Flag | Type | Description |\n|------|------|-------------|\n| `-o` | string | Output file path (required) |\n| `--home` | string | goctl template directory |\n| `--remote` | string | Remote template Git repository URL |\n| `--branch` | string | Remote template branch |\n\n---\n\n## Feature Details\n\n### Multiple Services Mode (`--multiple`)\n\nWhen a proto file contains multiple `service` definitions, the `--multiple` flag is required.\n\n```protobuf\nservice SearchService {\n  rpc Search(SearchReq) returns (SearchReply);\n}\n\nservice NotifyService {\n  rpc Notify(NotifyReq) returns (NotifyReply);\n}\n```\n\n**Directory differences with `--multiple`:**\n\n| Feature | Default mode | `--multiple` mode |\n|---------|-------------|-------------------|\n| Services per proto | Exactly 1 | 1 or more |\n| Client directory | Named after service | Fixed `client/` directory |\n| Code organization | Flat structure | Grouped by service name |\n\n**`--multiple=false` (default) directory structure:**\n\n```\noutput/\n├── greeterclient/\n│   └── greeter.go\n├── internal/\n│   ├── logic/\n│   │   └── sayhellologic.go\n│   └── server/\n│       └── greeterserver.go\n└── ...\n```\n\n**`--multiple=true` directory structure:**\n\n```\noutput/\n├── client/\n│   ├── searchservice/\n│   │   └── searchservice.go\n│   └── notifyservice/\n│       └── notifyservice.go\n├── internal/\n│   ├── logic/\n│   │   ├── searchservice/\n│   │   │   └── searchlogic.go\n│   │   └── notifyservice/\n│   │       └── notifylogic.go\n│   └── server/\n│       ├── searchservice/\n│       │   └── searchserviceserver.go\n│       └── notifyservice/\n│           └── notifyserviceserver.go\n└── ...\n```\n\n### External Proto Imports (`--proto_path`)\n\nUse `-I` / `--proto_path` to specify additional proto search directories. Supported scenarios:\n\n- **Same-directory import**: `import \"types.proto\";`\n- **Subdirectory import**: `import \"common/types.proto\";`\n- **External directory import**: Proto files outside the project\n- **Transitive imports**: A imports B, B imports C — goctl resolves recursively\n- **Cross-package imports**: Different `go_package` values generate correct Go imports automatically\n\n```bash\n# Search multiple directories for proto files\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./shared_protos -I /path/to/external_protos\n```\n\n### Service Naming\n\nBy default, the service name is derived from the proto **package name** (e.g., `package user;` → service name `user`). This allows multiple proto files to share the same package:\n\n```\nprotos/\n├── user_base.proto      # package user;\n├── user_auth.proto      # package user;\n└── user_profile.proto   # package user;\n```\n\nAll three files generate into a single `user` service.\n\nTo use the proto filename for naming (legacy behavior), add the `--name-from-filename` flag.\n\n### Streaming RPC\n\nAll three gRPC streaming patterns are supported:\n\n```protobuf\nservice StreamService {\n  rpc ServerStream(Req) returns (stream Reply);       // Server streaming\n  rpc ClientStream(stream Req) returns (Reply);       // Client streaming\n  rpc BidiStream(stream Req) returns (stream Reply);  // Bidirectional streaming\n}\n```\n\n### Google Well-Known Types\n\ngoctl automatically recognizes and handles Google protobuf well-known types:\n\n| Proto Type | Go Type |\n|-----------|---------|\n| `google.protobuf.Empty` | `emptypb.Empty` |\n| `google.protobuf.Timestamp` | `timestamppb.Timestamp` |\n| `google.protobuf.Duration` | `durationpb.Duration` |\n| `google.protobuf.Any` | `anypb.Any` |\n| `google.protobuf.Struct` | `structpb.Struct` |\n| `google.protobuf.FieldMask` | `fieldmaskpb.FieldMask` |\n| `google.protobuf.*Value` | `wrapperspb.*Value` |\n\nThese types can be used directly as RPC parameter types — goctl generates the correct imports automatically.\n\n---\n\n## Examples\n\nSee the [example/](example/) directory for 10 complete examples covering all generation scenarios.\n\n| # | Example | Scenario |\n|---|---------|----------|\n| 01 | [Basic service](example/01-basic/) | Single service, no imports |\n| 02 | [Sibling import](example/02-import-sibling/) | Import from same directory |\n| 03 | [Subdirectory import](example/03-import-subdir/) | Import from subdirectory |\n| 04 | [Transitive import](example/04-transitive-import/) | A → B → C dependency chain |\n| 05 | [Multiple services](example/05-multiple-services/) | `--multiple` mode |\n| 06 | [Well-known types](example/06-wellknown-types/) | Timestamp etc. in messages |\n| 07 | [External proto (same pkg)](example/07-external-proto-same-pkg/) | External proto, same go_package |\n| 08 | [External proto (diff pkg)](example/08-external-proto-diff-pkg/) | External proto, different go_package |\n| 09 | [Google well-known types as params](example/09-google-types-as-rpc/) | Empty/Timestamp as RPC parameters |\n| 10 | [Streaming](example/10-streaming/) | Server/client/bidirectional streaming |\n","tools/goctl/rpc/example/01-basic/README.md":"# Example 01: Basic RPC Service\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis is the simplest example of generating an RPC service with goctl.\n\n## Proto Definition\n\nA single `greeter.proto` file with one service and one RPC method, no external imports.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/greeter\";\n```\n\n## Generation Commands\n\n### Method 1: Quick Start with `goctl rpc new`\n\n```bash\n# Create a complete RPC project with one command\ngoctl rpc new greeter\n```\n\nThis generates the proto file and service code together:\n\n```\ngreeter/\n├── etc\n│   └── greeter.yaml\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── pinglogic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n### Method 2: Generate from an Existing Proto\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc greeter.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── greeter.yaml\n├── go.mod\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── sayhellologic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n## Key Points\n\n- This is the simplest scenario: one proto file, one service, one RPC method.\n- The `go_package` uses a full module path (`example.com/demo/greeter`), not a relative path.\n- The `--module` flag tells goctl the Go module name; `--go_opt=module=...` and `--go-grpc_opt=module=...` tell protoc to strip the module prefix from output paths.\n- The `--zrpc_out` flag specifies where the goctl-generated service code goes.\n- The `--go_out` and `--go-grpc_out` flags specify where protoc-generated code goes.\n- Edit the logic file (`internal/logic/sayhellologic.go`) to implement your business logic.\n","tools/goctl/rpc/example/02-import-sibling/README.md":"# Example 02: Importing a Sibling Proto File\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from the same directory.\n\n## Proto Definition\n\nTwo proto files in the same directory share the same `go_package`:\n\n- `types.proto` — Defines shared message types (`User`).\n- `user.proto` — Defines the RPC service, importing `types.proto`.\n\nBoth files use the same `go_package` with a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n`user.proto` imports `types.proto` via:\n\n```protobuf\nimport \"types.proto\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc user.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── usersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createuserlogic.go\n│   │   └── getuserlogic.go\n│   ├── server\n│   │   └── userserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── types.pb.go\n│   ├── user.pb.go\n│   └── user_grpc.pb.go\n├── userservice\n│   └── userservice.go\n└── usersvc.go\n```\n\n## Key Points\n\n- Two proto files (`user.proto` and `types.proto`) share the same `go_package = \"example.com/demo/pb\"`, compiled into a single Go package.\n- `user.proto` imports `types.proto` via `import \"types.proto\"`.\n- When multiple proto files share the same `go_package`, they compile into a single Go package.\n- Only the proto file containing `service` definitions needs to be passed to `goctl rpc protoc`.\n- The imported proto is automatically compiled by protoc and resolved by goctl.\n","tools/goctl/rpc/example/03-import-subdir/README.md":"# Example 03: Importing Proto from a Subdirectory\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from a subdirectory.\n\n## Proto Definition\n\nTwo proto files with **different** `go_package` values:\n\n- `order.proto` — Defines the `OrderService`, imports `common/types.proto`.\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `common/types.proto` — Defines reusable pagination and sorting messages.\n\n```protobuf\noption go_package = \"example.com/demo/pb/common\";\n```\n\n`order.proto` imports `common/types.proto` from a subdirectory:\n\n```protobuf\nimport \"common/types.proto\";\n```\n\nNote that the two files have **different** `go_package` values, so they compile into separate Go packages.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc order.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── ordersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── getorderlogic.go\n│   │   └── listorderslogic.go\n│   ├── server\n│   │   └── orderserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── orderservice\n│   └── orderservice.go\n├── ordersvc.go\n└── pb\n    ├── common\n    │   └── types.pb.go\n    ├── order.pb.go\n    └── order_grpc.pb.go\n```\n\n## Key Points\n\n- Two proto files have **different** `go_package` values, so they compile into separate Go packages (`pb/` and `pb/common/`).\n- `order.proto` imports `common/types.proto` from a subdirectory.\n- When imported protos have a different `go_package`, goctl automatically generates cross-package imports.\n- The `-I .` flag tells protoc to search from the current directory, enabling it to find `common/types.proto`.\n","tools/goctl/rpc/example/04-transitive-import/README.md":"# Example 04: Transitive Imports\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates transitive proto imports, where A imports B and B imports C.\n\n## Proto Definition\n\nThree proto files form a transitive import chain, all sharing the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `base.proto` — Layer C: defines base types (`BaseResp`).\n- `middleware.proto` — Layer B: imports `base.proto`, defines `RequestMeta`.\n- `main.proto` — Layer A: imports `middleware.proto`, defines the `PingService` (entry point).\n\nImport chain: `main.proto` → `middleware.proto` → `base.proto`\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc main.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── pingsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── pingserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── base.pb.go\n│   ├── main.pb.go\n│   ├── main_grpc.pb.go\n│   └── middleware.pb.go\n├── pingservice\n│   └── pingservice.go\n└── pingsvc.go\n```\n\n## Key Points\n\n- Three proto files (`main.proto` → `middleware.proto` → `base.proto`) form a transitive import chain.\n- goctl recursively resolves all transitive imports automatically.\n- All three files share the same `go_package = \"example.com/demo/pb\"`.\n- You only need to specify the entry proto file — goctl and protoc handle the rest.\n- Circular imports are detected and will cause an error (same as protoc behavior).\n","tools/goctl/rpc/example/05-multiple-services/README.md":"# Example 05: Multiple Services (`--multiple`)\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates generating multiple RPC services from a single proto file.\n\n## Proto Definition\n\nTwo proto files share the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `shared.proto` — Defines shared message types (`Meta`).\n- `multi.proto` — Defines **two** services: `SearchService` and `NotifyService`.\n\nThe `-m` (or `--multiple`) flag is required when a proto file contains more than one `service` block.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code with the `-m` flag:\n\n```bash\ngoctl rpc protoc multi.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . \\\n  -m\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── client\n│   ├── notifyservice\n│   │   └── notifyservice.go\n│   └── searchservice\n│       └── searchservice.go\n├── etc\n│   └── multisvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── notifyservice\n│   │   │   └── notifylogic.go\n│   │   └── searchservice\n│   │       └── searchlogic.go\n│   ├── server\n│   │   ├── notifyservice\n│   │   │   └── notifyserviceserver.go\n│   │   └── searchservice\n│   │       └── searchserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── multisvc.go\n└── pb\n    ├── multi.pb.go\n    ├── multi_grpc.pb.go\n    └── shared.pb.go\n```\n\n## Key Points\n\n- The `-m` (or `--multiple`) flag enables multiple-service mode.\n- In multiple mode, `client/` contains per-service subdirectories; `logic/` and `server/` are also grouped by service name.\n- Both services share a single entry point (`multisvc.go`) and config.\n- Without `--multiple`, goctl only allows one `service` block per proto file.\n- All services share the same `config.go` and `servicecontext.go`.\n","tools/goctl/rpc/example/06-wellknown-types/README.md":"# Example 06: Well-Known Types\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using a Google protobuf well-known type (`Timestamp`) as a message field.\n\n## Proto Definition\n\n`events.proto` uses `google.protobuf.Timestamp` as a message field type.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc events.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── eventsvc.yaml\n├── eventservice\n│   └── eventservice.go\n├── eventsvc.go\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createeventlogic.go\n│   │   └── listeventslogic.go\n│   ├── server\n│   │   └── eventserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── events.pb.go\n    └── events_grpc.pb.go\n```\n\n## Key Points\n\n- Uses the Google well-known type `google.protobuf.Timestamp` as a message field.\n- goctl automatically maps well-known types to Go imports; in this example, `Timestamp` maps to `timestamppb`.\n- No extra `--proto_path` needed for well-known types if protoc is properly installed.\n","tools/goctl/rpc/example/07-external-proto-same-pkg/README.md":"# Example 07: External Proto — Same `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where both files share the **same** `go_package`.\n\n## Proto Definition\n\nBoth `service.proto` and `ext.proto` use the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\nSource layout:\n\n```\n07-external-proto-same-pkg/\n├── ext_protos\n│   └── ext.proto        # External proto (go_package = \"example.com/demo/pb\")\n├── service.proto        # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- `service.proto` imports `ext.proto` and uses `ext.ExtReq` / `ext.ExtReply` as RPC types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── querylogic.go\n│   ├── server\n│   │   └── queryserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── ext.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n├── queryservice\n│   └── queryservice.go\n└── svc.go\n```\n\n## Key Points\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- Use `-I ./ext_protos` to add the external directory to the proto search path.\n- When the external proto has the **same** `go_package`, all types merge into one Go package — no cross-package imports are needed.\n","tools/goctl/rpc/example/08-external-proto-diff-pkg/README.md":"# Example 08: External Proto — Different `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where the files have **different** `go_package` values, requiring cross-package imports in the generated Go code.\n\n## Proto Definition\n\nThe proto files use different `go_package` values:\n\n- `service.proto`: `go_package = \"example.com/demo/pb\"`\n- `ext_protos/common/types.proto`: `go_package = \"example.com/demo/pb/common\"`\n\nSource layout:\n\n```\n08-external-proto-diff-pkg/\n├── ext_protos\n│   └── common\n│       └── types.proto    # External proto (go_package = \"example.com/demo/pb/common\")\n├── service.proto          # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `types.proto` has `go_package = \"example.com/demo/pb/common\"` — a **different** Go package.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── dataservice\n│   └── dataservice.go\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── fetchlogic.go\n│   ├── server\n│   │   └── dataserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── common\n│   │   └── types.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n└── svc.go\n```\n\n## Key Points\n\n- When the external proto has a **different** `go_package`, goctl generates cross-package Go imports automatically.\n- goctl resolves the proto package name (e.g., `common`) to the correct Go import path by parsing the imported proto's `go_package` option.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n","tools/goctl/rpc/example/09-google-types-as-rpc/README.md":"# Example 09: Google Well-Known Types as RPC Parameters\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using Google protobuf well-known types **directly** as RPC request or response types (not just as message fields).\n\n## Proto Definition\n\n`service.proto` uses `google.protobuf.Empty` and `google.protobuf.Timestamp` directly as RPC request/response types.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── healthsvc.yaml\n├── go.mod\n├── healthservice\n│   └── healthservice.go\n├── healthsvc.go\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── gettimelogic.go\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── healthserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── service.pb.go\n    └── service_grpc.pb.go\n```\n\n## Key Points\n\n- Uses Google well-known types (`google.protobuf.Empty`, `google.protobuf.Timestamp`) directly as RPC request/response types (not just message fields).\n- goctl correctly maps these to Go types (`emptypb.Empty`, `timestamppb.Timestamp`) and generates proper imports.\n- This differs from Example 06 where well-known types are used as message fields.\n","tools/goctl/rpc/example/10-streaming/README.md":"# Example 10: Streaming RPC\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates all three gRPC streaming patterns: server streaming, client streaming, and bidirectional streaming.\n\n## Proto Definition\n\n`stream.proto` defines three RPC methods demonstrating each streaming pattern.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc stream.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── streamsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── bidistreamlogic.go\n│   │   ├── clientstreamlogic.go\n│   │   └── serverstreamlogic.go\n│   ├── server\n│   │   └── streamserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── stream.pb.go\n│   └── stream_grpc.pb.go\n├── streamservice\n│   └── streamservice.go\n└── streamsvc.go\n```\n\n## Key Points\n\n- Supports three streaming patterns: server streaming (`stream` on response), client streaming (`stream` on request), and bidirectional streaming (`stream` on both).\n- goctl generates separate logic files for each streaming RPC method.\n- goctl generates streaming client wrapper methods; use the returned gRPC stream to send and receive messages.\n","tools/goctl/rpc/example/README.md":"# RPC Examples\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis directory contains complete examples for all `goctl rpc` code generation scenarios.\n\nEach example includes:\n- `.proto` source files\n- `README.md` (English), `README-cn.md` (中文), and `README-ko.md` (한국어) documentation\n\n## Examples\n\n| # | Directory | Scenario | Key Flags |\n|---|-----------|----------|-----------|\n| 01 | [01-basic](01-basic/) | Basic single service, no imports | — |\n| 02 | [02-import-sibling](02-import-sibling/) | Import sibling proto file | `--proto_path=.` |\n| 03 | [03-import-subdir](03-import-subdir/) | Import proto from subdirectory | `--proto_path=.` |\n| 04 | [04-transitive-import](04-transitive-import/) | Transitive imports (A → B → C) | `--proto_path=.` |\n| 05 | [05-multiple-services](05-multiple-services/) | Multiple services in one proto | `--multiple` |\n| 06 | [06-wellknown-types](06-wellknown-types/) | Google well-known types in messages | — |\n| 07 | [07-external-proto-same-pkg](07-external-proto-same-pkg/) | External proto, same `go_package` | `-I ./ext_protos` |\n| 08 | [08-external-proto-diff-pkg](08-external-proto-diff-pkg/) | External proto, different `go_package` | `-I ./ext_protos` |\n| 09 | [09-google-types-as-rpc](09-google-types-as-rpc/) | Google well-known types as RPC parameters | — |\n| 10 | [10-streaming](10-streaming/) | Server/client/bidirectional streaming | — |\n\n## Prerequisites\n\n- [Go](https://go.dev/) 1.22+\n- [protoc](https://github.com/protocolbuffers/protobuf/releases) (Protocol Buffers compiler)\n- [protoc-gen-go](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go) and [protoc-gen-go-grpc](https://pkg.go.dev/google.golang.org/grpc/cmd/protoc-gen-go-grpc)\n- [goctl](https://github.com/zeromicro/go-zero/tree/master/tools/goctl)\n\n## Quick Start\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n\n# Try the basic example\ncd 01-basic\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc greeter.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n"},"items":[{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"# GitHub Copilot Instructions for go-zero\n\nThis document provides guidelines for GitHub Copilot when assisting with development in the go-zero project.\n\n## Project Overview\n\ngo-zero is a web and RPC framework with lots of built-in engineering practices designed to ensure the stability of busy services with resilience design. It has been serving sites with tens of millions of users for years.\n\n### Key Architecture Components\n\n- **REST API framework** (`rest/`) - HTTP service framework with middleware chain support\n- **RPC framework** (`zrpc/`) - gRPC-based RPC framework with etcd service discovery and p2c_ewma load balancing\n- **Gateway** (`gateway/`) - API gateway supporting both HTTP and gRPC upstreams with proto-based routing\n- **MCP Server** (`mcp/`) - Model Context Protocol server for AI agent integration via SSE\n- **Core utilities** (`core/`) - Production-grade components:\n  - Resilience: circuit breakers (`breaker/`), rate limiters (`limit/`), adaptive load shedding (`load/`)\n  - Storage: SQL with cache (`stores/sqlc/`), Redis (`stores/redis/`), MongoDB (`stores/mongo/`)\n  - Concurrency: MapReduce (`mr/`), worker pools (`executors/`), sync primitives (`syncx/`)\n  - Observability: metrics (`metric/`), tracing (`trace/`), structured logging (`logx/`)\n- **Code generation tool** (`tools/goctl/`) - CLI tool for generating Go code from `.api` and `.proto` files\n\n## Coding Standards and Conventions\n\n### Code Style\n\n1. **Follow Go conventions**: Use `gofmt` for formatting, follow effective Go practices\n2. **Package naming**: Use lowercase, single-word package names when possible\n3. **Error handling**: Always handle errors explicitly, use `errorx.BatchError` for multiple errors\n4. **Context propagation**: Always pass `context.Context` as the first parameter for functions that may block\n5. **Configuration structures**: Use struct tags with JSON annotations, defaults, and validation\n\n**Pattern**: All service configs embed `service.ServiceConf` for common fields (Name, Log, Mode, Telemetry)\n```go\ntype Config struct {\n    service.ServiceConf              // Always embed for services\n    Host     string `json:\",default=0.0.0.0\"`\n    Port     int    // Required field (no default)\n    Timeout  int64  `json:\",default=3000\"`  // Timeouts in milliseconds\n    Optional string `json:\",optional\"`      // Optional field\n    Mode     string `json:\",default=pro,options=dev|test|rt|pre|pro\"`  // Validated options\n}\n```\n\n**Service modes**: `dev`/`test`/`rt` disable load shedding and stats; `pre`/`pro` enable all resilience features\n\n### Interface Design\n\n1. **Small interfaces**: Follow Go's preference for small, focused interfaces\n2. **Context methods**: Provide both context and non-context versions of methods\n3. **Options pattern**: Use functional options for complex configuration\n\nExample:\n```go\nfunc (c *Client) Get(key string, val any) error {\n    return c.GetCtx(context.Background(), key, val)\n}\n\nfunc (c *Client) GetCtx(ctx context.Context, key string, val any) error {\n    // implementation\n}\n```\n\n### Testing Patterns\n\n1. **Test file naming**: Use `*_test.go` suffix\n2. **Test function naming**: Use `TestFunctionName` pattern\n3. **Use testify/assert**: Prefer `assert` package for assertions\n4. **Table-driven tests**: Use table-driven tests for multiple scenarios\n5. **Mock interfaces**: Use `go.uber.org/mock` for mocking\n6. **Test helpers**: Use `redistest`, `mongtest` helpers for database testing\n\nExample test pattern:\n```go\nfunc TestSomething(t *testing.T) {\n    tests := []struct {\n        name     string\n        input    string\n        expected string\n        wantErr  bool\n    }{\n        {\"valid case\", \"input\", \"output\", false},\n        {\"error case\", \"bad\", \"\", true},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            result, err := SomeFunction(tt.input)\n            if tt.wantErr {\n                assert.Error(t, err)\n                return\n            }\n            assert.NoError(t, err)\n            assert.Equal(t, tt.expected, result)\n        })\n    }\n}\n```\n\n## Framework-Specific Guidelines\n\n### REST API Development\n\n1. **API Definition**: Use `.api` files to define REST APIs with goctl codegen\n2. **Handler pattern**: Separate business logic into logic packages (handlers call logic layer)\n3. **Middleware chain**: Middlewares wrap via `chain.Chain` interface - use `Append()` or `Prepend()` to control order\n   - Built-in middlewares (all in `rest/handler/`): tracing, logging, metrics, recovery, breaker, shedding, timeout, maxconns, maxbytes, gunzip\n   - Custom middleware: `func(http.Handler) http.Handler` - call `next.ServeHTTP(w, r)` to continue chain\n4. **Response handling**: Use `httpx.WriteJson(w, code, v)` for JSON responses\n5. **Error handling**: Use `httpx.Error(w, err)` or `httpx.ErrorCtx(ctx, w, err)` for HTTP error responses\n6. **Route registration**: Routes defined with `Method`, `Path`, and `Handler` - wildcards use `:param` syntax\n\n### RPC Development\n\n1. **Protocol Buffers**: Use protobuf for service definitions, generate code with goctl\n2. **Service discovery**: Use etcd for dynamic service registration/discovery, or direct endpoints for static routing\n3. **Load balancing**: Default is `p2c_ewma` (power of 2 choices with EWMA), configurable via `BalancerName`\n4. **Client configuration**: Support `Etcd`, `Endpoints`, or `Target` - use `BuildTarget()` to construct connection string\n5. **Interceptors**: Implement gRPC interceptors for cross-cutting concerns (auth, logging, metrics)\n6. **Health checks**: gRPC health checks enabled by default (`Health: true`)\n\n### Database Operations\n\n1. **SQL operations**: Use `sqlx.SqlConn` interface - methods always end with `Ctx` for context support\n2. **Caching pattern**: `stores/sqlc` provides `CachedConn` for automatic cache-aside pattern\n   - `QueryRowCtx`: Query with cache key, auto-populate on cache miss\n   - `ExecCtx`: Execute and delete cache keys\n3. **Transactions**: Use `sqlx.SqlConn.TransactCtx()` to get transaction session\n4. **Connection pooling**: Managed automatically (64 max idle/open, 1min lifetime)\n5. **Test helpers**: Use `redistest.CreateRedis(t)` for Redis, SQL mocks for DB testing\n\nExample cache pattern:\n```go\nerr := c.QueryRowCtx(ctx, &dest, key, func(ctx context.Context, conn sqlx.SqlConn) error {\n    return conn.QueryRowCtx(ctx, &dest, query, args...)\n})\n```\n\n### Configuration Management\n\n1. **YAML configuration**: Use YAML for configuration files\n2. **Environment variables**: Support environment variable overrides\n3. **Validation**: Include proper validation for configuration parameters\n4. **Sensible defaults**: Provide reasonable default values\n\n## Error Handling Best Practices\n\n1. **Wrap errors**: Use `fmt.Errorf` with `%w` verb to wrap errors\n2. **Custom errors**: Define custom error types when needed\n3. **Error logging**: Log errors appropriately with context\n4. **Graceful degradation**: Implement fallback mechanisms\n\n## Performance Considerations\n\n1. **Resource pools**: Use connection pools and worker pools\n2. **Circuit breakers**: Implement circuit breaker patterns for external calls\n3. **Rate limiting**: Apply rate limiting to protect services\n4. **Load shedding**: Implement adaptive load shedding\n5. **Metrics**: Add appropriate metrics and monitoring\n\n## Security Guidelines\n\n1. **Input validation**: Validate all input parameters\n2. **SQL injection prevention**: Use parameterized queries\n3. **Authentication**: Implement proper JWT token handling\n4. **HTTPS**: Support TLS/HTTPS configurations\n5. **CORS**: Configure CORS appropriately for web APIs\n\n## Documentation Standards\n\n1. **Package documentation**: Include package-level documentation\n2. **Function documentation**: Document exported functions with examples\n3. **API documentation**: Maintain API documentation in sync\n4. **README updates**: Update README for significant changes\n\n## GitHub Issue Management\n\n### Understanding and Categorizing Issues\n\nWhen analyzing GitHub issues, consider these common categories:\n\n1. **Bug Reports**: Stack traces, version info, reproduction steps\n2. **Feature Requests**: Use case, proposed solution, alternatives\n3. **Questions**: Usage, configuration, or architecture\n4. **Documentation Issues**: Missing, unclear, or incorrect docs\n5. **Performance Issues**: Benchmarks, profiling data, resource usage\n\n### Issue Analysis Checklist\n\n- Identify affected component (REST, RPC, Gateway, MCP, Core utilities, goctl)\n- Check versions (go-zero, Go)\n- Look for reproduction steps or code examples\n- Review code snippets, logs, or stack traces\n- Check if related to resilience features (breaker, load shedding, rate limiting)\n- Determine production impact\n\n### Responding to Issues\n\nBe helpful and professional. Ask clarifying questions when needed. Reference relevant documentation and code files. Provide code examples following project conventions. Suggest workarounds when applicable.\n\n### Chinese to English Translation\n\ngo-zero has an international user base. When encountering issues or comments written in Chinese, translate them to English to ensure all contributors can participate in discussions.\n\n#### Translation Guidelines\n\n1. **Update issue titles**: Edit the issue title to include English translation only\n2. **Translate comments in place**: Add a comment with the English translation, followed by the original Chinese text\n3. **Keep original Chinese**: After translating, include the original Chinese text in a blockquote for verification\n4. **Encourage English communication**: Politely suggest users write in English for better collaboration\n5. **Maintain technical accuracy**: Preserve technical terms, component names, and code exactly\n6. **Translate naturally**: Avoid literal word-by-word translation; use idiomatic English\n7. **Preserve formatting**: Keep markdown formatting, code blocks, and links intact\n8. **Keep URLs unchanged**: Don't translate URLs or file paths\n\n#### Common Technical Terms (Chinese → English)\n\n- 框架 → **Framework** | 中间件 → **Middleware** | 负载均衡 → **Load Balancing**\n- 熔断器 → **Circuit Breaker** | 限流 → **Rate Limiting** | 降载/过载保护 → **Load Shedding**\n- 服务发现 → **Service Discovery** | 配置 → **Configuration** | 弹性/容错 → **Resilience** | 微服务 → **Microservices**\n\n#### Translation Example\n\n**Original Chinese Title:** `goctl 执行环境问题`\n**Updated Title:** `goctl Execution Environment Issue`\n\n**Original Chinese Comment:** `我在项目中遇到熔断器配置问题`\n**Translation in Comment:**\n```markdown\nI encountered a circuit breaker configuration issue in my project.\n\n> Original (原文): 我在项目中遇到熔断器配置问题\n```\n\n### Common Issue Patterns and Solutions\n\n#### Configuration Issues\n- Check `service.ServiceConf` embedding and struct tags\n- Verify YAML syntax, defaults, and validation rules\n- Reference: [rest/config.go](rest/config.go), [zrpc/config.go](zrpc/config.go)\n\n#### Code Generation (goctl) Issues\n- Verify `.api` or `.proto` file syntax and goctl version\n- Reference: `tools/goctl/` directory\n\n#### RPC Connection Issues\n- Check etcd configuration, service discovery, and endpoints\n- Verify load balancing settings (p2c_ewma)\n\n#### Database/Cache Issues\n- Verify `sqlx.SqlConn` usage with context\n- Check cache key generation, invalidation, and connection pools\n- Use test helpers (`redistest`, `mongtest`)\n\n#### Performance Issues\n- Check if load shedding is enabled (mode: `pre`/`pro`)\n- Review circuit breaker thresholds, rate limiting, and context timeouts\n\n### Referencing Codebase\n\nWhen explaining issues, reference specific files and patterns:\n- REST API: `rest/`, `rest/handler/`, `rest/httpx/`\n- RPC: `zrpc/`, `zrpc/internal/`\n- Core utilities: `core/breaker/`, `core/limit/`, `core/load/`, etc.\n- Gateway: `gateway/`\n- MCP: `mcp/`\n- Code generation: `tools/goctl/`\n- Examples: `adhoc/` directory contains various examples\n\n### Encouraging Best Practices\n\nWhen responding to issues, gently guide users toward:\n- Proper error handling with context\n- Using resilience features (breakers, rate limiters)\n- Following testing patterns with table-driven tests\n- Implementing proper resource cleanup\n- Reading existing documentation in `docs/` and `readme.md`\n\n## Common Patterns to Follow\n\n### Service Configuration\n```go\ntype ServiceConf struct {\n    Name string\n    Log  logx.LogConf\n    Mode string `json:\",default=pro,options=[dev,test,pre,pro]\"`\n    // ... other common fields\n}\n```\n\n### Middleware Implementation\n```go\nfunc SomeMiddleware() rest.Middleware {\n    return func(next http.HandlerFunc) http.HandlerFunc {\n        return func(w http.ResponseWriter, r *http.Request) {\n            // Pre-processing\n            next.ServeHTTP(w, r)\n            // Post-processing\n        }\n    }\n}\n```\n\n### Resource Management\nAlways implement proper resource cleanup using defer and context cancellation.\n\n## Build and Test Commands\n\n- Build: `go build ./...`\n- Test: `go test ./...`\n- Test with race detection: `go test -race ./...`\n- Format: `gofmt -w .`\n- Code generation:\n  - REST API: `goctl api go -api *.api -dir .`\n  - RPC: `goctl rpc protoc *.proto --go_out=. --go-grpc_out=. --zrpc_out=.`\n  - Model from SQL: `goctl model mysql datasource -url=\"user:pass@tcp(host:port)/db\" -table=\"*\" -dir=\"./model\"`\n\n## Critical Architecture Patterns\n\n### Resilience Design Philosophy\ngo-zero implements defense-in-depth with multiple protection layers:\n1. **Circuit Breaker** (`core/breaker`): Google SRE breaker - tracks success/failure, opens on error threshold\n2. **Adaptive Load Shedding** (`core/load`): CPU-based auto-rejection when system overloaded (disabled in dev/test/rt modes)\n3. **Rate Limiting** (`core/limit`): Token bucket (Redis-based) and period limiters\n4. **Timeout Control**: Cascading timeouts via context - set at multiple levels (client, server, handler)\n\n### Middleware Chain Architecture\n`rest/chain` provides middleware composition:\n```go\n// Middleware signature\ntype Middleware func(http.Handler) http.Handler\n\n// Chain operations\nchain := chain.New(m1, m2)\nchain.Append(m3)    // Adds to end: m1 -> m2 -> m3\nchain.Prepend(m0)   // Adds to start: m0 -> m1 -> m2 -> m3\nhandler := chain.Then(finalHandler)\n```\n\n### Concurrency Patterns\n- **MapReduce** (`core/mr`): Parallel processing with worker pools - use for batch operations\n- **Executors** (`core/executors`): Bulk/period executors for batching operations\n- **SingleFlight** (`core/syncx`): Deduplicates concurrent identical requests\n\nRemember to run tests and ensure all checks pass before submitting changes. The project emphasizes high quality, performance, and reliability, so these should be primary considerations in all development work.","isInternal":false,"tokens":3429,"sizeBytes":14745},{"name":"example_cn.swagger.json","path":"tools/goctl/api/swagger/example/example_cn.swagger.json","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/api/swagger/example/example_cn.swagger.json","title":"Example Skill","category":"anthropic-skill","format":"json","content":"{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"演示 api 生成 swagger 文件的 api 完整写法\",\n    \"title\": \"演示 API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form 接口\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form 表单 api 演示\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-未登录\\u003cbr\\u003e1002-无权限操作\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"复杂的 json 请求体接口\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"post json api 演示\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"mapMapObject\",\n                \"mapMapPointerObject\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"objec\n\n<!-- [TRUNCATED AT 50KB] -->","isInternal":false,"tokens":6982,"sizeBytes":50104},{"name":"example.swagger.json","path":"tools/goctl/api/swagger/example/example.swagger.json","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/api/swagger/example/example.swagger.json","title":"Example Skill","category":"anthropic-skill","format":"json","content":"{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"Generating Swagger files using the API demo.\",\n    \"title\": \"Demo API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form demo\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-User not login\\u003cbr\\u003e1002-User permission denied\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"complex json request body API\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"postJson\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"number\": {\n                  \"type\": \"number\",\n                  \"example\": 1.1\n                },\n                \"object\": {\n                  \"type\": \"object\",\n                  \"required\": [\n                    \"integer\",\n                    \"number\",\n                    \"boolean\",\n                    \"string\",\n                    \"object\",\n                    \"pointerObject\"\n                  ],\n                  \"properties\": {\n                    \"boolean\": {\n                      \"type\": \"boolean\",\n                      \"enum\": [\n                        \"true\",\n                        \"false\"\n                      ],\n                      \"example\": true\n                    },\n                    \"integer\": {\n                      \"type\": \"integer\",\n                      \"example\": 1\n                    },\n                    \"number\": {\n                      \"type\": \"number\",\n                      \"example\": 1.1\n                    },\n                    \"object\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      },\n                      \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                    },\n                    \"pointerObject\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        }\n\n<!-- [TRUNCATED AT 50KB] -->","isInternal":false,"tokens":7010,"sizeBytes":50030},{"name":"readme.md","path":"tools/goctl/api/parser/readme.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/api/parser/readme.md","title":"parser Documentation","category":"plugin-manifest","format":"markdown","content":"# Api语法描述\n\n## api示例\n\n``` golang\n/**\n * api语法示例及语法说明\n */\n\n// api语法版本\nsyntax = \"v1\"\n\n// import literal\nimport \"foo.api\"\n\n// import group\nimport (\n    \"bar.api\"\n    \"foo/bar.api\"\n)\ninfo(\n    author: \"songmeizi\"\n    date:   \"2020-01-08\"\n    desc:   \"api语法示例及语法说明\"\n)\n\n// type literal\n\ntype Foo{\n    Foo int `json:\"foo\"`\n}\n\n// type group\n\ntype(\n    Bar{\n        Bar int `json:\"bar\"`\n    }\n)\n\n// service block\n@server(\n    jwt:   Auth\n    group: foo\n)\nservice foo-api{\n    @doc \"foo\"\n    @handler foo\n    post /foo (Foo) returns (Bar)\n}\n```\n\n## api语法结构\n\n* syntax语法声明\n* import语法块\n* info语法块\n* type语法块\n* service语法块\n* 隐藏通道\n\n> ### 温馨提示️\n> 在以上语法结构中，各个语法块从语法上来说，按照语法块为单位，可以在.api文件中任意位置声明，\n> 但是为了提高阅读效率，我们建议按照以上顺序进行声明，因为在将来可能会通过严格模式来控制语法块的顺序。\n\n### syntax语法声明\n\nsyntax是新加入的语法结构，该语法的引入可以解决：\n\n* 快速针对api版本定位存在问题的语法结构\n* 针对版本做语法解析\n* 防止api语法大版本升级导致前后不能向前兼容\n\n> ### 警告 ⚠️\n> 被import的api必须要和main api的syntax版本一致。\n\n**语法定义**\n\n``` antlrv4\n'syntax'={checkVersion(p)}STRING\n```\n\n**语法说明**\n> syntax：固定token，标志一个syntax语法结构的开始\n>\n> checkVersion：自定义go方法，检测`STRING`是否为一个合法的版本号，目前检测逻辑为，STRING必须是满足`(?m)\"v[1-9][0-9]*\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"v1\"\n>\n> 一个api语法文件只能有0或者1个syntax语法声明，如果没有syntax，则默认为v1版本\n>\n\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\nsyntax=\"v1\"\n```\n\neg2：规范写法(推荐)\n\n``` api\nsyntax = \"v2\"\n```\n\n**错误语法示例** ❌\n\neg1：\n\n``` api\nsyntax = \"v0\"\n```\n\neg2：\n\n``` api\nsyntax = v1\n```\n\neg3：\n\n``` api\nsyntax = \"V1\"\n```\n\n## import语法块\n\n随着业务规模增大，api中定义的结构体和服务越来越多，所有的语法描述均为一个api文件，这是多么糟糕的一个问题， 其会大大增加了阅读难度和维护难度，import语法块可以帮助我们解决这个问题，通过拆分api文件，\n不同的api文件按照一定规则声明，可以降低阅读难度和维护难度。\n\n> ### 警告 ⚠️\n> 这里import不像golang那样包含package声明，仅仅是一个文件路径的引入，最终解析后会把所有的声明都汇聚到一个spec.Spec中。\n> 不能import多个相同路径，否则会解析错误。\n\n**语法定义**\n\n``` antlrv4\n'import' {checkImportValue(p)}STRING  \n|'import' '(' ({checkImportValue(p)}STRING)+ ')'\n```\n\n**语法说明**\n> import：固定token，标志一个import语法的开始\n>\n> checkImportValue：自定义go方法，检测`STRING`是否为一个合法的文件路径，目前检测逻辑为，STRING必须是满足`(?m)\"(/?[a-zA-Z0-9_#-])+\\.api\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"foo.api\"\n>\n\n\n**正确语法示例** ✅\n\neg：\n\n``` api\nimport \"foo.api\"\nimport \"foo/bar.api\"\n\nimport(\n    \"bar.api\"\n    \"foo/bar/foo.api\"\n)\n```\n\n**错误语法示例** ❌\n\neg：\n\n``` api\nimport foo.api\nimport \"foo.txt\"\nimport (\n    bar.api\n    bar.api\n)\n```\n\n## info语法块\n\ninfo语法块是一个包含了多个键值对的语法体，其作用相当于一个api服务的描述，解析器会将其映射到spec.Spec中， 以备用于翻译成其他语言(golang、java等)\n时需要携带的meta元素。如果仅仅是对当前api的一个说明，而不考虑其翻译 时传递到其他语言，则使用简单的多行注释或者java风格的文档注释即可，关于注释说明请参考下文的 **隐藏通道**。\n\n> ### 警告 ⚠️\n> 不能使用重复的key，每个api文件只能有0或者1个info语法块\n\n**语法定义**\n\n``` antlrv4\n'info' '(' (ID {checkKeyValue(p)}VALUE)+ ')'\n```\n\n**语法说明**\n> info：固定token，标志一个info语法块的开始\n>\n> checkKeyValue：自定义go方法，检测`VALUE`是否为一个合法值。\n>\n> VALUE：key对应的值，可以为单行的除'\\r','\\n','/'后的任意字符，多行请以\"\"包裹，不过强烈建议所有都以\"\"包裹\n>\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ninfo(\nfoo: foo value\nbar:\"bar value\"\n    desc:\"long long long long\nlong long text\"\n)\n```\n\neg2：规范写法(推荐)\n\n``` api\ninfo(\n    foo: \"foo value\"\n    bar: \"bar value\"\n    desc: \"long long long long long long text\"\n)\n```\n\n**错误语法示例** ❌\n\neg1：没有key-value内容\n\n``` api\ninfo()\n```\n\neg2：不包含冒号\n\n``` api\ninfo(\n    foo value\n)\n```\n\neg3：key-value没有换行\n\n``` api\ninfo(foo:\"value\")\n```\n\neg4：没有key\n\n``` api\ninfo(\n    : \"value\"\n)\n```\n\neg5：非法的key\n\n``` api\ninfo(\n    12: \"value\"\n)\n```\n\neg6：移除旧版本多行语法\n\n``` api\ninfo(\n    foo: >\n    some text\n    <\n)\n```\n\n## type语法块\n\n在api服务中，我们需要用到一个结构体(类)来作为请求体，响应体的载体，因此我们需要声明一些结构体来完成这件事情， type语法块由golang的type演变而来，当然也保留着一些golang type的特性，沿用golang特性有：\n\n* 保留了golang内置数据类型`bool`,`int`,`int8`,`int16`,`int32`,`int64`,`uint`,`uint8`,`uint16`,`uint32`,`uint64`,`uintptr`\n  ,`float32`,`float64`,`complex64`,`complex128`,`string`,`byte`,`rune`,\n* 兼容golang struct风格声明\n* 保留golang关键字\n\n> ### 警告 ⚠️\n> * 不支持alias\n> * 不支持time.Time数据类型\n> * 结构体名称、字段名称、不能为golang关键字\n\n**语法定义**\n> 由于其和golang相似，因此不做详细说明，具体语法定义请在[ApiParser.g4](g4/ApiParser.g4)中查看typeSpec定义。\n\n**语法说明**\n\n> 参考golang写法\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ntype Foo struct{\n    Id int `path:\"id\"` // ①\n    Foo int `json:\"foo\"`\n}\n\ntype Bar struct{\n    // 非导出型字段\n    bar int `form:\"bar\"`\n}\n\ntype(\n    // 非导出型结构体\n    fooBar struct{\n        FooBar int\n    }\n)\n```\n\neg2：规范写法（推荐）\n\n``` api\ntype Foo{\n    Id int `path:\"id\"`\n    Foo int `json:\"foo\"`\n}\n\ntype Bar{\n    Bar int `form:\"bar\"`\n}\n\ntype(\n    FooBar{\n        FooBar int\n    }\n)\n```\n\n**错误语法示例** ❌\n\neg\n\n``` api\ntype Gender int // 不支持\n\n// 非struct token\ntype Foo structure{ \n  CreateTime time.Time // 不支持time.Time\n}\n\n// golang关键字 var\ntype var{} \n\ntype Foo{\n  // golang关键字 interface\n  Foo interface \n}\n\n\ntype Foo{\n  foo int \n  // map key必须要golang内置数据类型\n  m map[Bar]string\n}\n```\n\n**① tag说明**\n> tag定义和golang中json tag语法一样，除了json tag外，go-zero还提供了另外一些tag来实现对字段的描述，\n> 详情见下表。\n\n* tag表\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |json|json序列化tag|golang|request、response|`json:\"fooo\"`|\n  |path|路由path，如`/foo/:id`|go-zero|request|`path:\"id\"`|\n  |form|标志请求体是一个form（POST方法时）或者一个query(GET方法时`/search?name=keyword`)|go-zero|request|`form:\"name\"`|\n\n* tag修饰符\n  > 常见参数校验描述\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |optional|定义当前字段为可选参数|go-zero|request|`json:\"name,optional\"`|\n  |options|定义当前字段的枚举值,多个以竖线②隔开|go-zero|request|`json:\"gender,options=male\"`|\n  |default|定义当前字段默认值|go-zero|request|`json:\"gender,default=male\"`|\n  |range|定义当前字段数值范围|go-zero|request|`json:\"age,range=[0:120]\"`|\n\n  ② 竖线：|\n  > ### 温馨提示\n  > tag修饰符需要在tag value后以引文逗号,隔开\n\n## service语法块\n\nservice语法块用于定义api服务，包含服务名称，服务metadata，中间件声明，路由，handler等。\n\n> ### 警告 ⚠️\n> * main api和被import的api服务名称必须一致，不能出现服务名称歧义。\n> * handler名称不能重复\n> * 路由（请求方法+请求path）名称不能重复\n> * 请求体必须声明为普通（非指针）struct，响应体做了一些向前兼容处理，详请见下文说明\n>\n\n**语法定义**\n\n``` antlrv4\nserviceSpec:    atServer? serviceApi;\natServer:       '@server' lp='(' kvLit+ rp=')';\nserviceApi:     {match(p,\"service\")}serviceToken=ID serviceName lbrace='{' serviceRoute* rbrace='}';\nserviceRoute:   atDoc? (atServer|atHandler) route;\natDoc:          '@doc' lp='('? ((kvLit+)|STRING) rp=')'?;\natHandler:      '@handler' ID;\nroute:          {checkHttpMethod(p)}httpMethod=ID path request=body? returnToken=ID? response=replybody?;\nbody:           lp='(' (ID)? rp=')';\nreplybody:      lp='(' dataType? rp=')';\n// kv\nkvLit:          key=ID {checkKeyValue(p)}value=LINE_VALUE;\n\nserviceName:    (ID '-'?)+;\npath:           (('/' (ID ('-' ID)*))|('/:' (ID ('-' ID)?)))+;\n```\n\n**语法说明**\n\n> serviceSpec：包含了一个可选语法块`atServer`和`serviceApi`语法块，其遵循序列模式（编写service必须要按照顺序，否则会解析出错）\n>\n> atServer： 可选语法块，定义key-value结构的server metadata，'@server'表示这一个server语法块的开始，其可以用于描述serviceApi或者route语法块，其用于描述不同语法块时有一些特殊关键key\n> 需要值得注意，见 **atServer关键key描述说明**。\n>\n> serviceApi：包含了1到多个`serviceRoute`语法块\n>\n> serviceRoute：按照序列模式包含了`atDoc`,handler和`route`\n>\n> atDoc：可选语法块，一个路由的key-value描述，其在解析后会传递到spec.Spec结构体，如果不关心传递到spec.Spec,\n> 推荐用单行注释替代。\n>\n> handler：是对路由的handler层描述，可以通过atServer指定`handler` key来指定handler名称，\n> 也可以直接用atHandler语法块来定义handler名称\n>\n> atHandler：'@handler' 固定token，后接一个遵循正则`[_a-zA-Z][a-zA-Z_-]*`)的值，用于声明一个handler名称\n>\n> route：路由，有`httpMethod`、`path`、可选`request`、可选`response`组成，`httpMethod`是必须是小写。\n>\n> body：api请求体语法定义，必须要由()包裹的可选的ID值\n>\n> replyBody：api响应体语法定义，必须由()包裹的struct、~~array(向前兼容处理，后续可能会废弃，强烈推荐以struct包裹，不要直接用array作为响应体)~~\n>\n> kvLit： 同info key-value\n>\n> serviceName: 可以有多个'-'join的ID值\n>\n> path：api请求路径，必须以'/'或者'/:'开头，切不能以'/'结尾，中间可包含ID或者多个以'-'join的ID字符串\n\n**atServer关键key描述说明**\n\n修饰service时\n\n|key|描述|示例|\n|:---|:---|:---|\n|jwt|声明当前service下所有路由需要jwt鉴权，且会自动生成包含jwt逻辑的代码|`jwt: Auth`|\n|group|声明当前service或者路由文件分组|`group: login`|\n|middleware|声明当前service需要开启中间件|`middleware: AuthMiddleware`|\n\n修饰route时\n\n|key|描述|示例|\n|:---|:---|:---|\n|handler|声明一个handler|-|\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc(\n    summary: foo\n  )\n  @server(\n    handler: foo\n  )\n  // 非导出型body\n  post /foo/:id (foo) returns (bar)\n  \n  @doc \"bar\"\n  @handler bar\n  post /bar returns ([]int)// 不推荐数组作为响应体\n  \n  @handler fooBar\n  post /foo/bar (Foo) returns // 可以省略'returns'\n}\n```\n\neg2：规范写法（推荐）\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc \"foo\"\n  @handler: foo\n  post /foo/:id (Foo) returns (Bar)\n}\n\nservice foo-api{\n  @handler ping\n  get /ping\n  \n  @doc \"foo\"\n  @handler: bar\n  post /bar/:id (Foo)\n}\n\n```\n\n**错误语法示例** ❌\n\n``` api\n// 不支持空的server语法块\n@server(\n)\n// 不支持空的service语法块\nservice foo-api{\n}\n\nservice foo-api{\n  @doc kkkk // 简版doc必须用英文双引号引起来\n  @handler foo\n  post /foo\n  \n  @handler foo // 重复的handler\n  post /bar\n  \n  @handler fooBar\n  post /bar // 重复的路由\n  \n  // @handler和@doc顺序错误\n  @handler someHandler\n  @doc \"some doc\"\n  post /some/path\n  \n  // handler缺失\n  post /some/path/:id\n  \n  @handler reqTest\n  post /foo/req (*Foo) // 不支持除普通结构体外的其他数据类型作为请求体\n  \n  @handler replyTest\n  post /foo/reply returns (*Foo) // 不支持除普通结构体、数组(向前兼容，后续考虑废弃)外的其他数据类型作为响应体\n}\n```\n\n## 隐藏通道\n\n隐藏通道目前主要为空白符号，换行符号以及注释，这里我们只说注释，因为空白符号和换行符号我们目前拿来也无用。\n\n### 单行注释\n\n**语法定义**\n\n``` antlrv4\n'//' ~[\\r\\n]*\n```\n\n**语法说明**\n由语法定义可知道，单行注释必须要以`//`开头，内容为不能包含换行符\n\n**正确语法示例** ✅\n\n``` api\n// doc\n// comment\n```\n\n**错误语法示例** ❌\n\n``` api\n// break\nline comments\n```\n\n### java风格文档注释\n\n**语法定义**\n\n``` antlrv4\n'/*' .*? '*/'\n```\n\n**语法说明**\n\n由语法定义可知道，单行注释必须要以`/*`开头，`*/`结尾的任意字符。\n\n**正确语法示例** ✅\n\n``` api\n/**\n * java-style doc\n */\n```\n\n**错误语法示例** ❌\n\n``` api\n/*\n * java-style doc */\n */\n```\n\n## Doc&Comment\n\n如果想获取某一个元素的doc或者comment开发人员需要怎么定义？\n\n**Doc**\n> 我们规定上一个语法块（非隐藏通道内容）的行数line+1到当前语法块第一个元素前的所有注释(当行，或者多行)均为doc， 且保留了`//`、`/*`、`*/`原始标记。\n\n**Comment**\n> 我们规定当前语法块最后一个元素所在行开始的一个注释块(当行，或者多行)为comment 且保留了`//`、`/*`、`*/`原始标记。\n\n语法块Doc和Comment的支持情况\n\n|语法块|parent语法块|Doc|Comment|\n|:---|:---|:---|:---|\n|syntaxLit|api|✅|✅|\n|kvLit|infoSpec|✅|✅|\n|importLit|importSpec|✅|✅|\n|typeLit|api|✅|❌|\n|typeLit|typeBlock|✅|❌|\n|field|typeLit|✅|✅|\n|key-value|atServer|✅|✅|\n|atHandler|serviceRoute|✅|✅|\n|route|serviceRoute|✅|✅|\n\n以下为对应语法块解析后细带doc和comment的写法\n``` api\n// syntaxLit doc\nsyntax = \"v1\" // syntaxLit comment\n\ninfo(\n  // kvLit doc\n  author: songmeizi // kvLit comment\n)\n\n// typeLit doc\ntype Foo {}\n\ntype(\n  // typeLit doc\n  Bar{}\n  \n  FooBar{\n    // filed doc\n    Name int // filed comment\n  }\n)\n\n@server(\n  /**\n   * kvLit doc\n   * 开启jwt鉴权\n   */\n  jwt: Auth /**kvLit comment*/\n)\nservice foo-api{\n  // atHandler doc\n  @handler foo //atHandler comment\n  \n  /*\n   * route doc\n   * post请求\n   * path为 /foo\n   * 请求体：Foo\n   * 响应体：Foo\n   */\n  post /foo (Foo) returns (Foo) // route comment\n}\n```\n","isInternal":false,"tokens":5156,"sizeBytes":15054},{"name":"readme.md","path":"tools/goctl/config/readme.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/config/readme.md","title":"config Documentation","category":"plugin-manifest","format":"markdown","content":"# 配置项管理\n\n| 名称              | 是否可选 | 说明                                          |\n|-------------------|----------|-----------------------------------------------|\n| namingFormat      | YES      | 文件名称格式化符                      |\n\n# naming-format\n`namingFormat`可以用于对生成代码的文件名称进行格式化，和日期格式化符（yyyy-MM-dd）类似，在代码生成时可以根据这些配置项的格式化符进行格式化。\n\n## 格式化符(gozero)\n格式化符由`go`,`zero`组成，如常见的三种格式化风格你可以这样编写：\n* lower: `gozero`\n* camel: `goZero`\n* snake: `go_zero`\n\n常见格式化符生成示例\n源字符：welcome_to_go_zero\n\n| 格式化符   | 格式化结果            | 说明                      |\n|------------|-----------------------|---------------------------|\n| gozero     | welcometogozero       | 小写                      |\n| goZero     | welcomeToGoZero       | 驼峰                      |\n| go_zero    | welcome_to_go_zero    | snake                     |\n| Go#zero    | Welcome#to#go#zero    | #号分割Title类型          |\n| GOZERO     | WELCOMETOGOZERO       | 大写                      |\n| \\_go#zero_ | \\_welcome#to#go#zero_ | 下划线做前后缀，并且#分割 |\n\n错误格式化符示例\n* go\n* gOZero\n* zero\n* goZEro\n* goZERo\n* goZeRo\n* tal\n\n# 使用方法\n目前可通过在生成api、rpc、model时通过`--style`参数指定format格式，如：\n```shell script\ngoctl api go test.api -dir . -style gozero\n```\n```shell script\n goctl rpc proto -src test.proto -dir . -style go_zero\n```\n```shell script\ngoctl model mysql datasource -url=\"\" -table=\"*\" -dir ./snake -style GoZero\n```\n\n# 默认值\n当不指定-style时默认值为`gozero`\n","isInternal":false,"tokens":488,"sizeBytes":1770},{"name":"readme.md","path":"tools/goctl/model/mongo/readme.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/model/mongo/readme.md","title":"mongo Documentation","category":"plugin-manifest","format":"markdown","content":"# mongo生成model\n\n## 背景\n\n在业务务开发中，model(dao)数据访问层是一个服务必不可缺的一层，因此数据库访问的CURD也是必须要对外提供的访问方法， 而CURD在go-zero中就仅存在两种情况\n\n* 带缓存model\n* 不带缓存model\n\n从代码结构上来看，C-U-R-D四个方法就是固定的结构，因此我们可以将其交给goctl工具去完成，帮助我们提升开发效率。\n\n## 方案设计\n\nmongo的生成不同于mysql，mysql可以从scheme_information库中读取到一张表的信息（字段名称，数据类型，索引等），\n而mongo是文档型数据库，我们暂时无法从db中读取某一条记录来实现字段信息获取，就算有也不一定是完整信息（某些字段可能是omitempty修饰，可有可无）， 这里采用type自己编写+代码生成方式实现\n\n## 使用示例\n为 User 生成 mongo model\n```bash\n$ goctl model mongo -t User -c --dir .\n```\n\n### 生成示例代码\n\n#### usermodel.go\n```go\npackage model\n\nimport (\n\t\"github.com/zeromicro/go-zero/core/stores/cache\"\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n)\n\nvar _ UserModel = (*customUserModel)(nil)\n\ntype (\n\t// UserModel is an interface to be customized, add more methods here,\n\t// and implement the added methods in customUserModel.\n\tUserModel interface {\n\t\tuserModel\n\t}\n\n\tcustomUserModel struct {\n\t\t*defaultUserModel\n\t}\n)\n\n// NewUserModel returns a model for the mongo.\nfunc NewUserModel(url, db, collection string, c cache.CacheConf) UserModel {\n\tconn := monc.MustNewModel(url, db, collection, c)\n\treturn &customUserModel{\n\t\tdefaultUserModel: newDefaultUserModel(conn),\n\t}\n}\n\n```\n\n#### usermodelgen.go\n```go\n// Code generated by goctl. DO NOT EDIT.\npackage model\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n\t\"go.mongodb.org/mongo-driver/bson\"\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n\t\"go.mongodb.org/mongo-driver/mongo\"\n)\n\nvar prefixUserCacheKey = \"cache:user:\"\n\ntype userModel interface {\n\tInsert(ctx context.Context, data *User) error\n\tFindOne(ctx context.Context, id string) (*User, error)\n\tUpdate(ctx context.Context, data *User) (*mongo.UpdateResult, error)\n\tDelete(ctx context.Context, id string) (int64, error)\n}\n\ntype defaultUserModel struct {\n\tconn *monc.Model\n}\n\nfunc newDefaultUserModel(conn *monc.Model) *defaultUserModel {\n\treturn &defaultUserModel{conn: conn}\n}\n\nfunc (m *defaultUserModel) Insert(ctx context.Context, data *User) error {\n\tif !data.ID.IsZero() {\n\t\tdata.ID = primitive.NewObjectID()\n\t\tdata.CreateAt = time.Now()\n\t\tdata.UpdateAt = time.Now()\n\t}\n\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\t_, err := m.conn.InsertOne(ctx, key, data)\n\treturn err\n}\n\nfunc (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn nil, ErrInvalidObjectId\n\t}\n\n\tvar data User\n\tkey := prefixUserCacheKey + id\n\terr = m.conn.FindOne(ctx, key, &data, bson.M{\"_id\": oid})\n\tswitch err {\n\tcase nil:\n\t\treturn &data, nil\n\tcase monc.ErrNotFound:\n\t\treturn nil, ErrNotFound\n\tdefault:\n\t\treturn nil, err\n\t}\n}\n\nfunc (m *defaultUserModel) Update(ctx context.Context, data *User) (*mongo.UpdateResult, error) {\n\tdata.UpdateAt = time.Now()\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\tres, err := m.conn.ReplaceOne(ctx, key, bson.M{\"_id\": data.ID}, bson.M{\"$set\": data})\n\treturn res, err\n}\n\nfunc (m *defaultUserModel) Delete(ctx context.Context, id string) (int64, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn 0, ErrInvalidObjectId\n\t}\n\tkey := prefixUserCacheKey + id\n\tres, err := m.conn.DeleteOne(ctx, key, bson.M{\"_id\": oid})\n\treturn res, err\n}\n\n```\n\n#### usertypes.go\n```go\npackage model\n\nimport (\n\t\"time\"\n\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n)\n\ntype User struct {\n\tID primitive.ObjectID `bson:\"_id,omitempty\" json:\"id,omitempty\"`\n\t// TODO: Fill your own fields\n\tUpdateAt time.Time `bson:\"updateAt,omitempty\" json:\"updateAt,omitempty\"`\n\tCreateAt time.Time `bson:\"createAt,omitempty\" json:\"createAt,omitempty\"`\n}\n\n```\n\n#### error.go\n```go\npackage model\n\nimport (\n\t\"errors\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/mon\"\n)\n\nvar (\n\tErrNotFound        = mon.ErrNotFound\n\tErrInvalidObjectId = errors.New(\"invalid objectId\")\n)\n```\n\n### 文件目录预览\n\n```text\n.\n├── error.go\n├── usermodel.go\n├── usermodelgen.go\n└── usertypes.go\n```\n\n## 命令预览\n\n```text\nGenerate mongo model\n\nUsage:\n  goctl model mongo [flags]\n\nFlags:\n      --branch string   The branch of the remote repo, it does work with --remote\n  -c, --cache           Generate code with cache [optional]\n  -d, --dir string      The target dir\n  -h, --help            help for mongo\n      --home string     The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n      --remote string   The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n                                The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure\n      --style string    The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n  -t, --type strings    Specified model type name\n\n```\n\n> 温馨提示\n> \n> `--type` 支持slice传值，示例 `goctl model mongo -t=User -t=Class`\n\n","isInternal":false,"tokens":1513,"sizeBytes":5446},{"name":"README.MD","path":"tools/goctl/model/sql/README.MD","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/model/sql/README.MD","title":"sql Documentation","category":"plugin-manifest","format":"markdown","content":"# Goctl Model\n\ngoctl model 为go-zero下的工具模块中的组件之一，目前支持识别mysql ddl进行model层代码生成，通过命令行或者idea插件（即将支持）可以有选择地生成带redis cache或者不带redis cache的代码逻辑。\n\n## 快速开始\n\n* 通过ddl生成\n\n    ```shell script\n    goctl model mysql ddl -src=\"./*.sql\" -dir=\"./sql/model\" -c\n    ```\n\n    执行上述命令后即可快速生成CURD代码。\n\n    ```Plain Text\n    model\n    │   ├── error.go\n    │   └── usermodel.go\n    ```\n\n* 通过datasource生成\n\n    ```shell script\n    goctl model mysql datasource -url=\"user:password@tcp(127.0.0.1:3306)/database\" -table=\"*\"  -dir=\"./model\"\n    ```\n\n* 生成代码示例\n  \n\t```go\n\n\tpackage model\n    \n    import (\n    \t\"database/sql\"\n    \t\"fmt\"\n    \t\"strings\"\n    \t\"time\"\n        \n        \"github.com/zeromicro/go-zero/core/stores/builder\"\n    \t\"github.com/zeromicro/go-zero/core/stores/cache\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlc\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlx\"\n    \t\"github.com/zeromicro/go-zero/core/stringx\"\n    )\n    \n    var (\n    \tuserFieldNames          = builder.FieldNames(&User{})\n    \tuserRows                = strings.Join(userFieldNames, \",\")\n    \tuserRowsExpectAutoSet   = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \",\")\n    \tuserRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \"=?,\") + \"=?\"\n    \n    \tcacheUserPrefix       = \"cache:User:user:\"\n    \tcacheUserNamePrefix   = \"cache:User:name:\"\n    \tcacheUserMobilePrefix = \"cache:User:mobile:\"\n    \tcacheUserIdPrefix     = \"cache:User:id:\"\n    )\n    \n    type (\n    \tUserModel interface {\n    \t\tInsert(data User) (sql.Result, error)\n    \t\tFindOne(id int64) (*User, error)\n    \t\tFindOneByUser(user string) (*User, error)\n    \t\tFindOneByName(name string) (*User, error)\n    \t\tFindOneByMobile(mobile string) (*User, error)\n    \t\tUpdate(data User) error\n    \t\tDelete(id int64) error\n    \t}\n    \n    \tdefaultUserModel struct {\n    \t\tsqlc.CachedConn\n    \t\ttable string\n    \t}\n    \n    \tUser struct {\n    \t\tId         int64     `db:\"id\"`\n    \t\tUser       string    `db:\"user\"`     // 用户\n    \t\tName       string    `db:\"name\"`     // 用户名称\n    \t\tPassword   string    `db:\"password\"` // 用户密码\n    \t\tMobile     string    `db:\"mobile\"`   // 手机号\n    \t\tGender     string    `db:\"gender\"`   // 男｜女｜未公开\n    \t\tNickname   sql.NullString    `db:\"nickname\"` // 用户昵称\n    \t\tCreateTime sql.NullTime `db:\"create_time\"`\n    \t\tUpdateTime time.Time `db:\"update_time\"`\n    \t}\n    )\n    \n    func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {\n    \treturn &defaultUserModel{\n    \t\tCachedConn: sqlc.NewConn(conn, c),\n    \t\ttable:      \"user\",\n    \t}\n    }\n    \n    func (m *defaultUserModel) Insert(data User) (sql.Result, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \tret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"insert into %s (%s) values (?, ?, ?, ?, ?, ?)\", m.table, userRowsExpectAutoSet)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname)\n    \t}, userMobileKey, userKey, userNameKey)\n    \treturn ret, err\n    }\n    \n    func (m *defaultUserModel) FindOne(id int64) (*User, error) {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tvar resp User\n    \terr := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v any) error {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \t\treturn conn.QueryRow(v, query, id)\n    \t})\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByUser(user string) (*User, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, user)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where user = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, user); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByName(name string) (*User, error) {\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, name)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userNameKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where name = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, name); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByMobile(mobile string) (*User, error) {\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, mobile)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userMobileKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where mobile = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, mobile); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) Update(data User) error {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, data.Id)\n    \t_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"update %s set %s where id = ?\", m.table, userRowsWithPlaceHolder)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id)\n    \t}, userIdKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) Delete(id int64) error {\n    \tdata, err := m.FindOne(id)\n    \tif err != nil {\n    \t\treturn err\n    \t}\n    \n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \t_, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"delete from %s where id = ?\", m.table)\n    \t\treturn conn.Exec(query, id)\n    \t}, userIdKey, userKey, userNameKey, userMobileKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) formatPrimary(primary any) string {\n    \treturn fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, primary)\n    }\n    \n    func (m *defaultUserModel) queryPrimary(conn sqlx.SqlConn, v, primary any) error {\n    \tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \treturn conn.QueryRow(v, query, primary)\n    }\n\n\t```\n\n## 用法\n\n```Plain Text\ngoctl model mysql -h\n```\n\n```Plain Text\nNAME:\n   goctl model mysql - generate mysql model\"\n\nUSAGE:\n   goctl model mysql command [command options] [arguments...]\n\nCOMMANDS:\n   ddl         generate mysql model from ddl\"\n   datasource  generate model from datasource\"\n\nOPTIONS:\n   --help, -h  show help\n```\n\n## 生成规则\n\n* 默认规则\n  \n  我们默认用户在建表时会创建createTime、updateTime字段(忽略大小写、下划线命名风格)且默认值均为`CURRENT_TIMESTAMP`，而updateTime支持`ON UPDATE CURRENT_TIMESTAMP`，对于这两个字段生成`insert`、`update`时会被移除，不在赋值范畴内，当然，如果你不需要这两个字段那也无大碍。\n* 带缓存模式\n  * ddl\n\n\t```shell script\n\tgoctl model mysql -src={patterns} -dir={dir} -cache\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql ddl - generate mysql model from ddl\n    \n    USAGE:\n       goctl model mysql ddl [command options] [arguments...]\n    \n    OPTIONS:\n       --src value, -s value  the path or path globbing patterns of the ddl\n       --dir value, -d value  the target dir\n       --style value          the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --cache, -c            generate code with cache [optional]\n       --idea                 for idea plugin [optional]\n       --database, -db        the name of database [optional]\n\t```\n\n  * datasource\n\n\t```shell script\n\tgoctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir} -cache=true\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql datasource - generate model from datasource\n    \n    USAGE:\n       goctl model mysql datasource [command options] [arguments...]\n    \n    OPTIONS:\n       --url value              the data source of database,like \"root:password@tcp(127.0.0.1:3306)/database\n       --table value, -t value  the table or table globbing patterns in the database\n       --cache, -c              generate code with cache [optional]\n       --dir value, -d value    the target dir\n       --style value            the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --idea                   for idea plugin [optional]\n\n\n\t```\n\n\t示例用法请参考[用法](./example/makefile)\n  \n\t> NOTE: goctl model mysql ddl/datasource 均新增了一个`--style`参数，用于标记文件命名风格。\n\n  目前仅支持redis缓存，如果选择带缓存模式，即生成的`FindOne(ByXxx)`&`Delete`代码会生成带缓存逻辑的代码，目前仅支持单索引字段（除全文索引外），对于联合索引我们默认认为不需要带缓存，且不属于通用型代码，因此没有放在代码生成行列，如example中user表中的`id`、`name`、`mobile`字段均属于单字段索引。\n\n* 不带缓存模式\n\n  * ddl\n  \n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n\n  or\n  * ddl\n\n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n  \n生成代码仅基本的CURD结构。\n\n## 缓存\n\n  对于缓存这一块我选择用一问一答的形式进行罗列。我想这样能够更清晰的描述model中缓存的功能。\n\n* 缓存会缓存哪些信息？\n\n  对于主键字段缓存，会缓存整个结构体信息，而对于单索引字段（除全文索引）则缓存主键字段值。\n\n* 数据有更新（`update`）操作会清空缓存吗？\n  \n  会，但仅清空主键缓存的信息，why？这里就不做详细赘述了。\n\n* 为什么不按照单索引字段生成`updateByXxx`和`deleteByXxx`的代码？\n  \n  理论上是没任何问题，但是我们认为，对于model层的数据操作均是以整个结构体为单位，包括查询，我不建议只查询某部分字段（不反对），否则我们的缓存就没有意义了。\n\n* 为什么不支持`findPageLimit`、`findAll`这种模型代码生成？\n  \n  目前，我认为除了基本的CURD外，其他的代码均属于<i>业务型</i>代码，这个我觉得开发人员根据业务需要进行编写更好。\n\n# 类型转换规则\n\n| mysql dataType | golang dataType | golang Null dataType |\n|----------------|-----------------|----------------------------------------|\n| bool           | int64           | sql.NullInt64                          |\n| boolean        | int64           | sql.NullInt64                          |\n| tinyint        | int64           | sql.NullInt64                          |\n| smallint       | int64           | sql.NullInt64                          |\n| mediumint      | int64           | sql.NullInt64                          |\n| int            | int64           | sql.NullInt64                          |\n| integer        | int64           | sql.NullInt64                          |\n| bigint         | int64           | sql.NullInt64                          |\n| float          | float64         | sql.NullFloat64                        |\n| double         | float64         | sql.NullFloat64                        |\n| decimal        | float64         | sql.NullFloat64                        |\n| date           | time.Time       | sql.NullTime                           |\n| datetime       | time.Time       | sql.NullTime                           |\n| timestamp      | time.Time       | sql.NullTime                           |\n| time           | string          | sql.NullString                         |\n| year           | time.Time       | sql.NullInt64                          |\n| char           | string          | sql.NullString                         |\n| varchar        | string          | sql.NullString                         |\n| binary         | string          | sql.NullString                         |\n| varbinary      | string          | sql.NullString                         |\n| tinytext       | string          | sql.NullString                         |\n| text           | string          | sql.NullString                         |\n| mediumtext     | string          | sql.NullString                         |\n| longtext       | string          | sql.NullString                         |\n| enum           | string          | sql.NullString                         |\n| set            | string          | sql.NullString                         |\n| json           | string          | sql.NullString                         |\n\n","isInternal":false,"tokens":3780,"sizeBytes":14257},{"name":"readme.md","path":"tools/goctl/readme.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/readme.md","title":"goctl Documentation","category":"plugin-manifest","format":"markdown","content":"# goctl\n\nEnglish | [简体中文](readme-cn.md) | [한국어](readme-ko.md)\n\nRead document at https://go-zero.dev/docs/tutorials/cli/overview\n","isInternal":false,"tokens":45,"sizeBytes":142},{"name":"README.md","path":"tools/goctl/rpc/example/01-basic/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/01-basic/README.md","title":"01-basic Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 01: Basic RPC Service\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis is the simplest example of generating an RPC service with goctl.\n\n## Proto Definition\n\nA single `greeter.proto` file with one service and one RPC method, no external imports.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/greeter\";\n```\n\n## Generation Commands\n\n### Method 1: Quick Start with `goctl rpc new`\n\n```bash\n# Create a complete RPC project with one command\ngoctl rpc new greeter\n```\n\nThis generates the proto file and service code together:\n\n```\ngreeter/\n├── etc\n│   └── greeter.yaml\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── pinglogic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n### Method 2: Generate from an Existing Proto\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc greeter.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── greeter.yaml\n├── go.mod\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── sayhellologic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n## Key Points\n\n- This is the simplest scenario: one proto file, one service, one RPC method.\n- The `go_package` uses a full module path (`example.com/demo/greeter`), not a relative path.\n- The `--module` flag tells goctl the Go module name; `--go_opt=module=...` and `--go-grpc_opt=module=...` tell protoc to strip the module prefix from output paths.\n- The `--zrpc_out` flag specifies where the goctl-generated service code goes.\n- The `--go_out` and `--go-grpc_out` flags specify where protoc-generated code goes.\n- Edit the logic file (`internal/logic/sayhellologic.go`) to implement your business logic.\n","isInternal":false,"tokens":707,"sizeBytes":2625},{"name":"README.md","path":"tools/goctl/rpc/example/02-import-sibling/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/02-import-sibling/README.md","title":"02-import-sibling Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 02: Importing a Sibling Proto File\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from the same directory.\n\n## Proto Definition\n\nTwo proto files in the same directory share the same `go_package`:\n\n- `types.proto` — Defines shared message types (`User`).\n- `user.proto` — Defines the RPC service, importing `types.proto`.\n\nBoth files use the same `go_package` with a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n`user.proto` imports `types.proto` via:\n\n```protobuf\nimport \"types.proto\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc user.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── usersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createuserlogic.go\n│   │   └── getuserlogic.go\n│   ├── server\n│   │   └── userserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── types.pb.go\n│   ├── user.pb.go\n│   └── user_grpc.pb.go\n├── userservice\n│   └── userservice.go\n└── usersvc.go\n```\n\n## Key Points\n\n- Two proto files (`user.proto` and `types.proto`) share the same `go_package = \"example.com/demo/pb\"`, compiled into a single Go package.\n- `user.proto` imports `types.proto` via `import \"types.proto\"`.\n- When multiple proto files share the same `go_package`, they compile into a single Go package.\n- Only the proto file containing `service` definitions needs to be passed to `goctl rpc protoc`.\n- The imported proto is automatically compiled by protoc and resolved by goctl.\n","isInternal":false,"tokens":539,"sizeBytes":2093},{"name":"README.md","path":"tools/goctl/rpc/example/03-import-subdir/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/03-import-subdir/README.md","title":"03-import-subdir Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 03: Importing Proto from a Subdirectory\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from a subdirectory.\n\n## Proto Definition\n\nTwo proto files with **different** `go_package` values:\n\n- `order.proto` — Defines the `OrderService`, imports `common/types.proto`.\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `common/types.proto` — Defines reusable pagination and sorting messages.\n\n```protobuf\noption go_package = \"example.com/demo/pb/common\";\n```\n\n`order.proto` imports `common/types.proto` from a subdirectory:\n\n```protobuf\nimport \"common/types.proto\";\n```\n\nNote that the two files have **different** `go_package` values, so they compile into separate Go packages.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc order.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── ordersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── getorderlogic.go\n│   │   └── listorderslogic.go\n│   ├── server\n│   │   └── orderserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── orderservice\n│   └── orderservice.go\n├── ordersvc.go\n└── pb\n    ├── common\n    │   └── types.pb.go\n    ├── order.pb.go\n    └── order_grpc.pb.go\n```\n\n## Key Points\n\n- Two proto files have **different** `go_package` values, so they compile into separate Go packages (`pb/` and `pb/common/`).\n- `order.proto` imports `common/types.proto` from a subdirectory.\n- When imported protos have a different `go_package`, goctl automatically generates cross-package imports.\n- The `-I .` flag tells protoc to search from the current directory, enabling it to find `common/types.proto`.\n","isInternal":false,"tokens":557,"sizeBytes":2217},{"name":"README.md","path":"tools/goctl/rpc/example/04-transitive-import/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/04-transitive-import/README.md","title":"04-transitive-import Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 04: Transitive Imports\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates transitive proto imports, where A imports B and B imports C.\n\n## Proto Definition\n\nThree proto files form a transitive import chain, all sharing the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `base.proto` — Layer C: defines base types (`BaseResp`).\n- `middleware.proto` — Layer B: imports `base.proto`, defines `RequestMeta`.\n- `main.proto` — Layer A: imports `middleware.proto`, defines the `PingService` (entry point).\n\nImport chain: `main.proto` → `middleware.proto` → `base.proto`\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc main.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── pingsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── pingserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── base.pb.go\n│   ├── main.pb.go\n│   ├── main_grpc.pb.go\n│   └── middleware.pb.go\n├── pingservice\n│   └── pingservice.go\n└── pingsvc.go\n```\n\n## Key Points\n\n- Three proto files (`main.proto` → `middleware.proto` → `base.proto`) form a transitive import chain.\n- goctl recursively resolves all transitive imports automatically.\n- All three files share the same `go_package = \"example.com/demo/pb\"`.\n- You only need to specify the entry proto file — goctl and protoc handle the rest.\n- Circular imports are detected and will cause an error (same as protoc behavior).\n","isInternal":false,"tokens":537,"sizeBytes":2071},{"name":"README.md","path":"tools/goctl/rpc/example/05-multiple-services/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/05-multiple-services/README.md","title":"05-multiple-services Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 05: Multiple Services (`--multiple`)\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates generating multiple RPC services from a single proto file.\n\n## Proto Definition\n\nTwo proto files share the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `shared.proto` — Defines shared message types (`Meta`).\n- `multi.proto` — Defines **two** services: `SearchService` and `NotifyService`.\n\nThe `-m` (or `--multiple`) flag is required when a proto file contains more than one `service` block.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code with the `-m` flag:\n\n```bash\ngoctl rpc protoc multi.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . \\\n  -m\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── client\n│   ├── notifyservice\n│   │   └── notifyservice.go\n│   └── searchservice\n│       └── searchservice.go\n├── etc\n│   └── multisvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── notifyservice\n│   │   │   └── notifylogic.go\n│   │   └── searchservice\n│   │       └── searchlogic.go\n│   ├── server\n│   │   ├── notifyservice\n│   │   │   └── notifyserviceserver.go\n│   │   └── searchservice\n│   │       └── searchserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── multisvc.go\n└── pb\n    ├── multi.pb.go\n    ├── multi_grpc.pb.go\n    └── shared.pb.go\n```\n\n## Key Points\n\n- The `-m` (or `--multiple`) flag enables multiple-service mode.\n- In multiple mode, `client/` contains per-service subdirectories; `logic/` and `server/` are also grouped by service name.\n- Both services share a single entry point (`multisvc.go`) and config.\n- Without `--multiple`, goctl only allows one `service` block per proto file.\n- All services share the same `config.go` and `servicecontext.go`.\n","isInternal":false,"tokens":613,"sizeBytes":2319},{"name":"README.md","path":"tools/goctl/rpc/example/06-wellknown-types/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/06-wellknown-types/README.md","title":"06-wellknown-types Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 06: Well-Known Types\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using a Google protobuf well-known type (`Timestamp`) as a message field.\n\n## Proto Definition\n\n`events.proto` uses `google.protobuf.Timestamp` as a message field type.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc events.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── eventsvc.yaml\n├── eventservice\n│   └── eventservice.go\n├── eventsvc.go\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createeventlogic.go\n│   │   └── listeventslogic.go\n│   ├── server\n│   │   └── eventserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── events.pb.go\n    └── events_grpc.pb.go\n```\n\n## Key Points\n\n- Uses the Google well-known type `google.protobuf.Timestamp` as a message field.\n- goctl automatically maps well-known types to Go imports; in this example, `Timestamp` maps to `timestamppb`.\n- No extra `--proto_path` needed for well-known types if protoc is properly installed.\n","isInternal":false,"tokens":432,"sizeBytes":1668},{"name":"README.md","path":"tools/goctl/rpc/example/07-external-proto-same-pkg/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/07-external-proto-same-pkg/README.md","title":"07-external-proto-same-pkg Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 07: External Proto — Same `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where both files share the **same** `go_package`.\n\n## Proto Definition\n\nBoth `service.proto` and `ext.proto` use the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\nSource layout:\n\n```\n07-external-proto-same-pkg/\n├── ext_protos\n│   └── ext.proto        # External proto (go_package = \"example.com/demo/pb\")\n├── service.proto        # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- `service.proto` imports `ext.proto` and uses `ext.ExtReq` / `ext.ExtReply` as RPC types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── querylogic.go\n│   ├── server\n│   │   └── queryserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── ext.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n├── queryservice\n│   └── queryservice.go\n└── svc.go\n```\n\n## Key Points\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- Use `-I ./ext_protos` to add the external directory to the proto search path.\n- When the external proto has the **same** `go_package`, all types merge into one Go package — no cross-package imports are needed.\n","isInternal":false,"tokens":601,"sizeBytes":2242},{"name":"README.md","path":"tools/goctl/rpc/example/08-external-proto-diff-pkg/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/08-external-proto-diff-pkg/README.md","title":"08-external-proto-diff-pkg Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 08: External Proto — Different `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where the files have **different** `go_package` values, requiring cross-package imports in the generated Go code.\n\n## Proto Definition\n\nThe proto files use different `go_package` values:\n\n- `service.proto`: `go_package = \"example.com/demo/pb\"`\n- `ext_protos/common/types.proto`: `go_package = \"example.com/demo/pb/common\"`\n\nSource layout:\n\n```\n08-external-proto-diff-pkg/\n├── ext_protos\n│   └── common\n│       └── types.proto    # External proto (go_package = \"example.com/demo/pb/common\")\n├── service.proto          # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `types.proto` has `go_package = \"example.com/demo/pb/common\"` — a **different** Go package.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── dataservice\n│   └── dataservice.go\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── fetchlogic.go\n│   ├── server\n│   │   └── dataserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── common\n│   │   └── types.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n└── svc.go\n```\n\n## Key Points\n\n- When the external proto has a **different** `go_package`, goctl generates cross-package Go imports automatically.\n- goctl resolves the proto package name (e.g., `common`) to the correct Go import path by parsing the imported proto's `go_package` option.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n","isInternal":false,"tokens":635,"sizeBytes":2445},{"name":"README.md","path":"tools/goctl/rpc/example/09-google-types-as-rpc/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/09-google-types-as-rpc/README.md","title":"09-google-types-as-rpc Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 09: Google Well-Known Types as RPC Parameters\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using Google protobuf well-known types **directly** as RPC request or response types (not just as message fields).\n\n## Proto Definition\n\n`service.proto` uses `google.protobuf.Empty` and `google.protobuf.Timestamp` directly as RPC request/response types.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── healthsvc.yaml\n├── go.mod\n├── healthservice\n│   └── healthservice.go\n├── healthsvc.go\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── gettimelogic.go\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── healthserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── service.pb.go\n    └── service_grpc.pb.go\n```\n\n## Key Points\n\n- Uses Google well-known types (`google.protobuf.Empty`, `google.protobuf.Timestamp`) directly as RPC request/response types (not just message fields).\n- goctl correctly maps these to Go types (`emptypb.Empty`, `timestamppb.Timestamp`) and generates proper imports.\n- This differs from Example 06 where well-known types are used as message fields.\n","isInternal":false,"tokens":459,"sizeBytes":1844},{"name":"README.md","path":"tools/goctl/rpc/example/10-streaming/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/10-streaming/README.md","title":"10-streaming Documentation","category":"plugin-manifest","format":"markdown","content":"# Example 10: Streaming RPC\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates all three gRPC streaming patterns: server streaming, client streaming, and bidirectional streaming.\n\n## Proto Definition\n\n`stream.proto` defines three RPC methods demonstrating each streaming pattern.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc stream.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── streamsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── bidistreamlogic.go\n│   │   ├── clientstreamlogic.go\n│   │   └── serverstreamlogic.go\n│   ├── server\n│   │   └── streamserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── stream.pb.go\n│   └── stream_grpc.pb.go\n├── streamservice\n│   └── streamservice.go\n└── streamsvc.go\n```\n\n## Key Points\n\n- Supports three streaming patterns: server streaming (`stream` on response), client streaming (`stream` on request), and bidirectional streaming (`stream` on both).\n- goctl generates separate logic files for each streaming RPC method.\n- goctl generates streaming client wrapper methods; use the returned gRPC stream to send and receive messages.\n","isInternal":false,"tokens":444,"sizeBytes":1817},{"name":"README.md","path":"tools/goctl/rpc/example/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/example/README.md","title":"example Documentation","category":"plugin-manifest","format":"markdown","content":"# RPC Examples\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis directory contains complete examples for all `goctl rpc` code generation scenarios.\n\nEach example includes:\n- `.proto` source files\n- `README.md` (English), `README-cn.md` (中文), and `README-ko.md` (한국어) documentation\n\n## Examples\n\n| # | Directory | Scenario | Key Flags |\n|---|-----------|----------|-----------|\n| 01 | [01-basic](01-basic/) | Basic single service, no imports | — |\n| 02 | [02-import-sibling](02-import-sibling/) | Import sibling proto file | `--proto_path=.` |\n| 03 | [03-import-subdir](03-import-subdir/) | Import proto from subdirectory | `--proto_path=.` |\n| 04 | [04-transitive-import](04-transitive-import/) | Transitive imports (A → B → C) | `--proto_path=.` |\n| 05 | [05-multiple-services](05-multiple-services/) | Multiple services in one proto | `--multiple` |\n| 06 | [06-wellknown-types](06-wellknown-types/) | Google well-known types in messages | — |\n| 07 | [07-external-proto-same-pkg](07-external-proto-same-pkg/) | External proto, same `go_package` | `-I ./ext_protos` |\n| 08 | [08-external-proto-diff-pkg](08-external-proto-diff-pkg/) | External proto, different `go_package` | `-I ./ext_protos` |\n| 09 | [09-google-types-as-rpc](09-google-types-as-rpc/) | Google well-known types as RPC parameters | — |\n| 10 | [10-streaming](10-streaming/) | Server/client/bidirectional streaming | — |\n\n## Prerequisites\n\n- [Go](https://go.dev/) 1.22+\n- [protoc](https://github.com/protocolbuffers/protobuf/releases) (Protocol Buffers compiler)\n- [protoc-gen-go](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go) and [protoc-gen-go-grpc](https://pkg.go.dev/google.golang.org/grpc/cmd/protoc-gen-go-grpc)\n- [goctl](https://github.com/zeromicro/go-zero/tree/master/tools/goctl)\n\n## Quick Start\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n\n# Try the basic example\ncd 01-basic\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc greeter.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n","isInternal":false,"tokens":662,"sizeBytes":2303},{"name":"README.md","path":"tools/goctl/rpc/README.md","rawUrl":"https://raw.githubusercontent.com/zeromicro/go-zero/HEAD/tools/goctl/rpc/README.md","title":"rpc Documentation","category":"plugin-manifest","format":"markdown","content":"# goctl rpc — RPC Code Generation\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\ngoctl rpc is the RPC service code generation module of the `goctl` scaffold. It generates a complete zRPC service from `.proto` files. You only need to write the proto definition and business logic — all boilerplate code is generated automatically.\n\n## Features\n\n- **protoc compatible**: Fully compatible with protoc, all protoc arguments are passed through\n- **External proto imports**: Cross-directory and cross-package proto imports with automatic transitive dependency resolution\n- **Multiple services**: Define multiple services in a single proto file, auto-grouped by service name\n- **Streaming support**: Server streaming, client streaming, and bidirectional streaming\n- **Google well-known types**: Automatic recognition of supported `google.protobuf.*` types with correct Go imports\n- **Client generation**: Auto-generated RPC client wrapper code\n\n## Prerequisites\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n```\n\n## Quick Start\n\n### Method 1: Create a Service Instantly\n\n```bash\ngoctl rpc new greeter\n```\n\nGenerates a complete project structure:\n\n```\ngreeter/\n├── etc/\n│   └── greeter.yaml\n├── greeter/\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient/\n│   └── greeter.go\n└── internal/\n    ├── config/\n    │   └── config.go\n    ├── logic/\n    │   └── pinglogic.go\n    ├── server/\n    │   └── greeterserver.go\n    └── svc/\n        └── servicecontext.go\n```\n\n### Method 2: Generate from a Proto File\n\n1. Generate a proto template:\n\n```bash\ngoctl rpc template -o=user.proto\n```\n\n2. Initialize the output directory and generate service code:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n---\n\n## Command Reference\n\n### `goctl rpc protoc`\n\nGenerate zRPC service code from a `.proto` file.\n\n```bash\ngoctl rpc protoc <proto_file> [flags]\n```\n\n**Examples:**\n\n```bash\n# Basic usage\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n\n# Multiple services mode\ngoctl rpc protoc multi.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -m\n\n# Import external protos\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -I ./shared_protos\n\n# Use Google well-known types\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--zrpc_out` | | string | **required** | Output directory for zRPC service code |\n| `--go_out` | | string | **required** | Output directory for protoc Go code |\n| `--go-grpc_out` | | string | **required** | Output directory for protoc gRPC code |\n| `--go_opt` | | string | | Options for protoc-gen-go (e.g., `module=example.com/demo`) |\n| `--go-grpc_opt` | | string | | Options for protoc-gen-go-grpc (e.g., `module=example.com/demo`) |\n| `--proto_path` | `-I` | string[] | | Proto import search directories (repeatable) |\n| `--multiple` | `-m` | bool | `false` | Multiple services mode |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--style` | | string | `gozero` | File naming style |\n| `--module` | | string | | Custom Go module name |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc new`\n\nQuickly create a complete RPC service project.\n\n```bash\ngoctl rpc new <service_name> [flags]\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--style` | | string | `gozero` | File naming style |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--module` | | string | | Custom Go module name |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--idea` | | bool | `false` | Generate IDE project marker |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc template`\n\nGenerate a proto file template.\n\n```bash\ngoctl rpc template -o=<output_file> [flags]\n```\n\n**Flags:**\n\n| Flag | Type | Description |\n|------|------|-------------|\n| `-o` | string | Output file path (required) |\n| `--home` | string | goctl template directory |\n| `--remote` | string | Remote template Git repository URL |\n| `--branch` | string | Remote template branch |\n\n---\n\n## Feature Details\n\n### Multiple Services Mode (`--multiple`)\n\nWhen a proto file contains multiple `service` definitions, the `--multiple` flag is required.\n\n```protobuf\nservice SearchService {\n  rpc Search(SearchReq) returns (SearchReply);\n}\n\nservice NotifyService {\n  rpc Notify(NotifyReq) returns (NotifyReply);\n}\n```\n\n**Directory differences with `--multiple`:**\n\n| Feature | Default mode | `--multiple` mode |\n|---------|-------------|-------------------|\n| Services per proto | Exactly 1 | 1 or more |\n| Client directory | Named after service | Fixed `client/` directory |\n| Code organization | Flat structure | Grouped by service name |\n\n**`--multiple=false` (default) directory structure:**\n\n```\noutput/\n├── greeterclient/\n│   └── greeter.go\n├── internal/\n│   ├── logic/\n│   │   └── sayhellologic.go\n│   └── server/\n│       └── greeterserver.go\n└── ...\n```\n\n**`--multiple=true` directory structure:**\n\n```\noutput/\n├── client/\n│   ├── searchservice/\n│   │   └── searchservice.go\n│   └── notifyservice/\n│       └── notifyservice.go\n├── internal/\n│   ├── logic/\n│   │   ├── searchservice/\n│   │   │   └── searchlogic.go\n│   │   └── notifyservice/\n│   │       └── notifylogic.go\n│   └── server/\n│       ├── searchservice/\n│       │   └── searchserviceserver.go\n│       └── notifyservice/\n│           └── notifyserviceserver.go\n└── ...\n```\n\n### External Proto Imports (`--proto_path`)\n\nUse `-I` / `--proto_path` to specify additional proto search directories. Supported scenarios:\n\n- **Same-directory import**: `import \"types.proto\";`\n- **Subdirectory import**: `import \"common/types.proto\";`\n- **External directory import**: Proto files outside the project\n- **Transitive imports**: A imports B, B imports C — goctl resolves recursively\n- **Cross-package imports**: Different `go_package` values generate correct Go imports automatically\n\n```bash\n# Search multiple directories for proto files\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./shared_protos -I /path/to/external_protos\n```\n\n### Service Naming\n\nBy default, the service name is derived from the proto **package name** (e.g., `package user;` → service name `user`). This allows multiple proto files to share the same package:\n\n```\nprotos/\n├── user_base.proto      # package user;\n├── user_auth.proto      # package user;\n└── user_profile.proto   # package user;\n```\n\nAll three files generate into a single `user` service.\n\nTo use the proto filename for naming (legacy behavior), add the `--name-from-filename` flag.\n\n### Streaming RPC\n\nAll three gRPC streaming patterns are supported:\n\n```protobuf\nservice StreamService {\n  rpc ServerStream(Req) returns (stream Reply);       // Server streaming\n  rpc ClientStream(stream Req) returns (Reply);       // Client streaming\n  rpc BidiStream(stream Req) returns (stream Reply);  // Bidirectional streaming\n}\n```\n\n### Google Well-Known Types\n\ngoctl automatically recognizes and handles Google protobuf well-known types:\n\n| Proto Type | Go Type |\n|-----------|---------|\n| `google.protobuf.Empty` | `emptypb.Empty` |\n| `google.protobuf.Timestamp` | `timestamppb.Timestamp` |\n| `google.protobuf.Duration` | `durationpb.Duration` |\n| `google.protobuf.Any` | `anypb.Any` |\n| `google.protobuf.Struct` | `structpb.Struct` |\n| `google.protobuf.FieldMask` | `fieldmaskpb.FieldMask` |\n| `google.protobuf.*Value` | `wrapperspb.*Value` |\n\nThese types can be used directly as RPC parameter types — goctl generates the correct imports automatically.\n\n---\n\n## Examples\n\nSee the [example/](example/) directory for 10 complete examples covering all generation scenarios.\n\n| # | Example | Scenario |\n|---|---------|----------|\n| 01 | [Basic service](example/01-basic/) | Single service, no imports |\n| 02 | [Sibling import](example/02-import-sibling/) | Import from same directory |\n| 03 | [Subdirectory import](example/03-import-subdir/) | Import from subdirectory |\n| 04 | [Transitive import](example/04-transitive-import/) | A → B → C dependency chain |\n| 05 | [Multiple services](example/05-multiple-services/) | `--multiple` mode |\n| 06 | [Well-known types](example/06-wellknown-types/) | Timestamp etc. in messages |\n| 07 | [External proto (same pkg)](example/07-external-proto-same-pkg/) | External proto, same go_package |\n| 08 | [External proto (diff pkg)](example/08-external-proto-diff-pkg/) | External proto, different go_package |\n| 09 | [Google well-known types as params](example/09-google-types-as-rpc/) | Empty/Timestamp as RPC parameters |\n| 10 | [Streaming](example/10-streaming/) | Server/client/bidirectional streaming |\n","isInternal":false,"tokens":2730,"sizeBytes":10658}],"systemPromptSnippet":"<yakaai_skills repo=\"zeromicro/go-zero\">\n<!-- File: .github/copilot-instructions.md (Tokens: ~3429 | Category: copilot-instructions) -->\n# GitHub Copilot Instructions for go-zero\n\nThis document provides guidelines for GitHub Copilot when assisting with development in the go-zero project.\n\n## Project Overview\n\ngo-zero is a web and RPC framework with lots of built-in engineering practices designed to ensure the stability of busy services with resilience design. It has been serving sites with tens of millions of users for years.\n\n### Key Architecture Components\n\n- **REST API framework** (`rest/`) - HTTP service framework with middleware chain support\n- **RPC framework** (`zrpc/`) - gRPC-based RPC framework with etcd service discovery and p2c_ewma load balancing\n- **Gateway** (`gateway/`) - API gateway supporting both HTTP and gRPC upstreams with proto-based routing\n- **MCP Server** (`mcp/`) - Model Context Protocol server for AI agent integration via SSE\n- **Core utilities** (`core/`) - Production-grade components:\n  - Resilience: circuit breakers (`breaker/`), rate limiters (`limit/`), adaptive load shedding (`load/`)\n  - Storage: SQL with cache (`stores/sqlc/`), Redis (`stores/redis/`), MongoDB (`stores/mongo/`)\n  - Concurrency: MapReduce (`mr/`), worker pools (`executors/`), sync primitives (`syncx/`)\n  - Observability: metrics (`metric/`), tracing (`trace/`), structured logging (`logx/`)\n- **Code generation tool** (`tools/goctl/`) - CLI tool for generating Go code from `.api` and `.proto` files\n\n## Coding Standards and Conventions\n\n### Code Style\n\n1. **Follow Go conventions**: Use `gofmt` for formatting, follow effective Go practices\n2. **Package naming**: Use lowercase, single-word package names when possible\n3. **Error handling**: Always handle errors explicitly, use `errorx.BatchError` for multiple errors\n4. **Context propagation**: Always pass `context.Context` as the first parameter for functions that may block\n5. **Configuration structures**: Use struct tags with JSON annotations, defaults, and validation\n\n**Pattern**: All service configs embed `service.ServiceConf` for common fields (Name, Log, Mode, Telemetry)\n```go\ntype Config struct {\n    service.ServiceConf              // Always embed for services\n    Host     string `json:\",default=0.0.0.0\"`\n    Port     int    // Required field (no default)\n    Timeout  int64  `json:\",default=3000\"`  // Timeouts in milliseconds\n    Optional string `json:\",optional\"`      // Optional field\n    Mode     string `json:\",default=pro,options=dev|test|rt|pre|pro\"`  // Validated options\n}\n```\n\n**Service modes**: `dev`/`test`/`rt` disable load shedding and stats; `pre`/`pro` enable all resilience features\n\n### Interface Design\n\n1. **Small interfaces**: Follow Go's preference for small, focused interfaces\n2. **Context methods**: Provide both context and non-context versions of methods\n3. **Options pattern**: Use functional options for complex configuration\n\nExample:\n```go\nfunc (c *Client) Get(key string, val any) error {\n    return c.GetCtx(context.Background(), key, val)\n}\n\nfunc (c *Client) GetCtx(ctx context.Context, key string, val any) error {\n    // implementation\n}\n```\n\n### Testing Patterns\n\n1. **Test file naming**: Use `*_test.go` suffix\n2. **Test function naming**: Use `TestFunctionName` pattern\n3. **Use testify/assert**: Prefer `assert` package for assertions\n4. **Table-driven tests**: Use table-driven tests for multiple scenarios\n5. **Mock interfaces**: Use `go.uber.org/mock` for mocking\n6. **Test helpers**: Use `redistest`, `mongtest` helpers for database testing\n\nExample test pattern:\n```go\nfunc TestSomething(t *testing.T) {\n    tests := []struct {\n        name     string\n        input    string\n        expected string\n        wantErr  bool\n    }{\n        {\"valid case\", \"input\", \"output\", false},\n        {\"error case\", \"bad\", \"\", true},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            result, err := SomeFunction(tt.input)\n            if tt.wantErr {\n                assert.Error(t, err)\n                return\n            }\n            assert.NoError(t, err)\n            assert.Equal(t, tt.expected, result)\n        })\n    }\n}\n```\n\n## Framework-Specific Guidelines\n\n### REST API Development\n\n1. **API Definition**: Use `.api` files to define REST APIs with goctl codegen\n2. **Handler pattern**: Separate business logic into logic packages (handlers call logic layer)\n3. **Middleware chain**: Middlewares wrap via `chain.Chain` interface - use `Append()` or `Prepend()` to control order\n   - Built-in middlewares (all in `rest/handler/`): tracing, logging, metrics, recovery, breaker, shedding, timeout, maxconns, maxbytes, gunzip\n   - Custom middleware: `func(http.Handler) http.Handler` - call `next.ServeHTTP(w, r)` to continue chain\n4. **Response handling**: Use `httpx.WriteJson(w, code, v)` for JSON responses\n5. **Error handling**: Use `httpx.Error(w, err)` or `httpx.ErrorCtx(ctx, w, err)` for HTTP error responses\n6. **Route registration**: Routes defined with `Method`, `Path`, and `Handler` - wildcards use `:param` syntax\n\n### RPC Development\n\n1. **Protocol Buffers**: Use protobuf for service definitions, generate code with goctl\n2. **Service discovery**: Use etcd for dynamic service registration/discovery, or direct endpoints for static routing\n3. **Load balancing**: Default is `p2c_ewma` (power of 2 choices with EWMA), configurable via `BalancerName`\n4. **Client configuration**: Support `Etcd`, `Endpoints`, or `Target` - use `BuildTarget()` to construct connection string\n5. **Interceptors**: Implement gRPC interceptors for cross-cutting concerns (auth, logging, metrics)\n6. **Health checks**: gRPC health checks enabled by default (`Health: true`)\n\n### Database Operations\n\n1. **SQL operations**: Use `sqlx.SqlConn` interface - methods always end with `Ctx` for context support\n2. **Caching pattern**: `stores/sqlc` provides `CachedConn` for automatic cache-aside pattern\n   - `QueryRowCtx`: Query with cache key, auto-populate on cache miss\n   - `ExecCtx`: Execute and delete cache keys\n3. **Transactions**: Use `sqlx.SqlConn.TransactCtx()` to get transaction session\n4. **Connection pooling**: Managed automatically (64 max idle/open, 1min lifetime)\n5. **Test helpers**: Use `redistest.CreateRedis(t)` for Redis, SQL mocks for DB testing\n\nExample cache pattern:\n```go\nerr := c.QueryRowCtx(ctx, &dest, key, func(ctx context.Context, conn sqlx.SqlConn) error {\n    return conn.QueryRowCtx(ctx, &dest, query, args...)\n})\n```\n\n### Configuration Management\n\n1. **YAML configuration**: Use YAML for configuration files\n2. **Environment variables**: Support environment variable overrides\n3. **Validation**: Include proper validation for configuration parameters\n4. **Sensible defaults**: Provide reasonable default values\n\n## Error Handling Best Practices\n\n1. **Wrap errors**: Use `fmt.Errorf` with `%w` verb to wrap errors\n2. **Custom errors**: Define custom error types when needed\n3. **Error logging**: Log errors appropriately with context\n4. **Graceful degradation**: Implement fallback mechanisms\n\n## Performance Considerations\n\n1. **Resource pools**: Use connection pools and worker pools\n2. **Circuit breakers**: Implement circuit breaker patterns for external calls\n3. **Rate limiting**: Apply rate limiting to protect services\n4. **Load shedding**: Implement adaptive load shedding\n5. **Metrics**: Add appropriate metrics and monitoring\n\n## Security Guidelines\n\n1. **Input validation**: Validate all input parameters\n2. **SQL injection prevention**: Use parameterized queries\n3. **Authentication**: Implement proper JWT token handling\n4. **HTTPS**: Support TLS/HTTPS configurations\n5. **CORS**: Configure CORS appropriately for web APIs\n\n## Documentation Standards\n\n1. **Package documentation**: Include package-level documentation\n2. **Function documentation**: Document exported functions with examples\n3. **API documentation**: Maintain API documentation in sync\n4. **README updates**: Update README for significant changes\n\n## GitHub Issue Management\n\n### Understanding and Categorizing Issues\n\nWhen analyzing GitHub issues, consider these common categories:\n\n1. **Bug Reports**: Stack traces, version info, reproduction steps\n2. **Feature Requests**: Use case, proposed solution, alternatives\n3. **Questions**: Usage, configuration, or architecture\n4. **Documentation Issues**: Missing, unclear, or incorrect docs\n5. **Performance Issues**: Benchmarks, profiling data, resource usage\n\n### Issue Analysis Checklist\n\n- Identify affected component (REST, RPC, Gateway, MCP, Core utilities, goctl)\n- Check versions (go-zero, Go)\n- Look for reproduction steps or code examples\n- Review code snippets, logs, or stack traces\n- Check if related to resilience features (breaker, load shedding, rate limiting)\n- Determine production impact\n\n### Responding to Issues\n\nBe helpful and professional. Ask clarifying questions when needed. Reference relevant documentation and code files. Provide code examples following project conventions. Suggest workarounds when applicable.\n\n### Chinese to English Translation\n\ngo-zero has an international user base. When encountering issues or comments written in Chinese, translate them to English to ensure all contributors can participate in discussions.\n\n#### Translation Guidelines\n\n1. **Update issue titles**: Edit the issue title to include English translation only\n2. **Translate comments in place**: Add a comment with the English translation, followed by the original Chinese text\n3. **Keep original Chinese**: After translating, include the original Chinese text in a blockquote for verification\n4. **Encourage English communication**: Politely suggest users write in English for better collaboration\n5. **Maintain technical accuracy**: Preserve technical terms, component names, and code exactly\n6. **Translate naturally**: Avoid literal word-by-word translation; use idiomatic English\n7. **Preserve formatting**: Keep markdown formatting, code blocks, and links intact\n8. **Keep URLs unchanged**: Don't translate URLs or file paths\n\n#### Common Technical Terms (Chinese → English)\n\n- 框架 → **Framework** | 中间件 → **Middleware** | 负载均衡 → **Load Balancing**\n- 熔断器 → **Circuit Breaker** | 限流 → **Rate Limiting** | 降载/过载保护 → **Load Shedding**\n- 服务发现 → **Service Discovery** | 配置 → **Configuration** | 弹性/容错 → **Resilience** | 微服务 → **Microservices**\n\n#### Translation Example\n\n**Original Chinese Title:** `goctl 执行环境问题`\n**Updated Title:** `goctl Execution Environment Issue`\n\n**Original Chinese Comment:** `我在项目中遇到熔断器配置问题`\n**Translation in Comment:**\n```markdown\nI encountered a circuit breaker configuration issue in my project.\n\n> Original (原文): 我在项目中遇到熔断器配置问题\n```\n\n### Common Issue Patterns and Solutions\n\n#### Configuration Issues\n- Check `service.ServiceConf` embedding and struct tags\n- Verify YAML syntax, defaults, and validation rules\n- Reference: [rest/config.go](rest/config.go), [zrpc/config.go](zrpc/config.go)\n\n#### Code Generation (goctl) Issues\n- Verify `.api` or `.proto` file syntax and goctl version\n- Reference: `tools/goctl/` directory\n\n#### RPC Connection Issues\n- Check etcd configuration, service discovery, and endpoints\n- Verify load balancing settings (p2c_ewma)\n\n#### Database/Cache Issues\n- Verify `sqlx.SqlConn` usage with context\n- Check cache key generation, invalidation, and connection pools\n- Use test helpers (`redistest`, `mongtest`)\n\n#### Performance Issues\n- Check if load shedding is enabled (mode: `pre`/`pro`)\n- Review circuit breaker thresholds, rate limiting, and context timeouts\n\n### Referencing Codebase\n\nWhen explaining issues, reference specific files and patterns:\n- REST API: `rest/`, `rest/handler/`, `rest/httpx/`\n- RPC: `zrpc/`, `zrpc/internal/`\n- Core utilities: `core/breaker/`, `core/limit/`, `core/load/`, etc.\n- Gateway: `gateway/`\n- MCP: `mcp/`\n- Code generation: `tools/goctl/`\n- Examples: `adhoc/` directory contains various examples\n\n### Encouraging Best Practices\n\nWhen responding to issues, gently guide users toward:\n- Proper error handling with context\n- Using resilience features (breakers, rate limiters)\n- Following testing patterns with table-driven tests\n- Implementing proper resource cleanup\n- Reading existing documentation in `docs/` and `readme.md`\n\n## Common Patterns to Follow\n\n### Service Configuration\n```go\ntype ServiceConf struct {\n    Name string\n    Log  logx.LogConf\n    Mode string `json:\",default=pro,options=[dev,test,pre,pro]\"`\n    // ... other common fields\n}\n```\n\n### Middleware Implementation\n```go\nfunc SomeMiddleware() rest.Middleware {\n    return func(next http.HandlerFunc) http.HandlerFunc {\n        return func(w http.ResponseWriter, r *http.Request) {\n            // Pre-processing\n            next.ServeHTTP(w, r)\n            // Post-processing\n        }\n    }\n}\n```\n\n### Resource Management\nAlways implement proper resource cleanup using defer and context cancellation.\n\n## Build and Test Commands\n\n- Build: `go build ./...`\n- Test: `go test ./...`\n- Test with race detection: `go test -race ./...`\n- Format: `gofmt -w .`\n- Code generation:\n  - REST API: `goctl api go -api *.api -dir .`\n  - RPC: `goctl rpc protoc *.proto --go_out=. --go-grpc_out=. --zrpc_out=.`\n  - Model from SQL: `goctl model mysql datasource -url=\"user:pass@tcp(host:port)/db\" -table=\"*\" -dir=\"./model\"`\n\n## Critical Architecture Patterns\n\n### Resilience Design Philosophy\ngo-zero implements defense-in-depth with multiple protection layers:\n1. **Circuit Breaker** (`core/breaker`): Google SRE breaker - tracks success/failure, opens on error threshold\n2. **Adaptive Load Shedding** (`core/load`): CPU-based auto-rejection when system overloaded (disabled in dev/test/rt modes)\n3. **Rate Limiting** (`core/limit`): Token bucket (Redis-based) and period limiters\n4. **Timeout Control**: Cascading timeouts via context - set at multiple levels (client, server, handler)\n\n### Middleware Chain Architecture\n`rest/chain` provides middleware composition:\n```go\n// Middleware signature\ntype Middleware func(http.Handler) http.Handler\n\n// Chain operations\nchain := chain.New(m1, m2)\nchain.Append(m3)    // Adds to end: m1 -> m2 -> m3\nchain.Prepend(m0)   // Adds to start: m0 -> m1 -> m2 -> m3\nhandler := chain.Then(finalHandler)\n```\n\n### Concurrency Patterns\n- **MapReduce** (`core/mr`): Parallel processing with worker pools - use for batch operations\n- **Executors** (`core/executors`): Bulk/period executors for batching operations\n- **SingleFlight** (`core/syncx`): Deduplicates concurrent identical requests\n\nRemember to run tests and ensure all checks pass before submitting changes. The project emphasizes high quality, performance, and reliability, so these should be primary considerations in all development work.\n\n<!-- File: tools/goctl/api/swagger/example/example_cn.swagger.json (Tokens: ~6982 | Category: anthropic-skill) -->\n{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"演示 api 生成 swagger 文件的 api 完整写法\",\n    \"title\": \"演示 API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form 接口\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form 表单 api 演示\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-未登录\\u003cbr\\u003e1002-无权限操作\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"复杂的 json 请求体接口\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"post json api 演示\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"mapMapObject\",\n                \"mapMapPointerObject\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"objec\n\n<!-- [TRUNCATED AT 50KB] -->\n\n<!-- File: tools/goctl/api/swagger/example/example.swagger.json (Tokens: ~7010 | Category: anthropic-skill) -->\n{\n  \"consumes\": [\n    \"application/json\"\n  ],\n  \"produces\": [\n    \"application/json\"\n  ],\n  \"schemes\": [\n    \"https\"\n  ],\n  \"swagger\": \"2.0\",\n  \"info\": {\n    \"description\": \"Generating Swagger files using the API demo.\",\n    \"title\": \"Demo API\",\n    \"termsOfService\": \"https://github.com/zeromicro/go-zero\",\n    \"contact\": {\n      \"name\": \"keson.an\",\n      \"url\": \"https://github.com/zeromicro/go-zero\",\n      \"email\": \"example@gmail.com\"\n    },\n    \"license\": {\n      \"name\": \"MIT\",\n      \"url\": \"https://github.com/zeromicro/go-zero\"\n    },\n    \"version\": \"v1\"\n  },\n  \"host\": \"example.com\",\n  \"basePath\": \"/v1\",\n  \"paths\": {\n    \"/form\": {\n      \"post\": {\n        \"description\": \"form demo\",\n        \"consumes\": [\n          \"application/x-www-form-urlencoded\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"form\"\n        ],\n        \"summary\": \"form\",\n        \"parameters\": [\n          {\n            \"maximum\": 10000,\n            \"minimum\": 1,\n            \"type\": \"integer\",\n            \"name\": \"id\",\n            \"in\": \"formData\",\n            \"required\": true\n          },\n          {\n            \"type\": \"string\",\n            \"name\": \"name\",\n            \"in\": \"formData\",\n            \"required\": true\n          }\n        ],\n        \"responses\": {\n          \"201\": {\n            \"description\": \"\",\n            \"schema\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"code\": {\n                  \"description\": \"1001-User not login\\u003cbr\\u003e1002-User permission denied\",\n                  \"type\": \"integer\",\n                  \"example\": 0\n                },\n                \"data\": {\n                  \"$ref\": \"#/definitions/FormResp\"\n                },\n                \"msg\": {\n                  \"description\": \"business message\",\n                  \"type\": \"string\",\n                  \"example\": \"ok\"\n                }\n              }\n            }\n          }\n        }\n      }\n    },\n    \"/json/complex\": {\n      \"post\": {\n        \"description\": \"complex json request body API\",\n        \"consumes\": [\n          \"application/json\"\n        ],\n        \"produces\": [\n          \"application/json\"\n        ],\n        \"schemes\": [\n          \"https\"\n        ],\n        \"tags\": [\n          \"postJson\"\n        ],\n        \"summary\": \"jsonComplex\",\n        \"parameters\": [\n          {\n            \"name\": \"body\",\n            \"in\": \"body\",\n            \"required\": true,\n            \"schema\": {\n              \"type\": \"object\",\n              \"required\": [\n                \"integer\",\n                \"number\",\n                \"boolean\",\n                \"string\",\n                \"arrayInteger\",\n                \"arrayNumber\",\n                \"arrayBoolean\",\n                \"arrayString\",\n                \"arrayArrayInteger\",\n                \"arrayArrayNumber\",\n                \"arrayArrayBoolean\",\n                \"arrayArrayString\",\n                \"mapInteger\",\n                \"mapNumber\",\n                \"mapBoolean\",\n                \"mapString\",\n                \"mapArrayInteger\",\n                \"mapArrayNumber\",\n                \"mapArrayBoolean\",\n                \"mapArrayString\",\n                \"mapMapInteger\",\n                \"mapMapNumber\",\n                \"mapMapBoolean\",\n                \"mapMapString\",\n                \"object\",\n                \"pointerObject\",\n                \"arrayObject\",\n                \"arrayPointerObject\",\n                \"mapObject\",\n                \"mapPointerObject\",\n                \"arrayArrayObject\",\n                \"arrayArrayPointerObject\",\n                \"arrayMapObject\",\n                \"arrayMapPointerObject\",\n                \"mapArrayObject\",\n                \"mapArrayPointerObject\"\n              ],\n              \"properties\": {\n                \"arrayArrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"arrayArrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"arrayArrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"arrayArrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayArrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"arrayBoolean\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"arrayInteger\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"arrayMapObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayMapPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"arrayNumber\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"arrayObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayPointerObject\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"arrayString\": {\n                  \"type\": \"array\",\n                  \"items\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"boolean\": {\n                  \"type\": \"boolean\",\n                  \"enum\": [\n                    \"true\",\n                    \"false\"\n                  ],\n                  \"example\": true\n                },\n                \"integer\": {\n                  \"type\": \"integer\",\n                  \"example\": 1\n                },\n                \"mapArrayBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapArrayInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapArrayNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapArrayObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\",\n                        \"object\",\n                        \"pointerObject\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"object\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"pointerObject\": {\n                          \"type\": \"object\",\n                          \"required\": [\n                            \"integer\",\n                            \"number\",\n                            \"boolean\",\n                            \"string\"\n                          ],\n                          \"properties\": {\n                            \"boolean\": {\n                              \"type\": \"boolean\",\n                              \"enum\": [\n                                \"true\",\n                                \"false\"\n                              ],\n                              \"example\": true\n                            },\n                            \"integer\": {\n                              \"type\": \"integer\",\n                              \"example\": 1\n                            },\n                            \"number\": {\n                              \"type\": \"number\",\n                              \"example\": 1.1\n                            },\n                            \"string\": {\n                              \"type\": \"string\",\n                              \"example\": \"some text\"\n                            }\n                          },\n                          \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      }\n                    }\n                  }\n                },\n                \"mapArrayString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"array\",\n                    \"items\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"boolean\"\n                  }\n                },\n                \"mapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"integer\"\n                  }\n                },\n                \"mapMapBoolean\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"boolean\"\n                    }\n                  }\n                },\n                \"mapMapInteger\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"integer\"\n                    }\n                  }\n                },\n                \"mapMapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"number\"\n                    }\n                  }\n                },\n                \"mapMapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": {\n                      \"type\": \"string\"\n                    }\n                  }\n                },\n                \"mapNumber\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"number\"\n                  }\n                },\n                \"mapObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapPointerObject\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"object\",\n                    \"required\": [\n                      \"integer\",\n                      \"number\",\n                      \"boolean\",\n                      \"string\",\n                      \"object\",\n                      \"pointerObject\"\n                    ],\n                    \"properties\": {\n                      \"boolean\": {\n                        \"type\": \"boolean\",\n                        \"enum\": [\n                          \"true\",\n                          \"false\"\n                        ],\n                        \"example\": true\n                      },\n                      \"integer\": {\n                        \"type\": \"integer\",\n                        \"example\": 1\n                      },\n                      \"number\": {\n                        \"type\": \"number\",\n                        \"example\": 1.1\n                      },\n                      \"object\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"pointerObject\": {\n                        \"type\": \"object\",\n                        \"required\": [\n                          \"integer\",\n                          \"number\",\n                          \"boolean\",\n                          \"string\"\n                        ],\n                        \"properties\": {\n                          \"boolean\": {\n                            \"type\": \"boolean\",\n                            \"enum\": [\n                              \"true\",\n                              \"false\"\n                            ],\n                            \"example\": true\n                          },\n                          \"integer\": {\n                            \"type\": \"integer\",\n                            \"example\": 1\n                          },\n                          \"number\": {\n                            \"type\": \"number\",\n                            \"example\": 1.1\n                          },\n                          \"string\": {\n                            \"type\": \"string\",\n                            \"example\": \"some text\"\n                          }\n                        },\n                        \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                      },\n                      \"string\": {\n                        \"type\": \"string\",\n                        \"example\": \"some text\"\n                      }\n                    }\n                  }\n                },\n                \"mapString\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": {\n                    \"type\": \"string\"\n                  }\n                },\n                \"number\": {\n                  \"type\": \"number\",\n                  \"example\": 1.1\n                },\n                \"object\": {\n                  \"type\": \"object\",\n                  \"required\": [\n                    \"integer\",\n                    \"number\",\n                    \"boolean\",\n                    \"string\",\n                    \"object\",\n                    \"pointerObject\"\n                  ],\n                  \"properties\": {\n                    \"boolean\": {\n                      \"type\": \"boolean\",\n                      \"enum\": [\n                        \"true\",\n                        \"false\"\n                      ],\n                      \"example\": true\n                    },\n                    \"integer\": {\n                      \"type\": \"integer\",\n                      \"example\": 1\n                    },\n                    \"number\": {\n                      \"type\": \"number\",\n                      \"example\": 1.1\n                    },\n                    \"object\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        },\n                        \"integer\": {\n                          \"type\": \"integer\",\n                          \"example\": 1\n                        },\n                        \"number\": {\n                          \"type\": \"number\",\n                          \"example\": 1.1\n                        },\n                        \"string\": {\n                          \"type\": \"string\",\n                          \"example\": \"some text\"\n                        }\n                      },\n                      \"$ref\": \"#/definitions/ComplexJsonLevel2\"\n                    },\n                    \"pointerObject\": {\n                      \"type\": \"object\",\n                      \"required\": [\n                        \"integer\",\n                        \"number\",\n                        \"boolean\",\n                        \"string\"\n                      ],\n                      \"properties\": {\n                        \"boolean\": {\n                          \"type\": \"boolean\",\n                          \"enum\": [\n                            \"true\",\n                            \"false\"\n                          ],\n                          \"example\": true\n                        }\n\n<!-- [TRUNCATED AT 50KB] -->\n\n<!-- File: tools/goctl/api/parser/readme.md (Tokens: ~5156 | Category: plugin-manifest) -->\n# Api语法描述\n\n## api示例\n\n``` golang\n/**\n * api语法示例及语法说明\n */\n\n// api语法版本\nsyntax = \"v1\"\n\n// import literal\nimport \"foo.api\"\n\n// import group\nimport (\n    \"bar.api\"\n    \"foo/bar.api\"\n)\ninfo(\n    author: \"songmeizi\"\n    date:   \"2020-01-08\"\n    desc:   \"api语法示例及语法说明\"\n)\n\n// type literal\n\ntype Foo{\n    Foo int `json:\"foo\"`\n}\n\n// type group\n\ntype(\n    Bar{\n        Bar int `json:\"bar\"`\n    }\n)\n\n// service block\n@server(\n    jwt:   Auth\n    group: foo\n)\nservice foo-api{\n    @doc \"foo\"\n    @handler foo\n    post /foo (Foo) returns (Bar)\n}\n```\n\n## api语法结构\n\n* syntax语法声明\n* import语法块\n* info语法块\n* type语法块\n* service语法块\n* 隐藏通道\n\n> ### 温馨提示️\n> 在以上语法结构中，各个语法块从语法上来说，按照语法块为单位，可以在.api文件中任意位置声明，\n> 但是为了提高阅读效率，我们建议按照以上顺序进行声明，因为在将来可能会通过严格模式来控制语法块的顺序。\n\n### syntax语法声明\n\nsyntax是新加入的语法结构，该语法的引入可以解决：\n\n* 快速针对api版本定位存在问题的语法结构\n* 针对版本做语法解析\n* 防止api语法大版本升级导致前后不能向前兼容\n\n> ### 警告 ⚠️\n> 被import的api必须要和main api的syntax版本一致。\n\n**语法定义**\n\n``` antlrv4\n'syntax'={checkVersion(p)}STRING\n```\n\n**语法说明**\n> syntax：固定token，标志一个syntax语法结构的开始\n>\n> checkVersion：自定义go方法，检测`STRING`是否为一个合法的版本号，目前检测逻辑为，STRING必须是满足`(?m)\"v[1-9][0-9]*\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"v1\"\n>\n> 一个api语法文件只能有0或者1个syntax语法声明，如果没有syntax，则默认为v1版本\n>\n\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\nsyntax=\"v1\"\n```\n\neg2：规范写法(推荐)\n\n``` api\nsyntax = \"v2\"\n```\n\n**错误语法示例** ❌\n\neg1：\n\n``` api\nsyntax = \"v0\"\n```\n\neg2：\n\n``` api\nsyntax = v1\n```\n\neg3：\n\n``` api\nsyntax = \"V1\"\n```\n\n## import语法块\n\n随着业务规模增大，api中定义的结构体和服务越来越多，所有的语法描述均为一个api文件，这是多么糟糕的一个问题， 其会大大增加了阅读难度和维护难度，import语法块可以帮助我们解决这个问题，通过拆分api文件，\n不同的api文件按照一定规则声明，可以降低阅读难度和维护难度。\n\n> ### 警告 ⚠️\n> 这里import不像golang那样包含package声明，仅仅是一个文件路径的引入，最终解析后会把所有的声明都汇聚到一个spec.Spec中。\n> 不能import多个相同路径，否则会解析错误。\n\n**语法定义**\n\n``` antlrv4\n'import' {checkImportValue(p)}STRING  \n|'import' '(' ({checkImportValue(p)}STRING)+ ')'\n```\n\n**语法说明**\n> import：固定token，标志一个import语法的开始\n>\n> checkImportValue：自定义go方法，检测`STRING`是否为一个合法的文件路径，目前检测逻辑为，STRING必须是满足`(?m)\"(/?[a-zA-Z0-9_#-])+\\.api\"`正则。\n>\n> STRING：一串英文双引号包裹的字符串，如\"foo.api\"\n>\n\n\n**正确语法示例** ✅\n\neg：\n\n``` api\nimport \"foo.api\"\nimport \"foo/bar.api\"\n\nimport(\n    \"bar.api\"\n    \"foo/bar/foo.api\"\n)\n```\n\n**错误语法示例** ❌\n\neg：\n\n``` api\nimport foo.api\nimport \"foo.txt\"\nimport (\n    bar.api\n    bar.api\n)\n```\n\n## info语法块\n\ninfo语法块是一个包含了多个键值对的语法体，其作用相当于一个api服务的描述，解析器会将其映射到spec.Spec中， 以备用于翻译成其他语言(golang、java等)\n时需要携带的meta元素。如果仅仅是对当前api的一个说明，而不考虑其翻译 时传递到其他语言，则使用简单的多行注释或者java风格的文档注释即可，关于注释说明请参考下文的 **隐藏通道**。\n\n> ### 警告 ⚠️\n> 不能使用重复的key，每个api文件只能有0或者1个info语法块\n\n**语法定义**\n\n``` antlrv4\n'info' '(' (ID {checkKeyValue(p)}VALUE)+ ')'\n```\n\n**语法说明**\n> info：固定token，标志一个info语法块的开始\n>\n> checkKeyValue：自定义go方法，检测`VALUE`是否为一个合法值。\n>\n> VALUE：key对应的值，可以为单行的除'\\r','\\n','/'后的任意字符，多行请以\"\"包裹，不过强烈建议所有都以\"\"包裹\n>\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ninfo(\nfoo: foo value\nbar:\"bar value\"\n    desc:\"long long long long\nlong long text\"\n)\n```\n\neg2：规范写法(推荐)\n\n``` api\ninfo(\n    foo: \"foo value\"\n    bar: \"bar value\"\n    desc: \"long long long long long long text\"\n)\n```\n\n**错误语法示例** ❌\n\neg1：没有key-value内容\n\n``` api\ninfo()\n```\n\neg2：不包含冒号\n\n``` api\ninfo(\n    foo value\n)\n```\n\neg3：key-value没有换行\n\n``` api\ninfo(foo:\"value\")\n```\n\neg4：没有key\n\n``` api\ninfo(\n    : \"value\"\n)\n```\n\neg5：非法的key\n\n``` api\ninfo(\n    12: \"value\"\n)\n```\n\neg6：移除旧版本多行语法\n\n``` api\ninfo(\n    foo: >\n    some text\n    <\n)\n```\n\n## type语法块\n\n在api服务中，我们需要用到一个结构体(类)来作为请求体，响应体的载体，因此我们需要声明一些结构体来完成这件事情， type语法块由golang的type演变而来，当然也保留着一些golang type的特性，沿用golang特性有：\n\n* 保留了golang内置数据类型`bool`,`int`,`int8`,`int16`,`int32`,`int64`,`uint`,`uint8`,`uint16`,`uint32`,`uint64`,`uintptr`\n  ,`float32`,`float64`,`complex64`,`complex128`,`string`,`byte`,`rune`,\n* 兼容golang struct风格声明\n* 保留golang关键字\n\n> ### 警告 ⚠️\n> * 不支持alias\n> * 不支持time.Time数据类型\n> * 结构体名称、字段名称、不能为golang关键字\n\n**语法定义**\n> 由于其和golang相似，因此不做详细说明，具体语法定义请在[ApiParser.g4](g4/ApiParser.g4)中查看typeSpec定义。\n\n**语法说明**\n\n> 参考golang写法\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\ntype Foo struct{\n    Id int `path:\"id\"` // ①\n    Foo int `json:\"foo\"`\n}\n\ntype Bar struct{\n    // 非导出型字段\n    bar int `form:\"bar\"`\n}\n\ntype(\n    // 非导出型结构体\n    fooBar struct{\n        FooBar int\n    }\n)\n```\n\neg2：规范写法（推荐）\n\n``` api\ntype Foo{\n    Id int `path:\"id\"`\n    Foo int `json:\"foo\"`\n}\n\ntype Bar{\n    Bar int `form:\"bar\"`\n}\n\ntype(\n    FooBar{\n        FooBar int\n    }\n)\n```\n\n**错误语法示例** ❌\n\neg\n\n``` api\ntype Gender int // 不支持\n\n// 非struct token\ntype Foo structure{ \n  CreateTime time.Time // 不支持time.Time\n}\n\n// golang关键字 var\ntype var{} \n\ntype Foo{\n  // golang关键字 interface\n  Foo interface \n}\n\n\ntype Foo{\n  foo int \n  // map key必须要golang内置数据类型\n  m map[Bar]string\n}\n```\n\n**① tag说明**\n> tag定义和golang中json tag语法一样，除了json tag外，go-zero还提供了另外一些tag来实现对字段的描述，\n> 详情见下表。\n\n* tag表\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |json|json序列化tag|golang|request、response|`json:\"fooo\"`|\n  |path|路由path，如`/foo/:id`|go-zero|request|`path:\"id\"`|\n  |form|标志请求体是一个form（POST方法时）或者一个query(GET方法时`/search?name=keyword`)|go-zero|request|`form:\"name\"`|\n\n* tag修饰符\n  > 常见参数校验描述\n\n  |tag key |描述 |提供方 |有效范围 |示例 |\n    |:--- |:--- |:--- |:--- |:--- |\n  |optional|定义当前字段为可选参数|go-zero|request|`json:\"name,optional\"`|\n  |options|定义当前字段的枚举值,多个以竖线②隔开|go-zero|request|`json:\"gender,options=male\"`|\n  |default|定义当前字段默认值|go-zero|request|`json:\"gender,default=male\"`|\n  |range|定义当前字段数值范围|go-zero|request|`json:\"age,range=[0:120]\"`|\n\n  ② 竖线：|\n  > ### 温馨提示\n  > tag修饰符需要在tag value后以引文逗号,隔开\n\n## service语法块\n\nservice语法块用于定义api服务，包含服务名称，服务metadata，中间件声明，路由，handler等。\n\n> ### 警告 ⚠️\n> * main api和被import的api服务名称必须一致，不能出现服务名称歧义。\n> * handler名称不能重复\n> * 路由（请求方法+请求path）名称不能重复\n> * 请求体必须声明为普通（非指针）struct，响应体做了一些向前兼容处理，详请见下文说明\n>\n\n**语法定义**\n\n``` antlrv4\nserviceSpec:    atServer? serviceApi;\natServer:       '@server' lp='(' kvLit+ rp=')';\nserviceApi:     {match(p,\"service\")}serviceToken=ID serviceName lbrace='{' serviceRoute* rbrace='}';\nserviceRoute:   atDoc? (atServer|atHandler) route;\natDoc:          '@doc' lp='('? ((kvLit+)|STRING) rp=')'?;\natHandler:      '@handler' ID;\nroute:          {checkHttpMethod(p)}httpMethod=ID path request=body? returnToken=ID? response=replybody?;\nbody:           lp='(' (ID)? rp=')';\nreplybody:      lp='(' dataType? rp=')';\n// kv\nkvLit:          key=ID {checkKeyValue(p)}value=LINE_VALUE;\n\nserviceName:    (ID '-'?)+;\npath:           (('/' (ID ('-' ID)*))|('/:' (ID ('-' ID)?)))+;\n```\n\n**语法说明**\n\n> serviceSpec：包含了一个可选语法块`atServer`和`serviceApi`语法块，其遵循序列模式（编写service必须要按照顺序，否则会解析出错）\n>\n> atServer： 可选语法块，定义key-value结构的server metadata，'@server'表示这一个server语法块的开始，其可以用于描述serviceApi或者route语法块，其用于描述不同语法块时有一些特殊关键key\n> 需要值得注意，见 **atServer关键key描述说明**。\n>\n> serviceApi：包含了1到多个`serviceRoute`语法块\n>\n> serviceRoute：按照序列模式包含了`atDoc`,handler和`route`\n>\n> atDoc：可选语法块，一个路由的key-value描述，其在解析后会传递到spec.Spec结构体，如果不关心传递到spec.Spec,\n> 推荐用单行注释替代。\n>\n> handler：是对路由的handler层描述，可以通过atServer指定`handler` key来指定handler名称，\n> 也可以直接用atHandler语法块来定义handler名称\n>\n> atHandler：'@handler' 固定token，后接一个遵循正则`[_a-zA-Z][a-zA-Z_-]*`)的值，用于声明一个handler名称\n>\n> route：路由，有`httpMethod`、`path`、可选`request`、可选`response`组成，`httpMethod`是必须是小写。\n>\n> body：api请求体语法定义，必须要由()包裹的可选的ID值\n>\n> replyBody：api响应体语法定义，必须由()包裹的struct、~~array(向前兼容处理，后续可能会废弃，强烈推荐以struct包裹，不要直接用array作为响应体)~~\n>\n> kvLit： 同info key-value\n>\n> serviceName: 可以有多个'-'join的ID值\n>\n> path：api请求路径，必须以'/'或者'/:'开头，切不能以'/'结尾，中间可包含ID或者多个以'-'join的ID字符串\n\n**atServer关键key描述说明**\n\n修饰service时\n\n|key|描述|示例|\n|:---|:---|:---|\n|jwt|声明当前service下所有路由需要jwt鉴权，且会自动生成包含jwt逻辑的代码|`jwt: Auth`|\n|group|声明当前service或者路由文件分组|`group: login`|\n|middleware|声明当前service需要开启中间件|`middleware: AuthMiddleware`|\n\n修饰route时\n\n|key|描述|示例|\n|:---|:---|:---|\n|handler|声明一个handler|-|\n\n**正确语法示例** ✅\n\neg1：不规范写法\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc(\n    summary: foo\n  )\n  @server(\n    handler: foo\n  )\n  // 非导出型body\n  post /foo/:id (foo) returns (bar)\n  \n  @doc \"bar\"\n  @handler bar\n  post /bar returns ([]int)// 不推荐数组作为响应体\n  \n  @handler fooBar\n  post /foo/bar (Foo) returns // 可以省略'returns'\n}\n```\n\neg2：规范写法（推荐）\n\n``` api\n@server(\n  jwt: Auth\n  group: foo\n  middleware: AuthMiddleware\n)\nservice foo-api{\n  @doc \"foo\"\n  @handler: foo\n  post /foo/:id (Foo) returns (Bar)\n}\n\nservice foo-api{\n  @handler ping\n  get /ping\n  \n  @doc \"foo\"\n  @handler: bar\n  post /bar/:id (Foo)\n}\n\n```\n\n**错误语法示例** ❌\n\n``` api\n// 不支持空的server语法块\n@server(\n)\n// 不支持空的service语法块\nservice foo-api{\n}\n\nservice foo-api{\n  @doc kkkk // 简版doc必须用英文双引号引起来\n  @handler foo\n  post /foo\n  \n  @handler foo // 重复的handler\n  post /bar\n  \n  @handler fooBar\n  post /bar // 重复的路由\n  \n  // @handler和@doc顺序错误\n  @handler someHandler\n  @doc \"some doc\"\n  post /some/path\n  \n  // handler缺失\n  post /some/path/:id\n  \n  @handler reqTest\n  post /foo/req (*Foo) // 不支持除普通结构体外的其他数据类型作为请求体\n  \n  @handler replyTest\n  post /foo/reply returns (*Foo) // 不支持除普通结构体、数组(向前兼容，后续考虑废弃)外的其他数据类型作为响应体\n}\n```\n\n## 隐藏通道\n\n隐藏通道目前主要为空白符号，换行符号以及注释，这里我们只说注释，因为空白符号和换行符号我们目前拿来也无用。\n\n### 单行注释\n\n**语法定义**\n\n``` antlrv4\n'//' ~[\\r\\n]*\n```\n\n**语法说明**\n由语法定义可知道，单行注释必须要以`//`开头，内容为不能包含换行符\n\n**正确语法示例** ✅\n\n``` api\n// doc\n// comment\n```\n\n**错误语法示例** ❌\n\n``` api\n// break\nline comments\n```\n\n### java风格文档注释\n\n**语法定义**\n\n``` antlrv4\n'/*' .*? '*/'\n```\n\n**语法说明**\n\n由语法定义可知道，单行注释必须要以`/*`开头，`*/`结尾的任意字符。\n\n**正确语法示例** ✅\n\n``` api\n/**\n * java-style doc\n */\n```\n\n**错误语法示例** ❌\n\n``` api\n/*\n * java-style doc */\n */\n```\n\n## Doc&Comment\n\n如果想获取某一个元素的doc或者comment开发人员需要怎么定义？\n\n**Doc**\n> 我们规定上一个语法块（非隐藏通道内容）的行数line+1到当前语法块第一个元素前的所有注释(当行，或者多行)均为doc， 且保留了`//`、`/*`、`*/`原始标记。\n\n**Comment**\n> 我们规定当前语法块最后一个元素所在行开始的一个注释块(当行，或者多行)为comment 且保留了`//`、`/*`、`*/`原始标记。\n\n语法块Doc和Comment的支持情况\n\n|语法块|parent语法块|Doc|Comment|\n|:---|:---|:---|:---|\n|syntaxLit|api|✅|✅|\n|kvLit|infoSpec|✅|✅|\n|importLit|importSpec|✅|✅|\n|typeLit|api|✅|❌|\n|typeLit|typeBlock|✅|❌|\n|field|typeLit|✅|✅|\n|key-value|atServer|✅|✅|\n|atHandler|serviceRoute|✅|✅|\n|route|serviceRoute|✅|✅|\n\n以下为对应语法块解析后细带doc和comment的写法\n``` api\n// syntaxLit doc\nsyntax = \"v1\" // syntaxLit comment\n\ninfo(\n  // kvLit doc\n  author: songmeizi // kvLit comment\n)\n\n// typeLit doc\ntype Foo {}\n\ntype(\n  // typeLit doc\n  Bar{}\n  \n  FooBar{\n    // filed doc\n    Name int // filed comment\n  }\n)\n\n@server(\n  /**\n   * kvLit doc\n   * 开启jwt鉴权\n   */\n  jwt: Auth /**kvLit comment*/\n)\nservice foo-api{\n  // atHandler doc\n  @handler foo //atHandler comment\n  \n  /*\n   * route doc\n   * post请求\n   * path为 /foo\n   * 请求体：Foo\n   * 响应体：Foo\n   */\n  post /foo (Foo) returns (Foo) // route comment\n}\n```\n\n<!-- File: tools/goctl/config/readme.md (Tokens: ~488 | Category: plugin-manifest) -->\n# 配置项管理\n\n| 名称              | 是否可选 | 说明                                          |\n|-------------------|----------|-----------------------------------------------|\n| namingFormat      | YES      | 文件名称格式化符                      |\n\n# naming-format\n`namingFormat`可以用于对生成代码的文件名称进行格式化，和日期格式化符（yyyy-MM-dd）类似，在代码生成时可以根据这些配置项的格式化符进行格式化。\n\n## 格式化符(gozero)\n格式化符由`go`,`zero`组成，如常见的三种格式化风格你可以这样编写：\n* lower: `gozero`\n* camel: `goZero`\n* snake: `go_zero`\n\n常见格式化符生成示例\n源字符：welcome_to_go_zero\n\n| 格式化符   | 格式化结果            | 说明                      |\n|------------|-----------------------|---------------------------|\n| gozero     | welcometogozero       | 小写                      |\n| goZero     | welcomeToGoZero       | 驼峰                      |\n| go_zero    | welcome_to_go_zero    | snake                     |\n| Go#zero    | Welcome#to#go#zero    | #号分割Title类型          |\n| GOZERO     | WELCOMETOGOZERO       | 大写                      |\n| \\_go#zero_ | \\_welcome#to#go#zero_ | 下划线做前后缀，并且#分割 |\n\n错误格式化符示例\n* go\n* gOZero\n* zero\n* goZEro\n* goZERo\n* goZeRo\n* tal\n\n# 使用方法\n目前可通过在生成api、rpc、model时通过`--style`参数指定format格式，如：\n```shell script\ngoctl api go test.api -dir . -style gozero\n```\n```shell script\n goctl rpc proto -src test.proto -dir . -style go_zero\n```\n```shell script\ngoctl model mysql datasource -url=\"\" -table=\"*\" -dir ./snake -style GoZero\n```\n\n# 默认值\n当不指定-style时默认值为`gozero`\n\n<!-- File: tools/goctl/model/mongo/readme.md (Tokens: ~1513 | Category: plugin-manifest) -->\n# mongo生成model\n\n## 背景\n\n在业务务开发中，model(dao)数据访问层是一个服务必不可缺的一层，因此数据库访问的CURD也是必须要对外提供的访问方法， 而CURD在go-zero中就仅存在两种情况\n\n* 带缓存model\n* 不带缓存model\n\n从代码结构上来看，C-U-R-D四个方法就是固定的结构，因此我们可以将其交给goctl工具去完成，帮助我们提升开发效率。\n\n## 方案设计\n\nmongo的生成不同于mysql，mysql可以从scheme_information库中读取到一张表的信息（字段名称，数据类型，索引等），\n而mongo是文档型数据库，我们暂时无法从db中读取某一条记录来实现字段信息获取，就算有也不一定是完整信息（某些字段可能是omitempty修饰，可有可无）， 这里采用type自己编写+代码生成方式实现\n\n## 使用示例\n为 User 生成 mongo model\n```bash\n$ goctl model mongo -t User -c --dir .\n```\n\n### 生成示例代码\n\n#### usermodel.go\n```go\npackage model\n\nimport (\n\t\"github.com/zeromicro/go-zero/core/stores/cache\"\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n)\n\nvar _ UserModel = (*customUserModel)(nil)\n\ntype (\n\t// UserModel is an interface to be customized, add more methods here,\n\t// and implement the added methods in customUserModel.\n\tUserModel interface {\n\t\tuserModel\n\t}\n\n\tcustomUserModel struct {\n\t\t*defaultUserModel\n\t}\n)\n\n// NewUserModel returns a model for the mongo.\nfunc NewUserModel(url, db, collection string, c cache.CacheConf) UserModel {\n\tconn := monc.MustNewModel(url, db, collection, c)\n\treturn &customUserModel{\n\t\tdefaultUserModel: newDefaultUserModel(conn),\n\t}\n}\n\n```\n\n#### usermodelgen.go\n```go\n// Code generated by goctl. DO NOT EDIT.\npackage model\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/monc\"\n\t\"go.mongodb.org/mongo-driver/bson\"\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n\t\"go.mongodb.org/mongo-driver/mongo\"\n)\n\nvar prefixUserCacheKey = \"cache:user:\"\n\ntype userModel interface {\n\tInsert(ctx context.Context, data *User) error\n\tFindOne(ctx context.Context, id string) (*User, error)\n\tUpdate(ctx context.Context, data *User) (*mongo.UpdateResult, error)\n\tDelete(ctx context.Context, id string) (int64, error)\n}\n\ntype defaultUserModel struct {\n\tconn *monc.Model\n}\n\nfunc newDefaultUserModel(conn *monc.Model) *defaultUserModel {\n\treturn &defaultUserModel{conn: conn}\n}\n\nfunc (m *defaultUserModel) Insert(ctx context.Context, data *User) error {\n\tif !data.ID.IsZero() {\n\t\tdata.ID = primitive.NewObjectID()\n\t\tdata.CreateAt = time.Now()\n\t\tdata.UpdateAt = time.Now()\n\t}\n\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\t_, err := m.conn.InsertOne(ctx, key, data)\n\treturn err\n}\n\nfunc (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn nil, ErrInvalidObjectId\n\t}\n\n\tvar data User\n\tkey := prefixUserCacheKey + id\n\terr = m.conn.FindOne(ctx, key, &data, bson.M{\"_id\": oid})\n\tswitch err {\n\tcase nil:\n\t\treturn &data, nil\n\tcase monc.ErrNotFound:\n\t\treturn nil, ErrNotFound\n\tdefault:\n\t\treturn nil, err\n\t}\n}\n\nfunc (m *defaultUserModel) Update(ctx context.Context, data *User) (*mongo.UpdateResult, error) {\n\tdata.UpdateAt = time.Now()\n\tkey := prefixUserCacheKey + data.ID.Hex()\n\tres, err := m.conn.ReplaceOne(ctx, key, bson.M{\"_id\": data.ID}, bson.M{\"$set\": data})\n\treturn res, err\n}\n\nfunc (m *defaultUserModel) Delete(ctx context.Context, id string) (int64, error) {\n\toid, err := primitive.ObjectIDFromHex(id)\n\tif err != nil {\n\t\treturn 0, ErrInvalidObjectId\n\t}\n\tkey := prefixUserCacheKey + id\n\tres, err := m.conn.DeleteOne(ctx, key, bson.M{\"_id\": oid})\n\treturn res, err\n}\n\n```\n\n#### usertypes.go\n```go\npackage model\n\nimport (\n\t\"time\"\n\n\t\"go.mongodb.org/mongo-driver/bson/primitive\"\n)\n\ntype User struct {\n\tID primitive.ObjectID `bson:\"_id,omitempty\" json:\"id,omitempty\"`\n\t// TODO: Fill your own fields\n\tUpdateAt time.Time `bson:\"updateAt,omitempty\" json:\"updateAt,omitempty\"`\n\tCreateAt time.Time `bson:\"createAt,omitempty\" json:\"createAt,omitempty\"`\n}\n\n```\n\n#### error.go\n```go\npackage model\n\nimport (\n\t\"errors\"\n\n\t\"github.com/zeromicro/go-zero/core/stores/mon\"\n)\n\nvar (\n\tErrNotFound        = mon.ErrNotFound\n\tErrInvalidObjectId = errors.New(\"invalid objectId\")\n)\n```\n\n### 文件目录预览\n\n```text\n.\n├── error.go\n├── usermodel.go\n├── usermodelgen.go\n└── usertypes.go\n```\n\n## 命令预览\n\n```text\nGenerate mongo model\n\nUsage:\n  goctl model mongo [flags]\n\nFlags:\n      --branch string   The branch of the remote repo, it does work with --remote\n  -c, --cache           Generate code with cache [optional]\n  -d, --dir string      The target dir\n  -h, --help            help for mongo\n      --home string     The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n      --remote string   The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority\n                                The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure\n      --style string    The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n  -t, --type strings    Specified model type name\n\n```\n\n> 温馨提示\n> \n> `--type` 支持slice传值，示例 `goctl model mongo -t=User -t=Class`\n\n<!-- File: tools/goctl/model/sql/README.MD (Tokens: ~3780 | Category: plugin-manifest) -->\n# Goctl Model\n\ngoctl model 为go-zero下的工具模块中的组件之一，目前支持识别mysql ddl进行model层代码生成，通过命令行或者idea插件（即将支持）可以有选择地生成带redis cache或者不带redis cache的代码逻辑。\n\n## 快速开始\n\n* 通过ddl生成\n\n    ```shell script\n    goctl model mysql ddl -src=\"./*.sql\" -dir=\"./sql/model\" -c\n    ```\n\n    执行上述命令后即可快速生成CURD代码。\n\n    ```Plain Text\n    model\n    │   ├── error.go\n    │   └── usermodel.go\n    ```\n\n* 通过datasource生成\n\n    ```shell script\n    goctl model mysql datasource -url=\"user:password@tcp(127.0.0.1:3306)/database\" -table=\"*\"  -dir=\"./model\"\n    ```\n\n* 生成代码示例\n  \n\t```go\n\n\tpackage model\n    \n    import (\n    \t\"database/sql\"\n    \t\"fmt\"\n    \t\"strings\"\n    \t\"time\"\n        \n        \"github.com/zeromicro/go-zero/core/stores/builder\"\n    \t\"github.com/zeromicro/go-zero/core/stores/cache\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlc\"\n    \t\"github.com/zeromicro/go-zero/core/stores/sqlx\"\n    \t\"github.com/zeromicro/go-zero/core/stringx\"\n    )\n    \n    var (\n    \tuserFieldNames          = builder.FieldNames(&User{})\n    \tuserRows                = strings.Join(userFieldNames, \",\")\n    \tuserRowsExpectAutoSet   = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \",\")\n    \tuserRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, \"id\", \"create_time\", \"update_time\"), \"=?,\") + \"=?\"\n    \n    \tcacheUserPrefix       = \"cache:User:user:\"\n    \tcacheUserNamePrefix   = \"cache:User:name:\"\n    \tcacheUserMobilePrefix = \"cache:User:mobile:\"\n    \tcacheUserIdPrefix     = \"cache:User:id:\"\n    )\n    \n    type (\n    \tUserModel interface {\n    \t\tInsert(data User) (sql.Result, error)\n    \t\tFindOne(id int64) (*User, error)\n    \t\tFindOneByUser(user string) (*User, error)\n    \t\tFindOneByName(name string) (*User, error)\n    \t\tFindOneByMobile(mobile string) (*User, error)\n    \t\tUpdate(data User) error\n    \t\tDelete(id int64) error\n    \t}\n    \n    \tdefaultUserModel struct {\n    \t\tsqlc.CachedConn\n    \t\ttable string\n    \t}\n    \n    \tUser struct {\n    \t\tId         int64     `db:\"id\"`\n    \t\tUser       string    `db:\"user\"`     // 用户\n    \t\tName       string    `db:\"name\"`     // 用户名称\n    \t\tPassword   string    `db:\"password\"` // 用户密码\n    \t\tMobile     string    `db:\"mobile\"`   // 手机号\n    \t\tGender     string    `db:\"gender\"`   // 男｜女｜未公开\n    \t\tNickname   sql.NullString    `db:\"nickname\"` // 用户昵称\n    \t\tCreateTime sql.NullTime `db:\"create_time\"`\n    \t\tUpdateTime time.Time `db:\"update_time\"`\n    \t}\n    )\n    \n    func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {\n    \treturn &defaultUserModel{\n    \t\tCachedConn: sqlc.NewConn(conn, c),\n    \t\ttable:      \"user\",\n    \t}\n    }\n    \n    func (m *defaultUserModel) Insert(data User) (sql.Result, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \tret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"insert into %s (%s) values (?, ?, ?, ?, ?, ?)\", m.table, userRowsExpectAutoSet)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname)\n    \t}, userMobileKey, userKey, userNameKey)\n    \treturn ret, err\n    }\n    \n    func (m *defaultUserModel) FindOne(id int64) (*User, error) {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tvar resp User\n    \terr := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v any) error {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \t\treturn conn.QueryRow(v, query, id)\n    \t})\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByUser(user string) (*User, error) {\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, user)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where user = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, user); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByName(name string) (*User, error) {\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, name)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userNameKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where name = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, name); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) FindOneByMobile(mobile string) (*User, error) {\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, mobile)\n    \tvar resp User\n    \terr := m.QueryRowIndex(&resp, userMobileKey, m.formatPrimary, func(conn sqlx.SqlConn, v any) (i any, e error) {\n    \t\tquery := fmt.Sprintf(\"select %s from %s where mobile = ? limit 1\", userRows, m.table)\n    \t\tif err := conn.QueryRow(&resp, query, mobile); err != nil {\n    \t\t\treturn nil, err\n    \t\t}\n    \t\treturn resp.Id, nil\n    \t}, m.queryPrimary)\n    \tswitch err {\n    \tcase nil:\n    \t\treturn &resp, nil\n    \tcase sqlc.ErrNotFound:\n    \t\treturn nil, ErrNotFound\n    \tdefault:\n    \t\treturn nil, err\n    \t}\n    }\n    \n    func (m *defaultUserModel) Update(data User) error {\n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, data.Id)\n    \t_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"update %s set %s where id = ?\", m.table, userRowsWithPlaceHolder)\n    \t\treturn conn.Exec(query, data.User, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id)\n    \t}, userIdKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) Delete(id int64) error {\n    \tdata, err := m.FindOne(id)\n    \tif err != nil {\n    \t\treturn err\n    \t}\n    \n    \tuserIdKey := fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, id)\n    \tuserKey := fmt.Sprintf(\"%s%v\", cacheUserPrefix, data.User)\n    \tuserNameKey := fmt.Sprintf(\"%s%v\", cacheUserNamePrefix, data.Name)\n    \tuserMobileKey := fmt.Sprintf(\"%s%v\", cacheUserMobilePrefix, data.Mobile)\n    \t_, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {\n    \t\tquery := fmt.Sprintf(\"delete from %s where id = ?\", m.table)\n    \t\treturn conn.Exec(query, id)\n    \t}, userIdKey, userKey, userNameKey, userMobileKey)\n    \treturn err\n    }\n    \n    func (m *defaultUserModel) formatPrimary(primary any) string {\n    \treturn fmt.Sprintf(\"%s%v\", cacheUserIdPrefix, primary)\n    }\n    \n    func (m *defaultUserModel) queryPrimary(conn sqlx.SqlConn, v, primary any) error {\n    \tquery := fmt.Sprintf(\"select %s from %s where id = ? limit 1\", userRows, m.table)\n    \treturn conn.QueryRow(v, query, primary)\n    }\n\n\t```\n\n## 用法\n\n```Plain Text\ngoctl model mysql -h\n```\n\n```Plain Text\nNAME:\n   goctl model mysql - generate mysql model\"\n\nUSAGE:\n   goctl model mysql command [command options] [arguments...]\n\nCOMMANDS:\n   ddl         generate mysql model from ddl\"\n   datasource  generate model from datasource\"\n\nOPTIONS:\n   --help, -h  show help\n```\n\n## 生成规则\n\n* 默认规则\n  \n  我们默认用户在建表时会创建createTime、updateTime字段(忽略大小写、下划线命名风格)且默认值均为`CURRENT_TIMESTAMP`，而updateTime支持`ON UPDATE CURRENT_TIMESTAMP`，对于这两个字段生成`insert`、`update`时会被移除，不在赋值范畴内，当然，如果你不需要这两个字段那也无大碍。\n* 带缓存模式\n  * ddl\n\n\t```shell script\n\tgoctl model mysql -src={patterns} -dir={dir} -cache\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql ddl - generate mysql model from ddl\n    \n    USAGE:\n       goctl model mysql ddl [command options] [arguments...]\n    \n    OPTIONS:\n       --src value, -s value  the path or path globbing patterns of the ddl\n       --dir value, -d value  the target dir\n       --style value          the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --cache, -c            generate code with cache [optional]\n       --idea                 for idea plugin [optional]\n       --database, -db        the name of database [optional]\n\t```\n\n  * datasource\n\n\t```shell script\n\tgoctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir} -cache=true\n\t```\n\n\thelp\n\n\t```\n\tNAME:\n       goctl model mysql datasource - generate model from datasource\n    \n    USAGE:\n       goctl model mysql datasource [command options] [arguments...]\n    \n    OPTIONS:\n       --url value              the data source of database,like \"root:password@tcp(127.0.0.1:3306)/database\n       --table value, -t value  the table or table globbing patterns in the database\n       --cache, -c              generate code with cache [optional]\n       --dir value, -d value    the target dir\n       --style value            the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]\n       --idea                   for idea plugin [optional]\n\n\n\t```\n\n\t示例用法请参考[用法](./example/makefile)\n  \n\t> NOTE: goctl model mysql ddl/datasource 均新增了一个`--style`参数，用于标记文件命名风格。\n\n  目前仅支持redis缓存，如果选择带缓存模式，即生成的`FindOne(ByXxx)`&`Delete`代码会生成带缓存逻辑的代码，目前仅支持单索引字段（除全文索引外），对于联合索引我们默认认为不需要带缓存，且不属于通用型代码，因此没有放在代码生成行列，如example中user表中的`id`、`name`、`mobile`字段均属于单字段索引。\n\n* 不带缓存模式\n\n  * ddl\n  \n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n\n  or\n  * ddl\n\n      ```shell script\n        goctl model -src={patterns} -dir={dir}\n      ```\n\n  * datasource\n  \n      ```shell script\n        goctl model mysql datasource -url={datasource} -table={patterns}  -dir={dir}\n      ```\n  \n生成代码仅基本的CURD结构。\n\n## 缓存\n\n  对于缓存这一块我选择用一问一答的形式进行罗列。我想这样能够更清晰的描述model中缓存的功能。\n\n* 缓存会缓存哪些信息？\n\n  对于主键字段缓存，会缓存整个结构体信息，而对于单索引字段（除全文索引）则缓存主键字段值。\n\n* 数据有更新（`update`）操作会清空缓存吗？\n  \n  会，但仅清空主键缓存的信息，why？这里就不做详细赘述了。\n\n* 为什么不按照单索引字段生成`updateByXxx`和`deleteByXxx`的代码？\n  \n  理论上是没任何问题，但是我们认为，对于model层的数据操作均是以整个结构体为单位，包括查询，我不建议只查询某部分字段（不反对），否则我们的缓存就没有意义了。\n\n* 为什么不支持`findPageLimit`、`findAll`这种模型代码生成？\n  \n  目前，我认为除了基本的CURD外，其他的代码均属于<i>业务型</i>代码，这个我觉得开发人员根据业务需要进行编写更好。\n\n# 类型转换规则\n\n| mysql dataType | golang dataType | golang Null dataType |\n|----------------|-----------------|----------------------------------------|\n| bool           | int64           | sql.NullInt64                          |\n| boolean        | int64           | sql.NullInt64                          |\n| tinyint        | int64           | sql.NullInt64                          |\n| smallint       | int64           | sql.NullInt64                          |\n| mediumint      | int64           | sql.NullInt64                          |\n| int            | int64           | sql.NullInt64                          |\n| integer        | int64           | sql.NullInt64                          |\n| bigint         | int64           | sql.NullInt64                          |\n| float          | float64         | sql.NullFloat64                        |\n| double         | float64         | sql.NullFloat64                        |\n| decimal        | float64         | sql.NullFloat64                        |\n| date           | time.Time       | sql.NullTime                           |\n| datetime       | time.Time       | sql.NullTime                           |\n| timestamp      | time.Time       | sql.NullTime                           |\n| time           | string          | sql.NullString                         |\n| year           | time.Time       | sql.NullInt64                          |\n| char           | string          | sql.NullString                         |\n| varchar        | string          | sql.NullString                         |\n| binary         | string          | sql.NullString                         |\n| varbinary      | string          | sql.NullString                         |\n| tinytext       | string          | sql.NullString                         |\n| text           | string          | sql.NullString                         |\n| mediumtext     | string          | sql.NullString                         |\n| longtext       | string          | sql.NullString                         |\n| enum           | string          | sql.NullString                         |\n| set            | string          | sql.NullString                         |\n| json           | string          | sql.NullString                         |\n\n<!-- File: tools/goctl/readme.md (Tokens: ~45 | Category: plugin-manifest) -->\n# goctl\n\nEnglish | [简体中文](readme-cn.md) | [한국어](readme-ko.md)\n\nRead document at https://go-zero.dev/docs/tutorials/cli/overview\n\n<!-- File: tools/goctl/rpc/example/01-basic/README.md (Tokens: ~707 | Category: plugin-manifest) -->\n# Example 01: Basic RPC Service\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis is the simplest example of generating an RPC service with goctl.\n\n## Proto Definition\n\nA single `greeter.proto` file with one service and one RPC method, no external imports.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/greeter\";\n```\n\n## Generation Commands\n\n### Method 1: Quick Start with `goctl rpc new`\n\n```bash\n# Create a complete RPC project with one command\ngoctl rpc new greeter\n```\n\nThis generates the proto file and service code together:\n\n```\ngreeter/\n├── etc\n│   └── greeter.yaml\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── pinglogic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n### Method 2: Generate from an Existing Proto\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc greeter.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── greeter.yaml\n├── go.mod\n├── greeter\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeterclient\n│   └── greeter.go\n└── internal\n    ├── config\n    │   └── config.go\n    ├── logic\n    │   └── sayhellologic.go\n    ├── server\n    │   └── greeterserver.go\n    └── svc\n        └── servicecontext.go\n```\n\n## Key Points\n\n- This is the simplest scenario: one proto file, one service, one RPC method.\n- The `go_package` uses a full module path (`example.com/demo/greeter`), not a relative path.\n- The `--module` flag tells goctl the Go module name; `--go_opt=module=...` and `--go-grpc_opt=module=...` tell protoc to strip the module prefix from output paths.\n- The `--zrpc_out` flag specifies where the goctl-generated service code goes.\n- The `--go_out` and `--go-grpc_out` flags specify where protoc-generated code goes.\n- Edit the logic file (`internal/logic/sayhellologic.go`) to implement your business logic.\n\n<!-- File: tools/goctl/rpc/example/02-import-sibling/README.md (Tokens: ~539 | Category: plugin-manifest) -->\n# Example 02: Importing a Sibling Proto File\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from the same directory.\n\n## Proto Definition\n\nTwo proto files in the same directory share the same `go_package`:\n\n- `types.proto` — Defines shared message types (`User`).\n- `user.proto` — Defines the RPC service, importing `types.proto`.\n\nBoth files use the same `go_package` with a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n`user.proto` imports `types.proto` via:\n\n```protobuf\nimport \"types.proto\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc user.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── usersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createuserlogic.go\n│   │   └── getuserlogic.go\n│   ├── server\n│   │   └── userserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── types.pb.go\n│   ├── user.pb.go\n│   └── user_grpc.pb.go\n├── userservice\n│   └── userservice.go\n└── usersvc.go\n```\n\n## Key Points\n\n- Two proto files (`user.proto` and `types.proto`) share the same `go_package = \"example.com/demo/pb\"`, compiled into a single Go package.\n- `user.proto` imports `types.proto` via `import \"types.proto\"`.\n- When multiple proto files share the same `go_package`, they compile into a single Go package.\n- Only the proto file containing `service` definitions needs to be passed to `goctl rpc protoc`.\n- The imported proto is automatically compiled by protoc and resolved by goctl.\n\n<!-- File: tools/goctl/rpc/example/03-import-subdir/README.md (Tokens: ~557 | Category: plugin-manifest) -->\n# Example 03: Importing Proto from a Subdirectory\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing a proto file from a subdirectory.\n\n## Proto Definition\n\nTwo proto files with **different** `go_package` values:\n\n- `order.proto` — Defines the `OrderService`, imports `common/types.proto`.\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `common/types.proto` — Defines reusable pagination and sorting messages.\n\n```protobuf\noption go_package = \"example.com/demo/pb/common\";\n```\n\n`order.proto` imports `common/types.proto` from a subdirectory:\n\n```protobuf\nimport \"common/types.proto\";\n```\n\nNote that the two files have **different** `go_package` values, so they compile into separate Go packages.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc order.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── ordersvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── getorderlogic.go\n│   │   └── listorderslogic.go\n│   ├── server\n│   │   └── orderserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── orderservice\n│   └── orderservice.go\n├── ordersvc.go\n└── pb\n    ├── common\n    │   └── types.pb.go\n    ├── order.pb.go\n    └── order_grpc.pb.go\n```\n\n## Key Points\n\n- Two proto files have **different** `go_package` values, so they compile into separate Go packages (`pb/` and `pb/common/`).\n- `order.proto` imports `common/types.proto` from a subdirectory.\n- When imported protos have a different `go_package`, goctl automatically generates cross-package imports.\n- The `-I .` flag tells protoc to search from the current directory, enabling it to find `common/types.proto`.\n\n<!-- File: tools/goctl/rpc/example/04-transitive-import/README.md (Tokens: ~537 | Category: plugin-manifest) -->\n# Example 04: Transitive Imports\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates transitive proto imports, where A imports B and B imports C.\n\n## Proto Definition\n\nThree proto files form a transitive import chain, all sharing the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `base.proto` — Layer C: defines base types (`BaseResp`).\n- `middleware.proto` — Layer B: imports `base.proto`, defines `RequestMeta`.\n- `main.proto` — Layer A: imports `middleware.proto`, defines the `PingService` (entry point).\n\nImport chain: `main.proto` → `middleware.proto` → `base.proto`\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc main.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── pingsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── pingserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── base.pb.go\n│   ├── main.pb.go\n│   ├── main_grpc.pb.go\n│   └── middleware.pb.go\n├── pingservice\n│   └── pingservice.go\n└── pingsvc.go\n```\n\n## Key Points\n\n- Three proto files (`main.proto` → `middleware.proto` → `base.proto`) form a transitive import chain.\n- goctl recursively resolves all transitive imports automatically.\n- All three files share the same `go_package = \"example.com/demo/pb\"`.\n- You only need to specify the entry proto file — goctl and protoc handle the rest.\n- Circular imports are detected and will cause an error (same as protoc behavior).\n\n<!-- File: tools/goctl/rpc/example/05-multiple-services/README.md (Tokens: ~613 | Category: plugin-manifest) -->\n# Example 05: Multiple Services (`--multiple`)\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates generating multiple RPC services from a single proto file.\n\n## Proto Definition\n\nTwo proto files share the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n- `shared.proto` — Defines shared message types (`Meta`).\n- `multi.proto` — Defines **two** services: `SearchService` and `NotifyService`.\n\nThe `-m` (or `--multiple`) flag is required when a proto file contains more than one `service` block.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code with the `-m` flag:\n\n```bash\ngoctl rpc protoc multi.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . \\\n  -m\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── client\n│   ├── notifyservice\n│   │   └── notifyservice.go\n│   └── searchservice\n│       └── searchservice.go\n├── etc\n│   └── multisvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── notifyservice\n│   │   │   └── notifylogic.go\n│   │   └── searchservice\n│   │       └── searchlogic.go\n│   ├── server\n│   │   ├── notifyservice\n│   │   │   └── notifyserviceserver.go\n│   │   └── searchservice\n│   │       └── searchserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── multisvc.go\n└── pb\n    ├── multi.pb.go\n    ├── multi_grpc.pb.go\n    └── shared.pb.go\n```\n\n## Key Points\n\n- The `-m` (or `--multiple`) flag enables multiple-service mode.\n- In multiple mode, `client/` contains per-service subdirectories; `logic/` and `server/` are also grouped by service name.\n- Both services share a single entry point (`multisvc.go`) and config.\n- Without `--multiple`, goctl only allows one `service` block per proto file.\n- All services share the same `config.go` and `servicecontext.go`.\n\n<!-- File: tools/goctl/rpc/example/06-wellknown-types/README.md (Tokens: ~432 | Category: plugin-manifest) -->\n# Example 06: Well-Known Types\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using a Google protobuf well-known type (`Timestamp`) as a message field.\n\n## Proto Definition\n\n`events.proto` uses `google.protobuf.Timestamp` as a message field type.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc events.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── eventsvc.yaml\n├── eventservice\n│   └── eventservice.go\n├── eventsvc.go\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── createeventlogic.go\n│   │   └── listeventslogic.go\n│   ├── server\n│   │   └── eventserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── events.pb.go\n    └── events_grpc.pb.go\n```\n\n## Key Points\n\n- Uses the Google well-known type `google.protobuf.Timestamp` as a message field.\n- goctl automatically maps well-known types to Go imports; in this example, `Timestamp` maps to `timestamppb`.\n- No extra `--proto_path` needed for well-known types if protoc is properly installed.\n\n<!-- File: tools/goctl/rpc/example/07-external-proto-same-pkg/README.md (Tokens: ~601 | Category: plugin-manifest) -->\n# Example 07: External Proto — Same `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where both files share the **same** `go_package`.\n\n## Proto Definition\n\nBoth `service.proto` and `ext.proto` use the same `go_package`:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\nSource layout:\n\n```\n07-external-proto-same-pkg/\n├── ext_protos\n│   └── ext.proto        # External proto (go_package = \"example.com/demo/pb\")\n├── service.proto        # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- `service.proto` imports `ext.proto` and uses `ext.ExtReq` / `ext.ExtReply` as RPC types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── querylogic.go\n│   ├── server\n│   │   └── queryserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── ext.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n├── queryservice\n│   └── queryservice.go\n└── svc.go\n```\n\n## Key Points\n\n- `ext.proto` lives in a separate directory (`ext_protos/`), but has the same `go_package` as `service.proto`.\n- Use `-I ./ext_protos` to add the external directory to the proto search path.\n- When the external proto has the **same** `go_package`, all types merge into one Go package — no cross-package imports are needed.\n\n<!-- File: tools/goctl/rpc/example/08-external-proto-diff-pkg/README.md (Tokens: ~635 | Category: plugin-manifest) -->\n# Example 08: External Proto — Different `go_package`\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates importing proto files from an external directory where the files have **different** `go_package` values, requiring cross-package imports in the generated Go code.\n\n## Proto Definition\n\nThe proto files use different `go_package` values:\n\n- `service.proto`: `go_package = \"example.com/demo/pb\"`\n- `ext_protos/common/types.proto`: `go_package = \"example.com/demo/pb/common\"`\n\nSource layout:\n\n```\n08-external-proto-diff-pkg/\n├── ext_protos\n│   └── common\n│       └── types.proto    # External proto (go_package = \"example.com/demo/pb/common\")\n├── service.proto          # Service definition (go_package = \"example.com/demo/pb\")\n├── README.md\n├── README-cn.md\n└── README-ko.md\n```\n\n- `types.proto` has `go_package = \"example.com/demo/pb/common\"` — a **different** Go package.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code (note `-I ./ext_protos`):\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./ext_protos\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── dataservice\n│   └── dataservice.go\n├── etc\n│   └── svc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   └── fetchlogic.go\n│   ├── server\n│   │   └── dataserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── common\n│   │   └── types.pb.go\n│   ├── service.pb.go\n│   └── service_grpc.pb.go\n└── svc.go\n```\n\n## Key Points\n\n- When the external proto has a **different** `go_package`, goctl generates cross-package Go imports automatically.\n- goctl resolves the proto package name (e.g., `common`) to the correct Go import path by parsing the imported proto's `go_package` option.\n- `service.proto` uses `common.ExtReq` / `common.ExtReply` directly as RPC parameter types.\n\n<!-- File: tools/goctl/rpc/example/09-google-types-as-rpc/README.md (Tokens: ~459 | Category: plugin-manifest) -->\n# Example 09: Google Well-Known Types as RPC Parameters\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates using Google protobuf well-known types **directly** as RPC request or response types (not just as message fields).\n\n## Proto Definition\n\n`service.proto` uses `google.protobuf.Empty` and `google.protobuf.Timestamp` directly as RPC request/response types.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc service.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── healthsvc.yaml\n├── go.mod\n├── healthservice\n│   └── healthservice.go\n├── healthsvc.go\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── gettimelogic.go\n│   │   └── pinglogic.go\n│   ├── server\n│   │   └── healthserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n└── pb\n    ├── service.pb.go\n    └── service_grpc.pb.go\n```\n\n## Key Points\n\n- Uses Google well-known types (`google.protobuf.Empty`, `google.protobuf.Timestamp`) directly as RPC request/response types (not just message fields).\n- goctl correctly maps these to Go types (`emptypb.Empty`, `timestamppb.Timestamp`) and generates proper imports.\n- This differs from Example 06 where well-known types are used as message fields.\n\n<!-- File: tools/goctl/rpc/example/10-streaming/README.md (Tokens: ~444 | Category: plugin-manifest) -->\n# Example 10: Streaming RPC\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis example demonstrates all three gRPC streaming patterns: server streaming, client streaming, and bidirectional streaming.\n\n## Proto Definition\n\n`stream.proto` defines three RPC methods demonstrating each streaming pattern.\n\nThe `go_package` uses a full module path:\n\n```protobuf\noption go_package = \"example.com/demo/pb\";\n```\n\n## Generation Commands\n\nFirst, initialize the output directory with a `go.mod`:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\n```\n\nThen generate the code:\n\n```bash\ngoctl rpc protoc stream.proto \\\n  --go_out=output \\\n  --go-grpc_out=output \\\n  --zrpc_out=output \\\n  --go_opt=module=example.com/demo \\\n  --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I .\n```\n\nGenerated directory structure:\n\n```\noutput/\n├── etc\n│   └── streamsvc.yaml\n├── go.mod\n├── internal\n│   ├── config\n│   │   └── config.go\n│   ├── logic\n│   │   ├── bidistreamlogic.go\n│   │   ├── clientstreamlogic.go\n│   │   └── serverstreamlogic.go\n│   ├── server\n│   │   └── streamserviceserver.go\n│   └── svc\n│       └── servicecontext.go\n├── pb\n│   ├── stream.pb.go\n│   └── stream_grpc.pb.go\n├── streamservice\n│   └── streamservice.go\n└── streamsvc.go\n```\n\n## Key Points\n\n- Supports three streaming patterns: server streaming (`stream` on response), client streaming (`stream` on request), and bidirectional streaming (`stream` on both).\n- goctl generates separate logic files for each streaming RPC method.\n- goctl generates streaming client wrapper methods; use the returned gRPC stream to send and receive messages.\n\n<!-- File: tools/goctl/rpc/example/README.md (Tokens: ~662 | Category: plugin-manifest) -->\n# RPC Examples\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\nThis directory contains complete examples for all `goctl rpc` code generation scenarios.\n\nEach example includes:\n- `.proto` source files\n- `README.md` (English), `README-cn.md` (中文), and `README-ko.md` (한국어) documentation\n\n## Examples\n\n| # | Directory | Scenario | Key Flags |\n|---|-----------|----------|-----------|\n| 01 | [01-basic](01-basic/) | Basic single service, no imports | — |\n| 02 | [02-import-sibling](02-import-sibling/) | Import sibling proto file | `--proto_path=.` |\n| 03 | [03-import-subdir](03-import-subdir/) | Import proto from subdirectory | `--proto_path=.` |\n| 04 | [04-transitive-import](04-transitive-import/) | Transitive imports (A → B → C) | `--proto_path=.` |\n| 05 | [05-multiple-services](05-multiple-services/) | Multiple services in one proto | `--multiple` |\n| 06 | [06-wellknown-types](06-wellknown-types/) | Google well-known types in messages | — |\n| 07 | [07-external-proto-same-pkg](07-external-proto-same-pkg/) | External proto, same `go_package` | `-I ./ext_protos` |\n| 08 | [08-external-proto-diff-pkg](08-external-proto-diff-pkg/) | External proto, different `go_package` | `-I ./ext_protos` |\n| 09 | [09-google-types-as-rpc](09-google-types-as-rpc/) | Google well-known types as RPC parameters | — |\n| 10 | [10-streaming](10-streaming/) | Server/client/bidirectional streaming | — |\n\n## Prerequisites\n\n- [Go](https://go.dev/) 1.22+\n- [protoc](https://github.com/protocolbuffers/protobuf/releases) (Protocol Buffers compiler)\n- [protoc-gen-go](https://pkg.go.dev/google.golang.org/protobuf/cmd/protoc-gen-go) and [protoc-gen-go-grpc](https://pkg.go.dev/google.golang.org/grpc/cmd/protoc-gen-go-grpc)\n- [goctl](https://github.com/zeromicro/go-zero/tree/master/tools/goctl)\n\n## Quick Start\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n\n# Try the basic example\ncd 01-basic\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc greeter.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n<!-- File: tools/goctl/rpc/README.md (Tokens: ~2730 | Category: plugin-manifest) -->\n# goctl rpc — RPC Code Generation\n\nEnglish | [中文](README-cn.md) | [한국어](README-ko.md)\n\ngoctl rpc is the RPC service code generation module of the `goctl` scaffold. It generates a complete zRPC service from `.proto` files. You only need to write the proto definition and business logic — all boilerplate code is generated automatically.\n\n## Features\n\n- **protoc compatible**: Fully compatible with protoc, all protoc arguments are passed through\n- **External proto imports**: Cross-directory and cross-package proto imports with automatic transitive dependency resolution\n- **Multiple services**: Define multiple services in a single proto file, auto-grouped by service name\n- **Streaming support**: Server streaming, client streaming, and bidirectional streaming\n- **Google well-known types**: Automatic recognition of supported `google.protobuf.*` types with correct Go imports\n- **Client generation**: Auto-generated RPC client wrapper code\n\n## Prerequisites\n\n```bash\n# Install protoc plugins\ngo install google.golang.org/protobuf/cmd/protoc-gen-go@latest\ngo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest\n```\n\n## Quick Start\n\n### Method 1: Create a Service Instantly\n\n```bash\ngoctl rpc new greeter\n```\n\nGenerates a complete project structure:\n\n```\ngreeter/\n├── etc/\n│   └── greeter.yaml\n├── greeter/\n│   ├── greeter.pb.go\n│   └── greeter_grpc.pb.go\n├── greeter.go\n├── greeter.proto\n├── greeterclient/\n│   └── greeter.go\n└── internal/\n    ├── config/\n    │   └── config.go\n    ├── logic/\n    │   └── pinglogic.go\n    ├── server/\n    │   └── greeterserver.go\n    └── svc/\n        └── servicecontext.go\n```\n\n### Method 2: Generate from a Proto File\n\n1. Generate a proto template:\n\n```bash\ngoctl rpc template -o=user.proto\n```\n\n2. Initialize the output directory and generate service code:\n\n```bash\nmkdir -p output && cd output && go mod init example.com/demo && cd ..\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n---\n\n## Command Reference\n\n### `goctl rpc protoc`\n\nGenerate zRPC service code from a `.proto` file.\n\n```bash\ngoctl rpc protoc <proto_file> [flags]\n```\n\n**Examples:**\n\n```bash\n# Basic usage\ngoctl rpc protoc user.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n\n# Multiple services mode\ngoctl rpc protoc multi.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -m\n\n# Import external protos\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I . -I ./shared_protos\n\n# Use Google well-known types\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo -I .\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--zrpc_out` | | string | **required** | Output directory for zRPC service code |\n| `--go_out` | | string | **required** | Output directory for protoc Go code |\n| `--go-grpc_out` | | string | **required** | Output directory for protoc gRPC code |\n| `--go_opt` | | string | | Options for protoc-gen-go (e.g., `module=example.com/demo`) |\n| `--go-grpc_opt` | | string | | Options for protoc-gen-go-grpc (e.g., `module=example.com/demo`) |\n| `--proto_path` | `-I` | string[] | | Proto import search directories (repeatable) |\n| `--multiple` | `-m` | bool | `false` | Multiple services mode |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--style` | | string | `gozero` | File naming style |\n| `--module` | | string | | Custom Go module name |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc new`\n\nQuickly create a complete RPC service project.\n\n```bash\ngoctl rpc new <service_name> [flags]\n```\n\n**Flags:**\n\n| Flag | Short | Type | Default | Description |\n|------|-------|------|---------|-------------|\n| `--style` | | string | `gozero` | File naming style |\n| `--client` | `-c` | bool | `true` | Generate RPC client code |\n| `--module` | | string | | Custom Go module name |\n| `--verbose` | `-v` | bool | `false` | Enable verbose logging |\n| `--idea` | | bool | `false` | Generate IDE project marker |\n| `--name-from-filename` | | bool | `false` | Use filename instead of package name for service naming |\n| `--home` | | string | | goctl template directory |\n| `--remote` | | string | | Remote template Git repository URL |\n| `--branch` | | string | | Remote template branch |\n\n### `goctl rpc template`\n\nGenerate a proto file template.\n\n```bash\ngoctl rpc template -o=<output_file> [flags]\n```\n\n**Flags:**\n\n| Flag | Type | Description |\n|------|------|-------------|\n| `-o` | string | Output file path (required) |\n| `--home` | string | goctl template directory |\n| `--remote` | string | Remote template Git repository URL |\n| `--branch` | string | Remote template branch |\n\n---\n\n## Feature Details\n\n### Multiple Services Mode (`--multiple`)\n\nWhen a proto file contains multiple `service` definitions, the `--multiple` flag is required.\n\n```protobuf\nservice SearchService {\n  rpc Search(SearchReq) returns (SearchReply);\n}\n\nservice NotifyService {\n  rpc Notify(NotifyReq) returns (NotifyReply);\n}\n```\n\n**Directory differences with `--multiple`:**\n\n| Feature | Default mode | `--multiple` mode |\n|---------|-------------|-------------------|\n| Services per proto | Exactly 1 | 1 or more |\n| Client directory | Named after service | Fixed `client/` directory |\n| Code organization | Flat structure | Grouped by service name |\n\n**`--multiple=false` (default) directory structure:**\n\n```\noutput/\n├── greeterclient/\n│   └── greeter.go\n├── internal/\n│   ├── logic/\n│   │   └── sayhellologic.go\n│   └── server/\n│       └── greeterserver.go\n└── ...\n```\n\n**`--multiple=true` directory structure:**\n\n```\noutput/\n├── client/\n│   ├── searchservice/\n│   │   └── searchservice.go\n│   └── notifyservice/\n│       └── notifyservice.go\n├── internal/\n│   ├── logic/\n│   │   ├── searchservice/\n│   │   │   └── searchlogic.go\n│   │   └── notifyservice/\n│   │       └── notifylogic.go\n│   └── server/\n│       ├── searchservice/\n│       │   └── searchserviceserver.go\n│       └── notifyservice/\n│           └── notifyserviceserver.go\n└── ...\n```\n\n### External Proto Imports (`--proto_path`)\n\nUse `-I` / `--proto_path` to specify additional proto search directories. Supported scenarios:\n\n- **Same-directory import**: `import \"types.proto\";`\n- **Subdirectory import**: `import \"common/types.proto\";`\n- **External directory import**: Proto files outside the project\n- **Transitive imports**: A imports B, B imports C — goctl resolves recursively\n- **Cross-package imports**: Different `go_package` values generate correct Go imports automatically\n\n```bash\n# Search multiple directories for proto files\ngoctl rpc protoc service.proto \\\n  --go_out=output --go-grpc_out=output --zrpc_out=output \\\n  --go_opt=module=example.com/demo --go-grpc_opt=module=example.com/demo \\\n  --module=example.com/demo \\\n  -I . -I ./shared_protos -I /path/to/external_protos\n```\n\n### Service Naming\n\nBy default, the service name is derived from the proto **package name** (e.g., `package user;` → service name `user`). This allows multiple proto files to share the same package:\n\n```\nprotos/\n├── user_base.proto      # package user;\n├── user_auth.proto      # package user;\n└── user_profile.proto   # package user;\n```\n\nAll three files generate into a single `user` service.\n\nTo use the proto filename for naming (legacy behavior), add the `--name-from-filename` flag.\n\n### Streaming RPC\n\nAll three gRPC streaming patterns are supported:\n\n```protobuf\nservice StreamService {\n  rpc ServerStream(Req) returns (stream Reply);       // Server streaming\n  rpc ClientStream(stream Req) returns (Reply);       // Client streaming\n  rpc BidiStream(stream Req) returns (stream Reply);  // Bidirectional streaming\n}\n```\n\n### Google Well-Known Types\n\ngoctl automatically recognizes and handles Google protobuf well-known types:\n\n| Proto Type | Go Type |\n|-----------|---------|\n| `google.protobuf.Empty` | `emptypb.Empty` |\n| `google.protobuf.Timestamp` | `timestamppb.Timestamp` |\n| `google.protobuf.Duration` | `durationpb.Duration` |\n| `google.protobuf.Any` | `anypb.Any` |\n| `google.protobuf.Struct` | `structpb.Struct` |\n| `google.protobuf.FieldMask` | `fieldmaskpb.FieldMask` |\n| `google.protobuf.*Value` | `wrapperspb.*Value` |\n\nThese types can be used directly as RPC parameter types — goctl generates the correct imports automatically.\n\n---\n\n## Examples\n\nSee the [example/](example/) directory for 10 complete examples covering all generation scenarios.\n\n| # | Example | Scenario |\n|---|---------|----------|\n| 01 | [Basic service](example/01-basic/) | Single service, no imports |\n| 02 | [Sibling import](example/02-import-sibling/) | Import from same directory |\n| 03 | [Subdirectory import](example/03-import-subdir/) | Import from subdirectory |\n| 04 | [Transitive import](example/04-transitive-import/) | A → B → C dependency chain |\n| 05 | [Multiple services](example/05-multiple-services/) | `--multiple` mode |\n| 06 | [Well-known types](example/06-wellknown-types/) | Timestamp etc. in messages |\n| 07 | [External proto (same pkg)](example/07-external-proto-same-pkg/) | External proto, same go_package |\n| 08 | [External proto (diff pkg)](example/08-external-proto-diff-pkg/) | External proto, different go_package |\n| 09 | [Google well-known types as params](example/09-google-types-as-rpc/) | Empty/Timestamp as RPC parameters |\n| 10 | [Streaming](example/10-streaming/) | Server/client/bidirectional streaming |\n</yakaai_skills>"}