Full Code of cloudwego/hertz for AI

main 925126d9ae0d cached
450 files
2.5 MB
688.4k tokens
4647 symbols
1 requests
Download .txt
Showing preview only (2,744K chars total). Download the full file or copy to clipboard to get everything.
Repository: cloudwego/hertz
Branch: main
Commit: 925126d9ae0d
Files: 450
Total size: 2.5 MB

Directory structure:
gitextract_i3d5wkwv/

├── .codecov.yml
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── question.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── labels.json
│   └── workflows/
│       ├── cmd-tests.yml
│       ├── invalid_question.yml
│       ├── labeler.yml
│       ├── pr-check.yml
│       ├── unit-tests.yml
│       └── vulncheck.yml
├── .gitignore
├── .golangci.yaml
├── .licenserc.yaml
├── .typos.toml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── NOTICE
├── README.md
├── README_cn.md
├── ROADMAP.md
├── cmd/
│   └── hz/
│       ├── app/
│       │   └── app.go
│       ├── config/
│       │   ├── argument.go
│       │   └── cmd.go
│       ├── doc.go
│       ├── generator/
│       │   ├── client.go
│       │   ├── custom_files.go
│       │   ├── file.go
│       │   ├── handler.go
│       │   ├── layout.go
│       │   ├── layout_tpl.go
│       │   ├── model/
│       │   │   ├── define.go
│       │   │   ├── expr.go
│       │   │   ├── golang/
│       │   │   │   ├── constant.go
│       │   │   │   ├── enum.go
│       │   │   │   ├── file.go
│       │   │   │   ├── function.go
│       │   │   │   ├── init.go
│       │   │   │   ├── oneof.go
│       │   │   │   ├── struct.go
│       │   │   │   ├── typedef.go
│       │   │   │   └── variable.go
│       │   │   └── model.go
│       │   ├── model.go
│       │   ├── model_test.go
│       │   ├── package.go
│       │   ├── package_tpl.go
│       │   ├── router.go
│       │   ├── router_test.go
│       │   ├── template.go
│       │   └── template_funcs.go
│       ├── go.mod
│       ├── go.sum
│       ├── main.go
│       ├── meta/
│       │   ├── const.go
│       │   ├── manifest.go
│       │   └── manifest_test.go
│       ├── protobuf/
│       │   ├── api/
│       │   │   ├── api.pb.go
│       │   │   └── api.proto
│       │   ├── ast.go
│       │   ├── plugin.go
│       │   ├── plugin_stubs.go
│       │   ├── plugin_test.go
│       │   ├── resolver.go
│       │   ├── tag_test.go
│       │   ├── tags.go
│       │   └── test_data/
│       │       ├── protobuf_tag_test.out
│       │       └── test_tag.proto
│       ├── test_hz_unix.sh
│       ├── test_hz_windows.sh
│       ├── testdata/
│       │   ├── protobuf2/
│       │   │   ├── api.proto
│       │   │   ├── other/
│       │   │   │   ├── other.proto
│       │   │   │   └── other_base.proto
│       │   │   └── psm/
│       │   │       ├── base.proto
│       │   │       └── psm.proto
│       │   ├── protobuf3/
│       │   │   ├── api.proto
│       │   │   ├── other/
│       │   │   │   ├── other.proto
│       │   │   │   └── other_base.proto
│       │   │   └── psm/
│       │   │       ├── base.proto
│       │   │       └── psm.proto
│       │   └── thrift/
│       │       ├── common.thrift
│       │       ├── data/
│       │       │   ├── basic_data.thrift
│       │       │   └── data.thrift
│       │       └── psm.thrift
│       ├── thrift/
│       │   ├── ast.go
│       │   ├── plugin.go
│       │   ├── plugin_test.go
│       │   ├── resolver.go
│       │   ├── tag_test.go
│       │   ├── tags.go
│       │   ├── test_data/
│       │   │   ├── test_tag.thrift
│       │   │   └── thrift_tag_test.out
│       │   └── thriftgo_util.go
│       └── util/
│           ├── ast.go
│           ├── ast_test.go
│           ├── data.go
│           ├── data_test.go
│           ├── env.go
│           ├── fs.go
│           ├── logs/
│           │   ├── api.go
│           │   └── std.go
│           ├── string.go
│           ├── tool_install.go
│           └── tool_install_test.go
├── examples/
│   ├── html_rendering/
│   │   ├── index.tmpl
│   │   ├── main.go
│   │   └── template.html
│   └── standard/
│       └── main.go
├── go.mod
├── go.sum
├── internal/
│   ├── bytesconv/
│   │   ├── bytesconv.go
│   │   ├── bytesconv_32.go
│   │   ├── bytesconv_32_test.go
│   │   ├── bytesconv_64.go
│   │   ├── bytesconv_64_test.go
│   │   ├── bytesconv_table.go
│   │   ├── bytesconv_table_gen.go
│   │   ├── bytesconv_test.go
│   │   ├── bytesconv_timing_test.go
│   │   ├── doc.go
│   │   └── errors.go
│   ├── bytestr/
│   │   └── bytes.go
│   ├── nocopy/
│   │   └── nocopy.go
│   ├── stats/
│   │   ├── stats_util.go
│   │   ├── stats_util_test.go
│   │   ├── tracer.go
│   │   └── tracer_test.go
│   ├── tagexpr/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── example_test.go
│   │   ├── expr.go
│   │   ├── expr_test.go
│   │   ├── handler.go
│   │   ├── selector.go
│   │   ├── selector_test.go
│   │   ├── spec_func.go
│   │   ├── spec_func_test.go
│   │   ├── spec_operand.go
│   │   ├── spec_operator.go
│   │   ├── spec_range.go
│   │   ├── spec_range_test.go
│   │   ├── spec_selector.go
│   │   ├── spec_test.go
│   │   ├── tagexpr.go
│   │   ├── tagexpr_test.go
│   │   ├── tagparser.go
│   │   ├── tagparser_test.go
│   │   ├── utils.go
│   │   └── validator/
│   │       ├── README.md
│   │       ├── default.go
│   │       ├── example_test.go
│   │       ├── func.go
│   │       ├── validator.go
│   │       └── validator_test.go
│   ├── test/
│   │   └── mock/
│   │       └── binder/
│   │           ├── binder.go
│   │           └── binder_test.go
│   └── testutils/
│       ├── testutils.go
│       └── testutils_test.go
├── licenses/
│   ├── LICENSE-echo.txt
│   ├── LICENSE-fasthttp.txt
│   ├── LICENSE-fsnotify
│   ├── LICENSE-gin.txt
│   ├── LICENSE-go-version.txt
│   ├── LICENSE-protobuf.txt
│   ├── LICENSE-protoreflect.txt
│   ├── LICENSE-sprig.txt
│   └── LICENSE-yaml.txt
├── pkg/
│   ├── app/
│   │   ├── client/
│   │   │   ├── client.go
│   │   │   ├── client_test.go
│   │   │   ├── client_unix_test.go
│   │   │   ├── client_windows_test.go
│   │   │   ├── discovery/
│   │   │   │   ├── discovery.go
│   │   │   │   └── discovery_test.go
│   │   │   ├── loadbalance/
│   │   │   │   ├── lbcache.go
│   │   │   │   ├── lbcache_test.go
│   │   │   │   ├── loadbalance.go
│   │   │   │   ├── weight_random.go
│   │   │   │   └── weight_random_test.go
│   │   │   ├── middleware.go
│   │   │   ├── middleware_test.go
│   │   │   ├── option.go
│   │   │   ├── option_test.go
│   │   │   └── retry/
│   │   │       ├── option.go
│   │   │       ├── retry.go
│   │   │       └── retry_test.go
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── fs.go
│   │   ├── fs_test.go
│   │   ├── middlewares/
│   │   │   ├── client/
│   │   │   │   └── sd/
│   │   │   │       ├── discovery.go
│   │   │   │       ├── discovery_test.go
│   │   │   │       ├── options.go
│   │   │   │       └── options_test.go
│   │   │   └── server/
│   │   │       ├── basic_auth/
│   │   │       │   ├── basic_auth.go
│   │   │       │   ├── basic_auth_test.go
│   │   │       │   └── doc.go
│   │   │       └── recovery/
│   │   │           ├── option.go
│   │   │           ├── option_test.go
│   │   │           ├── recovery.go
│   │   │           └── recovery_test.go
│   │   └── server/
│   │       ├── binding/
│   │       │   ├── binder.go
│   │       │   ├── binder_test.go
│   │       │   ├── config.go
│   │       │   ├── default.go
│   │       │   ├── internal/
│   │       │   │   └── decoder/
│   │       │   │       ├── base_type_decoder.go
│   │       │   │       ├── customized_type_decoder.go
│   │       │   │       ├── decoder.go
│   │       │   │       ├── getter.go
│   │       │   │       ├── gjson_required.go
│   │       │   │       ├── map_type_decoder.go
│   │       │   │       ├── multipart_file_decoder.go
│   │       │   │       ├── reflect.go
│   │       │   │       ├── slice_getter.go
│   │       │   │       ├── slice_type_decoder.go
│   │       │   │       ├── sonic_required.go
│   │       │   │       ├── struct_type_decoder.go
│   │       │   │       ├── tag.go
│   │       │   │       ├── text_decoder.go
│   │       │   │       ├── util.go
│   │       │   │       └── util_test.go
│   │       │   ├── reflect.go
│   │       │   ├── reflect_internal_test.go
│   │       │   ├── reflect_test.go
│   │       │   ├── tagexpr_bind_test.go
│   │       │   ├── testdata/
│   │       │   │   ├── hello.pb.go
│   │       │   │   └── hello.proto
│   │       │   ├── validator.go
│   │       │   └── validator_test.go
│   │       ├── hertz.go
│   │       ├── hertz_test.go
│   │       ├── hertz_unix_test.go
│   │       ├── mocks_test.go
│   │       ├── option.go
│   │       ├── option_test.go
│   │       ├── registry/
│   │       │   ├── registry.go
│   │       │   └── registry_test.go
│   │       ├── render/
│   │       │   ├── data.go
│   │       │   ├── doc.go
│   │       │   ├── html.go
│   │       │   ├── html_test.go
│   │       │   ├── json.go
│   │       │   ├── json_test.go
│   │       │   ├── protobuf.go
│   │       │   ├── render.go
│   │       │   ├── render_test.go
│   │       │   ├── text.go
│   │       │   └── xml.go
│   │       └── server_bench_test.go
│   ├── common/
│   │   ├── adaptor/
│   │   │   ├── handler.go
│   │   │   ├── handler_test.go
│   │   │   ├── request.go
│   │   │   ├── request_test.go
│   │   │   ├── response.go
│   │   │   ├── utils.go
│   │   │   └── utils_test.go
│   │   ├── bytebufferpool/
│   │   │   ├── bytebuffer.go
│   │   │   ├── bytebuffer_test.go
│   │   │   ├── doc.go
│   │   │   ├── pool.go
│   │   │   └── pool_test.go
│   │   ├── compress/
│   │   │   ├── compress.go
│   │   │   ├── compress_test.go
│   │   │   └── doc.go
│   │   ├── config/
│   │   │   ├── client_option.go
│   │   │   ├── client_option_test.go
│   │   │   ├── option.go
│   │   │   ├── option_test.go
│   │   │   ├── request_option.go
│   │   │   └── request_option_test.go
│   │   ├── errors/
│   │   │   ├── errors.go
│   │   │   └── errors_test.go
│   │   ├── hlog/
│   │   │   ├── consts.go
│   │   │   ├── default.go
│   │   │   ├── default_test.go
│   │   │   ├── hlog.go
│   │   │   ├── hlog_test.go
│   │   │   ├── log.go
│   │   │   ├── system.go
│   │   │   └── system_test.go
│   │   ├── json/
│   │   │   ├── sonic.go
│   │   │   └── std.go
│   │   ├── stackless/
│   │   │   ├── doc.go
│   │   │   ├── func.go
│   │   │   ├── func_test.go
│   │   │   ├── func_timing_test.go
│   │   │   ├── writer.go
│   │   │   └── writer_test.go
│   │   ├── test/
│   │   │   ├── assert/
│   │   │   │   ├── assert.go
│   │   │   │   └── assert_test.go
│   │   │   └── mock/
│   │   │       ├── body_data.go
│   │   │       ├── body_data_test.go
│   │   │       ├── network.go
│   │   │       ├── network_test.go
│   │   │       ├── reader.go
│   │   │       ├── reader_test.go
│   │   │       ├── writer.go
│   │   │       └── writer_test.go
│   │   ├── testdata/
│   │   │   ├── conf/
│   │   │   │   └── p_s_m.yaml
│   │   │   ├── proto/
│   │   │   │   ├── test.pb.go
│   │   │   │   └── test.proto
│   │   │   ├── template/
│   │   │   │   ├── htmltemplate.html
│   │   │   │   └── index.tmpl
│   │   │   └── test.txt
│   │   ├── timer/
│   │   │   ├── doc.go
│   │   │   ├── timer.go
│   │   │   └── timer_test.go
│   │   ├── tracer/
│   │   │   ├── stats/
│   │   │   │   ├── event.go
│   │   │   │   ├── event_test.go
│   │   │   │   └── status.go
│   │   │   ├── traceinfo/
│   │   │   │   ├── httpstats.go
│   │   │   │   ├── interface.go
│   │   │   │   └── traceinfo.go
│   │   │   └── tracer.go
│   │   ├── ut/
│   │   │   ├── context.go
│   │   │   ├── context_test.go
│   │   │   ├── request.go
│   │   │   ├── request_test.go
│   │   │   ├── response.go
│   │   │   └── response_test.go
│   │   └── utils/
│   │       ├── bufpool.go
│   │       ├── chunk.go
│   │       ├── chunk_test.go
│   │       ├── env.go
│   │       ├── ioutil.go
│   │       ├── ioutil_test.go
│   │       ├── netaddr.go
│   │       ├── netaddr_test.go
│   │       ├── network.go
│   │       ├── network_test.go
│   │       ├── path.go
│   │       ├── path_test.go
│   │       ├── utils.go
│   │       └── utils_test.go
│   ├── network/
│   │   ├── connection.go
│   │   ├── dialer/
│   │   │   ├── dialer.go
│   │   │   ├── dialer_test.go
│   │   │   └── netpoll.go
│   │   ├── dialer.go
│   │   ├── netpoll/
│   │   │   ├── connection.go
│   │   │   ├── connection_test.go
│   │   │   ├── dial.go
│   │   │   ├── dial_test.go
│   │   │   ├── transport.go
│   │   │   └── transport_test.go
│   │   ├── standard/
│   │   │   ├── connection.go
│   │   │   ├── connection_test.go
│   │   │   ├── dial.go
│   │   │   ├── dial_test.go
│   │   │   ├── transport.go
│   │   │   ├── transport_test.go
│   │   │   └── unix_test.go
│   │   ├── transport.go
│   │   ├── utils.go
│   │   ├── utils_test.go
│   │   ├── version.go
│   │   ├── writer.go
│   │   └── writer_test.go
│   ├── protocol/
│   │   ├── args.go
│   │   ├── args_test.go
│   │   ├── client/
│   │   │   ├── client.go
│   │   │   └── client_test.go
│   │   ├── consts/
│   │   │   ├── default.go
│   │   │   ├── fs.go
│   │   │   ├── headers.go
│   │   │   ├── http2.go
│   │   │   ├── methods.go
│   │   │   └── status.go
│   │   ├── cookie.go
│   │   ├── cookie_test.go
│   │   ├── doc.go
│   │   ├── header.go
│   │   ├── header_test.go
│   │   ├── header_timing_test.go
│   │   ├── http1/
│   │   │   ├── client.go
│   │   │   ├── client_test.go
│   │   │   ├── client_unix_test.go
│   │   │   ├── ext/
│   │   │   │   ├── common.go
│   │   │   │   ├── common_test.go
│   │   │   │   ├── error.go
│   │   │   │   ├── headerscanner.go
│   │   │   │   ├── headerscanner_test.go
│   │   │   │   ├── stream.go
│   │   │   │   └── stream_test.go
│   │   │   ├── factory/
│   │   │   │   ├── client.go
│   │   │   │   └── server.go
│   │   │   ├── proxy/
│   │   │   │   └── proxy.go
│   │   │   ├── req/
│   │   │   │   ├── header.go
│   │   │   │   ├── header_test.go
│   │   │   │   ├── request.go
│   │   │   │   └── request_test.go
│   │   │   ├── resp/
│   │   │   │   ├── header.go
│   │   │   │   ├── header_test.go
│   │   │   │   ├── response.go
│   │   │   │   ├── response_test.go
│   │   │   │   ├── writer.go
│   │   │   │   └── writer_test.go
│   │   │   ├── server.go
│   │   │   ├── server_test.go
│   │   │   └── server_timing_test.go
│   │   ├── multipart.go
│   │   ├── multipart_test.go
│   │   ├── request.go
│   │   ├── request_test.go
│   │   ├── response.go
│   │   ├── response_test.go
│   │   ├── server.go
│   │   ├── sse/
│   │   │   ├── event.go
│   │   │   ├── event_test.go
│   │   │   ├── example_test.go
│   │   │   ├── reader.go
│   │   │   ├── reader_test.go
│   │   │   ├── request.go
│   │   │   ├── request_test.go
│   │   │   ├── utils.go
│   │   │   ├── utils_test.go
│   │   │   ├── writer.go
│   │   │   └── writer_test.go
│   │   ├── suite/
│   │   │   ├── client.go
│   │   │   └── server.go
│   │   ├── trailer.go
│   │   ├── trailer_test.go
│   │   ├── uri.go
│   │   ├── uri_test.go
│   │   ├── uri_timing_test.go
│   │   ├── uri_unix.go
│   │   ├── uri_unix_test.go
│   │   ├── uri_windows.go
│   │   └── uri_windows_test.go
│   └── route/
│       ├── consts/
│       │   └── const.go
│       ├── engine.go
│       ├── engine_test.go
│       ├── netpoll.go
│       ├── param/
│       │   └── param.go
│       ├── routergroup.go
│       ├── routergroup_test.go
│       ├── routes_test.go
│       ├── routes_timing_test.go
│       ├── tree.go
│       └── tree_test.go
├── scripts/
│   ├── .utils/
│   │   ├── check_go_mod.sh
│   │   ├── check_version.sh
│   │   └── funcs.sh
│   ├── release-hotfix.sh
│   └── release.sh
└── version.go

================================================
FILE CONTENTS
================================================

================================================
FILE: .codecov.yml
================================================
github_checks:
  annotations: false

ignore:
  - "images/.*"
  - "examples/.*"
  - "cmd/.*"

coverage:
  status:
    project:
      default:
        # pass if coverage drops by no more than 0.05%
        # this is possibly caused by unstable coverage.
        threshold: 0.05%
    patch:
      default:
        target: 80%


================================================
FILE: .gitattributes
================================================
# Handle line endings automatically for files detected as text
# and leave all files detected as binary untouched.
* text=auto eol=lf

# Force bash scripts to always use LF line endings so that if a repo is accessed
# in Unix via a file share from Windows, the scripts will work.
*.sh text eol=lf


================================================
FILE: .github/CODEOWNERS
================================================
# For more information, please refer to https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

*   @cloudwego/hertz-reviewers @cloudwego/hertz-approvers @cloudwego/hertz-maintainers


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**

A clear and concise description of what the bug is.

**To Reproduce**

Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**

A clear and concise description of what you expected to happen.

**Screenshots**

If applicable, add screenshots to help explain your problem.

**Hertz version:**

Please provide the version of Hertz you are using.

**Environment:**

The output of `go env`.

**Additional context**

Add any other context about the problem here.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**

A clear and concise description of what you want to happen.

**Describe alternatives you've considered**

A clear and concise description of any alternative solutions or features you've considered.

**Additional context**

Add any other context or screenshots about the feature request here.


================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Ask a question, so we can help you easily
title: ''
labels: ''
assignees: ''

---

**Describe the Question**

A clear and concise description of what the question is.

**Reproducible Code**

Please construct a minimum complete and reproducible example for us to get the same error. And tell us how to reproduce it like how you send a request or send what request.

**Expected behavior**

A clear and concise description of what you expected to happen.

**Screenshots**

If applicable, add screenshots to help explain your question.

**Hertz version:**

Please provide the version of Hertz you are using.

**Environment:**

The output of `go env`.

**Additional context**

Add any other context about the question here.


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
#### What type of PR is this?
<!--
Add one of the following kinds:

build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
docs: Documentation only changes
feat: A new feature
optimize: A new optimization
fix: A bug fix
perf: A code change that improves performance
refactor: A code change that neither fixes a bug nor adds a feature
style: Changes that do not affect the meaning of the code (white space, formatting, missing semi-colons, etc)
test: Adding missing tests or correcting existing tests
chore: Changes to the build process or auxiliary tools and libraries such as documentation generation
-->

#### Check the PR title.
<!--
The description of the title will be attached in Release Notes, 
so please describe it from user-oriented, what this PR does / why we need it.
Please check your PR title with the below requirements:
-->
- [ ] This PR title match the format: \<type\>(optional scope): \<description\>
- [ ] The description of this PR title is user-oriented and clear enough for others to understand.
- [ ] Attach the PR updating the user documentation if the current PR requires user awareness at the usage level. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)


#### (Optional) Translate the PR title into Chinese.


#### (Optional) More detailed description for this PR(en: English/zh: Chinese).
<!--
Provide more detailed info for review(e.g., it's recommended to provide perf data if this is a perf type PR).
-->
en:
zh(optional):

#### (Optional) Which issue(s) this PR fixes:
<!--
Automatically closes linked issue when PR is merged.
Eg: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->

#### (Optional) The PR that updates user documentation:
<!--
If the current PR requires user awareness at the usage level, please submit a PR to update user docs. [User docs repo](https://github.com/cloudwego/cloudwego.github.io)
-->

================================================
FILE: .github/labels.json
================================================
{
  "labels": {
    "invalid_issue": {
      "name": "invalid issue",
      "colour": "#CF2E1F",
      "description": "invalid issue (not related to Hertz or described in document or not enough information provided)"
    }
  },
  "issue": {
    "invalid_issue": {
      "requires": 3,
      "conditions": [
        {
          "type": "descriptionMatches",
          "pattern": "/^((?!Describe the bug).)*$/is"
        },
        {
          "type": "descriptionMatches",
          "pattern": "/^((?!Is your feature request related to a problem\\? Please describe).)*$/is"
        },
        {
          "type": "descriptionMatches",
          "pattern": "/^((?!Describe the Question).)*$/is"
        }
      ]
    }
  }
}


================================================
FILE: .github/workflows/cmd-tests.yml
================================================
name: Cmd Tests

on:
  push:
    paths:
      - 'cmd/**'
  pull_request:
    paths:
      - 'cmd/**'

jobs:
  hz-test-unix:
    runs-on: [ self-hosted, Linux, X64 ]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          cache: false # don't use cache for self-hosted runners

      - name: Setup Environment
        run: |
          echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
          echo "$(go env GOPATH)/bin" >> $GITHUB_PATH

      - name: Hz Test
        run: |
          cd cmd/hz
          sh test_hz_unix.sh


  hz-test-windows:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable

      - name: Install Protobuf
        shell: pwsh
        run: |
          Invoke-WebRequest https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protoc-3.19.4-win64.zip -OutFile protoc-3.19.4-win64.zip
          Expand-Archive protoc-3.19.4-win64.zip -DestinationPath protoc-3.19.4-win64
          $GOPATH=go env GOPATH
          Copy-Item -Path protoc-3.19.4-win64\bin\protoc.exe -Destination $GOPATH\bin
          Copy-Item -Path protoc-3.19.4-win64\include\* -Destination cmd\hz\testdata\include\google -Recurse
          protoc --version

      - name: Hz Test
        run: |
          cd cmd/hz
          sh test_hz_windows.sh


================================================
FILE: .github/workflows/invalid_question.yml
================================================
name: "Close Invalid Issue"
on:
  schedule:
    - cron: "0 0,8,16 * * *"

permissions:
  contents: read

jobs:
  stale:
    permissions:
      issues: write
    runs-on: ubuntu-latest
    env:
      ACTIONS_STEP_DEBUG: true
    steps:
      - name: Close Stale Issues
        uses: actions/stale@v6
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          stale-issue-message: "This issue has been marked as invalid question, please give more information by following the `issue` template. The issue will be closed in 1 days if no further activity occurs."
          stale-issue-label: "stale"
          days-before-stale: 0
          days-before-close: 1
          remove-stale-when-updated: true
          only-labels: "invalid issue"


================================================
FILE: .github/workflows/labeler.yml
================================================
name: "Labeler"
on:
  issues:
    types: [ opened, edited, reopened ]

jobs:
  triage:
    if: contains(github.event.issue.labels.*.name, 'invalid issue') || join(github.event.issue.labels) == ''
    runs-on: ubuntu-latest
    name: Label issues
    steps:
      - name: check out
        uses: actions/checkout@v3

      - name: labeler
        uses: jbinda/super-labeler-action@develop
        with:
          GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"


================================================
FILE: .github/workflows/pr-check.yml
================================================
name: Pull Request Check

on: [ pull_request ]

jobs:
  compliant:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check License Header
        uses: apache/skywalking-eyes/header@v0.4.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Check Spell
        uses: crate-ci/typos@master

  lint:
    runs-on: [ self-hosted, Linux, X64 ]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          cache: false # don't use cache for self-hosted runners

      - name: Golangci Lint
        # https://golangci-lint.run/
        uses: golangci/golangci-lint-action@v8
        with:
          version: latest
          only-new-issues: true


================================================
FILE: .github/workflows/unit-tests.yml
================================================
name: Unit Tests

on: [push, pull_request]

jobs:
  unit-test-x64:
    strategy:
      matrix:
        version: ["1.19", "1.20", oldstable, stable]
    runs-on: [self-hosted, Linux, X64]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.version }}
          cache: false # don't use cache for self-hosted runners

      - name: Unit Test
        run: go test -race ./...

  unit-test-arm64:
    strategy:
      matrix:
        version: ["1.19", "1.20", oldstable, stable]
    runs-on: [self-hosted, ARM64]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: ${{ matrix.version }}
          cache: false # don't use cache for self-hosted runners

      - name: Unit Test
        run: go test -race ./...


  unit-test-no-netpoll:
    runs-on: [self-hosted, Linux]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          cache: false # don't use cache for self-hosted runners

      - name: Unit Test
        run: HERTZ_NO_NETPOLL=1 go test -race ./...

  ut-windows:
    runs-on: [self-hosted, Windows]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          cache: false # don't use cache for self-hosted runners

      - name: Unit Test
        run: go test -race ./...

  code-cov:
    runs-on: [self-hosted, Linux, X64]
    steps:
      - uses: actions/checkout@v4
      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          cache: false # don't use cache for self-hosted runners

      - name: Unit Test
        run: go test -coverpkg=./... -coverprofile=coverage.txt ./...

      - uses: codecov/codecov-action@v5
        with:
          fail_ci_if_error: true


================================================
FILE: .github/workflows/vulncheck.yml
================================================
name: Run govulncheck

on:
  push:
    branches:
      - develop
    paths:
      - "**"
      - "!**.md"
  pull_request:
    paths:
      - "**"
      - "!**.md"

jobs:
  vulncheck-check:
    runs-on: ubuntu-latest
    env:
      GO111MODULE: on
    steps:
      - name: Fetch Repository
        uses: actions/checkout@v4

      - name: Install Go
        uses: actions/setup-go@v5
        with:
          go-version: stable
          check-latest: true
          cache: false

      - name: Install Govulncheck
        run: go install golang.org/x/vuln/cmd/govulncheck@latest

      - name: Run Govulncheck
        run: govulncheck ./...


================================================
FILE: .gitignore
================================================
.idea
.vscode
pkg/app/fs.go.hertz.gz
coverage.txt
coverage.out
# OSX trash
.DS_Store

# test benchmark tmp output
cpu.out
mem.out
*.test


================================================
FILE: .golangci.yaml
================================================
version: "2"
linters:
  default: none
  enable:
    - govet
    - ineffassign
    - staticcheck
    - unconvert
    - unused
  settings:
    staticcheck:
      checks:
        - all
        - -SA5008
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
      - legacy
      - std-error-handling
    paths:
      - third_party$
      - builtin$
      - examples$
formatters:
  enable:
    - goimports
  exclusions:
    generated: lax
    paths:
      - third_party$
      - builtin$
      - examples$


================================================
FILE: .licenserc.yaml
================================================
header:
  license:
    spdx-id: Apache-2.0
    copyright-owner: CloudWeGo Authors

  paths:
    - '**/*.go'
    - '**/*.s'

  paths-ignore:
    - pkg/common/testdata/**
    - cmd/hz/protobuf/api

  comment: on-failure


================================================
FILE: .typos.toml
================================================
# Typo check: https://github.com/crate-ci/typos

[files]
extend-exclude = ["go.mod", "go.sum"]

[default.extend-identifiers]
pn = "pn" # packageName in cmd/hz
ConnTLSer = "ConnTLSer"
OPTIO = "OPTIO" # b[:5] for OPTION

[default.extend-words]
typ = "typ"   # type
Flate = "Flate" # flate algorithm

[default]
# Only ignore these exact "weird-case" examples used to demonstrate case-insensitive matching.
extend-ignore-re = [
  # Comments showing header normalization examples:
  "\\bcONTENT-lenGTH\\b",
  # Test intentionally using odd case:
  "\\bconnecTION\\b",
]


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
conduct@cloudwego.io.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# How to Contribute

## Your First Pull Request
We use github for our codebase. You can start by reading [How To Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).

## Without Semantic Versioning
We keep the stable code in branch `main` like `golang.org/x`. Development base on branch `develop`. And we promise the **Forward Compatibility** by adding new package directory with suffix `v2/v3` when code has break changes.

## Branch Organization
We use [git-flow](https://nvie.com/posts/a-successful-git-branching-model/) as our branch organization, as known as [FDD](https://en.wikipedia.org/wiki/Feature-driven_development)

## Bugs
### 1. How to Find Known Issues
We are using [Github Issues](https://github.com/cloudwego/hertz/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesn’t already exist.

### 2. Reporting New Issues
Providing a reduced test code is a recommended way for reporting issues. Then can placed in:
- Just in issues
- [Golang Playground](https://play.golang.org/)

### 3. Security Bugs
Please do not report the safe disclosure of bugs to public issues. Contact us by [Support Email](mailto:conduct@cloudwego.io)

## How to Get in Touch
- [Email](mailto:conduct@cloudwego.io)

## Submit a Pull Request
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/cloudwego/hertz/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate existing efforts.
2. Please submit an issue instead of PR if you have a better suggestion for format tools. We won't accept a lot of file changes directly without issue statement and assignment.
3. Be sure that the issue describes the problem you're fixing, or documents the design for the feature you'd like to add. Before we accepting your work, we need to conduct some checks and evaluations. So, It will be better if you can discuss the design with us.
4. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the cloudwego/hertz repo.
5. In your forked repository, make your changes in a new git branch:
    ```
    git checkout -b my-fix-branch develop
    ```
6. Create your patch, including appropriate test cases.
7. Follow our [Style Guides](#code-style-guides).
8. Commit your changes using a descriptive commit message that follows [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit).
   Adherence to these conventions is necessary because release notes are automatically generated from these messages.
9. Push your branch to GitHub:
    ```
    git push origin my-fix-branch
    ```
10. In GitHub, send a pull request to `hertz:develop` with a clear and unambiguous title.

## Contribution Prerequisites
- Our development environment keeps up with [Go Official](https://golang.org/project/).
- You need fully checking with lint tools before submit your pull request. [gofmt](https://golang.org/pkg/cmd/gofmt/) and [golangci-lint](https://github.com/golangci/golangci-lint)
- You are familiar with [Github](https://github.com)
- Maybe you need familiar with [Actions](https://github.com/features/actions)(our default workflow tool).

## Code Style Guides

See [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).

Good resources:
- [Effective Go](https://golang.org/doc/effective_go)
- [Pingcap General advice](https://pingcap.github.io/style-guide/general.html)
- [Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md)


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
SHELL := /bin/bash

.PHONY: \
	help \
	coverage \
	vet \
	lint \
	fmt \
	version

all: imports fmt lint vet errors build

help:
	@echo 'Usage: make <OPTIONS> ... <TARGETS>'
	@echo ''
	@echo 'Available targets are:'
	@echo ''
	@echo '    help               Show this help screen.'
	@echo '    coverage           Report code tests coverage.'
	@echo '    vet                Run go vet.'
	@echo '    lint               Run golint.'
	@echo '    fmt                Run go fmt.'
	@echo '    version            Display Go version.'
	@echo ''
	@echo 'Targets run by default are: lint, vet.'
	@echo ''

print-%:
	@echo $* = $($*)

deps:
	go get golang.org/x/lint/golint

coverage:
	go test $(go list ./... | grep -v examples) -coverprofile coverage.txt ./...

vet:
	go vet ./...

lint: deps
	golint ./...

fmt:
	go install mvdan.cc/gofumpt@latest
	gofumpt -l -w -extra .

pre-dev:
	make pre-commit

pre-commit:
	bash script/pre-commit-hook

release: package-release sign-release

version:
	@go version

================================================
FILE: NOTICE
================================================
CloudWeGo
Copyright 2022 CloudWeGo Authors

Apache Thrift
Copyright (C) 2006 - 2019, The Apache Software Foundation

This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

================================================
FILE: README.md
================================================
# Hertz

English | [中文](README_cn.md)

[![Release](https://img.shields.io/github/v/release/cloudwego/hertz)](https://github.com/cloudwego/hertz/releases)
[![WebSite](https://img.shields.io/website?up_message=cloudwego&url=https%3A%2F%2Fwww.cloudwego.io%2F)](https://www.cloudwego.io/)
[![License](https://img.shields.io/github/license/cloudwego/hertz)](https://github.com/cloudwego/hertz/blob/main/LICENSE)
[![Go Report Card](https://goreportcard.com/badge/github.com/cloudwego/hertz)](https://goreportcard.com/report/github.com/cloudwego/hertz)
[![OpenIssue](https://img.shields.io/github/issues/cloudwego/hertz)](https://github.com/cloudwego/hertz/issues)
[![ClosedIssue](https://img.shields.io/github/issues-closed/cloudwego/hertz)](https://github.com/cloudwego/hertz/issues?q=is%3Aissue+is%3Aclosed)
![Stars](https://img.shields.io/github/stars/cloudwego/hertz)
![Forks](https://img.shields.io/github/forks/cloudwego/hertz)


Hertz [həːts] is a high-usability, high-performance and high-extensibility Golang HTTP framework that helps developers build microservices. It was originally a fork of [fasthttp](https://github.com/valyala/fasthttp) and inspired by [gin](https://github.com/gin-gonic/gin), [echo](https://github.com/labstack/echo) and combined with the internal requirements in ByteDance. At present, it has been widely used inside ByteDance. Nowadays, more and more microservices use Golang. If you have requirements for microservice performance and hope that the framework can fully meet the internal customizable requirements, Hertz will be a good choice.
## Basic Features
- High usability

  During the development process, it is often more important to write the correct code quickly. Therefore, in the iterative process of Hertz, we actively listen to users' opinions and continue to polish the framework, hoping to provide users with a better user experience and help users write correct code faster.
- High performance

  Hertz uses the self-developed high-performance network library Netpoll by default. In some special scenarios, compared to Go Net, Hertz has certain advantages in QPS and time delay. For performance data, please refer to the Echo data in the figure below.

  Comparison of four frameworks:
  ![Performance](images/performance-4.png)
  Comparison of three frameworks:
  ![Performance](images/performance-3.png)
  For detailed performance data, please refer to [hertz-benchmark](https://github.com/cloudwego/hertz-benchmark).
- High extensibility

  Hertz adopts a layered design, providing more interfaces and default extension implementations. Users can also extend by themselves. At the same time, thanks to the layered design of the framework, the extensibility of the framework will be much greater. At present, only stable capabilities are open-sourced to the community. More planning refers to [RoadMap](ROADMAP.md).
- Multi-protocol support

  The Hertz framework provides HTTP/1.1 and ALPN protocol support natively. In addition, due to the layered design, Hertz even supports custom build protocol resolution logic to meet any needs of protocol layer extensions.
- Network layer switching capability

  Hertz implements the function to switch between Netpoll and Go Net on demand. Users can choose the appropriate network library for different scenarios. And Hertz also supports the extension of network library in the form of plug-ins.
## Documentation
### [Getting Started](https://www.cloudwego.io/docs/hertz/getting-started/)
### Example
  The Hertz-Examples repository provides code out of the box. [more](https://www.cloudwego.io/zh/docs/hertz/tutorials/example/)
### Basic Features
  Contains introduction and use of general middleware, context selection, data binding, data rendering, direct access, logging, error handling. [more](https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/)
### Observability
  Contains instrumentation, logging, tracing. [more](https://www.cloudwego.io/docs/hertz/tutorials/observability/)
### Framework Extension
  Contains network library extensions, protocol extensions, logger extensions, monitoring extensions. [more](https://www.cloudwego.io/zh/docs/hertz/tutorials/framework-exten/)
### Reference
  Framework configurable items list. [more](https://www.cloudwego.io/zh/docs/hertz/reference/)
### FAQ
  Frequently Asked Questions. [more](https://www.cloudwego.io/zh/docs/hertz/faq/)
## Performance
  Performance testing can only provide a relative reference. In production, there are many factors that can affect actual performance.
  We provide the [hertz-benchmark](https://github.com/cloudwego/hertz-benchmark) project to track and compare the performance of Hertz and other frameworks in different situations for reference.
## Related Projects
- [Netpoll](https://github.com/cloudwego/netpoll): A high-performance network library. Hertz integrated by default.
- [Example](https://github.com/cloudwego/hertz-examples): Use examples of Hertz.
## Extensions
[Hertz-contrib](https://github.com/hertz-contrib) is a partial extension library of Hertz, which users can integrate into Hertz through options according to their needs, built and maintained by the community.

| Extensions                                                                                         | Description                                                                                                                                                                    |
|----------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Autotls](https://github.com/hertz-contrib/autotls)                                                | Make Hertz support Let's Encrypt.                                                                                                                                              |
| [Http2](https://github.com/hertz-contrib/http2)                                                    | HTTP2 support for Hertz.                                                                                                                                                       |
| [Websocket](https://github.com/hertz-contrib/websocket)                                            | Enable Hertz to support the Websocket protocol.                                                                                                                                |
| [Etag](https://github.com/hertz-contrib/etag)                                                      | Support ETag (or entity tag) HTTP response header for Hertz.                                                                                                                   |
| [Limiter](https://github.com/hertz-contrib/limiter)                                                | Provides a current limiter based on the bbr algorithm.                                                                                                                         |
| [Monitor-prometheus](https://github.com/hertz-contrib/monitor-prometheus)                          | Provides service monitoring based on Prometheus.                                                                                                                               |
| [Obs-opentelemetry](https://github.com/hertz-contrib/obs-opentelemetry)                            | Hertz's Opentelemetry extension that supports Metric, Logger, Tracing and works out of the box.                                                                                |
| [Opensergo](https://github.com/hertz-contrib/opensergo)                                            | The Opensergo extension.                                                                                                                                                       |
| [Pprof](https://github.com/hertz-contrib/pprof)                                                    | Extension for Hertz integration with Pprof.                                                                                                                                    |
| [Registry](https://github.com/hertz-contrib/registry)                                              | Provides service registry and discovery functions. So far, the supported service discovery extensions are nacos, consul, etcd, eureka, polaris, servicecomb, zookeeper, redis. |
| [Sentry](https://github.com/hertz-contrib/hertzsentry)                                             | Sentry extension provides some unified interfaces to help users perform real-time error monitoring.                                                                            |
| [Tracer](https://github.com/hertz-contrib/tracer)                                                  | Link tracing based on Opentracing.                                                                                                                                             |
| [Basicauth](https://github.com/cloudwego/hertz/tree/develop/pkg/app/middlewares/server/basic_auth) | Basicauth middleware can provide HTTP basic authentication.                                                                                                                    |
| [Jwt](https://github.com/hertz-contrib/jwt)                                                        | Jwt extension.                                                                                                                                                                 |
| [Keyauth](https://github.com/hertz-contrib/keyauth)                                                | Provides token-based authentication.                                                                                                                                           |
| [Requestid](https://github.com/hertz-contrib/requestid)                                            | Add request id in response.                                                                                                                                                    |
| [Sessions](https://github.com/hertz-contrib/sessions)                                              | Session middleware with multi-state store support.                                                                                                                             |
| [Casbin](https://github.com/hertz-contrib/casbin)                                                  | Supports various access control models by Casbin.                                                                                                                              |
| [Cors](https://github.com/hertz-contrib/cors)                                                      | Provides cross-domain resource sharing support.                                                                                                                                |
| [Csrf](https://github.com/hertz-contrib/csrf)                                                      | Csrf middleware is used to prevent cross-site request forgery attacks.                                                                                                         |
| [Secure](https://github.com/hertz-contrib/secure)                                                  | Secure middleware with multiple configuration items.                                                                                                                           |
| [Gzip](https://github.com/hertz-contrib/gzip)                                                      | A Gzip extension with multiple options.                                                                                                                                        |
| [I18n](https://github.com/hertz-contrib/i18n)                                                      | Helps translate Hertz programs into multi programming languages.                                                                                                               |
| [Lark](https://github.com/hertz-contrib/lark-hertz)                                                | Use hertz handle Lark/Feishu card message and event callback.                                                                                                                  |
| [Loadbalance](https://github.com/hertz-contrib/loadbalance)                                        | Provides load balancing algorithms for Hertz.                                                                                                                                  |
| [Logger](https://github.com/hertz-contrib/logger)                                                  | Logger extension for Hertz, which provides support for zap, logrus, zerologs logging frameworks.                                                                               |
| [Recovery](https://github.com/cloudwego/hertz/tree/develop/pkg/app/middlewares/server/recovery)    | Recovery middleware for Hertz.                                                                                                                                                 |
| [Reverseproxy](https://github.com/hertz-contrib/reverseproxy)                                      | Implement a reverse proxy.                                                                                                                                                     |
| [Swagger](https://github.com/hertz-contrib/swagger)                                                | Automatically generate RESTful API documentation with Swagger 2.0.                                                                                                             |
| [Cache](https://github.com/hertz-contrib/cache)                                                    | Hertz middleware for cache HTTP response with multi-backend support                                                                                                            |

## Blogs
- [ByteDance Practice on Go Network Library](https://www.cloudwego.io/blog/2020/05/24/bytedance-practices-on-go-network-library/)
- [Ultra-large-scale Enterprise-level Microservice HTTP Framework — Hertz is Officially Open Source!](https://www.cloudwego.io/zh/blog/2022/06/21/%E8%B6%85%E5%A4%A7%E8%A7%84%E6%A8%A1%E7%9A%84%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%BE%AE%E6%9C%8D%E5%8A%A1-http-%E6%A1%86%E6%9E%B6-hertz-%E6%AD%A3%E5%BC%8F%E5%BC%80%E6%BA%90/)
- [ByteDance Open Source Go HTTP Framework Hertz Design Practice](https://www.cloudwego.io/zh/blog/2022/06/21/%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8%E5%BC%80%E6%BA%90-go-http-%E6%A1%86%E6%9E%B6-hertz-%E8%AE%BE%E8%AE%A1%E5%AE%9E%E8%B7%B5/)
- [Help ByteDance Reduce Costs and Increase Efficiency, the Design Practice for Large-scale Enterprise-level HTTP Framework Hertz](https://www.cloudwego.io/zh/blog/2022/09/27/%E5%8A%A9%E5%8A%9B%E5%AD%97%E8%8A%82%E9%99%8D%E6%9C%AC%E5%A2%9E%E6%95%88%E5%A4%A7%E8%A7%84%E6%A8%A1%E4%BC%81%E4%B8%9A%E7%BA%A7-http-%E6%A1%86%E6%9E%B6-hertz-%E8%AE%BE%E8%AE%A1%E5%AE%9E%E8%B7%B5/)
- [Getting Started with Hertz: Performance Testing Guide](https://www.cloudwego.io/blog/2023/02/24/getting-started-with-hertz-performance-testing-guide/)

## Contributing

[Contributing](https://github.com/cloudwego/hertz/blob/main/CONTRIBUTING.md)
## RoadMap
[Hertz RoadMap](ROADMAP.md)
## License
Hertz is distributed under the [Apache License, version 2.0](https://github.com/cloudwego/hertz/blob/main/LICENSE). The licenses of third party dependencies of Hertz are explained [here](https://github.com/cloudwego/hertz/blob/main/licenses).
## Community
- Email: [conduct@cloudwego.io](conduct@cloudwego.io)
- How to become a member: [COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md)
- Issues: [Issues](https://github.com/cloudwego/hertz/issues)
- Slack: Join our CloudWeGo community [Slack Channel](https://join.slack.com/t/cloudwego/shared_invite/zt-tmcbzewn-UjXMF3ZQsPhl7W3tEDZboA).
- Lark: Scan the QR code below with [Lark](https://www.larksuite.com/zh_cn/download) to join our CloudWeGo/hertz user group.

![LarkGroup](images/lark_group.png)

## Contributors
Thank you for your contribution to Hertz!

[![Contributors](https://contrib.rocks/image?repo=cloudwego/hertz)](https://github.com/cloudwego/hertz/graphs/contributors)
## Landscapes

<p align="center">
<img src="https://landscape.cncf.io/images/cncf-landscape-horizontal-color.svg" width="150"/>&nbsp;&nbsp;<img src="https://www.cncf.io/wp-content/uploads/2023/04/cncf-main-site-logo.svg" width="200"/>
<br/><br/>
CloudWeGo enriches the <a href="https://landscape.cncf.io/">CNCF CLOUD NATIVE Landscape</a>.
</p>


================================================
FILE: README_cn.md
================================================
# Hertz

[English](README.md) | 中文

[![Release](https://img.shields.io/github/v/release/cloudwego/hertz)](https://github.com/cloudwego/hertz/releases)
[![WebSite](https://img.shields.io/website?up_message=cloudwego&url=https%3A%2F%2Fwww.cloudwego.io%2F)](https://www.cloudwego.io/)
[![License](https://img.shields.io/github/license/cloudwego/hertz)](https://github.com/cloudwego/hertz/blob/main/LICENSE)
[![Go Report Card](https://goreportcard.com/badge/github.com/cloudwego/hertz)](https://goreportcard.com/report/github.com/cloudwego/hertz)
[![OpenIssue](https://img.shields.io/github/issues/cloudwego/hertz)](https://github.com/cloudwego/hertz/issues)
[![ClosedIssue](https://img.shields.io/github/issues-closed/cloudwego/hertz)](https://github.com/cloudwego/hertz/issues?q=is%3Aissue+is%3Aclosed)
![Stars](https://img.shields.io/github/stars/cloudwego/hertz)
![Forks](https://img.shields.io/github/forks/cloudwego/hertz)

Hertz[həːts] 是一个 Golang 微服务 HTTP 框架,最初fork自[fasthttp](https://github.com/valyala/fasthttp),并在设计时参考了其他开源框架[gin](https://github.com/gin-gonic/gin)、[echo](https://github.com/labstack/echo) 的优势,并结合字节跳动内部的需求,使其具有高易用性、高
性能、高扩展性等特点,目前在字节跳动内部已广泛使用。如今越来越多的微服务选择使用 Golang,如果对微服务性能有要求,又希望框架能够充分满足内部的可定制化需求,Hertz 会是一个不错的选择。

## 框架特点
- 高易用性

  在开发过程中,快速写出来正确的代码往往是更重要的。因此,在 Hertz 在迭代过程中,积极听取用户意见,持续打磨框架,希望为用户提供一个更好的使用体验,帮助用户更快的写出正确的代码。
- 高性能

  Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景相较于 go net,Hertz 在 QPS、时延上均具有一定优势。关于性能数据,可参考下图 Echo 数据。
  
  四个框架的对比:
  ![Performance](images/performance-4.png)
  三个框架的对比:
  ![Performance](images/performance-3.png)
  关于详细的性能数据,可参考 [hertz-benchmark](https://github.com/cloudwego/hertz-benchmark)。
- 高扩展性

  Hertz 采用了分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。同时得益于框架的分层设计,框架的扩展性也会大很多。目前仅将稳定的能力开源给社区,更多的规划参考 [RoadMap](ROADMAP.md)。
- 多协议支持

  Hertz 框架原生提供 HTTP/1.1 及 ALPN 协议支持。除此之外,由于分层设计,Hertz 甚至支持自定义构建协议解析逻辑,以满足协议层扩展的任意需求。
- 网络层切换能力

  Hertz 实现了 Netpoll 和 Golang 原生网络库 间按需切换能力,用户可以针对不同的场景选择合适的网络库,同时也支持以插件的方式为 Hertz 扩展网络库实现。
## 详细文档
### [快速开始](https://www.cloudwego.io/zh/docs/hertz/getting-started/)
### Example
  Hertz-Examples 仓库提供了开箱即用的代码,[详见](https://www.cloudwego.io/zh/docs/hertz/tutorials/example/)。
### 用户指南
### 基本特性
  包含通用中间件的介绍和使用,上下文选择,数据绑定,数据渲染,直连访问,日志,错误处理,[详见文档](https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/)
### 可观测性
  包含日志,链路追踪,埋点,[详见文档](https://www.cloudwego.io/zh/docs/hertz/tutorials/observability/)
### 框架扩展
  包含网络库扩展,协议扩展,日志扩展,监控扩展,服务注册与发现扩展,[详见文档](https://www.cloudwego.io/zh/docs/hertz/tutorials/framework-exten/)
### 参考
  框架可配置项一览,[详见文档](https://www.cloudwego.io/zh/docs/hertz/reference/)
### FAQ
  常见问题排查,[详见文档](https://www.cloudwego.io/zh/docs/hertz/faq/)
## 框架性能
  性能测试只能提供相对参考,工业场景下,有诸多因素可以影响实际的性能表现
  我们提供了 [hertz-benchmark](https://github.com/cloudwego/hertz-benchmark) 项目用来长期追踪和比较 Hertz 与其他框架在不同情况下的性能数据以供参考
## 相关项目
- [Netpoll](https://github.com/cloudwego/netpoll): 自研高性能网络库,Hertz 默认集成
- [Example](https://github.com/cloudwego/hertz-examples): Hertz 使用例子

## 相关拓展
[hertz-Contrib](https://github.com/hertz-contrib) 是 Hertz 扩展生态所在组织,提供服务注册发现、可观测、安全、流量治理、协议、HTTP 通用能力等扩展,由社区共建与维护

| 拓展                                                                                                 | 描述                                                                                                |
|----------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|
| [Autotls](https://github.com/hertz-contrib/autotls)                                                | 为 Hertz 支持 Let's Encrypt 。                                                                        |
| [Http2](https://github.com/hertz-contrib/http2)                                                    | 提供对 HTTP2 的支持。                                                                                    |
| [Websocket](https://github.com/hertz-contrib/websocket)                                            | 使 Hertz 支持 Websocket 协议。                                                                          |
| [Etag](https://github.com/hertz-contrib/etag)                                                      | 提供 ETag HTTP 响应标头。                                                                                |
| [Limiter](https://github.com/hertz-contrib/limiter)                                                | 提供了基于 bbr 算法的限流器。                                                                                 |
| [Monitor-prometheus](https://github.com/hertz-contrib/monitor-prometheus)                          | 提供基于 Prometheus 服务监控功能。                                                                           |
| [Obs-opentelemetry](https://github.com/hertz-contrib/obs-opentelemetry)                            | Hertz 的 Opentelemetry 扩展,支持 Metric、Logger、Tracing 并且达到开箱即用。                                       |
| [Opensergo](https://github.com/hertz-contrib/opensergo)                                            | Opensergo 扩展。                                                                                     |
| [Pprof](https://github.com/hertz-contrib/pprof)                                                    | Hertz 集成 Pprof 的扩展。                                                                               |
| [Registry](https://github.com/hertz-contrib/registry)                                              | 提供服务注册与发现功能。到现在为止,支持的服务发现拓展有 nacos, consul, etcd, eureka, polaris, servicecomb, zookeeper, redis。 |
| [Sentry](https://github.com/hertz-contrib/hertzsentry)                                             | Sentry 拓展提供了一些统一的接口来帮助用户进行实时的错误监控。                                                                |
| [Tracer](https://github.com/hertz-contrib/tracer)                                                  | 基于 Opentracing 的链路追踪。                                                                             |
| [Basicauth](https://github.com/cloudwego/hertz/tree/develop/pkg/app/middlewares/server/basic_auth) | Basicauth 中间件能够提供 HTTP 基本身份验证。                                                                    |
| [Jwt](https://github.com/hertz-contrib/jwt)                                                        | Jwt 拓展。                                                                                           |
| [Keyauth](https://github.com/hertz-contrib/keyauth)                                                | 提供基于 token 的身份验证。                                                                                 |
| [Requestid](https://github.com/hertz-contrib/requestid)                                            | 在 response 中添加 request id。                                                                        |
| [Sessions](https://github.com/hertz-contrib/sessions)                                              | 具有多状态存储支持的 Session 中间件。                                                                           |
| [Casbin](https://github.com/hertz-contrib/casbin)                                                  | 通过 Casbin 支持各种访问控制模型。                                                                             |
| [Cors](https://github.com/hertz-contrib/cors)                                                      | 提供跨域资源共享支持。                                                                                       |
| [Csrf](https://github.com/hertz-contrib/csrf)                                                      | Csrf 中间件用于防止跨站点请求伪造攻击。                                                                            |
| [Secure](https://github.com/hertz-contrib/secure)                                                  | 具有多配置项的 Secure 中间件。                                                                               |
| [Gzip](https://github.com/hertz-contrib/gzip)                                                      | 含多个可选项的 Gzip 拓展。                                                                                  |
| [I18n](https://github.com/hertz-contrib/i18n)                                                      | 可帮助将 Hertz 程序翻译成多种语言。                                                                             |
| [Lark](https://github.com/hertz-contrib/lark-hertz)                                                | 在 Hertz 中处理 Lark/飞书的卡片消息和事件的回调。                                                                   |
| [Loadbalance](https://github.com/hertz-contrib/loadbalance)                                        | 提供适用于 Hertz 的负载均衡算法。                                                                              |
| [Logger](https://github.com/hertz-contrib/logger)                                                  | Hertz 的日志拓展,提供了对 zap、logrus、zerologs 日志框架的支持。                                                     |
| [Recovery](https://github.com/cloudwego/hertz/tree/develop/pkg/app/middlewares/server/recovery)    | Hertz 的异常恢复中间件。                                                                                   |
| [Reverseproxy](https://github.com/hertz-contrib/reverseproxy)                                      | 实现反向代理。                                                                                           |
| [Swagger](https://github.com/hertz-contrib/swagger)                                                | 使用 Swagger 2.0 自动生成 RESTful API 文档。                                                               |
| [Cache](https://github.com/hertz-contrib/cache)                                                    | 用于缓存 HTTP 接口内容的 Hertz 中间件,支持多种客户端。                                                                |

## 相关文章
- [字节跳动在 Go 网络库上的实践](https://www.cloudwego.io/zh/blog/2020/05/24/%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8%E5%9C%A8-go-%E7%BD%91%E7%BB%9C%E5%BA%93%E4%B8%8A%E7%9A%84%E5%AE%9E%E8%B7%B5/)
- [超大规模的企业级微服务 HTTP 框架 — Hertz 正式开源!](https://www.cloudwego.io/zh/blog/2022/06/21/%E8%B6%85%E5%A4%A7%E8%A7%84%E6%A8%A1%E7%9A%84%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%BE%AE%E6%9C%8D%E5%8A%A1-http-%E6%A1%86%E6%9E%B6-hertz-%E6%AD%A3%E5%BC%8F%E5%BC%80%E6%BA%90/)
- [字节跳动开源 Go HTTP 框架 Hertz 设计实践](https://www.cloudwego.io/zh/blog/2022/06/21/%E5%AD%97%E8%8A%82%E8%B7%B3%E5%8A%A8%E5%BC%80%E6%BA%90-go-http-%E6%A1%86%E6%9E%B6-hertz-%E8%AE%BE%E8%AE%A1%E5%AE%9E%E8%B7%B5/)
- [助力字节降本增效,大规模企业级 HTTP 框架 Hertz 设计实践](https://www.cloudwego.io/zh/blog/2022/09/27/%E5%8A%A9%E5%8A%9B%E5%AD%97%E8%8A%82%E9%99%8D%E6%9C%AC%E5%A2%9E%E6%95%88%E5%A4%A7%E8%A7%84%E6%A8%A1%E4%BC%81%E4%B8%9A%E7%BA%A7-http-%E6%A1%86%E6%9E%B6-hertz-%E8%AE%BE%E8%AE%A1%E5%AE%9E%E8%B7%B5/)
- [HTTP 框架 Hertz 实践入门:性能测试指南](https://www.cloudwego.io/zh/blog/2023/02/24/http-%E6%A1%86%E6%9E%B6-hertz-%E5%AE%9E%E8%B7%B5%E5%85%A5%E9%97%A8%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95%E6%8C%87%E5%8D%97/)

## 贡献代码
  [Contributing](https://github.com/cloudwego/hertz/blob/main/CONTRIBUTING.md)
## RoadMap
  [Hertz RoadMap](ROADMAP.md)
## 开源许可

Hertz 基于[Apache License 2.0](https://github.com/cloudwego/hertz/blob/main/LICENSE) 许可证,其依赖的三方组件的开源许可见 [Licenses](https://github.com/cloudwego/hertz/blob/main/licenses)。

## 联系我们
- Email: conduct@cloudwego.io
- 如何成为 member: [COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md)
- Issues: [Issues](https://github.com/cloudwego/hertz/issues)
- Slack: 加入我们的 [Slack 频道](https://join.slack.com/t/cloudwego/shared_invite/zt-tmcbzewn-UjXMF3ZQsPhl7W3tEDZboA)
- 飞书用户群([注册飞书](https://www.larksuite.com/zh_cn/download)进群)

  ![LarkGroup](images/lark_group_cn.png)

## 贡献者
感谢您对 Hertz 作出的贡献!

[![Contributors](https://contrib.rocks/image?repo=cloudwego/hertz)](https://github.com/cloudwego/hertz/graphs/contributors)
## Landscapes

<p align="center">
<img src="https://landscape.cncf.io/images/cncf-landscape-horizontal-color.svg" width="150"/>&nbsp;&nbsp;<img src="https://www.cncf.io/wp-content/uploads/2023/04/cncf-main-site-logo.svg" width="200"/>
<br/><br/>
CloudWeGo 丰富了 <a href="https://landscape.cncf.io/">CNCF 云原生生态</a>。
</p>


================================================
FILE: ROADMAP.md
================================================
# Hertz RoadMap

From 2025, instead of developing new features we will focus on optimizing core functionalities and user experience.

The following is a list of planned projects.

- [ ] Optimize `RequestContext` issues under concurrency.
- [ ] Refactor binding and validator for better extensibility, and deprecate built-in implementations.
- [ ] Make `netpoll` optional, and `pkg/network/standard` the default.
- [ ] Enhance Content-Encoding extension interface for better extensibility.
- [ ] Optimize `pkg/common/adaptor`, and deprecate implementations with `net/http` alternatives.
- [ ] Deprecate the built-in protobuf code generator, use [cloudwego/prutal](https://github.com/cloudwego/prutal)

All users are encouraged to provide suggestions on the projects listed above, or to submit proposals for enhancing current features.


================================================
FILE: cmd/hz/app/app.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package app

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/cloudwego/hertz/cmd/hz/config"
	"github.com/cloudwego/hertz/cmd/hz/generator"
	"github.com/cloudwego/hertz/cmd/hz/meta"
	"github.com/cloudwego/hertz/cmd/hz/protobuf"
	"github.com/cloudwego/hertz/cmd/hz/thrift"
	"github.com/cloudwego/hertz/cmd/hz/util"
	"github.com/cloudwego/hertz/cmd/hz/util/logs"
	"github.com/urfave/cli/v2"
)

// global args. MUST fork it when use
var globalArgs = config.NewArgument()

func New(c *cli.Context) error {
	args, err := globalArgs.Parse(c, meta.CmdNew)
	if err != nil {
		return cli.Exit(err, meta.LoadError)
	}
	setLogVerbose(args.Verbose)
	logs.Debugf("args: %#v\n", args)

	exist, err := util.PathExist(filepath.Join(args.OutDir, meta.ManifestFile))
	if err != nil {
		return cli.Exit(err, meta.LoadError)
	}

	if exist && !args.ForceNew {
		return cli.Exit(fmt.Errorf("the current is already a hertz project, if you want to regenerate it you can specify \"-force\""), meta.LoadError)
	}

	err = GenerateLayout(args)
	if err != nil {
		return cli.Exit(err, meta.GenerateLayoutError)
	}

	err = TriggerPlugin(args)
	if err != nil {
		return cli.Exit(err, meta.PluginError)
	}
	// ".hz" file converges to the hz tool
	manifest := new(meta.Manifest)
	args.InitManifest(manifest)
	err = manifest.Persist(args.OutDir)
	if err != nil {
		return cli.Exit(fmt.Errorf("persist manifest failed: %v", err), meta.PersistError)
	}
	if !args.NeedGoMod && args.IdlType == meta.IdlThrift {
		logs.Warn(meta.AddThriftReplace)
	}

	return nil
}

func Update(c *cli.Context) error {
	// begin to update
	args, err := globalArgs.Parse(c, meta.CmdUpdate)
	if err != nil {
		return cli.Exit(err, meta.LoadError)
	}
	setLogVerbose(args.Verbose)
	logs.Debugf("Args: %#v\n", args)

	manifest := new(meta.Manifest)
	err = manifest.InitAndValidate(args.OutDir)
	if err != nil {
		return cli.Exit(err, meta.LoadError)
	}
	// update argument by ".hz", can automatically get "handler_dir"/"model_dir"/"router_dir"
	args.UpdateByManifest(manifest)

	err = TriggerPlugin(args)
	if err != nil {
		return cli.Exit(err, meta.PluginError)
	}
	// If the "handler_dir"/"model_dir" is updated, write it back to ".hz"
	args.UpdateManifest(manifest)
	err = manifest.Persist(args.OutDir)
	if err != nil {
		return cli.Exit(fmt.Errorf("persist manifest failed: %v", err), meta.PersistError)
	}

	return nil
}

func Model(c *cli.Context) error {
	args, err := globalArgs.Parse(c, meta.CmdModel)
	if err != nil {
		return cli.Exit(err, meta.LoadError)
	}
	setLogVerbose(args.Verbose)
	logs.Debugf("Args: %#v\n", args)

	err = TriggerPlugin(args)
	if err != nil {
		return cli.Exit(err, meta.PluginError)
	}

	return nil
}

func Client(c *cli.Context) error {
	args, err := globalArgs.Parse(c, meta.CmdClient)
	if err != nil {
		return cli.Exit(err, meta.LoadError)
	}
	setLogVerbose(args.Verbose)
	logs.Debugf("Args: %#v\n", args)

	err = TriggerPlugin(args)
	if err != nil {
		return cli.Exit(err, meta.PluginError)
	}

	return nil
}

func PluginMode() {
	mode := os.Getenv(meta.EnvPluginMode)
	if len(os.Args) <= 1 && mode != "" {
		switch mode {
		case meta.ThriftPluginName:
			plugin := new(thrift.Plugin)
			os.Exit(plugin.Run())
		case meta.ProtocPluginName:
			plugin := new(protobuf.Plugin)
			os.Exit(plugin.Run())
		}
	}
}

func Init() *cli.App {
	// flags
	verboseFlag := cli.BoolFlag{Name: "verbose,vv", Usage: "turn on verbose mode", Destination: &globalArgs.Verbose}

	idlFlag := cli.StringSliceFlag{Name: "idl", Usage: "Specify the IDL file path. (.thrift or .proto)"}
	moduleFlag := cli.StringFlag{Name: "module", Aliases: []string{"mod"}, Usage: "Specify the Go module name.", Destination: &globalArgs.Gomod}
	serviceNameFlag := cli.StringFlag{Name: "service", Usage: "Specify the service name.", Destination: &globalArgs.ServiceName}
	outDirFlag := cli.StringFlag{Name: "out_dir", Usage: "Specify the project path.", Destination: &globalArgs.OutDir}
	handlerDirFlag := cli.StringFlag{Name: "handler_dir", Usage: "Specify the handler relative path (based on \"out_dir\").", Destination: &globalArgs.HandlerDir}
	modelDirFlag := cli.StringFlag{Name: "model_dir", Usage: "Specify the model relative path (based on \"out_dir\").", Destination: &globalArgs.ModelDir}
	routerDirFlag := cli.StringFlag{Name: "router_dir", Usage: "Specify the router relative path (based on \"out_dir\").", Destination: &globalArgs.RouterDir}
	useFlag := cli.StringFlag{Name: "use", Usage: "Specify the model package to import for handler.", Destination: &globalArgs.Use}
	baseDomainFlag := cli.StringFlag{Name: "base_domain", Usage: "Specify the request domain.", Destination: &globalArgs.BaseDomain}
	clientDirFlag := cli.StringFlag{Name: "client_dir", Usage: "Specify the client path. If not specified, IDL generated path is used for 'client' command; no client code is generated for 'new' command", Destination: &globalArgs.ClientDir}
	forceClientDirFlag := cli.StringFlag{Name: "force_client_dir", Usage: "Specify the client path, and won't use namespaces as subpaths", Destination: &globalArgs.ForceClientDir}

	optPkgFlag := cli.StringSliceFlag{Name: "option_package", Aliases: []string{"P"}, Usage: "Specify the package path. ({include_path}={import_path})"}
	includesFlag := cli.StringSliceFlag{Name: "proto_path", Aliases: []string{"I"}, Usage: "Add an IDL search path for includes. (Valid only if idl is protobuf)"}
	excludeFilesFlag := cli.StringSliceFlag{Name: "exclude_file", Aliases: []string{"E"}, Usage: "Specify the files that do not need to be updated."}
	thriftOptionsFlag := cli.StringSliceFlag{Name: "thriftgo", Aliases: []string{"t"}, Usage: "Specify arguments for the thriftgo. ({flag}={value})"}
	protoOptionsFlag := cli.StringSliceFlag{Name: "protoc", Aliases: []string{"p"}, Usage: "Specify arguments for the protoc. ({flag}={value})"}
	thriftPluginsFlag := cli.StringSliceFlag{Name: "thrift-plugins", Usage: "Specify plugins for the thriftgo. ({plugin_name}:{options})"}
	protoPluginsFlag := cli.StringSliceFlag{Name: "protoc-plugins", Usage: "Specify plugins for the protoc. ({plugin_name}:{options}:{out_dir})"}
	noRecurseFlag := cli.BoolFlag{Name: "no_recurse", Usage: "Generate master model only.", Destination: &globalArgs.NoRecurse}
	forceNewFlag := cli.BoolFlag{Name: "force", Aliases: []string{"f"}, Usage: "Force new a project, which will overwrite the generated files", Destination: &globalArgs.ForceNew}
	forceUpdateClientFlag := cli.BoolFlag{Name: "force_client", Usage: "Force update 'hertz_client.go'", Destination: &globalArgs.ForceUpdateClient}
	enableExtendsFlag := cli.BoolFlag{Name: "enable_extends", Usage: "Parse 'extends' for thrift IDL", Destination: &globalArgs.EnableExtends}
	sortRouterFlag := cli.BoolFlag{Name: "sort_router", Usage: "Sort router register code, to avoid code difference", Destination: &globalArgs.SortRouter}

	jsonEnumStrFlag := cli.BoolFlag{Name: "json_enumstr", Usage: "Use string instead of num for json enums when idl is thrift.", Destination: &globalArgs.JSONEnumStr}
	queryEnumIntFlag := cli.BoolFlag{Name: "query_enumint", Usage: "Use num instead of string for query enum parameter.", Destination: &globalArgs.QueryEnumAsInt}
	unsetOmitemptyFlag := cli.BoolFlag{Name: "unset_omitempty", Usage: "Remove 'omitempty' tag for generated struct.", Destination: &globalArgs.UnsetOmitempty}
	protoCamelJSONTag := cli.BoolFlag{Name: "pb_camel_json_tag", Usage: "Convert Name style for json tag to camel(Only works protobuf).", Destination: &globalArgs.ProtobufCamelJSONTag}
	snakeNameFlag := cli.BoolFlag{Name: "snake_tag", Usage: "Use snake_case style naming for tags. (Only works for 'form', 'query', 'json')", Destination: &globalArgs.SnakeName}
	rmTagFlag := cli.StringSliceFlag{Name: "rm_tag", Usage: "Remove the default tag(json/query/form). If the annotation tag is set explicitly, it will not be removed."}
	customLayout := cli.StringFlag{Name: "customize_layout", Usage: "Specify the path for layout template.", Destination: &globalArgs.CustomizeLayout}
	customLayoutData := cli.StringFlag{Name: "customize_layout_data_path", Usage: "Specify the path for layout template render data.", Destination: &globalArgs.CustomizeLayoutData}
	customPackage := cli.StringFlag{Name: "customize_package", Usage: "Specify the path for package template.", Destination: &globalArgs.CustomizePackage}
	handlerByMethod := cli.BoolFlag{Name: "handler_by_method", Usage: "Generate a separate handler file for each method.", Destination: &globalArgs.HandlerByMethod}
	trimGoPackage := cli.StringFlag{Name: "trim_gopackage", Aliases: []string{"trim_pkg"}, Usage: "Trim the prefix of go_package for protobuf.", Destination: &globalArgs.TrimGoPackage}

	// client flag
	enableClientOptionalFlag := cli.BoolFlag{Name: "enable_optional", Usage: "Optional field do not transfer for thrift if not set.(Only works for query tag)", Destination: &globalArgs.EnableClientOptional}

	// app
	app := cli.NewApp()
	app.Name = "hz"
	app.Usage = "A idl parser and code generator for Hertz projects"
	app.Version = meta.Version
	// The default separator for multiple parameters is modified to ";"
	app.SliceFlagSeparator = ";"

	// global flags
	app.Flags = []cli.Flag{
		&verboseFlag,
	}

	// Commands
	app.Commands = []*cli.Command{
		{
			Name:  meta.CmdNew,
			Usage: "Generate a new Hertz project",
			Flags: []cli.Flag{
				&idlFlag,
				&serviceNameFlag,
				&moduleFlag,
				&outDirFlag,
				&handlerDirFlag,
				&modelDirFlag,
				&routerDirFlag,
				&clientDirFlag,
				&useFlag,

				&includesFlag,
				&thriftOptionsFlag,
				&protoOptionsFlag,
				&optPkgFlag,
				&trimGoPackage,
				&noRecurseFlag,
				&forceNewFlag,
				&enableExtendsFlag,
				&sortRouterFlag,

				&jsonEnumStrFlag,
				&unsetOmitemptyFlag,
				&protoCamelJSONTag,
				&snakeNameFlag,
				&rmTagFlag,
				&excludeFilesFlag,
				&customLayout,
				&customLayoutData,
				&customPackage,
				&handlerByMethod,
				&protoPluginsFlag,
				&thriftPluginsFlag,
			},
			Action: New,
		},
		{
			Name:  meta.CmdUpdate,
			Usage: "Update an existing Hertz project",
			Flags: []cli.Flag{
				&idlFlag,
				&moduleFlag,
				&outDirFlag,
				&handlerDirFlag,
				&modelDirFlag,
				&clientDirFlag,
				&useFlag,

				&includesFlag,
				&thriftOptionsFlag,
				&protoOptionsFlag,
				&optPkgFlag,
				&trimGoPackage,
				&noRecurseFlag,
				&enableExtendsFlag,
				&sortRouterFlag,

				&jsonEnumStrFlag,
				&unsetOmitemptyFlag,
				&protoCamelJSONTag,
				&snakeNameFlag,
				&rmTagFlag,
				&excludeFilesFlag,
				&customPackage,
				&handlerByMethod,
				&protoPluginsFlag,
				&thriftPluginsFlag,
			},
			Action: Update,
		},
		{
			Name:  meta.CmdModel,
			Usage: "Generate model code only",
			Flags: []cli.Flag{
				&idlFlag,
				&moduleFlag,
				&outDirFlag,
				&modelDirFlag,

				&includesFlag,
				&thriftOptionsFlag,
				&protoOptionsFlag,
				&noRecurseFlag,
				&trimGoPackage,

				&jsonEnumStrFlag,
				&unsetOmitemptyFlag,
				&protoCamelJSONTag,
				&snakeNameFlag,
				&rmTagFlag,
				&excludeFilesFlag,
			},
			Action: Model,
		},
		{
			Name:  meta.CmdClient,
			Usage: "Generate hertz client based on IDL",
			Flags: []cli.Flag{
				&idlFlag,
				&moduleFlag,
				&baseDomainFlag,
				&modelDirFlag,
				&clientDirFlag,
				&useFlag,
				&forceClientDirFlag,
				&forceUpdateClientFlag,

				&includesFlag,
				&thriftOptionsFlag,
				&protoOptionsFlag,
				&noRecurseFlag,
				&enableExtendsFlag,
				&trimGoPackage,

				&jsonEnumStrFlag,
				&enableClientOptionalFlag,
				&queryEnumIntFlag,
				&unsetOmitemptyFlag,
				&protoCamelJSONTag,
				&snakeNameFlag,
				&rmTagFlag,
				&excludeFilesFlag,
				&customPackage,
				&protoPluginsFlag,
				&thriftPluginsFlag,
			},
			Action: Client,
		},
	}
	return app
}

func setLogVerbose(verbose bool) {
	if verbose {
		logs.SetLevel(logs.LevelDebug)
	} else {
		logs.SetLevel(logs.LevelWarn)
	}
}

func GenerateLayout(args *config.Argument) error {
	lg := &generator.LayoutGenerator{
		TemplateGenerator: generator.TemplateGenerator{
			OutputDir: args.OutDir,
			Excludes:  args.Excludes,
		},
	}

	layout := generator.Layout{
		GoModule:        args.Gomod,
		ServiceName:     args.ServiceName,
		UseApacheThrift: args.IdlType == meta.IdlThrift,
		HasIdl:          0 != len(args.IdlPaths),
		ModelDir:        args.ModelDir,
		HandlerDir:      args.HandlerDir,
		RouterDir:       args.RouterDir,
		NeedGoMod:       args.NeedGoMod,
	}

	if args.CustomizeLayout == "" {
		// generate by default
		err := lg.GenerateByService(layout)
		if err != nil {
			return fmt.Errorf("generating layout failed: %v", err)
		}
	} else {
		// generate by customized layout
		configPath, dataPath := args.CustomizeLayout, args.CustomizeLayoutData
		logs.Infof("get customized layout info, layout_config_path: %s, template_data_path: %s", configPath, dataPath)
		exist, err := util.PathExist(configPath)
		if err != nil {
			return fmt.Errorf("check customized layout config file exist failed: %v", err)
		}
		if !exist {
			return errors.New("layout_config_path doesn't exist")
		}
		lg.ConfigPath = configPath
		// generate by service info
		if dataPath == "" {
			err := lg.GenerateByService(layout)
			if err != nil {
				return fmt.Errorf("generating layout failed: %v", err)
			}
		} else {
			// generate by customized data
			err := lg.GenerateByConfig(dataPath)
			if err != nil {
				return fmt.Errorf("generating layout failed: %v", err)
			}
		}
	}

	err := lg.Persist()
	if err != nil {
		return fmt.Errorf("generating layout failed: %v", err)
	}
	return nil
}

func TriggerPlugin(args *config.Argument) error {
	if len(args.IdlPaths) == 0 {
		return nil
	}
	cmd, err := config.BuildPluginCmd(args)
	if err != nil {
		return fmt.Errorf("build plugin command failed: %v", err)
	}

	compiler, err := config.IdlTypeToCompiler(args.IdlType)
	if err != nil {
		return fmt.Errorf("get compiler failed: %v", err)
	}

	logs.Debugf("begin to trigger plugin, compiler: %s, idl_paths: %v", compiler, args.IdlPaths)
	buf, err := cmd.CombinedOutput()
	if err != nil {
		out := strings.TrimSpace(string(buf))
		if !strings.HasSuffix(out, meta.TheUseOptionMessage) {
			return fmt.Errorf("plugin %s_gen_hertz returns error: %v, cause:\n%v", compiler, err, string(buf))
		}
	}

	// If len(buf) != 0, the plugin returned the log.
	if len(buf) != 0 {
		fmt.Println(string(buf))
	}
	logs.Debugf("end run plugin %s_gen_hertz", compiler)
	return nil
}


================================================
FILE: cmd/hz/config/argument.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package config

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/cloudwego/hertz/cmd/hz/meta"
	"github.com/cloudwego/hertz/cmd/hz/util"
	"github.com/cloudwego/hertz/cmd/hz/util/logs"
	"github.com/urfave/cli/v2"
)

type Argument struct {
	// Mode              meta.Mode // operating mode(0-compiler, 1-plugin)
	CmdType        string // command type
	Verbose        bool   // print verbose log
	Cwd            string // execution path
	OutDir         string // output path
	HandlerDir     string // handler path
	ModelDir       string // model path
	RouterDir      string // router path
	ClientDir      string // client path
	BaseDomain     string // request domain
	ForceClientDir string // client dir (not use namespace as a subpath)

	IdlType       string   // idl type
	IdlPaths      []string // master idl path
	RawOptPkg     []string // user-specified package import path
	OptPkgMap     map[string]string
	Includes      []string
	PkgPrefix     string
	TrimGoPackage string // trim go_package for protobuf, avoid to generate multiple directory

	Gopath      string // $GOPATH
	Gosrc       string // $GOPATH/src
	Gomod       string
	Gopkg       string // $GOPATH/src/{{gopkg}}
	ServiceName string // service name
	Use         string
	NeedGoMod   bool

	JSONEnumStr          bool
	QueryEnumAsInt       bool
	UnsetOmitempty       bool
	ProtobufCamelJSONTag bool
	ProtocOptions        []string // options to pass through to protoc
	ThriftOptions        []string // options to pass through to thriftgo for go flag
	ProtobufPlugins      []string
	ThriftPlugins        []string
	SnakeName            bool
	RmTags               []string
	Excludes             []string
	NoRecurse            bool
	HandlerByMethod      bool
	ForceNew             bool
	ForceUpdateClient    bool
	SnakeStyleMiddleware bool
	EnableExtends        bool
	SortRouter           bool

	// client flag
	EnableClientOptional bool

	CustomizeLayout     string
	CustomizeLayoutData string
	CustomizePackage    string
	ModelBackend        string
}

func NewArgument() *Argument {
	return &Argument{
		OptPkgMap:     make(map[string]string),
		Includes:      make([]string, 0, 4),
		Excludes:      make([]string, 0, 4),
		ProtocOptions: make([]string, 0, 4),
		ThriftOptions: make([]string, 0, 4),
	}
}

// Parse initializes a new argument based on its own information
func (arg *Argument) Parse(c *cli.Context, cmd string) (*Argument, error) {
	// v2 cli cannot put the StringSlice flag to struct, so we need to parse it here
	arg.parseStringSlice(c)
	args := arg.Fork()
	args.CmdType = cmd

	err := args.checkPath()
	if err != nil {
		return nil, err
	}

	err = args.checkIDL()
	if err != nil {
		return nil, err
	}

	err = args.checkPackage()
	if err != nil {
		return nil, err
	}

	return args, nil
}

func (arg *Argument) parseStringSlice(c *cli.Context) {
	arg.IdlPaths = c.StringSlice("idl")
	arg.Includes = c.StringSlice("proto_path")
	arg.Excludes = c.StringSlice("exclude_file")
	arg.RawOptPkg = c.StringSlice("option_package")
	arg.ThriftOptions = c.StringSlice("thriftgo")
	arg.ProtocOptions = c.StringSlice("protoc")
	arg.ThriftPlugins = c.StringSlice("thrift-plugins")
	arg.ProtobufPlugins = c.StringSlice("protoc-plugins")
	arg.RmTags = c.StringSlice("rm_tag")
}

func (arg *Argument) UpdateByManifest(m *meta.Manifest) {
	if arg.HandlerDir == "" && m.HandlerDir != "" {
		logs.Infof("use \"handler_dir\" in \".hz\" as the handler generated dir\n")
		arg.HandlerDir = m.HandlerDir
	}
	if arg.ModelDir == "" && m.ModelDir != "" {
		logs.Infof("use \"model_dir\" in \".hz\" as the model generated dir\n")
		arg.ModelDir = m.ModelDir
	}
	if len(m.RouterDir) != 0 {
		logs.Infof("use \"router_dir\" in \".hz\" as the router generated dir\n")
		arg.RouterDir = m.RouterDir
	}
}

// checkPath sets the project path and verifies that the model、handler、router and client path is compliant
func (arg *Argument) checkPath() error {
	dir, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("get current path failed: %s", err)
	}
	arg.Cwd = dir
	if arg.OutDir == "" {
		arg.OutDir = dir
	}
	if !filepath.IsAbs(arg.OutDir) {
		ap := filepath.Join(arg.Cwd, arg.OutDir)
		arg.OutDir = ap
	}
	if arg.ModelDir != "" && filepath.IsAbs(arg.ModelDir) {
		return fmt.Errorf("model path %s must be relative to out_dir", arg.ModelDir)
	}
	if arg.HandlerDir != "" && filepath.IsAbs(arg.HandlerDir) {
		return fmt.Errorf("handler path %s must be relative to out_dir", arg.HandlerDir)
	}
	if arg.RouterDir != "" && filepath.IsAbs(arg.RouterDir) {
		return fmt.Errorf("router path %s must be relative to out_dir", arg.RouterDir)
	}
	if arg.ClientDir != "" && filepath.IsAbs(arg.ClientDir) {
		return fmt.Errorf("router path %s must be relative to out_dir", arg.ClientDir)
	}
	return nil
}

// checkIDL check if the idl path exists, set and check the idl type
func (arg *Argument) checkIDL() error {
	for i, path := range arg.IdlPaths {
		abPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("idl path %s is not absolute", path)
		}
		ext := filepath.Ext(abPath)
		if ext == "" || ext[0] != '.' {
			return fmt.Errorf("idl path %s is not a valid file", path)
		}
		ext = ext[1:]
		switch ext {
		case meta.IdlThrift:
			arg.IdlType = meta.IdlThrift
		case meta.IdlProto:
			arg.IdlType = meta.IdlProto
		default:
			return fmt.Errorf("IDL type %s is not supported", ext)
		}
		arg.IdlPaths[i] = abPath
	}
	return nil
}

func (arg *Argument) IsUpdate() bool {
	return arg.CmdType == meta.CmdUpdate
}

func (arg *Argument) IsNew() bool {
	return arg.CmdType == meta.CmdNew
}

// checkPackage check and set the gopath、 module and package name
func (arg *Argument) checkPackage() error {
	gopath, err := util.GetGOPATH()
	if err != nil {
		return fmt.Errorf("get gopath failed: %s", err)
	}
	if gopath == "" {
		return fmt.Errorf("GOPATH is not set")
	}

	arg.Gopath = gopath
	arg.Gosrc = filepath.Join(gopath, "src")

	// Generate the project under gopath, use the relative path as the package name
	if strings.HasPrefix(arg.Cwd, arg.Gosrc) {
		if gopkg, err := filepath.Rel(arg.Gosrc, arg.Cwd); err != nil {
			return fmt.Errorf("get relative path to GOPATH/src failed: %s", err)
		} else {
			arg.Gopkg = gopkg
		}
	}
	if len(arg.Gomod) == 0 { // not specified "go module"
		// search go.mod recursively
		module, path, ok := util.SearchGoMod(arg.Cwd, true)
		if ok { // find go.mod in upper level, use it as project module, don't generate go.mod
			rel, err := filepath.Rel(path, arg.Cwd)
			if err != nil {
				return fmt.Errorf("can not get relative path, err :%v", err)
			}
			arg.Gomod = filepath.Join(module, rel)
			logs.Debugf("find module '%s' from '%s/go.mod', so use it as module name", module, path)
		}
		if len(arg.Gomod) == 0 { // don't find go.mod in upper level, use relative path as module name, generate go.mod
			logs.Debugf("use gopath's relative path '%s' as the module name", arg.Gopkg)
			// gopkg will be "" under non-gopath
			arg.Gomod = arg.Gopkg
			arg.NeedGoMod = true
		}
		arg.Gomod = filepath.ToSlash(arg.Gomod)
	} else { // specified "go module"
		// search go.mod in current path
		module, path, ok := util.SearchGoMod(arg.Cwd, false)
		if ok { // go.mod exists in current path, check module name, don't generate go.mod
			if module != arg.Gomod {
				return fmt.Errorf("module name given by the '-module/mod' option ('%s') is not consist with the name defined in go.mod ('%s' from %s), try to remove '-module/mod' option in your command\n", arg.Gomod, module, path)
			}
		} else { // go.mod don't exist in current path, generate go.mod
			arg.NeedGoMod = true
		}
	}

	if len(arg.Gomod) == 0 {
		return fmt.Errorf("can not get go module, please specify a module name with the '-module/mod' flag")
	}

	if len(arg.RawOptPkg) > 0 {
		arg.OptPkgMap = make(map[string]string, len(arg.RawOptPkg))
		for _, op := range arg.RawOptPkg {
			ps := strings.SplitN(op, "=", 2)
			if len(ps) != 2 {
				return fmt.Errorf("invalid option package: %s", op)
			}
			arg.OptPkgMap[ps[0]] = ps[1]
		}
		arg.RawOptPkg = nil
	}
	return nil
}

func (arg *Argument) Pack() ([]string, error) {
	data, err := util.PackArgs(arg)
	if err != nil {
		return nil, fmt.Errorf("pack argument failed: %s", err)
	}
	return data, nil
}

func (arg *Argument) Unpack(data []string) error {
	err := util.UnpackArgs(data, arg)
	if err != nil {
		return fmt.Errorf("unpack argument failed: %s", err)
	}
	return nil
}

// Fork can copy its own parameters to a new argument
func (arg *Argument) Fork() *Argument {
	args := NewArgument()
	*args = *arg
	util.CopyString2StringMap(arg.OptPkgMap, args.OptPkgMap)
	util.CopyStringSlice(&arg.Includes, &args.Includes)
	util.CopyStringSlice(&arg.Excludes, &args.Excludes)
	util.CopyStringSlice(&arg.ProtocOptions, &args.ProtocOptions)
	util.CopyStringSlice(&arg.ThriftOptions, &args.ThriftOptions)
	return args
}

func (arg *Argument) GetGoPackage() (string, error) {
	if arg.Gomod != "" {
		return arg.Gomod, nil
	} else if arg.Gopkg != "" {
		return arg.Gopkg, nil
	}
	return "", fmt.Errorf("project package name is not set")
}

func IdlTypeToCompiler(idlType string) (string, error) {
	switch idlType {
	case meta.IdlProto:
		return meta.TpCompilerProto, nil
	case meta.IdlThrift:
		return meta.TpCompilerThrift, nil
	default:
		return "", fmt.Errorf("IDL type %s is not supported", idlType)
	}
}

func (arg *Argument) ModelPackagePrefix() (string, error) {
	ret := arg.Gomod
	if arg.ModelDir == "" {
		path, err := util.RelativePath(meta.ModelDir)
		if !strings.HasPrefix(path, "/") {
			path = "/" + path
		}
		if err != nil {
			return "", err
		}
		ret += path
	} else {
		path, err := util.RelativePath(arg.ModelDir)
		if err != nil {
			return "", err
		}
		ret += "/" + path
	}
	return filepath.ToSlash(ret), nil
}

func (arg *Argument) ModelOutDir() string {
	ret := arg.OutDir
	if arg.ModelDir == "" {
		ret = filepath.Join(ret, meta.ModelDir)
	} else {
		ret = filepath.Join(ret, arg.ModelDir)
	}
	return ret
}

func (arg *Argument) GetHandlerDir() (string, error) {
	if arg.HandlerDir == "" {
		return util.RelativePath(meta.HandlerDir)
	}
	return util.RelativePath(arg.HandlerDir)
}

func (arg *Argument) GetModelDir() (string, error) {
	if arg.ModelDir == "" {
		return util.RelativePath(meta.ModelDir)
	}
	return util.RelativePath(arg.ModelDir)
}

func (arg *Argument) GetRouterDir() (string, error) {
	if arg.RouterDir == "" {
		return util.RelativePath(meta.RouterDir)
	}
	return util.RelativePath(arg.RouterDir)
}

func (arg *Argument) GetClientDir() (string, error) {
	if arg.ClientDir == "" {
		return "", nil
	}
	return util.RelativePath(arg.ClientDir)
}

func (arg *Argument) InitManifest(m *meta.Manifest) {
	m.Version = meta.Version
	m.HandlerDir = arg.HandlerDir
	m.ModelDir = arg.ModelDir
	m.RouterDir = arg.RouterDir
}

func (arg *Argument) UpdateManifest(m *meta.Manifest) {
	m.Version = meta.Version
	if arg.HandlerDir != m.HandlerDir {
		m.HandlerDir = arg.HandlerDir
	}
	if arg.HandlerDir != m.ModelDir {
		m.ModelDir = arg.ModelDir
	}
	// "router_dir" must not be defined by "update" command
}


================================================
FILE: cmd/hz/config/cmd.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package config

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"syscall"

	"github.com/cloudwego/hertz/cmd/hz/meta"
	"github.com/cloudwego/hertz/cmd/hz/util"
	"github.com/cloudwego/hertz/cmd/hz/util/logs"
)

func lookupTool(idlType string) (string, error) {
	tool := meta.TpCompilerThrift
	if idlType == meta.IdlProto {
		tool = meta.TpCompilerProto
	}

	path, err := exec.LookPath(tool)
	logs.Debugf("[DEBUG]path:%v", path)
	if err != nil {
		goPath, err := util.GetGOPATH()
		if err != nil {
			return "", fmt.Errorf("get 'GOPATH' failed for find %s : %v", tool, path)
		}
		path = filepath.Join(goPath, "bin", tool)
	}

	isExist, err := util.PathExist(path)
	if err != nil {
		return "", fmt.Errorf("check '%s' path error: %v", path, err)
	}

	if !isExist {
		if tool == meta.TpCompilerThrift {
			// If thriftgo does not exist, the latest version will be installed automatically.
			err := util.InstallAndCheckThriftgo()
			if err != nil {
				return "", fmt.Errorf("can't install '%s' automatically, please install it manually for https://github.com/cloudwego/thriftgo, err : %v", tool, err)
			}
		} else {
			// todo: protoc automatic installation
			return "", fmt.Errorf("%s is not installed, please install it first", tool)
		}
	}

	if tool == meta.TpCompilerThrift {
		// If thriftgo exists, the version is detected; if the version is lower than v0.2.0 then the latest version of thriftgo is automatically installed.
		err := util.CheckAndUpdateThriftgo()
		if err != nil {
			return "", fmt.Errorf("update thriftgo version failed, please install it manually for https://github.com/cloudwego/thriftgo, err: %v", err)
		}
	}

	return path, nil
}

// link removes the previous symbol link and rebuilds a new one.
func link(src, dst string) error {
	err := syscall.Unlink(dst)
	if err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("unlink %q: %s", dst, err)
	}
	err = os.Symlink(src, dst)
	if err != nil {
		return fmt.Errorf("symlink %q: %s", dst, err)
	}
	return nil
}

func BuildPluginCmd(args *Argument) (*exec.Cmd, error) {
	exe, err := os.Executable()
	if err != nil {
		return nil, fmt.Errorf("failed to detect current executable, err: %v", err)
	}

	argPacks, err := args.Pack()
	if err != nil {
		return nil, err
	}
	kas := strings.Join(argPacks, ",")

	path, err := lookupTool(args.IdlType)
	if err != nil {
		return nil, err
	}
	cmd := &exec.Cmd{
		Path: path,
	}

	if args.IdlType == meta.IdlThrift {
		// thriftgo
		os.Setenv(meta.EnvPluginMode, meta.ThriftPluginName)
		cmd.Args = append(cmd.Args, meta.TpCompilerThrift)
		for _, inc := range args.Includes {
			cmd.Args = append(cmd.Args, "-i", inc)
		}

		if args.Verbose {
			cmd.Args = append(cmd.Args, "-v")
		}
		thriftOpt, err := args.GetThriftgoOptions()
		if err != nil {
			return nil, err
		}
		cmd.Args = append(cmd.Args,
			"-o", args.ModelOutDir(),
			"-g", thriftOpt,
			"-p", "hertz="+exe+":"+kas,
		)
		for _, p := range args.ThriftPlugins {
			cmd.Args = append(cmd.Args, "-p", p)
		}
		if !args.NoRecurse {
			cmd.Args = append(cmd.Args, "-r")
		}
	} else {
		// protoc
		os.Setenv(meta.EnvPluginMode, meta.ProtocPluginName)
		cmd.Args = append(cmd.Args, meta.TpCompilerProto)
		for _, inc := range args.Includes {
			cmd.Args = append(cmd.Args, "-I", inc)
		}
		for _, inc := range args.IdlPaths {
			cmd.Args = append(cmd.Args, "-I", filepath.Dir(inc))
		}
		cmd.Args = append(cmd.Args,
			"--plugin=protoc-gen-hertz="+exe,
			"--hertz_out="+args.OutDir,
			"--hertz_opt="+kas,
		)
		for _, p := range args.ProtobufPlugins {
			pluginParams := strings.Split(p, ":")
			if len(pluginParams) != 3 {
				logs.Warnf("Failed to get the correct protoc plugin parameters for %. "+
					"Please specify the protoc plugin in the form of \"plugin_name:options:out_dir\"", p)
				os.Exit(1)
			}
			// pluginParams[0] -> plugin name, pluginParams[1] -> plugin options, pluginParams[2] -> out_dir
			cmd.Args = append(cmd.Args,
				fmt.Sprintf("--%s_out=%s", pluginParams[0], pluginParams[2]),
				fmt.Sprintf("--%s_opt=%s", pluginParams[0], pluginParams[1]),
			)
		}
		for _, kv := range args.ProtocOptions {
			cmd.Args = append(cmd.Args, "--"+kv)
		}
	}

	cmd.Args = append(cmd.Args, args.IdlPaths...)
	logs.Infof(strings.Join(cmd.Args, " "))
	logs.Flush()
	return cmd, nil
}

func (arg *Argument) GetThriftgoOptions() (string, error) {
	defaultOpt := "reserve_comments,gen_json_tag=false,"
	prefix, err := arg.ModelPackagePrefix()
	if err != nil {
		return "", err
	}
	arg.ThriftOptions = append(arg.ThriftOptions, "package_prefix="+prefix)
	if arg.JSONEnumStr {
		arg.ThriftOptions = append(arg.ThriftOptions, "json_enum_as_text")
	}
	gas := "go:" + defaultOpt + strings.Join(arg.ThriftOptions, ",")
	return gas, nil
}


================================================
FILE: cmd/hz/doc.go
================================================
// Copyright 2022 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// Package "github.com/cloudwego/hertz/cmd/hz" contains packages for building the hz command line tool.
// APIs exported by packages under this directory do not promise any backward
// compatibility, so please do not rely on them.

package main


================================================
FILE: cmd/hz/generator/client.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"path"
	"path/filepath"
	"strings"

	"github.com/cloudwego/hertz/cmd/hz/generator/model"
	"github.com/cloudwego/hertz/cmd/hz/util"
)

type ClientMethod struct {
	*HttpMethod
	BodyParamsCode   string
	QueryParamsCode  string
	PathParamsCode   string
	HeaderParamsCode string
	FormValueCode    string
	FormFileCode     string
}

type ClientConfig struct {
	QueryEnumAsInt bool
}

type ClientFile struct {
	Config        ClientConfig
	FilePath      string
	PackageName   string
	ServiceName   string
	BaseDomain    string
	Imports       map[string]*model.Model
	ClientMethods []*ClientMethod
}

func (pkgGen *HttpPackageGenerator) genClient(pkg *HttpPackage, clientDir string) error {
	for _, s := range pkg.Services {
		cliDir := util.SubDir(clientDir, util.ToSnakeCase(s.Name))
		if len(pkgGen.ForceClientDir) != 0 {
			cliDir = pkgGen.ForceClientDir
		}
		hertzClientPath := filepath.Join(cliDir, hertzClientTplName)
		isExist, err := util.PathExist(hertzClientPath)
		if err != nil {
			return err
		}
		baseDomain := s.BaseDomain
		if len(pkgGen.BaseDomain) != 0 {
			baseDomain = pkgGen.BaseDomain
		}
		client := ClientFile{
			FilePath:      filepath.Join(cliDir, util.ToSnakeCase(s.Name)+".go"),
			PackageName:   util.ToSnakeCase(filepath.Base(cliDir)),
			ServiceName:   util.ToCamelCase(s.Name),
			ClientMethods: s.ClientMethods,
			BaseDomain:    baseDomain,
			Config:        ClientConfig{QueryEnumAsInt: pkgGen.QueryEnumAsInt},
		}
		if !isExist || pkgGen.ForceUpdateClient {
			err := pkgGen.TemplateGenerator.Generate(client, hertzClientTplName, hertzClientPath, false)
			if err != nil {
				return err
			}
		}
		client.Imports = make(map[string]*model.Model, len(client.ClientMethods))
		for _, m := range client.ClientMethods {
			// Iterate over the request and return parameters of the method to get import path.
			for key, mm := range m.Models {
				if v, ok := client.Imports[mm.PackageName]; ok && v.Package != mm.Package {
					client.Imports[key] = mm
					continue
				}
				client.Imports[mm.PackageName] = mm
			}
		}
		if len(pkgGen.UseDir) != 0 {
			oldModelPkg := util.SubPackage(pkgGen.ProjPackage, filepath.Clean(pkgGen.ModelDir))
			newModelPkg := path.Clean(pkgGen.UseDir)
			for _, m := range client.ClientMethods {
				for _, mm := range m.Models {
					mm.Package = strings.Replace(mm.Package, oldModelPkg, newModelPkg, 1)
				}
			}
		}
		err = pkgGen.TemplateGenerator.Generate(client, idlClientName, client.FilePath, false)
		if err != nil {
			return err
		}
	}
	return nil
}


================================================
FILE: cmd/hz/generator/custom_files.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/cloudwego/hertz/cmd/hz/util"
	"github.com/cloudwego/hertz/cmd/hz/util/logs"
)

type FilePathRenderInfo struct {
	MasterIDLName  string // master IDL name
	GenPackage     string // master IDL generate code package
	HandlerDir     string // handler generate dir
	ModelDir       string // model generate dir
	RouterDir      string // router generate dir
	ProjectDir     string // projectDir
	GoModule       string // go module
	ServiceName    string // service name, changed as services are traversed
	MethodName     string // method name, changed as methods are traversed
	HandlerGenPath string // "api.gen_path" value
}

type IDLPackageRenderInfo struct {
	FilePathRenderInfo
	ServiceInfos *HttpPackage
}

type CustomizedFileForMethod struct {
	*HttpMethod
	FilePath       string
	FilePackage    string
	ServiceInfo    *Service              // service info for this method
	IDLPackageInfo *IDLPackageRenderInfo // IDL info for this service
}

type CustomizedFileForService struct {
	*Service
	FilePath       string
	FilePackage    string
	IDLPackageInfo *IDLPackageRenderInfo // IDL info for this service
}

type CustomizedFileForIDL struct {
	*IDLPackageRenderInfo
	FilePath    string
	FilePackage string
}

// todo: 1. how to import other file, if the other file name is a template

// genCustomizedFile generate customized file template
func (pkgGen *HttpPackageGenerator) genCustomizedFile(pkg *HttpPackage) error {
	filePathRenderInfo := FilePathRenderInfo{
		MasterIDLName: pkg.IdlName,
		GenPackage:    pkg.Package,
		HandlerDir:    pkgGen.HandlerDir,
		ModelDir:      pkgGen.ModelDir,
		RouterDir:     pkgGen.RouterDir,
		ProjectDir:    pkgGen.OutputDir,
		GoModule:      pkgGen.ProjPackage,
		// methodName & serviceName will change as traverse
	}

	idlPackageRenderInfo := IDLPackageRenderInfo{
		FilePathRenderInfo: filePathRenderInfo,
		ServiceInfos:       pkg,
	}

	for _, tplInfo := range pkgGen.tplsInfo {
		// the default template has been automatically generated by the tool, so skip
		if tplInfo.Default {
			continue
		}

		// loop generate file
		if tplInfo.LoopService || tplInfo.LoopMethod {
			loopMethod := tplInfo.LoopMethod
			loopService := tplInfo.LoopService
			if loopService && !loopMethod { // only loop service
				for _, service := range idlPackageRenderInfo.ServiceInfos.Services {
					filePathRenderInfo.ServiceName = service.Name
					err := pkgGen.genLoopService(tplInfo, filePathRenderInfo, service, &idlPackageRenderInfo)
					if err != nil {
						return err
					}
				}
			} else { // loop service & method, because if loop method, the service must be looped
				for _, service := range idlPackageRenderInfo.ServiceInfos.Services {
					for _, method := range service.Methods {
						filePathRenderInfo.ServiceName = service.Name
						filePathRenderInfo.MethodName = method.Name
						filePathRenderInfo.HandlerGenPath = method.OutputDir
						err := pkgGen.genLoopMethod(tplInfo, filePathRenderInfo, method, service, &idlPackageRenderInfo)
						if err != nil {
							return err
						}
					}
				}
			}
		} else { // generate customized file single
			err := pkgGen.genSingleCustomizedFile(tplInfo, filePathRenderInfo, idlPackageRenderInfo)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

// renderFilePath used to render file path template to get real file path
func renderFilePath(tplInfo *Template, filePathRenderInfo FilePathRenderInfo) (string, error) {
	tpl, err := template.New(tplInfo.Path).Funcs(funcMap).Parse(tplInfo.Path)
	if err != nil {
		return "", fmt.Errorf("parse file path template(%s) failed, err: %v", tplInfo.Path, err)
	}
	filePath := bytes.NewBuffer(nil)
	err = tpl.Execute(filePath, filePathRenderInfo)
	if err != nil {
		return "", fmt.Errorf("render file path template(%s) failed, err: %v", tplInfo.Path, err)
	}

	return filePath.String(), nil
}

func renderInsertKey(tplInfo *Template, data interface{}) (string, error) {
	tpl, err := template.New(tplInfo.UpdateBehavior.InsertKey).Funcs(funcMap).Parse(tplInfo.UpdateBehavior.InsertKey)
	if err != nil {
		return "", fmt.Errorf("parse insert key template(%s) failed, err: %v", tplInfo.UpdateBehavior.InsertKey, err)
	}
	insertKey := bytes.NewBuffer(nil)
	err = tpl.Execute(insertKey, data)
	if err != nil {
		return "", fmt.Errorf("render insert key template(%s) failed, err: %v", tplInfo.UpdateBehavior.InsertKey, err)
	}

	return insertKey.String(), nil
}

// renderImportTpl will render import template
// it will return the []string, like blow:
// ["import", alias "import", import]
// other format will be error
func renderImportTpl(tplInfo *Template, data interface{}) ([]string, error) {
	var importList []string
	for _, impt := range tplInfo.UpdateBehavior.ImportTpl {
		tpl, err := template.New(impt).Funcs(funcMap).Parse(impt)
		if err != nil {
			return nil, fmt.Errorf("parse import template(%s) failed, err: %v", impt, err)
		}
		imptContent := bytes.NewBuffer(nil)
		err = tpl.Execute(imptContent, data)
		if err != nil {
			return nil, fmt.Errorf("render import template(%s) failed, err: %v", impt, err)
		}
		importList = append(importList, imptContent.String())
	}
	var ret []string
	for _, impts := range importList {
		// 'import render result' may have multiple imports
		if strings.Contains(impts, "\n") {
			for _, impt := range strings.Split(impts, "\n") {
				ret = append(ret, impt)
			}
		} else {
			ret = append(ret, impts)
		}
	}

	return ret, nil
}

// renderAppendContent used to render append content for 'update' command
func renderAppendContent(tplInfo *Template, renderInfo interface{}) (string, error) {
	tpl, err := template.New(tplInfo.Path).Funcs(funcMap).Parse(tplInfo.UpdateBehavior.AppendTpl)
	if err != nil {
		return "", fmt.Errorf("parse append content template(%s) failed, err: %v", tplInfo.Path, err)
	}
	appendContent := bytes.NewBuffer(nil)
	err = tpl.Execute(appendContent, renderInfo)
	if err != nil {
		return "", fmt.Errorf("render append content template(%s) failed, err: %v", tplInfo.Path, err)
	}

	return appendContent.String(), nil
}

// appendUpdateFile used to append content to file for 'update' command
func appendUpdateFile(tplInfo *Template, renderInfo interface{}, fileContent []byte) ([]byte, error) {
	// render insert content
	appendContent, err := renderAppendContent(tplInfo, renderInfo)
	if err != nil {
		return []byte(""), err
	}
	buf := bytes.NewBuffer(nil)
	_, err = buf.Write(fileContent)
	if err != nil {
		return []byte(""), fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
	}
	// "\r\n" && "\n" has the same suffix
	if !bytes.HasSuffix(buf.Bytes(), []byte("\n")) {
		_, err = buf.WriteString("\n")
		if err != nil {
			return []byte(""), fmt.Errorf("write file(%s) line break failed, err: %v", tplInfo.Path, err)
		}
	}
	_, err = buf.WriteString(appendContent)
	if err != nil {
		return []byte(""), fmt.Errorf("append file(%s) failed, err: %v", tplInfo.Path, err)
	}

	return buf.Bytes(), nil
}

func getInsertImportContent(tplInfo *Template, renderInfo interface{}, fileContent []byte) ([][2]string, error) {
	importContent, err := renderImportTpl(tplInfo, renderInfo)
	if err != nil {
		return nil, err
	}
	var imptSlice [][2]string
	for _, impt := range importContent {
		// import has to format
		// 1. alias "import"
		// 2. "import"
		// 3. import (can not contain '"')
		impt = strings.TrimSpace(impt)
		if !strings.Contains(impt, "\"") { // 3. import (can not contain '"')
			if bytes.Contains(fileContent, []byte(impt)) {
				continue
			}
			imptSlice = append(imptSlice, [2]string{"", impt})
		} else {
			if !strings.HasSuffix(impt, "\"") {
				return nil, fmt.Errorf("import can not has suffix \"\"\", for file: %s", tplInfo.Path)
			}
			if strings.HasPrefix(impt, "\"") { // 2. "import"
				if bytes.Contains(fileContent, []byte(impt[1:len(impt)-1])) {
					continue
				}
				imptSlice = append(imptSlice, [2]string{"", impt[1 : len(impt)-1]})
			} else { // 3. alias "import"
				idx := strings.Index(impt, "\"")
				if idx == -1 {
					return nil, fmt.Errorf("error import format for file: %s", tplInfo.Path)
				}
				if bytes.Contains(fileContent, []byte(impt[idx+1:len(impt)-1])) {
					continue
				}
				imptSlice = append(imptSlice, [2]string{impt[:idx], impt[idx+1 : len(impt)-1]})
			}
		}
	}

	return imptSlice, nil
}

// genLoopService used to generate files by 'service'
func (pkgGen *HttpPackageGenerator) genLoopService(tplInfo *Template, filePathRenderInfo FilePathRenderInfo, service *Service, idlPackageRenderInfo *IDLPackageRenderInfo) error {
	filePath, err := renderFilePath(tplInfo, filePathRenderInfo)
	if err != nil {
		return err
	}
	// determine if a custom file exists
	exist, err := util.PathExist(filePath)
	if err != nil {
		return fmt.Errorf("judge file(%s) exists failed, err: %v", filePath, err)
	}
	if !exist { // create file
		data := CustomizedFileForService{
			Service:        service,
			FilePath:       filePath,
			FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
			IDLPackageInfo: idlPackageRenderInfo,
		}
		err = pkgGen.TemplateGenerator.Generate(data, tplInfo.Path, filePath, false)
		if err != nil {
			return err
		}
	} else {
		switch tplInfo.UpdateBehavior.Type {
		case Skip:
			// do nothing
			logs.Infof("do not update file '%s', because the update behavior is 'Unchanged'", filePath)
		case Cover:
			// re-generate
			logs.Infof("re-generate file '%s', because the update behavior is 'Regenerate'", filePath)
			data := CustomizedFileForService{
				Service:        service,
				FilePath:       filePath,
				FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
				IDLPackageInfo: idlPackageRenderInfo,
			}
			err := pkgGen.TemplateGenerator.Generate(data, tplInfo.Path, filePath, false)
			if err != nil {
				return err
			}
		case Append: // todo: append logic need to be optimized for method
			fileContent, err := ioutil.ReadFile(filePath)
			if err != nil {
				return err
			}
			var appendContent []byte
			// get insert content
			if tplInfo.UpdateBehavior.AppendKey == "method" {
				for _, method := range service.Methods {
					data := CustomizedFileForMethod{
						HttpMethod:     method,
						FilePath:       filePath,
						FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
						ServiceInfo:    service,
						IDLPackageInfo: idlPackageRenderInfo,
					}
					insertKey, err := renderInsertKey(tplInfo, data)
					if err != nil {
						return err
					}
					if bytes.Contains(fileContent, []byte(insertKey)) {
						continue
					}
					imptSlice, err := getInsertImportContent(tplInfo, data, fileContent)
					if err != nil {
						return err
					}
					// insert new import to the fileContent
					for _, impt := range imptSlice {
						if bytes.Contains(fileContent, []byte(impt[1])) {
							continue
						}
						fileContent, err = util.AddImportForContent(fileContent, impt[0], impt[1])
						// insert import error do not influence the generated file
						if err != nil {
							logs.Warnf("can not add import(%s) for file(%s), err: %v\n", impt[1], filePath, err)
						}
					}
					appendContent, err = appendUpdateFile(tplInfo, data, appendContent)
					if err != nil {
						return err
					}
				}
				if len(tplInfo.UpdateBehavior.AppendLocation) == 0 { // default, append to end of file
					buf := bytes.NewBuffer(nil)
					_, err = buf.Write(fileContent)
					if err != nil {
						return fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
					}
					_, err = buf.Write(appendContent)
					if err != nil {
						return fmt.Errorf("append file(%s) failed, err: %v", tplInfo.Path, err)
					}
					logs.Infof("append content for file '%s', because the update behavior is 'Append' and appendKey is 'method'", filePath)
					pkgGen.files = append(pkgGen.files, File{filePath, buf.String(), false, ""})
				} else { // 'append location', append new content after 'append location'
					part := bytes.Split(fileContent, []byte(tplInfo.UpdateBehavior.AppendLocation))
					if len(part) == 0 {
						return fmt.Errorf("can not find append location '%s' for file '%s'\n", tplInfo.UpdateBehavior.AppendLocation, filePath)
					}
					if len(part) != 2 {
						return fmt.Errorf("do not support multiple append location '%s' for file '%s'\n", tplInfo.UpdateBehavior.AppendLocation, filePath)
					}
					buf := bytes.NewBuffer(nil)
					err = writeBytes(buf, part[0], []byte(tplInfo.UpdateBehavior.AppendLocation), appendContent, part[1])
					if err != nil {
						return fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
					}
					logs.Infof("append content for file '%s', because the update behavior is 'Append' and appendKey is 'method'", filePath)
					pkgGen.files = append(pkgGen.files, File{filePath, buf.String(), false, ""})
				}
			} else {
				logs.Warnf("Loop 'service' field for '%s' only append content by appendKey for 'method', so cannot append content", filePath)
			}
		default:
			// do nothing
			logs.Warnf("unknown update behavior, do nothing")
		}
	}
	return nil
}

// genLoopMethod used to generate files by 'method'
func (pkgGen *HttpPackageGenerator) genLoopMethod(tplInfo *Template, filePathRenderInfo FilePathRenderInfo, method *HttpMethod, service *Service, idlPackageRenderInfo *IDLPackageRenderInfo) error {
	filePath, err := renderFilePath(tplInfo, filePathRenderInfo)
	if err != nil {
		return err
	}
	// determine if a custom file exists
	exist, err := util.PathExist(filePath)
	if err != nil {
		return fmt.Errorf("judge file(%s) exists failed, err: %v", filePath, err)
	}

	if !exist { // create file
		data := CustomizedFileForMethod{
			HttpMethod:     method,
			FilePath:       filePath,
			FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
			ServiceInfo:    service,
			IDLPackageInfo: idlPackageRenderInfo,
		}
		err := pkgGen.TemplateGenerator.Generate(data, tplInfo.Path, filePath, false)
		if err != nil {
			return err
		}
	} else {
		switch tplInfo.UpdateBehavior.Type {
		case Skip:
			// do nothing
			logs.Infof("do not update file '%s', because the update behavior is 'Unchanged'", filePath)
		case Cover:
			// re-generate
			logs.Infof("re-generate file '%s', because the update behavior is 'Regenerate'", filePath)
			data := CustomizedFileForMethod{
				HttpMethod:     method,
				FilePath:       filePath,
				FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
				ServiceInfo:    service,
				IDLPackageInfo: idlPackageRenderInfo,
			}
			err := pkgGen.TemplateGenerator.Generate(data, tplInfo.Path, filePath, false)
			if err != nil {
				return err
			}
		case Append:
			// for loop method, no need to append something; so do nothing
			logs.Warnf("do not append content for file '%s', because the update behavior is 'Append' and loop 'method' have no need to append content", filePath)
		default:
			// do nothing
			logs.Warnf("unknown update behavior, do nothing")
		}
	}

	return nil
}

// genSingleCustomizedFile used to generate file by 'master IDL'
func (pkgGen *HttpPackageGenerator) genSingleCustomizedFile(tplInfo *Template, filePathRenderInfo FilePathRenderInfo, idlPackageRenderInfo IDLPackageRenderInfo) error {
	// generate file single
	filePath, err := renderFilePath(tplInfo, filePathRenderInfo)
	if err != nil {
		return err
	}
	// determine if a custom file exists
	exist, err := util.PathExist(filePath)
	if err != nil {
		return fmt.Errorf("judge file(%s) exists failed, err: %v", filePath, err)
	}

	if !exist { // create file
		data := CustomizedFileForIDL{
			IDLPackageRenderInfo: &idlPackageRenderInfo,
			FilePath:             filePath,
			FilePackage:          util.SplitPackage(filepath.Dir(filePath), ""),
		}
		err := pkgGen.TemplateGenerator.Generate(data, tplInfo.Path, filePath, false)
		if err != nil {
			return err
		}
	} else {
		switch tplInfo.UpdateBehavior.Type {
		case Skip:
			// do nothing
			logs.Infof("do not update file '%s', because the update behavior is 'Unchanged'", filePath)
		case Cover:
			// re-generate
			logs.Infof("re-generate file '%s', because the update behavior is 'Regenerate'", filePath)
			data := CustomizedFileForIDL{
				IDLPackageRenderInfo: &idlPackageRenderInfo,
				FilePath:             filePath,
				FilePackage:          util.SplitPackage(filepath.Dir(filePath), ""),
			}
			err := pkgGen.TemplateGenerator.Generate(data, tplInfo.Path, filePath, false)
			if err != nil {
				return err
			}
		case Append: // todo: append logic need to be optimized for single file
			fileContent, err := ioutil.ReadFile(filePath)
			if err != nil {
				return err
			}
			if tplInfo.UpdateBehavior.AppendKey == "method" {
				var appendContent []byte
				for _, service := range idlPackageRenderInfo.ServiceInfos.Services {
					for _, method := range service.Methods {
						data := CustomizedFileForMethod{
							HttpMethod:     method,
							FilePath:       filePath,
							FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
							ServiceInfo:    service,
							IDLPackageInfo: &idlPackageRenderInfo,
						}
						insertKey, err := renderInsertKey(tplInfo, data)
						if err != nil {
							return err
						}
						if bytes.Contains(fileContent, []byte(insertKey)) {
							continue
						}
						imptSlice, err := getInsertImportContent(tplInfo, data, fileContent)
						if err != nil {
							return err
						}
						for _, impt := range imptSlice {
							if bytes.Contains(fileContent, []byte(impt[1])) {
								continue
							}
							fileContent, err = util.AddImportForContent(fileContent, impt[0], impt[1])
							if err != nil {
								logs.Warnf("can not add import(%s) for file(%s)\n", impt[1], filePath)
							}
						}

						appendContent, err = appendUpdateFile(tplInfo, data, appendContent)
						if err != nil {
							return err
						}
					}
				}
				if len(tplInfo.UpdateBehavior.AppendLocation) == 0 { // default, append to end of file
					buf := bytes.NewBuffer(nil)
					_, err = buf.Write(fileContent)
					if err != nil {
						return fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
					}
					_, err = buf.Write(appendContent)
					if err != nil {
						return fmt.Errorf("append file(%s) failed, err: %v", tplInfo.Path, err)
					}
					logs.Infof("append content for file '%s', because the update behavior is 'Append' and appendKey is 'method'", filePath)
					pkgGen.files = append(pkgGen.files, File{filePath, buf.String(), false, ""})
				} else { // 'append location', append new content after 'append location'
					part := bytes.Split(fileContent, []byte(tplInfo.UpdateBehavior.AppendLocation))
					if len(part) == 0 {
						return fmt.Errorf("can not find append location '%s' for file '%s'\n", tplInfo.UpdateBehavior.AppendLocation, filePath)
					}
					if len(part) != 2 {
						return fmt.Errorf("do not support multiple append location '%s' for file '%s'\n", tplInfo.UpdateBehavior.AppendLocation, filePath)
					}
					buf := bytes.NewBuffer(nil)
					err = writeBytes(buf, part[0], []byte(tplInfo.UpdateBehavior.AppendLocation), appendContent, part[1])
					if err != nil {
						return fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
					}
					logs.Infof("append content for file '%s', because the update behavior is 'Append' and appendKey is 'method'", filePath)
					pkgGen.files = append(pkgGen.files, File{filePath, buf.String(), false, ""})
				}
			} else if tplInfo.UpdateBehavior.AppendKey == "service" {
				var appendContent []byte
				for _, service := range idlPackageRenderInfo.ServiceInfos.Services {
					data := CustomizedFileForService{
						Service:        service,
						FilePath:       filePath,
						FilePackage:    util.SplitPackage(filepath.Dir(filePath), ""),
						IDLPackageInfo: &idlPackageRenderInfo,
					}
					insertKey, err := renderInsertKey(tplInfo, data)
					if err != nil {
						return err
					}
					if bytes.Contains(fileContent, []byte(insertKey)) {
						continue
					}
					imptSlice, err := getInsertImportContent(tplInfo, data, fileContent)
					if err != nil {
						return err
					}
					for _, impt := range imptSlice {
						if bytes.Contains(fileContent, []byte(impt[1])) {
							continue
						}
						fileContent, err = util.AddImportForContent(fileContent, impt[0], impt[1])
						if err != nil {
							logs.Warnf("can not add import(%s) for file(%s)\n", impt[1], filePath)
						}
					}
					appendContent, err = appendUpdateFile(tplInfo, data, appendContent)
					if err != nil {
						return err
					}
				}
				if len(tplInfo.UpdateBehavior.AppendLocation) == 0 { // default, append to end of file
					buf := bytes.NewBuffer(nil)
					_, err = buf.Write(fileContent)
					if err != nil {
						return fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
					}
					_, err = buf.Write(appendContent)
					if err != nil {
						return fmt.Errorf("append file(%s) failed, err: %v", tplInfo.Path, err)
					}
					logs.Infof("append content for file '%s', because the update behavior is 'Append' and appendKey is 'service'", filePath)
					pkgGen.files = append(pkgGen.files, File{filePath, buf.String(), false, ""})
				} else { // 'append location', append new content after 'append location'
					part := bytes.Split(fileContent, []byte(tplInfo.UpdateBehavior.AppendLocation))
					if len(part) == 0 {
						return fmt.Errorf("can not find append location '%s' for file '%s'\n", tplInfo.UpdateBehavior.AppendLocation, filePath)
					}
					if len(part) != 2 {
						return fmt.Errorf("do not support multiple append location '%s' for file '%s'\n", tplInfo.UpdateBehavior.AppendLocation, filePath)
					}
					buf := bytes.NewBuffer(nil)
					err = writeBytes(buf, part[0], []byte(tplInfo.UpdateBehavior.AppendLocation), appendContent, part[1])
					if err != nil {
						return fmt.Errorf("write file(%s) failed, err: %v", tplInfo.Path, err)
					}
					logs.Infof("append content for file '%s', because the update behavior is 'Append' and appendKey is 'service'", filePath)
					pkgGen.files = append(pkgGen.files, File{filePath, buf.String(), false, ""})
				}
			} else { // add append content to the file directly
				data := CustomizedFileForIDL{
					IDLPackageRenderInfo: &idlPackageRenderInfo,
					FilePath:             filePath,
					FilePackage:          util.SplitPackage(filepath.Dir(filePath), ""),
				}
				file, err := appendUpdateFile(tplInfo, data, fileContent)
				if err != nil {
					return err
				}
				pkgGen.files = append(pkgGen.files, File{filePath, string(file), false, ""})
			}
		default:
			// do nothing
			logs.Warnf("unknown update behavior, do nothing")
		}
	}

	return nil
}

func writeBytes(buf *bytes.Buffer, bytes ...[]byte) error {
	for _, b := range bytes {
		_, err := buf.Write(b)
		if err != nil {
			return err
		}
	}

	return nil
}


================================================
FILE: cmd/hz/generator/file.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"fmt"
	"go/format"
	"path/filepath"
	"strings"

	"github.com/cloudwego/hertz/cmd/hz/util"
)

type File struct {
	Path        string
	Content     string
	NoRepeat    bool
	FileTplName string
}

// Lint is used to statically analyze and format go code
func (file *File) Lint() error {
	name := filepath.Base(file.Path)
	if strings.HasSuffix(name, ".go") {
		out, err := format.Source(util.Str2Bytes(file.Content))
		if err != nil {
			return fmt.Errorf("lint file '%s' failed, err: %v", name, err.Error())
		}
		file.Content = util.Bytes2Str(out)
	}
	return nil
}


================================================
FILE: cmd/hz/generator/handler.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"path"
	"path/filepath"
	"strings"

	"github.com/cloudwego/hertz/cmd/hz/generator/model"
	"github.com/cloudwego/hertz/cmd/hz/util"
	"github.com/cloudwego/hertz/cmd/hz/util/logs"
)

type HttpMethod struct {
	Name               string
	HTTPMethod         string
	Comment            string
	RequestTypeName    string
	RequestTypePackage string
	RequestTypeRawName string
	ReturnTypeName     string
	ReturnTypePackage  string
	ReturnTypeRawName  string
	Path               string
	Serializer         string
	OutputDir          string
	RefPackage         string // handler import dir
	RefPackageAlias    string // handler import alias
	ModelPackage       map[string]string
	GenHandler         bool // Whether to generate one handler, when an idl interface corresponds to multiple http method
	// Annotations     map[string]string
	Models map[string]*model.Model
}

type Handler struct {
	FilePath    string
	PackageName string
	ProjPackage string
	Imports     map[string]*model.Model
	Methods     []*HttpMethod
}

type SingleHandler struct {
	*HttpMethod
	FilePath    string
	PackageName string
	ProjPackage string
}

type Client struct {
	Handler
	ServiceName string
}

func (pkgGen *HttpPackageGenerator) genHandler(pkg *HttpPackage, handlerDir, handlerPackage string, root *RouterNode) error {
	for _, s := range pkg.Services {
		var handler Handler
		if pkgGen.HandlerByMethod { // generate handler by method
			for _, m := range s.Methods {
				filePath := filepath.Join(handlerDir, m.OutputDir, util.ToSnakeCase(m.Name)+".go")
				handler = Handler{
					FilePath:    filePath,
					PackageName: util.SplitPackage(filepath.Dir(filePath), ""),
					Methods:     []*HttpMethod{m},
					ProjPackage: pkgGen.ProjPackage,
				}

				if err := pkgGen.processHandler(&handler, root, handlerDir, m.OutputDir, true); err != nil {
					return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
				}

				if m.GenHandler {
					if err := pkgGen.updateHandler(handler, handlerTplName, handler.FilePath, false); err != nil {
						return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
					}
				}
			}
		} else { // generate handler service
			tmpHandlerDir := handlerDir
			tmpHandlerPackage := handlerPackage
			if len(s.ServiceGenDir) != 0 {
				tmpHandlerDir = s.ServiceGenDir
				tmpHandlerPackage = util.SubPackage(pkgGen.ProjPackage, strings.TrimPrefix(tmpHandlerDir, "/"))
			}
			handler = Handler{
				FilePath:    filepath.Join(tmpHandlerDir, util.ToSnakeCase(s.Name)+".go"),
				PackageName: util.SplitPackage(tmpHandlerPackage, ""),
				Methods:     s.Methods,
				ProjPackage: pkgGen.ProjPackage,
			}

			for _, m := range s.Methods {
				m.RefPackage = tmpHandlerPackage
				m.RefPackageAlias = util.BaseName(tmpHandlerPackage, "")
			}

			if err := pkgGen.processHandler(&handler, root, "", "", false); err != nil {
				return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
			}

			// Avoid generating duplicate handlers when IDL interface corresponds to multiple http methods
			methods := handler.Methods
			handler.Methods = []*HttpMethod{}
			for _, m := range methods {
				if m.GenHandler {
					handler.Methods = append(handler.Methods, m)
				}
			}

			if err := pkgGen.updateHandler(handler, handlerTplName, handler.FilePath, false); err != nil {
				return fmt.Errorf("generate handler %s failed, err: %v", handler.FilePath, err.Error())
			}
		}

		if len(pkgGen.ClientDir) != 0 {
			clientDir := util.SubDir(pkgGen.ClientDir, pkg.Package)
			clientPackage := util.SubPackage(pkgGen.ProjPackage, clientDir)
			client := Client{}
			client.Handler = handler
			client.ServiceName = s.Name
			client.PackageName = util.SplitPackage(clientPackage, "")
			client.FilePath = filepath.Join(clientDir, util.ToSnakeCase(s.Name)+".go")
			if err := pkgGen.updateClient(client, clientTplName, client.FilePath, false); err != nil {
				return fmt.Errorf("generate client %s failed, err: %v", client.FilePath, err.Error())
			}
		}

	}
	return nil
}

func (pkgGen *HttpPackageGenerator) processHandler(handler *Handler, root *RouterNode, handlerDir, projectOutDir string, handlerByMethod bool) error {
	singleHandlerPackage := ""
	if handlerByMethod {
		singleHandlerPackage = util.SubPackage(pkgGen.ProjPackage, filepath.Join(handlerDir, projectOutDir))
	}
	handler.Imports = make(map[string]*model.Model, len(handler.Methods))
	for _, m := range handler.Methods {
		// Iterate over the request and return parameters of the method to get import path.
		for key, mm := range m.Models {
			if v, ok := handler.Imports[mm.PackageName]; ok && v.Package != mm.Package {
				handler.Imports[key] = mm
				continue
			}
			handler.Imports[mm.PackageName] = mm
		}
		err := root.Update(m, handler.PackageName, singleHandlerPackage, pkgGen.SortRouter)
		if err != nil {
			return err
		}
	}

	if len(pkgGen.UseDir) != 0 {
		oldModelPkg := util.SubPackage(pkgGen.ProjPackage, filepath.Clean(pkgGen.ModelDir))
		newModelPkg := path.Clean(pkgGen.UseDir)
		for _, m := range handler.Methods {
			for _, mm := range m.Models {
				mm.Package = strings.Replace(mm.Package, oldModelPkg, newModelPkg, 1)
			}
		}
	}

	handler.Format()
	return nil
}

func (pkgGen *HttpPackageGenerator) updateHandler(handler interface{}, handlerTpl, filePath string, noRepeat bool) error {
	if pkgGen.tplsInfo[handlerTpl].Disable {
		return nil
	}
	isExist, err := util.PathExist(filePath)
	if err != nil {
		return err
	}
	if !isExist {
		return pkgGen.TemplateGenerator.Generate(handler, handlerTpl, filePath, noRepeat)
	}
	if pkgGen.HandlerByMethod { // method by handler, do not need to insert new content
		return nil
	}

	file, err := ioutil.ReadFile(filePath)
	if err != nil {
		return err
	}

	// insert new model imports
	for alias, model := range handler.(Handler).Imports {
		if bytes.Contains(file, []byte(model.Package)) {
			continue
		}
		file, err = util.AddImportForContent(file, alias, model.Package)
		if err != nil {
			return err
		}
	}
	// insert customized imports
	if tplInfo, exist := pkgGen.TemplateGenerator.tplsInfo[handlerTpl]; exist {
		if len(tplInfo.UpdateBehavior.ImportTpl) != 0 {
			imptSlice, err := getInsertImportContent(tplInfo, handler, file)
			if err != nil {
				return err
			}
			for _, impt := range imptSlice {
				if bytes.Contains(file, []byte(impt[1])) {
					continue
				}
				file, err = util.AddImportForContent(file, impt[0], impt[1])
				if err != nil {
					logs.Warnf("can not add import(%s) for file(%s), err: %v\n", impt[1], filePath, err)
				}
			}
		}
	}

	// insert new handler
	for _, method := range handler.(Handler).Methods {
		if bytes.Contains(file, []byte(fmt.Sprintf("func %s(", method.Name))) {
			continue
		}

		// Generate additional handlers using templates
		handlerSingleTpl := pkgGen.tpls[handlerSingleTplName]
		if handlerSingleTpl == nil {
			return fmt.Errorf("tpl %s not found", handlerSingleTplName)
		}
		data := SingleHandler{
			HttpMethod:  method,
			FilePath:    handler.(Handler).FilePath,
			PackageName: handler.(Handler).PackageName,
			ProjPackage: handler.(Handler).ProjPackage,
		}
		handlerFunc := bytes.NewBuffer(nil)
		err = handlerSingleTpl.Execute(handlerFunc, data)
		if err != nil {
			return fmt.Errorf("execute template \"%s\" failed, %v", handlerSingleTplName, err)
		}

		buf := bytes.NewBuffer(nil)
		_, err = buf.Write(file)
		if err != nil {
			return fmt.Errorf("write handler \"%s\" failed, %v", method.Name, err)
		}
		_, err = buf.Write(handlerFunc.Bytes())
		if err != nil {
			return fmt.Errorf("write handler \"%s\" failed, %v", method.Name, err)
		}
		file = buf.Bytes()
	}

	pkgGen.files = append(pkgGen.files, File{filePath, string(file), false, ""})

	return nil
}

func (pkgGen *HttpPackageGenerator) updateClient(client interface{}, clientTpl, filePath string, noRepeat bool) error {
	isExist, err := util.PathExist(filePath)
	if err != nil {
		return err
	}
	if !isExist {
		return pkgGen.TemplateGenerator.Generate(client, clientTpl, filePath, noRepeat)
	}
	logs.Infof("Client file:%s has been generated, so don't update it", filePath)

	return nil
}

func (m *HttpMethod) InitComment() {
	text := strings.TrimLeft(strings.TrimSpace(m.Comment), "/")
	if text == "" {
		text = "// " + m.Name + " ."
	} else if strings.HasPrefix(text, m.Name) {
		text = "// " + text
	} else {
		text = "// " + m.Name + " " + text
	}
	text = strings.Replace(text, "\n", "\n// ", -1)
	if !strings.Contains(text, "@router ") {
		text += "\n// @router " + m.Path
	}
	m.Comment = text + " [" + m.HTTPMethod + "]"
}

func MapSerializer(serializer string) string {
	switch serializer {
	case "json":
		return "JSON"
	case "thrift":
		return "Thrift"
	case "pb":
		return "ProtoBuf"
	default:
		return "JSON"
	}
}

func (h *Handler) Format() {
	for _, m := range h.Methods {
		m.Serializer = MapSerializer(m.Serializer)
		m.InitComment()
	}
}


================================================
FILE: cmd/hz/generator/layout.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"reflect"
	"strings"

	"github.com/cloudwego/hertz/cmd/hz/meta"
	"github.com/cloudwego/hertz/cmd/hz/util"
	"gopkg.in/yaml.v2"
)

// Layout contains the basic information of idl
type Layout struct {
	OutDir          string
	GoModule        string
	ServiceName     string
	UseApacheThrift bool
	HasIdl          bool
	NeedGoMod       bool
	ModelDir        string
	HandlerDir      string
	RouterDir       string
}

// LayoutGenerator contains the information generated by generating the layout template
type LayoutGenerator struct {
	ConfigPath string
	TemplateGenerator
}

var (
	layoutConfig  = defaultLayoutConfig
	packageConfig = defaultPkgConfig
)

func SetDefaultTemplateConfig() {
	layoutConfig = defaultLayoutConfig
	packageConfig = defaultPkgConfig
}

func (lg *LayoutGenerator) Init() error {
	config := layoutConfig
	// unmarshal from user-defined config file if it exists
	if lg.ConfigPath != "" {
		cdata, err := ioutil.ReadFile(lg.ConfigPath)
		if err != nil {
			return fmt.Errorf("read layout config from  %s failed, err: %v", lg.ConfigPath, err.Error())
		}
		config = TemplateConfig{}
		if err = yaml.Unmarshal(cdata, &config); err != nil {
			return fmt.Errorf("unmarshal layout config failed, err: %v", err.Error())
		}
	}

	if reflect.DeepEqual(config, TemplateConfig{}) {
		return errors.New("empty config")
	}
	lg.Config = &config

	return lg.TemplateGenerator.Init()
}

// checkInited initialize template definition
func (lg *LayoutGenerator) checkInited() error {
	if lg.tpls == nil || lg.dirs == nil {
		if err := lg.Init(); err != nil {
			return fmt.Errorf("init layout config failed, err: %v", err.Error())
		}
	}
	return nil
}

func (lg *LayoutGenerator) Generate(data map[string]interface{}) error {
	if err := lg.checkInited(); err != nil {
		return err
	}
	return lg.TemplateGenerator.Generate(data, "", "", false)
}

func (lg *LayoutGenerator) GenerateByService(service Layout) error {
	if err := lg.checkInited(); err != nil {
		return err
	}

	if len(service.HandlerDir) != 0 {
		// override the default "biz/handler/ping.go" to "HANDLER_DIR/ping.go"
		defaultPingDir := defaultHandlerDir + sp + "ping.go"
		if tpl, exist := lg.tpls[defaultPingDir]; exist {
			delete(lg.tpls, defaultPingDir)
			newPingDir := filepath.Clean(service.HandlerDir + sp + "ping.go")
			lg.tpls[newPingDir] = tpl
		}
	}

	if len(service.RouterDir) != 0 {
		defaultRegisterDir := defaultRouterDir + sp + registerTplName
		if tpl, exist := lg.tpls[defaultRegisterDir]; exist {
			delete(lg.tpls, defaultRegisterDir)
			newRegisterDir := filepath.Clean(service.RouterDir + sp + registerTplName)
			lg.tpls[newRegisterDir] = tpl
		}
	}

	if !service.NeedGoMod {
		gomodFile := "go.mod"
		if _, exist := lg.tpls[gomodFile]; exist {
			delete(lg.tpls, gomodFile)
		}
	}

	if util.IsWindows() {
		buildSh := "build.sh"
		bootstrapSh := defaultScriptDir + sp + "bootstrap.sh"
		if _, exist := lg.tpls[buildSh]; exist {
			delete(lg.tpls, buildSh)
		}
		if _, exist := lg.tpls[bootstrapSh]; exist {
			delete(lg.tpls, bootstrapSh)
		}
	}

	sd, err := serviceToLayoutData(service)
	if err != nil {
		return err
	}

	rd, err := serviceToRouterData(service)
	if err != nil {
		return err
	}
	if service.HasIdl {
		for k := range lg.tpls {
			if strings.Contains(k, registerTplName) {
				delete(lg.tpls, k)
				break
			}
		}
	}

	data := map[string]interface{}{
		"*":                                    sd,
		layoutConfig.Layouts[routerIndex].Path: rd, // router.go
		layoutConfig.Layouts[routerGenIndex].Path: rd, // router_gen.go
	}

	return lg.Generate(data)
}

// serviceToLayoutData stores go mod, serviceName, UseApacheThrift mapping
func serviceToLayoutData(service Layout) (map[string]interface{}, error) {
	goMod := service.GoModule
	if goMod == "" {
		return nil, errors.New("please specify go-module")
	}
	handlerPkg := filepath.Base(defaultHandlerDir)
	if len(service.HandlerDir) != 0 {
		handlerPkg = filepath.Base(service.HandlerDir)
	}
	routerPkg := filepath.Base(defaultRouterDir)
	if len(service.RouterDir) != 0 {
		routerPkg = filepath.Base(service.RouterDir)
	}
	serviceName := service.ServiceName
	if len(serviceName) == 0 {
		serviceName = meta.DefaultServiceName
	}

	return map[string]interface{}{
		"GoModule":        goMod,
		"ServiceName":     serviceName,
		"UseApacheThrift": service.UseApacheThrift,
		"HandlerPkg":      handlerPkg,
		"RouterPkg":       routerPkg,
	}, nil
}

// serviceToRouterData stores the registers function, router import path, handler import path
func serviceToRouterData(service Layout) (map[string]interface{}, error) {
	routerDir := sp + defaultRouterDir
	handlerDir := sp + defaultHandlerDir
	if len(service.RouterDir) != 0 {
		routerDir = sp + service.RouterDir
	}
	if len(service.HandlerDir) != 0 {
		handlerDir = sp + service.HandlerDir
	}
	return map[string]interface{}{
		"Registers":      []string{},
		"RouterPkgPath":  service.GoModule + filepath.ToSlash(routerDir),
		"HandlerPkgPath": service.GoModule + filepath.ToSlash(handlerDir),
	}, nil
}

func (lg *LayoutGenerator) GenerateByConfig(configPath string) error {
	if err := lg.checkInited(); err != nil {
		return err
	}
	buf, err := ioutil.ReadFile(configPath)
	if err != nil {
		return fmt.Errorf("read data file '%s' failed, err: %v", configPath, err.Error())
	}
	var data map[string]interface{}
	if err := json.Unmarshal(buf, &data); err != nil {
		return fmt.Errorf("unmarshal json data failed, err: %v", err.Error())
	}
	return lg.Generate(data)
}

func (lg *LayoutGenerator) Degenerate() error {
	return lg.TemplateGenerator.Degenerate()
}


================================================
FILE: cmd/hz/generator/layout_tpl.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import "path/filepath"

//-----------------------------------Default Layout-----------------------------------------

const (
	sp = string(filepath.Separator)

	defaultBizDir     = "biz"
	defaultModelDir   = "biz" + sp + "model"
	defaultHandlerDir = "biz" + sp + "handler"
	defaultServiceDir = "biz" + sp + "service"
	defaultDalDir     = "biz" + sp + "dal"
	defaultScriptDir  = "script"
	defaultConfDir    = "conf"
	defaultRouterDir  = "biz" + sp + "router"
	defaultClientDir  = "biz" + sp + "client"
)

const (
	routerGenIndex = 8
	routerIndex    = 9

	RegisterFile = "router_gen.go"
)

var defaultLayoutConfig = TemplateConfig{
	Layouts: []Template{
		{
			Path: defaultDalDir + sp,
		},
		{
			Path: defaultHandlerDir + sp,
		},
		{
			Path: defaultModelDir + sp,
		},
		{
			Path: defaultServiceDir + sp,
		},
		{
			Path: "main.go",
			Body: `// Code generated by hertz generator.

package main

import (
	"github.com/cloudwego/hertz/pkg/app/server"
)

func main() {
	h := server.Default()

	register(h)
	h.Spin()
}
			`,
		},
		{
			Path:   "go.mod",
			Delims: [2]string{"{{", "}}"},
			Body: `module {{.GoModule}}
{{- if .UseApacheThrift}}
replace github.com/apache/thrift => github.com/apache/thrift v0.13.0
{{- end}}
			`,
		},
		{
			Path: ".gitignore",
			Body: `*.o
*.a
*.so
_obj
_test
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.exe~
*.test
*.prof
*.rar
*.zip
*.gz
*.psd
*.bmd
*.cfg
*.pptx
*.log
*nohup.out
*settings.pyc
*.sublime-project
*.sublime-workspace
!.gitkeep
.DS_Store
/.idea
/.vscode
/output
*.local.yml
dumped_hertz_remote_config.json
		  `,
		},
		{
			Path: defaultHandlerDir + sp + "ping.go",
			Body: `// Code generated by hertz generator.

package {{.HandlerPkg}}

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/common/utils"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

// Ping .
func Ping(ctx context.Context, c *app.RequestContext) {
	c.JSON(consts.StatusOK, utils.H{
		"message": "pong",
	})
}
`,
		},
		{
			Path: RegisterFile,
			Body: `// Code generated by hertz generator. DO NOT EDIT.

package main

import (
	"github.com/cloudwego/hertz/pkg/app/server"
	router "{{.RouterPkgPath}}"
)

// register registers all routers.
func register(r *server.Hertz) {

	router.GeneratedRegister(r)

	customizedRegister(r)
}
`,
		},
		{
			Path: "router.go",
			Body: `// Code generated by hertz generator.

package main

import (
	"github.com/cloudwego/hertz/pkg/app/server"
	handler "{{.HandlerPkgPath}}"
)

// customizeRegister registers customize routers.
func customizedRegister(r *server.Hertz){
	r.GET("/ping", handler.Ping)

	// your code ...
}
`,
		},
		{
			Path: defaultRouterDir + sp + registerTplName,
			Body: `// Code generated by hertz generator. DO NOT EDIT.

package {{.RouterPkg}}

import (
	"github.com/cloudwego/hertz/pkg/app/server"
)

// GeneratedRegister registers routers generated by IDL.
func GeneratedRegister(r *server.Hertz){
	` + insertPointNew + `
}
`,
		},
		{
			Path: "build.sh",
			Body: `#!/bin/bash
RUN_NAME={{.ServiceName}}
mkdir -p output/bin
cp script/* output 2>/dev/null
chmod +x output/bootstrap.sh
go build -o output/bin/${RUN_NAME}`,
		},
		{
			Path: defaultScriptDir + sp + "bootstrap.sh",
			Body: `#!/bin/bash
CURDIR=$(cd $(dirname $0); pwd)
BinaryName={{.ServiceName}}
echo "$CURDIR/bin/${BinaryName}"
exec $CURDIR/bin/${BinaryName}`,
		},
	},
}


================================================
FILE: cmd/hz/generator/model/define.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package model

var (
	BaseTypes      = []*Type{TypeBool, TypeByte, TypeInt8, TypeInt16, TypeInt32, TypeInt64, TypeUint8, TypeUint16, TypeUint32, TypeUint64, TypeFloat64, TypeString, TypeBinary}
	ContainerTypes = []*Type{TypeBaseList, TypeBaseMap, TypeBaseSet}
	BaseModel      = Model{}
)

var (
	TypeBool = &Type{
		Name:  "bool",
		Scope: &BaseModel,
		Kind:  KindBool,
	}
	TypeByte = &Type{
		Name:  "int8",
		Scope: &BaseModel,
		Kind:  KindInt8,
	}
	TypePbByte = &Type{
		Name:  "byte",
		Scope: &BaseModel,
		Kind:  KindInt8,
	}
	TypeUint8 = &Type{
		Name:  "uint8",
		Scope: &BaseModel,
		Kind:  KindInt8,
	}
	TypeUint16 = &Type{
		Name:  "uint16",
		Scope: &BaseModel,
		Kind:  KindInt16,
	}
	TypeUint32 = &Type{
		Name:  "uint32",
		Scope: &BaseModel,
		Kind:  KindInt32,
	}
	TypeUint64 = &Type{
		Name:  "uint64",
		Scope: &BaseModel,
		Kind:  KindInt64,
	}
	TypeUint = &Type{
		Name:  "uint",
		Scope: &BaseModel,
		Kind:  KindInt,
	}
	TypeInt8 = &Type{
		Name:  "int8",
		Scope: &BaseModel,
		Kind:  KindInt8,
	}
	TypeInt16 = &Type{
		Name:  "int16",
		Scope: &BaseModel,
		Kind:  KindInt16,
	}
	TypeInt32 = &Type{
		Name:  "int32",
		Scope: &BaseModel,
		Kind:  KindInt32,
	}
	TypeInt64 = &Type{
		Name:  "int64",
		Scope: &BaseModel,
		Kind:  KindInt64,
	}
	TypeInt = &Type{
		Name:  "int",
		Scope: &BaseModel,
		Kind:  KindInt,
	}
	TypeFloat32 = &Type{
		Name:  "float32",
		Scope: &BaseModel,
		Kind:  KindFloat64,
	}
	TypeFloat64 = &Type{
		Name:  "float64",
		Scope: &BaseModel,
		Kind:  KindFloat64,
	}
	TypeString = &Type{
		Name:  "string",
		Scope: &BaseModel,
		Kind:  KindString,
	}
	TypeBinary = &Type{
		Name:     "binary",
		Scope:    &BaseModel,
		Kind:     KindSlice,
		Category: CategoryBinary,
		Extra:    []*Type{TypePbByte},
	}

	TypeBaseMap = &Type{
		Name:     "map",
		Scope:    &BaseModel,
		Kind:     KindMap,
		Category: CategoryMap,
	}
	TypeBaseSet = &Type{
		Name:     "set",
		Scope:    &BaseModel,
		Kind:     KindSlice,
		Category: CategorySet,
	}
	TypeBaseList = &Type{
		Name:     "list",
		Scope:    &BaseModel,
		Kind:     KindSlice,
		Category: CategoryList,
	}
)

func NewCategoryType(typ *Type, cg Category) *Type {
	cyp := *typ
	cyp.Category = cg
	return &cyp
}

func NewStructType(name string, cg Category) *Type {
	return &Type{
		Name:     name,
		Scope:    nil,
		Kind:     KindStruct,
		Category: cg,
		Indirect: false,
		Extra:    nil,
		HasNew:   true,
	}
}

func NewFuncType(name string, cg Category) *Type {
	return &Type{
		Name:     name,
		Scope:    nil,
		Kind:     KindFunc,
		Category: cg,
		Indirect: false,
		Extra:    nil,
		HasNew:   false,
	}
}

func IsBaseType(typ *Type) bool {
	for _, t := range BaseTypes {
		if typ == t {
			return true
		}
	}
	return false
}

func NewEnumType(name string, cg Category) *Type {
	return &Type{
		Name:     name,
		Scope:    &BaseModel,
		Kind:     KindInt,
		Category: cg,
		Indirect: false,
		Extra:    nil,
		HasNew:   true,
	}
}

func NewOneofType(name string) *Type {
	return &Type{
		Name:     name,
		Scope:    &BaseModel,
		Kind:     KindInterface,
		Indirect: false,
		Extra:    nil,
		HasNew:   true,
	}
}


================================================
FILE: cmd/hz/generator/model/expr.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package model

import (
	"fmt"
	"strconv"
)

type BoolExpression struct {
	Src bool
}

func (boolExpr BoolExpression) Expression() string {
	if boolExpr.Src {
		return "true"
	} else {
		return "false"
	}
}

type StringExpression struct {
	Src string
}

func (stringExpr StringExpression) Expression() string {
	return fmt.Sprintf("%q", stringExpr.Src)
}

type NumberExpression struct {
	Src string
}

func (numExpr NumberExpression) Expression() string {
	return numExpr.Src
}

type ListExpression struct {
	ElementType *Type
	Elements    []Literal
}

type IntExpression struct {
	Src int
}

func (intExpr IntExpression) Expression() string {
	return strconv.Itoa(intExpr.Src)
}

type DoubleExpression struct {
	Src float64
}

func (doubleExpr DoubleExpression) Expression() string {
	return strconv.FormatFloat(doubleExpr.Src, 'f', -1, 64)
}

func (listExpr ListExpression) Expression() string {
	ret := "[]" + listExpr.ElementType.Name + "{\n"
	for _, e := range listExpr.Elements {
		ret += e.Expression() + ",\n"
	}
	ret += "\n}"
	return ret
}

type MapExpression struct {
	KeyType   *Type
	ValueType *Type
	Elements  map[string]Literal
}

func (mapExpr MapExpression) Expression() string {
	ret := "map[" + mapExpr.KeyType.Name + "]" + mapExpr.ValueType.Name + "{\n"
	for k, e := range mapExpr.Elements {
		ret += fmt.Sprintf("%q: %s,\n", k, e.Expression())
	}
	ret += "\n}"
	return ret
}


================================================
FILE: cmd/hz/generator/model/golang/constant.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

var constants = `
{{define "Constants"}}
const {{.Name}} {{.Type.ResolveName ROOT}} = {{.Value.Expression}}
{{end}}
`


================================================
FILE: cmd/hz/generator/model/golang/enum.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

// Enum .
var enum = `
{{define "Enum"}}
{{- $EnumType := (Identify .Name)}}
type {{$EnumType}} {{.GoType}}

const (
	{{- range $i, $e := .Values}}
	{{$EnumType}}_{{$e.Name}} {{$EnumType}} = {{$e.Value.Expression}}
	{{- end}}
)

func (p {{$EnumType}}) String() string {
	switch p {
	{{- range $i, $e := .Values}}
	case {{$EnumType}}_{{$e.Name}}:
		return "{{printf "%s%s" $EnumType $e.Name | SnakeCase}}"
	{{- end}}
	}
	return "<UNSET>"
}

func {{$EnumType}}FromString(s string) ({{$EnumType}}, error) {
	switch s {
	{{- range $i, $e := .Values}}
	case "{{printf "%s%s" $EnumType $e.Name | SnakeCase}}":
		return {{$EnumType}}_{{$e.Name}}, nil
	{{- end}}
	}
	return {{$EnumType}}(0), fmt.Errorf("not a valid {{$EnumType}} string")
}

{{- if Features.MarshalEnumToText}}

func (p {{$EnumType}}) MarshalText() ([]byte, error) {
	return []byte(p.String()), nil
}

func (p *{{$EnumType}}) UnmarshalText(text []byte) error {
	q, err := {{$EnumType}}FromString(string(text))
	if err != nil {
		return err
	}
	*p = q
	return nil
}
{{- end}}
{{end}}
`


================================================
FILE: cmd/hz/generator/model/golang/file.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

var file = `{{$ROOT := . -}}
// Code generated by hz.

package {{.PackageName}}

import (
	"fmt"
{{- range $alias, $model := .Imports}}
	{{$model.PackageName}} "{{$model.Package}}"
{{- end}}
)

{{- range .Typedefs}}
{{template "Typedef" .}}
{{- end}}

{{- range .Constants}}
{{template "Constants" .}}
{{- end}}

{{- range .Variables}}
{{template "Variables" .}}
{{- end}}

{{- range .Functions}}
{{template "Function" .}}
{{- end}}

{{- range .Enums}}
{{template "Enum" .}}
{{- end}}

{{- range .Oneofs}}
{{template "Oneof" .}}
{{- end}}

{{- range .Structs}}
{{template "Struct" .}}
{{- end}}

{{- range .Methods}}
{{template "Method" .}}
{{- end}}
`


================================================
FILE: cmd/hz/generator/model/golang/function.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

var function = `
{{define "Function"}}
func {{template "FuncBody" . -}}
{{end}}{{/* define "Function" */}}

{{define "FuncBody"}}
{{- .Name -}}(
{{- range $i, $arg := .Args -}}
{{- if gt $i 0}}, {{end -}}
{{$arg.Name}} {{$arg.Type.ResolveName ROOT}}
{{- end -}}{{/* range */}})
{{- if gt (len .Rets) 0}} ({{end -}}
{{- range $i, $ret := .Rets -}}
{{- if gt $i 0}}, {{end -}}
{{$ret.Type.ResolveName ROOT}}
{{- end -}}{{/* range */}}
{{- if gt (len .Rets) 0}}) {{end -}}{
{{.Code}}
}
{{end}}{{/* define "FuncBody" */}}
`

var method = `
{{define "Method"}}
func ({{.ReceiverName}} {{.ReceiverType.ResolveName ROOT}}) 
{{- template "FuncBody" .Function -}}
{{end}}
`


================================================
FILE: cmd/hz/generator/model/golang/init.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

import (
	"fmt"
	"strings"
	"text/template"
)

var tpls *template.Template

var list = map[string]string{
	"file":      file,
	"typedef":   typedef,
	"constants": constants,
	"variables": variables,
	"function":  function,
	"enum":      enum,
	"struct":    structLike,
	"method":    method,
	"oneof":     oneof,
}

/***********************Export API*******************************/

func Template() (*template.Template, error) {
	if tpls != nil {
		return tpls, nil
	}
	tpls = new(template.Template)

	tpls = tpls.Funcs(funcMap)

	var err error
	for k, li := range list {
		tpls, err = tpls.Parse(li)
		if err != nil {
			return nil, fmt.Errorf("parse template '%s' failed, err: %v", k, err.Error())
		}
	}
	return tpls, nil
}

func List() map[string]string {
	return list
}

/***********************Template Funcs**************************/

var funcMap = template.FuncMap{
	"Features":            getFeatures,
	"Identify":            identify,
	"CamelCase":           camelCase,
	"SnakeCase":           snakeCase,
	"GetTypedefReturnStr": getTypedefReturnStr,
}

func Funcs(name string, fn interface{}) error {
	if _, ok := funcMap[name]; ok {
		return fmt.Errorf("duplicate function: %s has been registered", name)
	}
	funcMap[name] = fn
	return nil
}

func identify(name string) string {
	return name
}

func camelCase(name string) string {
	return name
}

func snakeCase(name string) string {
	return name
}

func getTypedefReturnStr(name string) string {
	if strings.Contains(name, ".") {
		idx := strings.LastIndex(name, ".")
		return name[:idx] + "." + "New" + name[idx+1:] + "()"

	}
	return "New" + name + "()"
}

/***********************Template Options**************************/

type feature struct {
	MarshalEnumToText  bool
	TypedefAsTypeAlias bool
}

var features = feature{}

func getFeatures() feature {
	return features
}

func SetOption(opt string) error {
	switch opt {
	case "MarshalEnumToText":
		features.MarshalEnumToText = true
	case "TypedefAsTypeAlias":
		features.TypedefAsTypeAlias = true
	}
	return nil
}

var Options = []string{
	"MarshalEnumToText",
	"TypedefAsTypeAlias",
}

func GetOptions() []string {
	return Options
}


================================================
FILE: cmd/hz/generator/model/golang/oneof.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

var oneof = `
{{define "Oneof"}}
type {{$.InterfaceName}} interface {
	{{$.InterfaceName}}()
}

{{range $i, $f := .Choices}}
type {{$f.MessageName}}_{{$f.ChoiceName}} struct {
	{{$f.ChoiceName}} {{$f.Type.ResolveName ROOT}}
}
{{end}}

{{range $i, $f := .Choices}}
func (*{{$f.MessageName}}_{{$f.ChoiceName}}) {{$.InterfaceName}}() {}
{{end}}

{{range $i, $f := .Choices}}
func (p *{{$f.MessageName}}) Get{{$f.ChoiceName}}() {{$f.Type.ResolveName ROOT}} {
	if p, ok := p.Get{{$.OneofName}}().(*{{$f.MessageName}}_{{$f.ChoiceName}}); ok {
		return p.{{$f.ChoiceName}}
	}
	return {{$f.Type.ResolveDefaultValue}}
}
{{end}}

{{end}}
`


================================================
FILE: cmd/hz/generator/model/golang/struct.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

// StructLike is the code template for struct, union, and exception.
var structLike = `
{{define "Struct"}}
{{- $TypeName := (Identify .Name) -}}
{{$MessageLeadingComments := .LeadingComments}}
{{if ne (len $MessageLeadingComments) 0}}
//{{$MessageLeadingComments}}
{{end -}}
type {{$TypeName}} struct {
{{- range $i, $f := .Fields}}
{{- $FieldLeadingComments := $f.LeadingComments}}
{{$FieldTrailingComments := $f.TrailingComments -}}
{{- if ne (len $FieldLeadingComments) 0 -}}
    //{{$FieldLeadingComments}}
{{end -}}
{{- if $f.IsPointer -}}
	{{$f.Name}} *{{$f.Type.ResolveName ROOT}} {{$f.GenGoTags}}{{if ne (len $FieldTrailingComments) 0}} //{{$FieldTrailingComments}}{{end -}}
{{- else -}}
	{{$f.Name}} {{$f.Type.ResolveName ROOT}} {{$f.GenGoTags}}{{if ne (len $FieldTrailingComments) 0}} //{{$FieldTrailingComments}}{{end -}}
{{- end -}}
{{- end}}
}

func New{{$TypeName}}() *{{$TypeName}} {
	return &{{$TypeName}}{
		{{template "StructLikeDefault" .}}
	}
}

{{template "FieldGetOrSet" .}}

{{if eq .Category 14}}
func (p *{{$TypeName}}) CountSetFields{{$TypeName}}() int {
	count := 0
	{{- range $i, $f := .Fields}}
	{{- if $f.Type.IsSettable}}
	if p.IsSet{{$f.Name}}() {
		count++
	}
	{{- end}}
	{{- end}}
	return count
}
{{- end}}

func (p *{{$TypeName}}) String() string {
	if p == nil {
		return "<nil>"
	}
	return fmt.Sprintf("{{$TypeName}}(%+v)", *p)
}

{{- if eq .Category 15}}
func (p *{{$TypeName}}) Error() string {
	return p.String()
}
{{- end}}
{{- end}}{{/* define "StructLike" */}}

{{- define "StructLikeDefault"}}
{{- range $i, $f := .Fields}}
	{{- if $f.IsSetDefault}}
		{{$f.Name}}: {{$f.DefaultValue.Expression}},
	{{- end}}
{{- end}}
{{- end -}}{{/* define "StructLikeDefault" */}}

{{- define "FieldGetOrSet"}}
{{- $TypeName := (Identify .Name)}}
{{- range $i, $f := .Fields}}
{{$FieldName := $f.Name}}
{{$FieldTypeName := $f.Type.ResolveName ROOT}}

{{- if $f.Type.IsSettable}}
func (p *{{$TypeName}}) IsSet{{$FieldName}}() bool {
	return p.{{$FieldName}} != nil
}
{{- end}}{{/* IsSettable . */}}

func (p *{{$TypeName}}) Get{{$FieldName}}() {{$FieldTypeName}} {
	{{- if $f.Type.IsSettable}}
	if !p.IsSet{{$FieldName}}() {
		return {{with $f.DefaultValue}}{{$f.DefaultValue.Expression}}{{else}}nil{{end}}
	}
	{{- end}}
{{- if $f.IsPointer}}
	return *p.{{$FieldName}}
{{else}}
	return p.{{$FieldName}}
{{- end -}}
}

func (p *{{$TypeName}}) Set{{$FieldName}}(val {{$FieldTypeName}}) {
{{- if $f.IsPointer}}
	*p.{{$FieldName}} = val
{{else}}
	p.{{$FieldName}} = val
{{- end -}}
}
{{- end}}{{/* range .Fields */}}
{{- end}}{{/* define "FieldGetOrSet" */}}
`


================================================
FILE: cmd/hz/generator/model/golang/typedef.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

// Typedef .
var typedef = `
{{define "Typedef"}}
{{- $NewTypeName := (Identify .Alias)}}
{{- $OldTypeName := .Type.ResolveNameForTypedef ROOT}}
type {{$NewTypeName}} = {{$OldTypeName}}

{{if eq .Type.Kind 25}}{{if .Type.HasNew}}
func New{{$NewTypeName}}() *{{$NewTypeName}} {
	return {{(GetTypedefReturnStr $OldTypeName)}}
}
{{- end}}{{- end}}
{{- end}}
`


================================================
FILE: cmd/hz/generator/model/golang/variable.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package golang

var variables = `
{{- define "Variables"}}
var {{.Name}} {{.Type.ResolveName ROOT}} = {{.Value.Expression}}
{{end}}
`


================================================
FILE: cmd/hz/generator/model/model.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package model

import (
	"errors"
	"fmt"
	"strings"
)

type Kind uint

const (
	KindInvalid Kind = iota
	KindBool
	KindInt
	KindInt8
	KindInt16
	KindInt32
	KindInt64
	KindUint
	KindUint8
	KindUint16
	KindUint32
	KindUint64
	KindUintptr
	KindFloat32
	KindFloat64
	KindComplex64
	KindComplex128
	KindArray
	KindChan
	KindFunc
	KindInterface
	KindMap
	KindPtr
	KindSlice
	KindString
	KindStruct
	KindUnsafePointer
)

type Category int64

const (
	CategoryConstant  Category = 1
	CategoryBinary    Category = 8
	CategoryMap       Category = 9
	CategoryList      Category = 10
	CategorySet       Category = 11
	CategoryEnum      Category = 12
	CategoryStruct    Category = 13
	CategoryUnion     Category = 14
	CategoryException Category = 15
	CategoryTypedef   Category = 16
	CategoryService   Category = 17
)

type Model struct {
	FilePath string
	Package  string
	Imports  map[string]*Model //{{import}}:Model

	// rendering data
	PackageName string
	// Imports     map[string]string //{{alias}}:{{import}}
	Typedefs  []TypeDef
	Constants []Constant
	Variables []Variable
	Functions []Function
	Enums     []Enum
	Structs   []Struct
	Methods   []Method
	Oneofs    []Oneof
}

func (m Model) IsEmpty() bool {
	return len(m.Typedefs) == 0 && len(m.Constants) == 0 && len(m.Variables) == 0 &&
		len(m.Functions) == 0 && len(m.Enums) == 0 && len(m.Structs) == 0 && len(m.Methods) == 0
}

type Models []*Model

func (a *Models) MergeMap(b map[string]*Model) {
	for _, v := range b {
		insert := true
		for _, p := range *a {
			if p == v {
				insert = false
			}
		}
		if insert {
			*a = append(*a, v)
		}
	}
	return
}

func (a *Models) MergeArray(b []*Model) {
	for _, v := range b {
		insert := true
		for _, p := range *a {
			if p == v {
				insert = false
			}
		}
		if insert {
			*a = append(*a, v)
		}
	}
	return
}

type RequiredNess int

const (
	RequiredNess_Default  RequiredNess = 0
	RequiredNess_Required RequiredNess = 1
	RequiredNess_Optional RequiredNess = 2
)

type Type struct {
	Name     string
	Scope    *Model
	Kind     Kind
	Indirect bool
	Category Category
	Extra    []*Type // [{key_type},{value_type}] for map, [{element_type}] for list or set
	HasNew   bool
}

func (rt *Type) ResolveDefaultValue() string {
	if rt == nil {
		return ""
	}
	switch rt.Kind {
	case KindInt, KindInt8, KindInt16, KindInt32, KindInt64, KindUint, KindUint16, KindUint32, KindUint64,
		KindFloat32, KindFloat64, KindComplex64, KindComplex128:
		return "0"
	case KindBool:
		return "false"
	case KindString:
		return "\"\""
	default:
		return "nil"
	}
}

func (rt *Type) ResolveNameForTypedef(scope *Model) (string, error) {
	if rt == nil {
		return "", errors.New("type is nil")
	}
	name := rt.Name
	if rt.Scope == nil {
		return rt.Name, nil
	}

	switch rt.Kind {
	case KindArray, KindSlice:
		if len(rt.Extra) != 1 {
			return "", fmt.Errorf("the type: %s should have 1 extra type, but has %d", rt.Name, len(rt.Extra))
		}
		resolveName, err := rt.Extra[0].ResolveName(scope)
		if err != nil {
			return "", err
		}
		name = fmt.Sprintf("[]%s", resolveName)
	case KindMap:
		if len(rt.Extra) != 2 {
			return "", fmt.Errorf("the type: %s should have 2 extra types, but has %d", rt.Name, len(rt.Extra))
		}
		resolveKey, err := rt.Extra[0].ResolveName(scope)
		if err != nil {
			return "", err
		}
		resolveValue, err := rt.Extra[1].ResolveName(scope)
		if err != nil {
			return "", err
		}
		name = fmt.Sprintf("map[%s]%s", resolveKey, resolveValue)
	case KindChan:
		if len(rt.Extra) != 1 {
			return "", fmt.Errorf("the type: %s should have 1 extra type, but has %d", rt.Name, len(rt.Extra))
		}
		resolveName, err := rt.Extra[0].ResolveName(scope)
		if err != nil {
			return "", err
		}
		name = fmt.Sprintf("chan %s", resolveName)
	}

	if scope != nil && rt.Scope != &BaseModel && rt.Scope.Package != scope.Package {
		name = rt.Scope.PackageName + "." + name
	}
	return name, nil
}

func (rt *Type) ResolveName(scope *Model) (string, error) {
	if rt == nil {
		return "", fmt.Errorf("type is nil")
	}
	name := rt.Name
	if rt.Scope == nil {
		if rt.Kind == KindStruct {
			return "*" + rt.Name, nil
		}
		return rt.Name, nil
	}

	if rt.Category == CategoryTypedef {
		if scope != nil && rt.Scope != &BaseModel && rt.Scope.Package != scope.Package {
			name = rt.Scope.PackageName + "." + name
		}

		if rt.Kind == KindStruct {
			name = "*" + name
		}

		return name, nil
	}

	switch rt.Kind {
	case KindArray, KindSlice:
		if len(rt.Extra) != 1 {
			return "", fmt.Errorf("The type: %s should have 1 extra type, but has %d", rt.Name, len(rt.Extra))
		}
		resolveName, err := rt.Extra[0].ResolveName(scope)
		if err != nil {
			return "", err
		}
		name = fmt.Sprintf("[]%s", resolveName)
	case KindMap:
		if len(rt.Extra) != 2 {
			return "", fmt.Errorf("The type: %s should have 2 extra type, but has %d", rt.Name, len(rt.Extra))
		}
		resolveKey, err := rt.Extra[0].ResolveName(scope)
		if err != nil {
			return "", err
		}
		resolveValue, err := rt.Extra[1].ResolveName(scope)
		if err != nil {
			return "", err
		}
		name = fmt.Sprintf("map[%s]%s", resolveKey, resolveValue)
	case KindChan:
		if len(rt.Extra) != 1 {
			return "", fmt.Errorf("The type: %s should have 1 extra type, but has %d", rt.Name, len(rt.Extra))
		}
		resolveName, err := rt.Extra[0].ResolveName(scope)
		if err != nil {
			return "", err
		}
		name = fmt.Sprintf("chan %s", resolveName)
	}

	if scope != nil && rt.Scope != &BaseModel && rt.Scope.Package != scope.Package {
		name = rt.Scope.PackageName + "." + name
	}

	if rt.Kind == KindStruct {
		name = "*" + name
	}
	return name, nil
}

func (rt *Type) IsBinary() bool {
	return rt.Category == CategoryBinary && (rt.Kind == KindSlice || rt.Kind == KindArray)
}

func (rt *Type) IsBaseType() bool {
	return rt.Kind < KindComplex64
}

func (rt *Type) IsSettable() bool {
	switch rt.Kind {
	case KindArray, KindChan, KindFunc, KindInterface, KindMap, KindPtr, KindSlice, KindUnsafePointer:
		return true
	}
	return false
}

type TypeDef struct {
	Scope *Model
	Alias string
	Type  *Type
}

type Constant struct {
	Scope *Model
	Name  string
	Type  *Type
	Value Literal
}

type Literal interface {
	Expression() string
}

type Variable struct {
	Scope *Model
	Name  string
	Type  *Type
	Value Literal
}

type Function struct {
	Scope *Model
	Name  string
	Args  []Variable
	Rets  []Variable
	Code  string
}

type Method struct {
	Scope        *Model
	ReceiverName string
	ReceiverType *Type
	ByPtr        bool
	Function
}

type Enum struct {
	Scope  *Model
	Name   string
	GoType string
	Values []Constant
}

type Struct struct {
	Scope           *Model
	Name            string
	Fields          []Field
	Category        Category
	LeadingComments string
}

type Field struct {
	Scope            *Struct
	Name             string
	Type             *Type
	IsSetDefault     bool
	DefaultValue     Literal
	Required         RequiredNess
	Tags             Tags
	LeadingComments  string
	TrailingComments string
	IsPointer        bool
}

type Oneof struct {
	MessageName   string
	OneofName     string
	InterfaceName string
	Choices       []Choice
}

type Choice struct {
	MessageName string
	ChoiceName  string
	Type        *Type
}

type Tags []Tag

type Tag struct {
	Key       string
	Value     string
	IsDefault bool // default tag
}

func (ts Tags) String() string {
	ret := make([]string, 0, len(ts))
	for _, t := range ts {
		ret = append(ret, fmt.Sprintf("%v:%q", t.Key, t.Value))
	}
	return strings.Join(ret, " ")
}

func (ts *Tags) Remove(name string) {
	ret := make([]Tag, 0, len(*ts))
	for _, t := range *ts {
		if t.Key != name {
			ret = append(ret, t)
		}
	}
	*ts = ret
}

func (ts Tags) Len() int { return len(ts) }

func (ts Tags) Less(i, j int) bool {
	return ts[i].Key < ts[j].Key
}

func (ts Tags) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] }

func (f Field) GenGoTags() string {
	if len(f.Tags) == 0 {
		return ""
	}

	return fmt.Sprintf("`%s`", f.Tags.String())
}


================================================
FILE: cmd/hz/generator/model.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"fmt"
	"path/filepath"
	"strings"
	"text/template"

	"github.com/cloudwego/hertz/cmd/hz/generator/model"
	"github.com/cloudwego/hertz/cmd/hz/generator/model/golang"
	"github.com/cloudwego/hertz/cmd/hz/meta"
	"github.com/cloudwego/hertz/cmd/hz/util"
)

//---------------------------------Backend----------------------------------

type Option string

const (
	OptionMarshalEnumToText  Option = "MarshalEnumToText"
	OptionTypedefAsTypeAlias Option = "TypedefAsTypeAlias"
)

type Backend interface {
	Template() (*template.Template, error)
	List() map[string]string
	SetOption(opts string) error
	GetOptions() []string
	Funcs(name string, fn interface{}) error
}

type GolangBackend struct{}

func (gb *GolangBackend) Template() (*template.Template, error) {
	return golang.Template()
}

func (gb *GolangBackend) List() map[string]string {
	return golang.List()
}

func (gb *GolangBackend) SetOption(opts string) error {
	return golang.SetOption(opts)
}

func (gb *GolangBackend) GetOptions() []string {
	return golang.GetOptions()
}

func (gb *GolangBackend) Funcs(name string, fn interface{}) error {
	return golang.Funcs(name, fn)
}

func switchBackend(backend meta.Backend) Backend {
	switch backend {
	case meta.BackendGolang:
		return &GolangBackend{}
	}
	return loadThirdPartyBackend(string(backend))
}

func loadThirdPartyBackend(plugin string) Backend {
	panic("no implement yet!")
}

/**********************Generating*************************/

func (pkgGen *HttpPackageGenerator) LoadBackend(backend meta.Backend) error {
	bd := switchBackend(backend)
	if bd == nil {
		return fmt.Errorf("no found backend '%s'", backend)
	}
	for _, opt := range pkgGen.Options {
		if err := bd.SetOption(string(opt)); err != nil {
			return fmt.Errorf("set option %s error, err: %v", opt, err.Error())
		}
	}

	err := bd.Funcs("ROOT", func() *model.Model {
		return pkgGen.curModel
	})
	if err != nil {
		return fmt.Errorf("register global function in model template failed, err: %v", err.Error())
	}

	tpl, err := bd.Template()
	if err != nil {
		return fmt.Errorf("load backend %s failed, err: %v", backend, err.Error())
	}

	if pkgGen.tpls == nil {
		pkgGen.tpls = map[string]*template.Template{}
	}
	pkgGen.tpls[modelTplName] = tpl
	pkgGen.loadedBackend = bd
	return nil
}

func (pkgGen *HttpPackageGenerator) GenModel(data *model.Model, gen bool) error {
	if pkgGen.processedModels == nil {
		pkgGen.processedModels = map[*model.Model]bool{}
	}

	if _, ok := pkgGen.processedModels[data]; !ok {
		var path string
		var updatePackage bool
		if strings.HasPrefix(data.Package, pkgGen.ProjPackage) && data.PackageName != pkgGen.ProjPackage {
			path = data.Package[len(pkgGen.ProjPackage):]
		} else {
			path = data.Package
			updatePackage = true
		}
		modelDir := util.SubDir(pkgGen.ModelDir, path)
		if updatePackage {
			data.Package = util.SubPackage(pkgGen.ProjPackage, modelDir)
		}
		data.FilePath = filepath.Join(modelDir, util.BaseNameAndTrim(data.FilePath)+".go")

		pkgGen.processedModels[data] = true
	}

	for _, dep := range data.Imports {
		if err := pkgGen.GenModel(dep, false); err != nil {
			return fmt.Errorf("generate model %s failed, err: %v", dep.FilePath, err.Error())
		}
	}

	if gen && !data.IsEmpty() {
		pkgGen.curModel = data
		removeDuplicateImport(data)
		err := pkgGen.TemplateGenerator.Generate(data, modelTplName, data.FilePath, false)
		pkgGen.curModel = nil
		return err
	}
	return nil
}

// Idls with the same Package do not need to refer to each other
func removeDuplicateImport(data *model.Model) {
	for k, v := range data.Imports {
		if data.Package == v.Package {
			delete(data.Imports, k)
		}
	}
}


================================================
FILE: cmd/hz/generator/model_test.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"testing"
	"text/template"

	"github.com/cloudwego/hertz/cmd/hz/generator/model"
	"github.com/cloudwego/hertz/cmd/hz/meta"
)

type StringValue struct {
	src string
}

func (sv *StringValue) Expression() string {
	return sv.src
}

func TestIdlGenerator_GenModel(t *testing.T) {
	typeModel := &model.Type{
		Name:     "Model",
		Kind:     model.KindStruct,
		Indirect: true,
	}
	typeErr := &model.Type{
		Name:     "error",
		Kind:     model.KindInterface,
		Indirect: false,
	}

	type fields struct {
		ConfigPath  string
		OutputDir   string
		Backend     meta.Backend
		handlerDir  string
		routerDir   string
		modelDir    string
		ProjPackage string
		Config      *TemplateConfig
		tpls        map[string]*template.Template
	}
	type args struct {
		data *model.Model
	}
	tests := []struct {
		name    string
		fields  fields
		args    args
		wantErr bool
	}{
		{
			name: "",
			fields: fields{
				OutputDir: "./testdata",
				Backend:   meta.BackendGolang,
			},
			args: args{
				data: &model.Model{
					FilePath:    "idl/main.thrift",
					Package:     "model/psm",
					PackageName: "psm",
					Imports: map[string]*model.Model{
						"base": {
							Package:     "model/base",
							PackageName: "base",
						},
					},
					Typedefs: []model.TypeDef{
						{
							Alias: "HerztModel",
							Type:  typeModel,
						},
					},
					Constants: []model.Constant{
						{
							Name:  "OBJ",
							Type:  typeErr,
							Value: &StringValue{"fmt.Errorf(\"EOF\")"},
						},
					},
					Variables: []model.Variable{
						{
							Name:  "Object",
							Type:  typeModel,
							Value: &StringValue{"&Model{}"},
						},
					},
					Functions: []model.Function{
						{
							Name: "Init",
							Args: nil,
							Rets: []model.Variable{
								{
									Name: "err",
									Type: typeErr,
								},
							},
							Code: "return nil",
						},
					},
					Enums: []model.Enum{
						{
							Name: "Sex",
							Values: []model.Constant{
								{
									Name: "Male",
									Type: &model.Type{
										Name:     "int",
										Kind:     model.KindInt,
										Indirect: false,
										Category: 1,
									},
									Value: &StringValue{"1"},
								},
								{
									Name: "Femal",
									Type: &model.Type{
										Name:     "int",
										Kind:     model.KindInt,
										Indirect: false,
										Category: 1,
									},
									Value: &StringValue{"2"},
								},
							},
						},
					},
					Structs: []model.Struct{
						{
							Name: "Model",
							Fields: []model.Field{
								{
									Name: "A",
									Type: &model.Type{
										Name:     "[]byte",
										Kind:     model.KindSlice,
										Indirect: false,
										Category: model.CategoryBinary,
									},
									IsSetDefault: true,
									DefaultValue: &StringValue{"[]byte(\"\")"},
								},
								{
									Name: "B",
									Type: &model.Type{
										Name:     "Base",
										Kind:     model.KindStruct,
										Indirect: false,
									},
								},
							},
							Category: model.CategoryUnion,
						},
					},
					Methods: []model.Method{
						{
							ReceiverName: "self",
							ReceiverType: typeModel,
							ByPtr:        true,
							Function: model.Function{
								Name: "Bind",
								Args: []model.Variable{
									{
										Name: "c",
										Type: &model.Type{
											Name: "RequestContext",
											Scope: &model.Model{
												PackageName: "hertz",
											},
											Kind:     model.KindStruct,
											Indirect: true,
										},
									},
								},
								Rets: []model.Variable{
									{
										Name: "error",
										Type: typeErr,
									},
								},
								Code: "return nil",
							},
						},
					},
				},
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			self := &HttpPackageGenerator{
				ConfigPath:  tt.fields.ConfigPath,
				Backend:     tt.fields.Backend,
				HandlerDir:  tt.fields.handlerDir,
				RouterDir:   tt.fields.routerDir,
				ModelDir:    tt.fields.modelDir,
				ProjPackage: tt.fields.ProjPackage,
				TemplateGenerator: TemplateGenerator{
					OutputDir: tt.fields.OutputDir,
					Config:    tt.fields.Config,
					tpls:      tt.fields.tpls,
				},
				Options: []Option{
					OptionTypedefAsTypeAlias,
					OptionMarshalEnumToText,
				},
			}

			err := self.LoadBackend(meta.BackendGolang)
			if err != nil {
				t.Fatal(err)
			}

			if err := self.GenModel(tt.args.data, true); (err != nil) != tt.wantErr {
				t.Errorf("IdlGenerator.GenModel() error = %v, wantErr %v", err, tt.wantErr)
			}
			if err := self.Persist(); err != nil {
				t.Fatal(err)
			}
		})
	}
}


================================================
FILE: cmd/hz/generator/package.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

import (
	"errors"
	"fmt"
	"io/ioutil"
	"path/filepath"
	"reflect"
	"text/template"

	"github.com/cloudwego/hertz/cmd/hz/generator/model"
	"github.com/cloudwego/hertz/cmd/hz/meta"
	"github.com/cloudwego/hertz/cmd/hz/util"
	"gopkg.in/yaml.v2"
)

type HttpPackage struct {
	IdlName    string
	Package    string
	Services   []*Service
	Models     []*model.Model
	RouterInfo *Router
}

type Service struct {
	Name          string
	Methods       []*HttpMethod
	ClientMethods []*ClientMethod
	Models        []*model.Model // all dependency models
	BaseDomain    string         // base domain for client code
	ServiceGroup  string         // service level router group
	ServiceGenDir string         // handler_dir for handler_by_service
}

// HttpPackageGenerator is used to record the configuration related to generating hertz http code.
type HttpPackageGenerator struct {
	ConfigPath     string       // package template path
	Backend        meta.Backend // model template
	Options        []Option
	CmdType        string
	ProjPackage    string // go module for project
	HandlerDir     string
	RouterDir      string
	ModelDir       string // like: biz/model or biz\model (Windows)
	UseDir         string // XXX: should be UsePkg, not a filepath?
	ClientDir      string // client dir for "new"/"update" command
	IdlClientDir   string // client dir for "client" command
	ForceClientDir string // client dir without namespace for "client" command
	BaseDomain     string // request domain for "client" command
	QueryEnumAsInt bool   // client code use number for query parameter
	ServiceGenDir  string

	NeedModel            bool
	HandlerByMethod      bool // generate handler files with method dimension
	SnakeStyleMiddleware bool // use snake name style for middleware
	SortRouter           bool
	ForceUpdateClient    bool // force update 'hertz_client.go'

	loadedBackend   Backend
	curModel        *model.Model
	processedModels map[*model.Model]bool

	TemplateGenerator
}

func (pkgGen *HttpPackageGenerator) Init() error {
	defaultConfig := packageConfig
	customConfig := TemplateConfig{}
	// unmarshal from user-defined config file if it exists
	if pkgGen.ConfigPath != "" {
		cdata, err := ioutil.ReadFile(pkgGen.ConfigPath)
		if err != nil {
			return fmt.Errorf("read layout config from  %s failed, err: %v", pkgGen.ConfigPath, err.Error())
		}
		if err = yaml.Unmarshal(cdata, &customConfig); err != nil {
			return fmt.Errorf("unmarshal layout config failed, err: %v", err.Error())
		}
		if reflect.DeepEqual(customConfig, TemplateConfig{}) {
			return errors.New("empty config")
		}
	}

	if pkgGen.tpls == nil {
		pkgGen.tpls = make(map[string]*template.Template, len(defaultConfig.Layouts))
	}
	if pkgGen.tplsInfo == nil {
		pkgGen.tplsInfo = make(map[string]*Template, len(defaultConfig.Layouts))
	}

	// extract routerTplName/middlewareTplName/handlerTplName/registerTplName/modelTplName/clientTplName directories
	// load default template
	for _, layout := range defaultConfig.Layouts {
		// default template use "fileName" as template name
		path := filepath.Base(layout.Path)
		err := pkgGen.loadLayout(layout, path, true)
		if err != nil {
			return err
		}
	}

	// override the default template, other customized file template will be loaded by "TemplateGenerator.Init"
	for _, layout := range customConfig.Layouts {
		if !IsDefaultPackageTpl(layout.Path) {
			continue
		}
		err := pkgGen.loadLayout(layout, layout.Path, true)
		if err != nil {
			return err
		}
	}

	pkgGen.Config = &customConfig
	// load Model tpl if need
	if pkgGen.Backend != "" {
		if err := pkgGen.LoadBackend(pkgGen.Backend); err != nil {
			return fmt.Errorf("load model template failed, err: %v", err.Error())
		}
	}

	pkgGen.processedModels = make(map[*model.Model]bool)
	pkgGen.TemplateGenerator.isPackageTpl = true

	return pkgGen.TemplateGenerator.Init()
}

func (pkgGen *HttpPackageGenerator) checkInited() (bool, error) {
	if pkgGen.tpls == nil {
		if err := pkgGen.Init(); err != nil {
			return false, fmt.Errorf("init layout config failed, err: %v", err.Error())
		}
	}
	return pkgGen.ConfigPath == "", nil
}

func (pkgGen *HttpPackageGenerator) Generate(pkg *HttpPackage) error {
	if _, err := pkgGen.checkInited(); err != nil {
		return err
	}
	if len(pkg.Models) != 0 {
		for _, m := range pkg.Models {
			if err := pkgGen.GenModel(m, pkgGen.NeedModel); err != nil {
				return fmt.Errorf("generate model %s failed, err: %v", m.FilePath, err.Error())
			}
		}
	}

	if pkgGen.CmdType == meta.CmdClient {
		// default client dir
		clientDir := pkgGen.IdlClientDir
		// user specify client dir
		if len(pkgGen.ClientDir) != 0 {
			clientDir = pkgGen.ClientDir
		}
		if err := pkgGen.genClient(pkg, clientDir); err != nil {
			return err
		}
		if err := pkgGen.genCustomizedFile(pkg); err != nil {
			return err
		}
		return nil
	}

	// this is for handler_by_service, the handler_dir is {$HANDLER_DIR}/{$PKG}
	handlerDir := util.SubDir(pkgGen.HandlerDir, pkg.Package)
	if pkgGen.HandlerByMethod {
		handlerDir = pkgGen.HandlerDir
	}
	handlerPackage := util.SubPackage(pkgGen.ProjPackage, handlerDir)
	routerDir := util.SubDir(pkgGen.RouterDir, pkg.Package)
	routerPackage := util.SubPackage(pkgGen.ProjPackage, routerDir)

	root := NewRouterTree()
	if err := pkgGen.genHandler(pkg, handlerDir, handlerPackage, root); err != nil {
		return err
	}

	if err := pkgGen.genRouter(pkg, root, handlerPackage, routerDir, routerPackage); err != nil {
		return err
	}

	if err := pkgGen.genCustomizedFile(pkg); err != nil {
		return err
	}

	return nil
}


================================================
FILE: cmd/hz/generator/package_tpl.go
================================================
/*
 * Copyright 2022 CloudWeGo Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package generator

var (
	routerTplName           = "router.go"
	middlewareTplName       = "middleware.go"
	middlewareSingleTplName = "middleware_single.go"
	handlerTplName          = "handler.go"
	handlerSingleTplName    = "handler_single.go"
	modelTplName            = "model.go"
	registerTplName         = "register.go"
	clientTplName           = "client.go"       // generate a default client for server
	hertzClientTplName      = "hertz_client.go" // underlying client for client command
	idlClientName           = "idl_client.go"   // client of service for quick call

	insertPointNew        = "//INSERT_POINT: DO NOT DELETE THIS LINE!"
	insertPointPatternNew = `//INSERT_POINT\: DO NOT DELETE THIS LINE\!`
)

var templateNameSet = map[string]string{
	routerTplName:           routerTplName,
	middlewareTplName:       middlewareTplName,
	middlewareSingleTplName: middlewareSingleTplName,
	handlerTplName:          handlerTplName,
	handlerSingleTplName:    handlerSingleTplName,
	modelTplName:            modelTplName,
	registerTplName:         registerTplName,
	clientTplName:           clientTplName,
	hertzClientTplName:      hertzClientTplName,
	idlClientName:           idlClientName,
}

func IsDefaultPackageTpl(name string) bool {
	if _, exist := templateNameSet[name]; exist {
		return true
	}

	return false
}

var defaultPkgConfig = TemplateConfig{
	Layouts: []Template{
		{
			Path:   defaultHandlerDir + sp + handlerTplName,
			Delims: [2]string{"{{", "}}"},
			Body: `// Code generated by hertz generator.

package {{.PackageName}}

import (
	"context"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/protocol/consts"

{{- range $k, $v := .Imports}}
	{{$k}} "{{$v.Package}}"
{{- end}}
)

{{range $_, $MethodInfo := .Methods}}
{{$MethodInfo.Comment}}
func {{$MethodInfo.Name}}(ctx context.Context, c *app.RequestContext) { 
	var err error
	{{if ne $MethodInfo.RequestTypeName "" -}}
	var req {{$MethodInfo.RequestTypeName}}
	err = c.BindAndValidate(&req)
	if err != nil {
		c.String(consts.StatusBadRequest, err.Error())
		return
	}
	{{end}}
	resp := new({{$MethodInfo.ReturnTypeName}})

	c.{{.Serializer}}(consts.StatusOK, resp)
}
{{end}}
			`,
		},
		{
			Path:   defaultRouterDir + sp + routerTplName,
			Delims: [2]string{"{{", "}}"},
			Body: `// Code generated by hertz generator. DO NOT EDIT.

package {{$.PackageName}}

import (
	"github.com/cloudwego/hertz/pkg/app/server"

    {{- range $k, $v := .HandlerPackages}}
        {{$k}} "{{$v}}"
    {{- end}}
)

/*
 This file will register all the routes of the services in the master idl.
 And it will update automatically when you use the "update" command for the idl.
 So don't modify the contents of the file, or your code will be deleted when it is updated.
 */

{{define "g"}}
{{- if eq .Path "/"}}r
{{- else}}{{.GroupName}}{{end}}
{{- end}}

{{define "G"}}
{{- if ne .Handler ""}}
	{{- .GroupName}}.{{.HttpMethod}}("{{.Path}}", append({{.HandlerMiddleware}}Mw(), {{.Handler}})...)
{{- end}}
{{- if ne (len .Children) 0}}
{{.MiddleWare}} := {{template "g" .}}.Group("{{.Path}}", {{.GroupMiddleware}}Mw()...)
{{- end}}
{{- range $_, $router := .Children}}
{{- if ne .Handler ""}}
	{{template "G" $router}}
{{- else}}
	{	{{template "G" $router}}
	}
{{- end}}
{{- end}}
{{- end}}

// Register register routes based on the IDL 'api.${HTTP Method}' annotation.
func Register(r *server.Hertz) {
{{template "G" .Router}}
}

		`,
		},
		{
			Path: defaultRouterDir + sp + registerTplName,
			Body: `// Code generated by hertz generator. DO NOT EDIT.

package {{.PackageName}}

import (
	"github.com/cloudwego/hertz/pkg/app/server"
	{{$.DepPkgAlias}} "{{$.DepPkg}}"
)

// GeneratedRegister registers routers generated by IDL.
func GeneratedRegister(r *server.Hertz){
	` + insertPointNew + `
	{{$.DepPkgAlias}}.Register(r)
}
`,
		},
		// Model tp
Download .txt
gitextract_i3d5wkwv/

├── .codecov.yml
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── feature_request.md
│   │   └── question.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── labels.json
│   └── workflows/
│       ├── cmd-tests.yml
│       ├── invalid_question.yml
│       ├── labeler.yml
│       ├── pr-check.yml
│       ├── unit-tests.yml
│       └── vulncheck.yml
├── .gitignore
├── .golangci.yaml
├── .licenserc.yaml
├── .typos.toml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── NOTICE
├── README.md
├── README_cn.md
├── ROADMAP.md
├── cmd/
│   └── hz/
│       ├── app/
│       │   └── app.go
│       ├── config/
│       │   ├── argument.go
│       │   └── cmd.go
│       ├── doc.go
│       ├── generator/
│       │   ├── client.go
│       │   ├── custom_files.go
│       │   ├── file.go
│       │   ├── handler.go
│       │   ├── layout.go
│       │   ├── layout_tpl.go
│       │   ├── model/
│       │   │   ├── define.go
│       │   │   ├── expr.go
│       │   │   ├── golang/
│       │   │   │   ├── constant.go
│       │   │   │   ├── enum.go
│       │   │   │   ├── file.go
│       │   │   │   ├── function.go
│       │   │   │   ├── init.go
│       │   │   │   ├── oneof.go
│       │   │   │   ├── struct.go
│       │   │   │   ├── typedef.go
│       │   │   │   └── variable.go
│       │   │   └── model.go
│       │   ├── model.go
│       │   ├── model_test.go
│       │   ├── package.go
│       │   ├── package_tpl.go
│       │   ├── router.go
│       │   ├── router_test.go
│       │   ├── template.go
│       │   └── template_funcs.go
│       ├── go.mod
│       ├── go.sum
│       ├── main.go
│       ├── meta/
│       │   ├── const.go
│       │   ├── manifest.go
│       │   └── manifest_test.go
│       ├── protobuf/
│       │   ├── api/
│       │   │   ├── api.pb.go
│       │   │   └── api.proto
│       │   ├── ast.go
│       │   ├── plugin.go
│       │   ├── plugin_stubs.go
│       │   ├── plugin_test.go
│       │   ├── resolver.go
│       │   ├── tag_test.go
│       │   ├── tags.go
│       │   └── test_data/
│       │       ├── protobuf_tag_test.out
│       │       └── test_tag.proto
│       ├── test_hz_unix.sh
│       ├── test_hz_windows.sh
│       ├── testdata/
│       │   ├── protobuf2/
│       │   │   ├── api.proto
│       │   │   ├── other/
│       │   │   │   ├── other.proto
│       │   │   │   └── other_base.proto
│       │   │   └── psm/
│       │   │       ├── base.proto
│       │   │       └── psm.proto
│       │   ├── protobuf3/
│       │   │   ├── api.proto
│       │   │   ├── other/
│       │   │   │   ├── other.proto
│       │   │   │   └── other_base.proto
│       │   │   └── psm/
│       │   │       ├── base.proto
│       │   │       └── psm.proto
│       │   └── thrift/
│       │       ├── common.thrift
│       │       ├── data/
│       │       │   ├── basic_data.thrift
│       │       │   └── data.thrift
│       │       └── psm.thrift
│       ├── thrift/
│       │   ├── ast.go
│       │   ├── plugin.go
│       │   ├── plugin_test.go
│       │   ├── resolver.go
│       │   ├── tag_test.go
│       │   ├── tags.go
│       │   ├── test_data/
│       │   │   ├── test_tag.thrift
│       │   │   └── thrift_tag_test.out
│       │   └── thriftgo_util.go
│       └── util/
│           ├── ast.go
│           ├── ast_test.go
│           ├── data.go
│           ├── data_test.go
│           ├── env.go
│           ├── fs.go
│           ├── logs/
│           │   ├── api.go
│           │   └── std.go
│           ├── string.go
│           ├── tool_install.go
│           └── tool_install_test.go
├── examples/
│   ├── html_rendering/
│   │   ├── index.tmpl
│   │   ├── main.go
│   │   └── template.html
│   └── standard/
│       └── main.go
├── go.mod
├── go.sum
├── internal/
│   ├── bytesconv/
│   │   ├── bytesconv.go
│   │   ├── bytesconv_32.go
│   │   ├── bytesconv_32_test.go
│   │   ├── bytesconv_64.go
│   │   ├── bytesconv_64_test.go
│   │   ├── bytesconv_table.go
│   │   ├── bytesconv_table_gen.go
│   │   ├── bytesconv_test.go
│   │   ├── bytesconv_timing_test.go
│   │   ├── doc.go
│   │   └── errors.go
│   ├── bytestr/
│   │   └── bytes.go
│   ├── nocopy/
│   │   └── nocopy.go
│   ├── stats/
│   │   ├── stats_util.go
│   │   ├── stats_util_test.go
│   │   ├── tracer.go
│   │   └── tracer_test.go
│   ├── tagexpr/
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── example_test.go
│   │   ├── expr.go
│   │   ├── expr_test.go
│   │   ├── handler.go
│   │   ├── selector.go
│   │   ├── selector_test.go
│   │   ├── spec_func.go
│   │   ├── spec_func_test.go
│   │   ├── spec_operand.go
│   │   ├── spec_operator.go
│   │   ├── spec_range.go
│   │   ├── spec_range_test.go
│   │   ├── spec_selector.go
│   │   ├── spec_test.go
│   │   ├── tagexpr.go
│   │   ├── tagexpr_test.go
│   │   ├── tagparser.go
│   │   ├── tagparser_test.go
│   │   ├── utils.go
│   │   └── validator/
│   │       ├── README.md
│   │       ├── default.go
│   │       ├── example_test.go
│   │       ├── func.go
│   │       ├── validator.go
│   │       └── validator_test.go
│   ├── test/
│   │   └── mock/
│   │       └── binder/
│   │           ├── binder.go
│   │           └── binder_test.go
│   └── testutils/
│       ├── testutils.go
│       └── testutils_test.go
├── licenses/
│   ├── LICENSE-echo.txt
│   ├── LICENSE-fasthttp.txt
│   ├── LICENSE-fsnotify
│   ├── LICENSE-gin.txt
│   ├── LICENSE-go-version.txt
│   ├── LICENSE-protobuf.txt
│   ├── LICENSE-protoreflect.txt
│   ├── LICENSE-sprig.txt
│   └── LICENSE-yaml.txt
├── pkg/
│   ├── app/
│   │   ├── client/
│   │   │   ├── client.go
│   │   │   ├── client_test.go
│   │   │   ├── client_unix_test.go
│   │   │   ├── client_windows_test.go
│   │   │   ├── discovery/
│   │   │   │   ├── discovery.go
│   │   │   │   └── discovery_test.go
│   │   │   ├── loadbalance/
│   │   │   │   ├── lbcache.go
│   │   │   │   ├── lbcache_test.go
│   │   │   │   ├── loadbalance.go
│   │   │   │   ├── weight_random.go
│   │   │   │   └── weight_random_test.go
│   │   │   ├── middleware.go
│   │   │   ├── middleware_test.go
│   │   │   ├── option.go
│   │   │   ├── option_test.go
│   │   │   └── retry/
│   │   │       ├── option.go
│   │   │       ├── retry.go
│   │   │       └── retry_test.go
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── fs.go
│   │   ├── fs_test.go
│   │   ├── middlewares/
│   │   │   ├── client/
│   │   │   │   └── sd/
│   │   │   │       ├── discovery.go
│   │   │   │       ├── discovery_test.go
│   │   │   │       ├── options.go
│   │   │   │       └── options_test.go
│   │   │   └── server/
│   │   │       ├── basic_auth/
│   │   │       │   ├── basic_auth.go
│   │   │       │   ├── basic_auth_test.go
│   │   │       │   └── doc.go
│   │   │       └── recovery/
│   │   │           ├── option.go
│   │   │           ├── option_test.go
│   │   │           ├── recovery.go
│   │   │           └── recovery_test.go
│   │   └── server/
│   │       ├── binding/
│   │       │   ├── binder.go
│   │       │   ├── binder_test.go
│   │       │   ├── config.go
│   │       │   ├── default.go
│   │       │   ├── internal/
│   │       │   │   └── decoder/
│   │       │   │       ├── base_type_decoder.go
│   │       │   │       ├── customized_type_decoder.go
│   │       │   │       ├── decoder.go
│   │       │   │       ├── getter.go
│   │       │   │       ├── gjson_required.go
│   │       │   │       ├── map_type_decoder.go
│   │       │   │       ├── multipart_file_decoder.go
│   │       │   │       ├── reflect.go
│   │       │   │       ├── slice_getter.go
│   │       │   │       ├── slice_type_decoder.go
│   │       │   │       ├── sonic_required.go
│   │       │   │       ├── struct_type_decoder.go
│   │       │   │       ├── tag.go
│   │       │   │       ├── text_decoder.go
│   │       │   │       ├── util.go
│   │       │   │       └── util_test.go
│   │       │   ├── reflect.go
│   │       │   ├── reflect_internal_test.go
│   │       │   ├── reflect_test.go
│   │       │   ├── tagexpr_bind_test.go
│   │       │   ├── testdata/
│   │       │   │   ├── hello.pb.go
│   │       │   │   └── hello.proto
│   │       │   ├── validator.go
│   │       │   └── validator_test.go
│   │       ├── hertz.go
│   │       ├── hertz_test.go
│   │       ├── hertz_unix_test.go
│   │       ├── mocks_test.go
│   │       ├── option.go
│   │       ├── option_test.go
│   │       ├── registry/
│   │       │   ├── registry.go
│   │       │   └── registry_test.go
│   │       ├── render/
│   │       │   ├── data.go
│   │       │   ├── doc.go
│   │       │   ├── html.go
│   │       │   ├── html_test.go
│   │       │   ├── json.go
│   │       │   ├── json_test.go
│   │       │   ├── protobuf.go
│   │       │   ├── render.go
│   │       │   ├── render_test.go
│   │       │   ├── text.go
│   │       │   └── xml.go
│   │       └── server_bench_test.go
│   ├── common/
│   │   ├── adaptor/
│   │   │   ├── handler.go
│   │   │   ├── handler_test.go
│   │   │   ├── request.go
│   │   │   ├── request_test.go
│   │   │   ├── response.go
│   │   │   ├── utils.go
│   │   │   └── utils_test.go
│   │   ├── bytebufferpool/
│   │   │   ├── bytebuffer.go
│   │   │   ├── bytebuffer_test.go
│   │   │   ├── doc.go
│   │   │   ├── pool.go
│   │   │   └── pool_test.go
│   │   ├── compress/
│   │   │   ├── compress.go
│   │   │   ├── compress_test.go
│   │   │   └── doc.go
│   │   ├── config/
│   │   │   ├── client_option.go
│   │   │   ├── client_option_test.go
│   │   │   ├── option.go
│   │   │   ├── option_test.go
│   │   │   ├── request_option.go
│   │   │   └── request_option_test.go
│   │   ├── errors/
│   │   │   ├── errors.go
│   │   │   └── errors_test.go
│   │   ├── hlog/
│   │   │   ├── consts.go
│   │   │   ├── default.go
│   │   │   ├── default_test.go
│   │   │   ├── hlog.go
│   │   │   ├── hlog_test.go
│   │   │   ├── log.go
│   │   │   ├── system.go
│   │   │   └── system_test.go
│   │   ├── json/
│   │   │   ├── sonic.go
│   │   │   └── std.go
│   │   ├── stackless/
│   │   │   ├── doc.go
│   │   │   ├── func.go
│   │   │   ├── func_test.go
│   │   │   ├── func_timing_test.go
│   │   │   ├── writer.go
│   │   │   └── writer_test.go
│   │   ├── test/
│   │   │   ├── assert/
│   │   │   │   ├── assert.go
│   │   │   │   └── assert_test.go
│   │   │   └── mock/
│   │   │       ├── body_data.go
│   │   │       ├── body_data_test.go
│   │   │       ├── network.go
│   │   │       ├── network_test.go
│   │   │       ├── reader.go
│   │   │       ├── reader_test.go
│   │   │       ├── writer.go
│   │   │       └── writer_test.go
│   │   ├── testdata/
│   │   │   ├── conf/
│   │   │   │   └── p_s_m.yaml
│   │   │   ├── proto/
│   │   │   │   ├── test.pb.go
│   │   │   │   └── test.proto
│   │   │   ├── template/
│   │   │   │   ├── htmltemplate.html
│   │   │   │   └── index.tmpl
│   │   │   └── test.txt
│   │   ├── timer/
│   │   │   ├── doc.go
│   │   │   ├── timer.go
│   │   │   └── timer_test.go
│   │   ├── tracer/
│   │   │   ├── stats/
│   │   │   │   ├── event.go
│   │   │   │   ├── event_test.go
│   │   │   │   └── status.go
│   │   │   ├── traceinfo/
│   │   │   │   ├── httpstats.go
│   │   │   │   ├── interface.go
│   │   │   │   └── traceinfo.go
│   │   │   └── tracer.go
│   │   ├── ut/
│   │   │   ├── context.go
│   │   │   ├── context_test.go
│   │   │   ├── request.go
│   │   │   ├── request_test.go
│   │   │   ├── response.go
│   │   │   └── response_test.go
│   │   └── utils/
│   │       ├── bufpool.go
│   │       ├── chunk.go
│   │       ├── chunk_test.go
│   │       ├── env.go
│   │       ├── ioutil.go
│   │       ├── ioutil_test.go
│   │       ├── netaddr.go
│   │       ├── netaddr_test.go
│   │       ├── network.go
│   │       ├── network_test.go
│   │       ├── path.go
│   │       ├── path_test.go
│   │       ├── utils.go
│   │       └── utils_test.go
│   ├── network/
│   │   ├── connection.go
│   │   ├── dialer/
│   │   │   ├── dialer.go
│   │   │   ├── dialer_test.go
│   │   │   └── netpoll.go
│   │   ├── dialer.go
│   │   ├── netpoll/
│   │   │   ├── connection.go
│   │   │   ├── connection_test.go
│   │   │   ├── dial.go
│   │   │   ├── dial_test.go
│   │   │   ├── transport.go
│   │   │   └── transport_test.go
│   │   ├── standard/
│   │   │   ├── connection.go
│   │   │   ├── connection_test.go
│   │   │   ├── dial.go
│   │   │   ├── dial_test.go
│   │   │   ├── transport.go
│   │   │   ├── transport_test.go
│   │   │   └── unix_test.go
│   │   ├── transport.go
│   │   ├── utils.go
│   │   ├── utils_test.go
│   │   ├── version.go
│   │   ├── writer.go
│   │   └── writer_test.go
│   ├── protocol/
│   │   ├── args.go
│   │   ├── args_test.go
│   │   ├── client/
│   │   │   ├── client.go
│   │   │   └── client_test.go
│   │   ├── consts/
│   │   │   ├── default.go
│   │   │   ├── fs.go
│   │   │   ├── headers.go
│   │   │   ├── http2.go
│   │   │   ├── methods.go
│   │   │   └── status.go
│   │   ├── cookie.go
│   │   ├── cookie_test.go
│   │   ├── doc.go
│   │   ├── header.go
│   │   ├── header_test.go
│   │   ├── header_timing_test.go
│   │   ├── http1/
│   │   │   ├── client.go
│   │   │   ├── client_test.go
│   │   │   ├── client_unix_test.go
│   │   │   ├── ext/
│   │   │   │   ├── common.go
│   │   │   │   ├── common_test.go
│   │   │   │   ├── error.go
│   │   │   │   ├── headerscanner.go
│   │   │   │   ├── headerscanner_test.go
│   │   │   │   ├── stream.go
│   │   │   │   └── stream_test.go
│   │   │   ├── factory/
│   │   │   │   ├── client.go
│   │   │   │   └── server.go
│   │   │   ├── proxy/
│   │   │   │   └── proxy.go
│   │   │   ├── req/
│   │   │   │   ├── header.go
│   │   │   │   ├── header_test.go
│   │   │   │   ├── request.go
│   │   │   │   └── request_test.go
│   │   │   ├── resp/
│   │   │   │   ├── header.go
│   │   │   │   ├── header_test.go
│   │   │   │   ├── response.go
│   │   │   │   ├── response_test.go
│   │   │   │   ├── writer.go
│   │   │   │   └── writer_test.go
│   │   │   ├── server.go
│   │   │   ├── server_test.go
│   │   │   └── server_timing_test.go
│   │   ├── multipart.go
│   │   ├── multipart_test.go
│   │   ├── request.go
│   │   ├── request_test.go
│   │   ├── response.go
│   │   ├── response_test.go
│   │   ├── server.go
│   │   ├── sse/
│   │   │   ├── event.go
│   │   │   ├── event_test.go
│   │   │   ├── example_test.go
│   │   │   ├── reader.go
│   │   │   ├── reader_test.go
│   │   │   ├── request.go
│   │   │   ├── request_test.go
│   │   │   ├── utils.go
│   │   │   ├── utils_test.go
│   │   │   ├── writer.go
│   │   │   └── writer_test.go
│   │   ├── suite/
│   │   │   ├── client.go
│   │   │   └── server.go
│   │   ├── trailer.go
│   │   ├── trailer_test.go
│   │   ├── uri.go
│   │   ├── uri_test.go
│   │   ├── uri_timing_test.go
│   │   ├── uri_unix.go
│   │   ├── uri_unix_test.go
│   │   ├── uri_windows.go
│   │   └── uri_windows_test.go
│   └── route/
│       ├── consts/
│       │   └── const.go
│       ├── engine.go
│       ├── engine_test.go
│       ├── netpoll.go
│       ├── param/
│       │   └── param.go
│       ├── routergroup.go
│       ├── routergroup_test.go
│       ├── routes_test.go
│       ├── routes_timing_test.go
│       ├── tree.go
│       └── tree_test.go
├── scripts/
│   ├── .utils/
│   │   ├── check_go_mod.sh
│   │   ├── check_version.sh
│   │   └── funcs.sh
│   ├── release-hotfix.sh
│   └── release.sh
└── version.go
Download .txt
Showing preview only (409K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4647 symbols across 351 files)

FILE: cmd/hz/app/app.go
  function New (line 39) | func New(c *cli.Context) error {
  function Update (line 79) | func Update(c *cli.Context) error {
  function Model (line 110) | func Model(c *cli.Context) error {
  function Client (line 126) | func Client(c *cli.Context) error {
  function PluginMode (line 142) | func PluginMode() {
  function Init (line 156) | func Init() *cli.App {
  function setLogVerbose (line 350) | func setLogVerbose(verbose bool) {
  function GenerateLayout (line 358) | func GenerateLayout(args *config.Argument) error {
  function TriggerPlugin (line 417) | func TriggerPlugin(args *config.Argument) error {

FILE: cmd/hz/config/argument.go
  type Argument (line 31) | type Argument struct
    method Parse (line 99) | func (arg *Argument) Parse(c *cli.Context, cmd string) (*Argument, err...
    method parseStringSlice (line 123) | func (arg *Argument) parseStringSlice(c *cli.Context) {
    method UpdateByManifest (line 135) | func (arg *Argument) UpdateByManifest(m *meta.Manifest) {
    method checkPath (line 151) | func (arg *Argument) checkPath() error {
    method checkIDL (line 180) | func (arg *Argument) checkIDL() error {
    method IsUpdate (line 204) | func (arg *Argument) IsUpdate() bool {
    method IsNew (line 208) | func (arg *Argument) IsNew() bool {
    method checkPackage (line 213) | func (arg *Argument) checkPackage() error {
    method Pack (line 281) | func (arg *Argument) Pack() ([]string, error) {
    method Unpack (line 289) | func (arg *Argument) Unpack(data []string) error {
    method Fork (line 298) | func (arg *Argument) Fork() *Argument {
    method GetGoPackage (line 309) | func (arg *Argument) GetGoPackage() (string, error) {
    method ModelPackagePrefix (line 329) | func (arg *Argument) ModelPackagePrefix() (string, error) {
    method ModelOutDir (line 350) | func (arg *Argument) ModelOutDir() string {
    method GetHandlerDir (line 360) | func (arg *Argument) GetHandlerDir() (string, error) {
    method GetModelDir (line 367) | func (arg *Argument) GetModelDir() (string, error) {
    method GetRouterDir (line 374) | func (arg *Argument) GetRouterDir() (string, error) {
    method GetClientDir (line 381) | func (arg *Argument) GetClientDir() (string, error) {
    method InitManifest (line 388) | func (arg *Argument) InitManifest(m *meta.Manifest) {
    method UpdateManifest (line 395) | func (arg *Argument) UpdateManifest(m *meta.Manifest) {
  function NewArgument (line 88) | func NewArgument() *Argument {
  function IdlTypeToCompiler (line 318) | func IdlTypeToCompiler(idlType string) (string, error) {

FILE: cmd/hz/config/cmd.go
  function lookupTool (line 32) | func lookupTool(idlType string) (string, error) {
  function link (line 78) | func link(src, dst string) error {
  function BuildPluginCmd (line 90) | func BuildPluginCmd(args *Argument) (*exec.Cmd, error) {
  method GetThriftgoOptions (line 175) | func (arg *Argument) GetThriftgoOptions() (string, error) {

FILE: cmd/hz/generator/client.go
  type ClientMethod (line 28) | type ClientMethod struct
  type ClientConfig (line 38) | type ClientConfig struct
  type ClientFile (line 42) | type ClientFile struct
  method genClient (line 52) | func (pkgGen *HttpPackageGenerator) genClient(pkg *HttpPackage, clientDi...

FILE: cmd/hz/generator/custom_files.go
  type FilePathRenderInfo (line 31) | type FilePathRenderInfo struct
  type IDLPackageRenderInfo (line 44) | type IDLPackageRenderInfo struct
  type CustomizedFileForMethod (line 49) | type CustomizedFileForMethod struct
  type CustomizedFileForService (line 57) | type CustomizedFileForService struct
  type CustomizedFileForIDL (line 64) | type CustomizedFileForIDL struct
  method genCustomizedFile (line 73) | func (pkgGen *HttpPackageGenerator) genCustomizedFile(pkg *HttpPackage) ...
  function renderFilePath (line 132) | func renderFilePath(tplInfo *Template, filePathRenderInfo FilePathRender...
  function renderInsertKey (line 146) | func renderInsertKey(tplInfo *Template, data interface{}) (string, error) {
  function renderImportTpl (line 164) | func renderImportTpl(tplInfo *Template, data interface{}) ([]string, err...
  function renderAppendContent (line 194) | func renderAppendContent(tplInfo *Template, renderInfo interface{}) (str...
  function appendUpdateFile (line 209) | func appendUpdateFile(tplInfo *Template, renderInfo interface{}, fileCon...
  function getInsertImportContent (line 235) | func getInsertImportContent(tplInfo *Template, renderInfo interface{}, f...
  method genLoopService (line 278) | func (pkgGen *HttpPackageGenerator) genLoopService(tplInfo *Template, fi...
  method genLoopMethod (line 400) | func (pkgGen *HttpPackageGenerator) genLoopMethod(tplInfo *Template, fil...
  method genSingleCustomizedFile (line 455) | func (pkgGen *HttpPackageGenerator) genSingleCustomizedFile(tplInfo *Tem...
  function writeBytes (line 648) | func writeBytes(buf *bytes.Buffer, bytes ...[]byte) error {

FILE: cmd/hz/generator/file.go
  type File (line 28) | type File struct
    method Lint (line 36) | func (file *File) Lint() error {

FILE: cmd/hz/generator/handler.go
  type HttpMethod (line 32) | type HttpMethod struct
    method InitComment (line 287) | func (m *HttpMethod) InitComment() {
  type Handler (line 53) | type Handler struct
    method Format (line 316) | func (h *Handler) Format() {
  type SingleHandler (line 61) | type SingleHandler struct
  type Client (line 68) | type Client struct
  method genHandler (line 73) | func (pkgGen *HttpPackageGenerator) genHandler(pkg *HttpPackage, handler...
  method processHandler (line 150) | func (pkgGen *HttpPackageGenerator) processHandler(handler *Handler, roo...
  method updateHandler (line 185) | func (pkgGen *HttpPackageGenerator) updateHandler(handler interface{}, h...
  method updateClient (line 274) | func (pkgGen *HttpPackageGenerator) updateClient(client interface{}, cli...
  function MapSerializer (line 303) | func MapSerializer(serializer string) string {

FILE: cmd/hz/generator/layout.go
  type Layout (line 34) | type Layout struct
  type LayoutGenerator (line 47) | type LayoutGenerator struct
    method Init (line 62) | func (lg *LayoutGenerator) Init() error {
    method checkInited (line 85) | func (lg *LayoutGenerator) checkInited() error {
    method Generate (line 94) | func (lg *LayoutGenerator) Generate(data map[string]interface{}) error {
    method GenerateByService (line 101) | func (lg *LayoutGenerator) GenerateByService(service Layout) error {
    method GenerateByConfig (line 215) | func (lg *LayoutGenerator) GenerateByConfig(configPath string) error {
    method Degenerate (line 230) | func (lg *LayoutGenerator) Degenerate() error {
  function SetDefaultTemplateConfig (line 57) | func SetDefaultTemplateConfig() {
  function serviceToLayoutData (line 171) | func serviceToLayoutData(service Layout) (map[string]interface{}, error) {
  function serviceToRouterData (line 199) | func serviceToRouterData(service Layout) (map[string]interface{}, error) {

FILE: cmd/hz/generator/layout_tpl.go
  constant sp (line 24) | sp = string(filepath.Separator)
  constant defaultBizDir (line 26) | defaultBizDir     = "biz"
  constant defaultModelDir (line 27) | defaultModelDir   = "biz" + sp + "model"
  constant defaultHandlerDir (line 28) | defaultHandlerDir = "biz" + sp + "handler"
  constant defaultServiceDir (line 29) | defaultServiceDir = "biz" + sp + "service"
  constant defaultDalDir (line 30) | defaultDalDir     = "biz" + sp + "dal"
  constant defaultScriptDir (line 31) | defaultScriptDir  = "script"
  constant defaultConfDir (line 32) | defaultConfDir    = "conf"
  constant defaultRouterDir (line 33) | defaultRouterDir  = "biz" + sp + "router"
  constant defaultClientDir (line 34) | defaultClientDir  = "biz" + sp + "client"
  constant routerGenIndex (line 38) | routerGenIndex = 8
  constant routerIndex (line 39) | routerIndex    = 9
  constant RegisterFile (line 41) | RegisterFile = "router_gen.go"

FILE: cmd/hz/generator/model.go
  type Option (line 33) | type Option
  constant OptionMarshalEnumToText (line 36) | OptionMarshalEnumToText  Option = "MarshalEnumToText"
  constant OptionTypedefAsTypeAlias (line 37) | OptionTypedefAsTypeAlias Option = "TypedefAsTypeAlias"
  type Backend (line 40) | type Backend interface
  type GolangBackend (line 48) | type GolangBackend struct
    method Template (line 50) | func (gb *GolangBackend) Template() (*template.Template, error) {
    method List (line 54) | func (gb *GolangBackend) List() map[string]string {
    method SetOption (line 58) | func (gb *GolangBackend) SetOption(opts string) error {
    method GetOptions (line 62) | func (gb *GolangBackend) GetOptions() []string {
    method Funcs (line 66) | func (gb *GolangBackend) Funcs(name string, fn interface{}) error {
  function switchBackend (line 70) | func switchBackend(backend meta.Backend) Backend {
  function loadThirdPartyBackend (line 78) | func loadThirdPartyBackend(plugin string) Backend {
  method LoadBackend (line 84) | func (pkgGen *HttpPackageGenerator) LoadBackend(backend meta.Backend) er...
  method GenModel (line 115) | func (pkgGen *HttpPackageGenerator) GenModel(data *model.Model, gen bool...
  function removeDuplicateImport (line 155) | func removeDuplicateImport(data *model.Model) {

FILE: cmd/hz/generator/model/define.go
  function NewCategoryType (line 134) | func NewCategoryType(typ *Type, cg Category) *Type {
  function NewStructType (line 140) | func NewStructType(name string, cg Category) *Type {
  function NewFuncType (line 152) | func NewFuncType(name string, cg Category) *Type {
  function IsBaseType (line 164) | func IsBaseType(typ *Type) bool {
  function NewEnumType (line 173) | func NewEnumType(name string, cg Category) *Type {
  function NewOneofType (line 185) | func NewOneofType(name string) *Type {

FILE: cmd/hz/generator/model/expr.go
  type BoolExpression (line 24) | type BoolExpression struct
    method Expression (line 28) | func (boolExpr BoolExpression) Expression() string {
  type StringExpression (line 36) | type StringExpression struct
    method Expression (line 40) | func (stringExpr StringExpression) Expression() string {
  type NumberExpression (line 44) | type NumberExpression struct
    method Expression (line 48) | func (numExpr NumberExpression) Expression() string {
  type ListExpression (line 52) | type ListExpression struct
    method Expression (line 73) | func (listExpr ListExpression) Expression() string {
  type IntExpression (line 57) | type IntExpression struct
    method Expression (line 61) | func (intExpr IntExpression) Expression() string {
  type DoubleExpression (line 65) | type DoubleExpression struct
    method Expression (line 69) | func (doubleExpr DoubleExpression) Expression() string {
  type MapExpression (line 82) | type MapExpression struct
    method Expression (line 88) | func (mapExpr MapExpression) Expression() string {

FILE: cmd/hz/generator/model/golang/init.go
  function Template (line 41) | func Template() (*template.Template, error) {
  function List (line 59) | func List() map[string]string {
  function Funcs (line 73) | func Funcs(name string, fn interface{}) error {
  function identify (line 81) | func identify(name string) string {
  function camelCase (line 85) | func camelCase(name string) string {
  function snakeCase (line 89) | func snakeCase(name string) string {
  function getTypedefReturnStr (line 93) | func getTypedefReturnStr(name string) string {
  type feature (line 104) | type feature struct
  function getFeatures (line 111) | func getFeatures() feature {
  function SetOption (line 115) | func SetOption(opt string) error {
  function GetOptions (line 130) | func GetOptions() []string {

FILE: cmd/hz/generator/model/model.go
  type Kind (line 25) | type Kind
  constant KindInvalid (line 28) | KindInvalid Kind = iota
  constant KindBool (line 29) | KindBool
  constant KindInt (line 30) | KindInt
  constant KindInt8 (line 31) | KindInt8
  constant KindInt16 (line 32) | KindInt16
  constant KindInt32 (line 33) | KindInt32
  constant KindInt64 (line 34) | KindInt64
  constant KindUint (line 35) | KindUint
  constant KindUint8 (line 36) | KindUint8
  constant KindUint16 (line 37) | KindUint16
  constant KindUint32 (line 38) | KindUint32
  constant KindUint64 (line 39) | KindUint64
  constant KindUintptr (line 40) | KindUintptr
  constant KindFloat32 (line 41) | KindFloat32
  constant KindFloat64 (line 42) | KindFloat64
  constant KindComplex64 (line 43) | KindComplex64
  constant KindComplex128 (line 44) | KindComplex128
  constant KindArray (line 45) | KindArray
  constant KindChan (line 46) | KindChan
  constant KindFunc (line 47) | KindFunc
  constant KindInterface (line 48) | KindInterface
  constant KindMap (line 49) | KindMap
  constant KindPtr (line 50) | KindPtr
  constant KindSlice (line 51) | KindSlice
  constant KindString (line 52) | KindString
  constant KindStruct (line 53) | KindStruct
  constant KindUnsafePointer (line 54) | KindUnsafePointer
  type Category (line 57) | type Category
  constant CategoryConstant (line 60) | CategoryConstant  Category = 1
  constant CategoryBinary (line 61) | CategoryBinary    Category = 8
  constant CategoryMap (line 62) | CategoryMap       Category = 9
  constant CategoryList (line 63) | CategoryList      Category = 10
  constant CategorySet (line 64) | CategorySet       Category = 11
  constant CategoryEnum (line 65) | CategoryEnum      Category = 12
  constant CategoryStruct (line 66) | CategoryStruct    Category = 13
  constant CategoryUnion (line 67) | CategoryUnion     Category = 14
  constant CategoryException (line 68) | CategoryException Category = 15
  constant CategoryTypedef (line 69) | CategoryTypedef   Category = 16
  constant CategoryService (line 70) | CategoryService   Category = 17
  type Model (line 73) | type Model struct
    method IsEmpty (line 91) | func (m Model) IsEmpty() bool {
  type Models (line 96) | type Models
    method MergeMap (line 98) | func (a *Models) MergeMap(b map[string]*Model) {
    method MergeArray (line 113) | func (a *Models) MergeArray(b []*Model) {
  type RequiredNess (line 128) | type RequiredNess
  constant RequiredNess_Default (line 131) | RequiredNess_Default  RequiredNess = 0
  constant RequiredNess_Required (line 132) | RequiredNess_Required RequiredNess = 1
  constant RequiredNess_Optional (line 133) | RequiredNess_Optional RequiredNess = 2
  type Type (line 136) | type Type struct
    method ResolveDefaultValue (line 146) | func (rt *Type) ResolveDefaultValue() string {
    method ResolveNameForTypedef (line 163) | func (rt *Type) ResolveNameForTypedef(scope *Model) (string, error) {
    method ResolveName (line 212) | func (rt *Type) ResolveName(scope *Model) (string, error) {
    method IsBinary (line 280) | func (rt *Type) IsBinary() bool {
    method IsBaseType (line 284) | func (rt *Type) IsBaseType() bool {
    method IsSettable (line 288) | func (rt *Type) IsSettable() bool {
  type TypeDef (line 296) | type TypeDef struct
  type Constant (line 302) | type Constant struct
  type Literal (line 309) | type Literal interface
  type Variable (line 313) | type Variable struct
  type Function (line 320) | type Function struct
  type Method (line 328) | type Method struct
  type Enum (line 336) | type Enum struct
  type Struct (line 343) | type Struct struct
  type Field (line 351) | type Field struct
    method GenGoTags (line 411) | func (f Field) GenGoTags() string {
  type Oneof (line 364) | type Oneof struct
  type Choice (line 371) | type Choice struct
  type Tags (line 377) | type Tags
    method String (line 385) | func (ts Tags) String() string {
    method Remove (line 393) | func (ts *Tags) Remove(name string) {
    method Len (line 403) | func (ts Tags) Len() int { return len(ts) }
    method Less (line 405) | func (ts Tags) Less(i, j int) bool {
    method Swap (line 409) | func (ts Tags) Swap(i, j int) { ts[i], ts[j] = ts[j], ts[i] }
  type Tag (line 379) | type Tag struct

FILE: cmd/hz/generator/model_test.go
  type StringValue (line 27) | type StringValue struct
    method Expression (line 31) | func (sv *StringValue) Expression() string {
  function TestIdlGenerator_GenModel (line 35) | func TestIdlGenerator_GenModel(t *testing.T) {

FILE: cmd/hz/generator/package.go
  type HttpPackage (line 33) | type HttpPackage struct
  type Service (line 41) | type Service struct
  type HttpPackageGenerator (line 52) | type HttpPackageGenerator struct
    method Init (line 82) | func (pkgGen *HttpPackageGenerator) Init() error {
    method checkInited (line 142) | func (pkgGen *HttpPackageGenerator) checkInited() (bool, error) {
    method Generate (line 151) | func (pkgGen *HttpPackageGenerator) Generate(pkg *HttpPackage) error {

FILE: cmd/hz/generator/package_tpl.go
  function IsDefaultPackageTpl (line 48) | func IsDefaultPackageTpl(name string) bool {

FILE: cmd/hz/generator/router.go
  type Router (line 34) | type Router struct
  type RouterNode (line 41) | type RouterNode struct
    method Sort (line 75) | func (routerNode *RouterNode) Sort() {
    method Update (line 79) | func (routerNode *RouterNode) Update(method *HttpMethod, handlerType, ...
    method RawHandlerName (line 97) | func (routerNode *RouterNode) RawHandlerName() string {
    method DyeGroupName (line 105) | func (routerNode *RouterNode) DyeGroupName(snakeStyleMiddleware bool) ...
    method DFS (line 179) | func (routerNode *RouterNode) DFS(i int, hook func(layer int, node *Ro...
    method Insert (line 198) | func (routerNode *RouterNode) Insert(name string, method *HttpMethod, ...
    method FindNearest (line 254) | func (routerNode *RouterNode) FindNearest(paths []string, method strin...
  type RegisterInfo (line 58) | type RegisterInfo struct
  function NewRouterTree (line 65) | func NewRouterTree() *RouterNode {
  function getHttpMethod (line 247) | func getHttpMethod(method string) string {
  type childrenRouterInfo (line 281) | type childrenRouterInfo
    method Len (line 284) | func (c childrenRouterInfo) Len() int {
    method Less (line 290) | func (c childrenRouterInfo) Less(i, j int) bool {
    method Swap (line 321) | func (c childrenRouterInfo) Swap(i, j int) {
  function removeNonLetterPrefix (line 311) | func removeNonLetterPrefix(str string) string {
  method updateRegister (line 330) | func (pkgGen *HttpPackageGenerator) updateRegister(pkg, rDir, pkgName st...
  function checkDupRegister (line 377) | func checkDupRegister(file []byte, insertReg string) bool {
  function appendMw (line 381) | func appendMw(mws []string, mw string) ([]string, string) {
  function stringsIncludes (line 395) | func stringsIncludes(strs []string, str string) bool {
  method genRouter (line 404) | func (pkgGen *HttpPackageGenerator) genRouter(pkg *HttpPackage, root *Ro...
  method updateMiddlewareReg (line 473) | func (pkgGen *HttpPackageGenerator) updateMiddlewareReg(router interface...
  function convertToMiddlewareName (line 540) | func convertToMiddlewareName(path string) string {

FILE: cmd/hz/generator/router_test.go
  function Test_checkDupRegister (line 21) | func Test_checkDupRegister(t *testing.T) {

FILE: cmd/hz/generator/template.go
  type TemplateConfig (line 35) | type TemplateConfig struct
  constant Skip (line 40) | Skip   = "skip"
  constant Cover (line 41) | Cover  = "cover"
  constant Append (line 42) | Append = "append"
  type Template (line 45) | type Template struct
  type UpdateBehavior (line 56) | type UpdateBehavior struct
  type TemplateGenerator (line 67) | type TemplateGenerator struct
    method Init (line 80) | func (tg *TemplateGenerator) Init() error {
    method loadLayout (line 143) | func (tg *TemplateGenerator) loadLayout(layout Template, tplName strin...
    method Generate (line 161) | func (tg *TemplateGenerator) Generate(input interface{}, tplName, file...
    method Persist (line 218) | func (tg *TemplateGenerator) Persist() error {
    method GetFormatAndExcludedFiles (line 268) | func (tg *TemplateGenerator) GetFormatAndExcludedFiles() ([]File, erro...
    method Files (line 307) | func (tg *TemplateGenerator) Files() []File {
    method Degenerate (line 311) | func (tg *TemplateGenerator) Degenerate() error {

FILE: cmd/hz/generator/template_funcs.go
  function getUniqueHandlerOutDir (line 42) | func getUniqueHandlerOutDir(methods []*HttpMethod) (ret []string) {

FILE: cmd/hz/main.go
  function main (line 26) | func main() {
  function Run (line 34) | func Run() {

FILE: cmd/hz/meta/const.go
  constant Version (line 25) | Version = "v0.9.7"
  constant DefaultServiceName (line 27) | DefaultServiceName = "hertz_service"
  type Mode (line 30) | type Mode
  constant SysType (line 33) | SysType = runtime.GOOS
  constant WindowsOS (line 35) | WindowsOS = "windows"
  constant EnvPluginMode (line 37) | EnvPluginMode = "HERTZ_PLUGIN_MODE"
  constant CmdUpdate (line 41) | CmdUpdate = "update"
  constant CmdNew (line 42) | CmdNew    = "new"
  constant CmdModel (line 43) | CmdModel  = "model"
  constant CmdClient (line 44) | CmdClient = "client"
  constant IdlThrift (line 49) | IdlThrift = "thrift"
  constant IdlProto (line 50) | IdlProto  = "proto"
  constant TpCompilerThrift (line 55) | TpCompilerThrift = "thriftgo"
  constant TpCompilerProto (line 56) | TpCompilerProto  = "protoc"
  constant ProtocPluginName (line 61) | ProtocPluginName = "protoc-gen-hertz"
  constant ThriftPluginName (line 62) | ThriftPluginName = "thrift-gen-hertz"
  constant LoadError (line 67) | LoadError           = 1
  constant GenerateLayoutError (line 68) | GenerateLayoutError = 2
  constant PersistError (line 69) | PersistError        = 3
  constant PluginError (line 70) | PluginError         = 4
  constant ModelDir (line 75) | ModelDir   = "biz" + string(filepath.Separator) + "model"
  constant RouterDir (line 76) | RouterDir  = "biz" + string(filepath.Separator) + "router"
  constant HandlerDir (line 77) | HandlerDir = "biz" + string(filepath.Separator) + "handler"
  type Backend (line 81) | type Backend
  constant BackendGolang (line 84) | BackendGolang Backend = "golang"
  constant SetBodyParam (line 89) | SetBodyParam = "setBodyParam(req).\n"
  constant TheUseOptionMessage (line 93) | TheUseOptionMessage = "'model code' is not generated due to the '-use' o...
  constant AddThriftReplace (line 95) | AddThriftReplace = "do not generate 'go.mod', please add 'replace github...

FILE: cmd/hz/meta/manifest.go
  constant ManifestFile (line 29) | ManifestFile = ".hz"
  type Manifest (line 31) | type Manifest struct
    method InitAndValidate (line 45) | func (manifest *Manifest) InitAndValidate(dir string) error {
    method String (line 66) | func (manifest *Manifest) String() string {
    method Persist (line 73) | func (manifest *Manifest) Persist(dir string) error {
  function init (line 40) | func init() {
  constant hzTitle (line 64) | hzTitle = "// Code generated by hz. DO NOT EDIT."
  function loadConfigFile (line 85) | func loadConfigFile(path string) (*Manifest, error) {

FILE: cmd/hz/meta/manifest_test.go
  function TestValidate (line 25) | func TestValidate(t *testing.T) {

FILE: cmd/hz/protobuf/api/api.pb.go
  constant _ (line 19) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 21) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  function init (line 656) | func init() { file_api_proto_init() }
  function file_api_proto_init (line 657) | func file_api_proto_init() {

FILE: cmd/hz/protobuf/ast.go
  function getGoPackage (line 44) | func getGoPackage(f *descriptorpb.FileDescriptorProto, pkgMap map[string...
  function switchBaseType (line 72) | func switchBaseType(typ descriptorpb.FieldDescriptorProto_Type) *model.T...
  function astToService (line 110) | func astToService(ast *descriptorpb.FileDescriptorProto, resolver *Resol...
  function getCompatibleAnnotation (line 274) | func getCompatibleAnnotation(options proto.Message, anno, compatibleAnno...
  function parseAnnotationToClient (line 284) | func parseAnnotationToClient(clientMethod *generator.ClientMethod, gen *...
  function getMethod (line 376) | func getMethod(file *protogen.File, s *descriptorpb.ServiceDescriptorPro...
  function astToModel (line 392) | func astToModel(ast *descriptorpb.FileDescriptorProto, rs *Resolver) (*m...
  function getMessageLeadingComments (line 581) | func getMessageLeadingComments(stMessage *desc.MessageDescriptor) string {
  function getFiledComments (line 592) | func getFiledComments(f *descriptorpb.FieldDescriptorProto, stMessage *d...
  function formatComments (line 611) | func formatComments(comments string) string {
  function getNestedMessageInfoMap (line 623) | func getNestedMessageInfoMap(stMessage *desc.MessageDescriptor) map[stri...
  function parseDefaultValue (line 635) | func parseDefaultValue(typ descriptorpb.FieldDescriptorProto_Type, val s...
  function isPointer (line 660) | func isPointer(f *descriptorpb.FieldDescriptorProto, isProto3 bool) bool {
  function resolveOneof (line 683) | func resolveOneof(stMessage *desc.MessageDescriptor, oneofMap map[string...
  function getNewFieldName (line 747) | func getNewFieldName(fieldName string, fieldNameSet map[string]bool) str...
  function checkDuplicatedFileName (line 755) | func checkDuplicatedFileName(vs []model.Field) {

FILE: cmd/hz/protobuf/plugin.go
  type Plugin (line 73) | type Plugin struct
    method Run (line 99) | func (plugin *Plugin) Run() int {
    method setLogger (line 158) | func (plugin *Plugin) setLogger() {
    method recvWarningLogger (line 165) | func (plugin *Plugin) recvWarningLogger() string {
    method recvVerboseLogger (line 172) | func (plugin *Plugin) recvVerboseLogger() string {
    method parseArgs (line 181) | func (plugin *Plugin) parseArgs(param string) (*config.Argument, error) {
    method Response (line 203) | func (plugin *Plugin) Response(resp *pluginpb.CodeGeneratorResponse) e...
    method Handle (line 215) | func (plugin *Plugin) Handle(req *pluginpb.CodeGeneratorRequest, args ...
    method fixGoPackage (line 309) | func (plugin *Plugin) fixGoPackage(req *pluginpb.CodeGeneratorRequest,...
    method fixModelPathAndPackage (line 334) | func (plugin *Plugin) fixModelPathAndPackage(pkg string) (impt string) {
    method GenerateFiles (line 355) | func (plugin *Plugin) GenerateFiles(pluginPb *protogen.Plugin) error {
    method GenerateFile (line 382) | func (plugin *Plugin) GenerateFile(gen *protogen.Plugin, f *protogen.F...
    method getIdlInfo (line 555) | func (plugin *Plugin) getIdlInfo(ast *descriptorpb.FileDescriptorProto...
    method genHttpPackage (line 596) | func (plugin *Plugin) genHttpPackage(ast *descriptorpb.FileDescriptorP...
  type RemoveTags (line 86) | type RemoveTags
    method Exist (line 88) | func (rm *RemoveTags) Exist(tag string) bool {
  function generateFile (line 401) | func generateFile(gen *protogen.Plugin, file *protogen.File, rmTags Remo...
  function genMessage (line 445) | func genMessage(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, ...
  function genMessageFields (line 470) | func genMessageFields(g *protogen.GeneratedFile, f *fileInfo, m *message...
  function genMessageField (line 483) | func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageI...

FILE: cmd/hz/protobuf/plugin_stubs.go
  constant FileDescriptorProto_Name_field_number (line 64) | FileDescriptorProto_Name_field_number             protoreflect.FieldNumb...
  constant FileDescriptorProto_Package_field_number (line 65) | FileDescriptorProto_Package_field_number          protoreflect.FieldNumb...
  constant FileDescriptorProto_Dependency_field_number (line 66) | FileDescriptorProto_Dependency_field_number       protoreflect.FieldNumb...
  constant FileDescriptorProto_PublicDependency_field_number (line 67) | FileDescriptorProto_PublicDependency_field_number protoreflect.FieldNumb...
  constant FileDescriptorProto_WeakDependency_field_number (line 68) | FileDescriptorProto_WeakDependency_field_number   protoreflect.FieldNumb...
  constant FileDescriptorProto_MessageType_field_number (line 69) | FileDescriptorProto_MessageType_field_number      protoreflect.FieldNumb...
  constant FileDescriptorProto_EnumType_field_number (line 70) | FileDescriptorProto_EnumType_field_number         protoreflect.FieldNumb...
  constant FileDescriptorProto_Service_field_number (line 71) | FileDescriptorProto_Service_field_number          protoreflect.FieldNumb...
  constant FileDescriptorProto_Extension_field_number (line 72) | FileDescriptorProto_Extension_field_number        protoreflect.FieldNumb...
  constant FileDescriptorProto_Options_field_number (line 73) | FileDescriptorProto_Options_field_number          protoreflect.FieldNumb...
  constant FileDescriptorProto_SourceCodeInfo_field_number (line 74) | FileDescriptorProto_SourceCodeInfo_field_number   protoreflect.FieldNumb...
  constant FileDescriptorProto_Syntax_field_number (line 75) | FileDescriptorProto_Syntax_field_number           protoreflect.FieldNumb...
  constant WeakFieldPrefix_goname (line 78) | WeakFieldPrefix_goname = "XXX_weak_"
  type fileInfo (line 80) | type fileInfo struct
  type enumInfo (line 98) | type enumInfo struct
  type messageInfo (line 105) | type messageInfo struct
  type extensionInfo (line 115) | type extensionInfo struct
  type structFields (line 119) | type structFields struct
    method append (line 124) | func (sf *structFields) append(name string) {
  type structTags (line 134) | type structTags
    method String (line 136) | func (tags structTags) String() string {
  type goImportPath (line 151) | type goImportPath interface
  type trailingComment (line 156) | type trailingComment
    method String (line 158) | func (c trailingComment) String() string {
  function newFileInfo (line 181) | func newFileInfo(file *protogen.File) *fileInfo
  function genPackageKnownComment (line 184) | func genPackageKnownComment(f *fileInfo) protogen.Comments
  function genStandaloneComments (line 187) | func genStandaloneComments(g *protogen.GeneratedFile, f *fileInfo, n int32)
  function genGeneratedHeader (line 190) | func genGeneratedHeader(gen *protogen.Plugin, g *protogen.GeneratedFile,...
  function genImport (line 193) | func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileI...
  function genEnum (line 196) | func genEnum(g *protogen.GeneratedFile, f *fileInfo, e *enumInfo)
  function genMessageInternalFields (line 199) | func genMessageInternalFields(g *protogen.GeneratedFile, f *fileInfo, m ...
  function genExtensions (line 202) | func genExtensions(g *protogen.GeneratedFile, f *fileInfo)
  function genReflectFileDescriptor (line 205) | func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.Generate...
  function appendDeprecationSuffix (line 208) | func appendDeprecationSuffix(prefix protogen.Comments, deprecated bool) ...
  function genMessageDefaultDecls (line 211) | func genMessageDefaultDecls(g *protogen.GeneratedFile, f *fileInfo, m *m...
  function genMessageKnownFunctions (line 214) | func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m ...
  function genMessageMethods (line 217) | func genMessageMethods(g *protogen.GeneratedFile, f *fileInfo, m *messag...
  function genMessageOneofWrapperTypes (line 220) | func genMessageOneofWrapperTypes(g *protogen.GeneratedFile, f *fileInfo,...
  function oneofInterfaceName (line 223) | func oneofInterfaceName(oneof *protogen.Oneof) string
  function fieldGoType (line 226) | func fieldGoType(g *protogen.GeneratedFile, f *fileInfo, field *protogen...
  function fieldProtobufTagValue (line 229) | func fieldProtobufTagValue(field *protogen.Field) string
  function fieldJSONTagValue (line 232) | func fieldJSONTagValue(field *protogen.Field) string

FILE: cmd/hz/protobuf/plugin_test.go
  function TestPlugin_Handle (line 29) | func TestPlugin_Handle(t *testing.T) {
  function TestFixModelPathAndPackage (line 52) | func TestFixModelPathAndPackage(t *testing.T) {

FILE: cmd/hz/protobuf/resolver.go
  type Symbol (line 29) | type Symbol struct
  type NameSpace (line 38) | type NameSpace
  type PackageReference (line 61) | type PackageReference struct
  function getReferPkgMap (line 69) | func getReferPkgMap(pkgMap map[string]string, incs []*descriptorpb.FileD...
  type FileInfos (line 106) | type FileInfos struct
  type Resolver (line 111) | type Resolver struct
    method GetRefModel (line 187) | func (resolver *Resolver) GetRefModel(includeBase string) (*model.Mode...
    method getBaseType (line 198) | func (resolver *Resolver) getBaseType(f *descriptorpb.FieldDescriptorP...
    method ResolveType (line 249) | func (resolver *Resolver) ResolveType(f *descriptorpb.FieldDescriptorP...
    method ResolveIdentifier (line 267) | func (resolver *Resolver) ResolveIdentifier(id string) (ret *Symbol, e...
    method getFieldType (line 290) | func (resolver *Resolver) getFieldType(f *descriptorpb.FieldDescriptor...
    method Get (line 305) | func (resolver *Resolver) Get(name string) *Symbol {
    method ExportReferred (line 337) | func (resolver *Resolver) ExportReferred(all, needMain bool) (ret []*P...
    method LoadAll (line 354) | func (resolver *Resolver) LoadAll(ast *descriptorpb.FileDescriptorProt...
    method LoadOne (line 461) | func (resolver *Resolver) LoadOne(ast *descriptorpb.FileDescriptorProt...
    method GetFiles (line 528) | func (resolver *Resolver) GetFiles() FileInfos {
  function updateFiles (line 124) | func updateFiles(fileName string, files FileInfos) (FileInfos, error) {
  function NewResolver (line 150) | func NewResolver(ast *descriptorpb.FileDescriptorProto, files FileInfos,...
  function IsMapEntry (line 224) | func IsMapEntry(nt *descriptorpb.DescriptorProto) bool {
  function checkListType (line 229) | func checkListType(typ *model.Type, label descriptorpb.FieldDescriptorPr...
  function getNestedType (line 238) | func getNestedType(f *descriptorpb.FieldDescriptorProto, nested []*descr...
  function mergeNamespace (line 383) | func mergeNamespace(first, second NameSpace) NameSpace {
  function LoadBaseIdentifier (line 392) | func LoadBaseIdentifier(ast *descriptorpb.FileDescriptorProto) map[strin...

FILE: cmd/hz/protobuf/tag_test.go
  function TestTagGenerate (line 29) | func TestTagGenerate(t *testing.T) {

FILE: cmd/hz/protobuf/tags.go
  function CheckTagOption (line 42) | func CheckTagOption(args *config.Argument) (ret []generator.Option) {
  function checkSnakeName (line 61) | func checkSnakeName(name string) string {
  type httpOption (line 97) | type httpOption struct
  type httpOptions (line 102) | type httpOptions
    method Len (line 104) | func (s httpOptions) Len() int {
    method Swap (line 108) | func (s httpOptions) Swap(i, j int) {
    method Less (line 112) | func (s httpOptions) Less(i, j int) bool {
  function getAllOptions (line 116) | func getAllOptions(extensions map[*protoimpl.ExtensionInfo]string, opts ...
  function checkFirstOptions (line 129) | func checkFirstOptions(extensions map[*protoimpl.ExtensionInfo]string, o...
  function checkFirstOption (line 141) | func checkFirstOption(ext *protoimpl.ExtensionInfo, opts ...protoreflect...
  function checkOption (line 151) | func checkOption(ext *protoimpl.ExtensionInfo, opts ...protoreflect.Prot...
  function tag (line 161) | func tag(k string, v interface{}) model.Tag {
  function defaultBindingTags (line 170) | func defaultBindingTags(f *descriptorpb.FieldDescriptorProto) []model.Tag {
  function jsonTag (line 196) | func jsonTag(f *descriptorpb.FieldDescriptorProto) (ret model.Tag) {
  function injectTagsToModel (line 212) | func injectTagsToModel(f *descriptorpb.FieldDescriptorProto, gf *model.F...
  function getJsonValue (line 269) | func getJsonValue(f *descriptorpb.FieldDescriptorProto, val string) stri...
  function checkRequire (line 284) | func checkRequire(f *descriptorpb.FieldDescriptorProto, val string) stri...
  function m2s (line 294) | func m2s(mt model.Tag) (ret [2]string) {
  function reflectJsonTag (line 300) | func reflectJsonTag(f protoreflect.FieldDescriptor) (ret model.Tag) {
  function defaultBindingStructTags (line 318) | func defaultBindingStructTags(f protoreflect.FieldDescriptor) []model.Tag {
  function injectTagsToStructTags (line 375) | func injectTagsToStructTags(f protoreflect.FieldDescriptor, out *structT...
  function getStructJsonValue (line 451) | func getStructJsonValue(f protoreflect.FieldDescriptor, val string) stri...
  function checkStructRequire (line 467) | func checkStructRequire(f protoreflect.FieldDescriptor, val string) stri...

FILE: cmd/hz/thrift/ast.go
  function getGoPackage (line 38) | func getGoPackage(ast *parser.Thrift, pkgMap map[string]string) string {
  function astToService (line 54) | func astToService(ast *parser.Thrift, resolver *Resolver, args *config.A...
  function newHTTPMethod (line 235) | func newHTTPMethod(s *parser.Service, m *parser.Function, method *genera...
  function parseAnnotationToClient (line 247) | func parseAnnotationToClient(clientMethod *generator.ClientMethod, p *pa...
  type extendServiceList (line 356) | type extendServiceList
    method exist (line 358) | func (svr extendServiceList) exist(serviceName string) bool {
  function getExtendServices (line 367) | func getExtendServices(ast *parser.Thrift) (res extendServiceList) {
  function getAllExtendFunction (line 378) | func getAllExtendFunction(svc *parser.Service, ast *parser.Thrift, resol...
  function processExtendsType (line 449) | func processExtendsType(f *parser.Function, base string) {
  function getUniqueResolveDependentName (line 496) | func getUniqueResolveDependentName(name string, resolver *Resolver) stri...
  function addResolverDependency (line 508) | func addResolverDependency(resolver *Resolver, ast *parser.Thrift, args ...
  function switchBaseType (line 557) | func switchBaseType(typ *parser.Type) *model.Type {
  function newBaseType (line 583) | func newBaseType(typ *model.Type, cg model.Category) *model.Type {
  function newStructType (line 589) | func newStructType(name string, cg model.Category) *model.Type {
  function newEnumType (line 601) | func newEnumType(name string, cg model.Category) *model.Type {
  function newFuncType (line 610) | func newFuncType(name string, cg model.Category) *model.Type {
  method getFieldType (line 622) | func (resolver *Resolver) getFieldType(typ *parser.Type) (*model.Type, e...
  type ResolvedSymbol (line 633) | type ResolvedSymbol struct
    method Expression (line 639) | func (rs ResolvedSymbol) Expression() string {
  function astToModel (line 661) | func astToModel(ast *parser.Thrift, rs *Resolver) (*model.Model, error) {
  function removeCommentsSlash (line 886) | func removeCommentsSlash(comments string) string {
  function isPointer (line 894) | func isPointer(f *parser.Field, rs *Resolver) (bool, error) {
  function getNewFieldName (line 913) | func getNewFieldName(fieldName string, fieldNameSet map[string]bool) str...
  function checkDuplicatedFileName (line 921) | func checkDuplicatedFileName(vs []model.Field) {

FILE: cmd/hz/thrift/plugin.go
  type Plugin (line 41) | type Plugin struct
    method Run (line 59) | func (plugin *Plugin) Run() int {
    method Handle (line 117) | func (plugin *Plugin) Handle(args *config.Argument) (*thriftgo_plugin....
    method setLogger (line 235) | func (plugin *Plugin) setLogger() {
    method recvWarningLogger (line 242) | func (plugin *Plugin) recvWarningLogger() string {
    method recvVerboseLogger (line 249) | func (plugin *Plugin) recvVerboseLogger() string {
    method handleRequest (line 258) | func (plugin *Plugin) handleRequest() ([]byte, error) {
    method parseArgs (line 275) | func (plugin *Plugin) parseArgs() (*config.Argument, error) {
    method initNameStyle (line 289) | func (plugin *Plugin) initNameStyle() error {
    method getPackageInfo (line 307) | func (plugin *Plugin) getPackageInfo() (*generator.HttpPackage, error) {
    method response (line 355) | func (plugin *Plugin) response(res *thriftgo_plugin.Response) error {
    method InsertTag (line 367) | func (plugin *Plugin) InsertTag() ([]*thriftgo_plugin.Generated, error) {
    method GetResponse (line 422) | func (plugin *Plugin) GetResponse(files []generator.File, outputDir st...
  function NewPlugin (line 50) | func NewPlugin(args *config.Argument, req *thriftgo_plugin.Request) *Plu...
  function getTagString (line 445) | func getTagString(f *parser.Field, rmTags []string) (string, error) {

FILE: cmd/hz/thrift/plugin_test.go
  function TestRun (line 28) | func TestRun(t *testing.T) {

FILE: cmd/hz/thrift/resolver.go
  type PackageReference (line 49) | type PackageReference struct
  function getReferPkgMap (line 57) | func getReferPkgMap(pkgMap map[string]string, incs []*parser.Include, ma...
  type Symbol (line 93) | type Symbol struct
  type NameSpace (line 100) | type NameSpace
  type Resolver (line 102) | type Resolver struct
    method GetRefModel (line 132) | func (resolver *Resolver) GetRefModel(includeBase string) (*model.Mode...
    method getBaseType (line 143) | func (resolver *Resolver) getBaseType(typ *parser.Type) (*model.Type, ...
    method ResolveType (line 163) | func (resolver *Resolver) ResolveType(typ *parser.Type) (*model.Type, ...
    method ResolveConstantValue (line 204) | func (resolver *Resolver) ResolveConstantValue(constant *parser.ConstV...
    method ResolveIdentifier (line 256) | func (resolver *Resolver) ResolveIdentifier(id string) (ret ResolvedSy...
    method ResolveTypeName (line 290) | func (resolver *Resolver) ResolveTypeName(typ *parser.Type) (string, e...
    method Get (line 336) | func (resolver *Resolver) Get(name string) *Symbol {
    method ExportReferred (line 354) | func (resolver *Resolver) ExportReferred(all, needMain bool) (ret []*P...
    method LoadAll (line 371) | func (resolver *Resolver) LoadAll(ast *parser.Thrift) error {
    method LoadOne (line 465) | func (resolver *Resolver) LoadOne(ast *parser.Thrift) (NameSpace, erro...
  function NewResolver (line 112) | func NewResolver(ast *parser.Thrift, model *model.Model, pkgMap map[stri...
  function LoadBaseIdentifier (line 404) | func LoadBaseIdentifier() NameSpace {
  function switchConstantType (line 580) | func switchConstantType(constant parser.ConstType) (*model.Type, error) {
  function newTypedefType (line 593) | func newTypedefType(t *model.Type, name string) model.Type {

FILE: cmd/hz/thrift/tag_test.go
  function TestInsertTag (line 28) | func TestInsertTag(t *testing.T) {

FILE: cmd/hz/thrift/tags.go
  constant AnnotationQuery (line 33) | AnnotationQuery    = "api.query"
  constant AnnotationForm (line 34) | AnnotationForm     = "api.form"
  constant AnnotationPath (line 35) | AnnotationPath     = "api.path"
  constant AnnotationHeader (line 36) | AnnotationHeader   = "api.header"
  constant AnnotationCookie (line 37) | AnnotationCookie   = "api.cookie"
  constant AnnotationBody (line 38) | AnnotationBody     = "api.body"
  constant AnnotationRawBody (line 39) | AnnotationRawBody  = "api.raw_body"
  constant AnnotationJsConv (line 40) | AnnotationJsConv   = "api.js_conv"
  constant AnnotationNone (line 41) | AnnotationNone     = "api.none"
  constant AnnotationFileName (line 42) | AnnotationFileName = "api.file_name"
  constant AnnotationValidator (line 44) | AnnotationValidator = "api.vd"
  constant AnnotationGoTag (line 46) | AnnotationGoTag = "go.tag"
  constant ApiGet (line 50) | ApiGet        = "api.get"
  constant ApiPost (line 51) | ApiPost       = "api.post"
  constant ApiPut (line 52) | ApiPut        = "api.put"
  constant ApiPatch (line 53) | ApiPatch      = "api.patch"
  constant ApiDelete (line 54) | ApiDelete     = "api.delete"
  constant ApiOptions (line 55) | ApiOptions    = "api.options"
  constant ApiHEAD (line 56) | ApiHEAD       = "api.head"
  constant ApiAny (line 57) | ApiAny        = "api.any"
  constant ApiPath (line 58) | ApiPath       = "api.path"
  constant ApiSerializer (line 59) | ApiSerializer = "api.serializer"
  constant ApiGenPath (line 60) | ApiGenPath    = "api.handler_path"
  constant ApiBaseDomain (line 64) | ApiBaseDomain    = "api.base_domain"
  constant ApiServiceGroup (line 65) | ApiServiceGroup  = "api.service_group"
  constant ApiServiceGenDir (line 66) | ApiServiceGenDir = "api.service_gen_dir"
  constant ApiServicePath (line 67) | ApiServicePath   = "api.service_path"
  function CheckTagOption (line 108) | func CheckTagOption(args *config.Argument) []generator.Option {
  function checkSnakeName (line 125) | func checkSnakeName(name string) string {
  function getAnnotation (line 132) | func getAnnotation(input parser.Annotations, target string) []string {
  type httpAnnotation (line 145) | type httpAnnotation struct
  type httpAnnotations (line 150) | type httpAnnotations
    method Len (line 152) | func (s httpAnnotations) Len() int {
    method Swap (line 156) | func (s httpAnnotations) Swap(i, j int) {
    method Less (line 160) | func (s httpAnnotations) Less(i, j int) bool {
  function getAnnotations (line 164) | func getAnnotations(input parser.Annotations, targets map[string]string)...
  function defaultBindingTags (line 185) | func defaultBindingTags(f *parser.Field) []model.Tag {
  function jsonTag (line 233) | func jsonTag(f *parser.Field) (ret model.Tag) {
  function tag (line 248) | func tag(k, v string) model.Tag {
  function annotationToTags (line 255) | func annotationToTags(as parser.Annotations, targets map[string]string) ...
  function injectTags (line 268) | func injectTags(f *parser.Field, gf *model.Field, needDefault, needGoTag...
  function getJsonValue (line 333) | func getJsonValue(f *parser.Field, val string) string {
  function checkRequire (line 346) | func checkRequire(f *parser.Field, val string) string {
  function checkGoTag (line 355) | func checkGoTag(as parser.Annotations, tags *model.Tags) error {

FILE: cmd/hz/util/ast.go
  function AddImport (line 31) | func AddImport(file, alias, impt string) ([]byte, error) {
  function AddImportForContent (line 42) | func AddImportForContent(fileContent []byte, alias, impt string) ([]byte...
  function addImport (line 52) | func addImport(fset *token.FileSet, f *ast.File, alias, impt string) ([]...

FILE: cmd/hz/util/ast_test.go
  function TestAddImport (line 29) | func TestAddImport(t *testing.T) {

FILE: cmd/hz/util/data.go
  function CopyStringSlice (line 33) | func CopyStringSlice(from, to *[]string) {
  function CopyString2StringMap (line 45) | func CopyString2StringMap(from, to map[string]string) {
  function PackArgs (line 54) | func PackArgs(c interface{}) (res []string, err error) {
  function UnpackArgs (line 123) | func UnpackArgs(args []string, c interface{}) error {
  function MapForm (line 196) | func MapForm(input []string) (map[string][]string, error) {
  function GetFirstKV (line 211) | func GetFirstKV(m map[string][]string) (string, []string) {
  function ToCamelCase (line 218) | func ToCamelCase(name string) string {
  function ToSnakeCase (line 222) | func ToSnakeCase(name string) string {
  function unifyPath (line 227) | func unifyPath(path string) string {
  function BaseName (line 235) | func BaseName(include, subFixToTrim string) string {
  function BaseNameAndTrim (line 248) | func BaseNameAndTrim(include string) string {
  function SplitPackageName (line 261) | func SplitPackageName(pkg, subFixToTrim string) string {
  function SplitPackage (line 271) | func SplitPackage(pkg, subFixToTrim string) string {
  function ImportToSanitizedPath (line 284) | func ImportToSanitizedPath(path string) string {
  function ToVarName (line 294) | func ToVarName(paths []string) string {
  function SplitGoTags (line 313) | func SplitGoTags(input string) []string {
  function SubPackage (line 339) | func SubPackage(mod, dir string) string {
  function SubDir (line 346) | func SubDir(root, subPkg string) string {
  function GetPackageUniqueName (line 357) | func GetPackageUniqueName(name string) (string, error) {
  function GetMiddlewareUniqueName (line 367) | func GetMiddlewareUniqueName(name string) (string, error) {
  function GetHandlerPackageUniqueName (line 376) | func GetHandlerPackageUniqueName(name string) (string, error) {
  function getUniqueName (line 386) | func getUniqueName(name string, uniqueNameSet map[string]bool) (string, ...
  function ToGoFuncName (line 409) | func ToGoFuncName(s string) string {

FILE: cmd/hz/util/data_test.go
  function TestUniqueName (line 21) | func TestUniqueName(t *testing.T) {

FILE: cmd/hz/util/env.go
  function GetGOPATH (line 33) | func GetGOPATH() (gopath string, err error) {
  function GetBuildGoPaths (line 61) | func GetBuildGoPaths() []string {
  function SearchGoMod (line 85) | func SearchGoMod(cwd string, recurse bool) (moduleName, path string, fou...
  function InitGoMod (line 114) | func InitGoMod(module string) error {
  function IsWindows (line 136) | func IsWindows() bool {

FILE: cmd/hz/util/fs.go
  function PathExist (line 24) | func PathExist(path string) (bool, error) {
  function RelativePath (line 36) | func RelativePath(path string) (string, error) {

FILE: cmd/hz/util/logs/api.go
  function init (line 19) | func init() {
  function SetLogger (line 23) | func SetLogger(logger Logger) {
  constant LevelDebug (line 28) | LevelDebug = 1 + iota
  constant LevelInfo (line 29) | LevelInfo
  constant LevelWarn (line 30) | LevelWarn
  constant LevelError (line 31) | LevelError
  type Logger (line 35) | type Logger interface
  function Errorf (line 46) | func Errorf(format string, v ...interface{}) {
  function Warnf (line 50) | func Warnf(format string, v ...interface{}) {
  function Infof (line 54) | func Infof(format string, v ...interface{}) {
  function Debugf (line 58) | func Debugf(format string, v ...interface{}) {
  function Error (line 62) | func Error(format string, v ...interface{}) {
  function Warn (line 66) | func Warn(format string, v ...interface{}) {
  function Info (line 70) | func Info(format string, v ...interface{}) {
  function Debug (line 74) | func Debug(format string, v ...interface{}) {
  function Flush (line 78) | func Flush() {
  function SetLevel (line 82) | func SetLevel(level int) {

FILE: cmd/hz/util/logs/std.go
  type StdLogger (line 27) | type StdLogger struct
    method Debugf (line 54) | func (stdLogger *StdLogger) Debugf(format string, v ...interface{}) {
    method Infof (line 64) | func (stdLogger *StdLogger) Infof(format string, v ...interface{}) {
    method Warnf (line 74) | func (stdLogger *StdLogger) Warnf(format string, v ...interface{}) {
    method Errorf (line 84) | func (stdLogger *StdLogger) Errorf(format string, v ...interface{}) {
    method Flush (line 94) | func (stdLogger *StdLogger) Flush() {
    method FlushOut (line 101) | func (stdLogger *StdLogger) FlushOut() {
    method Err (line 106) | func (stdLogger *StdLogger) Err() string {
    method Warn (line 110) | func (stdLogger *StdLogger) Warn() string {
    method FlushErr (line 114) | func (stdLogger *StdLogger) FlushErr() {
    method OutLines (line 119) | func (stdLogger *StdLogger) OutLines() []string {
    method Out (line 128) | func (stdLogger *StdLogger) Out() []byte {
    method SetLevel (line 132) | func (stdLogger *StdLogger) SetLevel(level int) error {
  function NewStdLogger (line 39) | func NewStdLogger(level int) *StdLogger {

FILE: cmd/hz/util/string.go
  function Str2Bytes (line 26) | func Str2Bytes(in string) (out []byte) {
  function Bytes2Str (line 35) | func Bytes2Str(in []byte) (out string) {
  function TrimLastChar (line 44) | func TrimLastChar(s string) string {
  function AddSlashForComments (line 53) | func AddSlashForComments(s string) string {
  function CamelString (line 59) | func CamelString(s string) string {
  function SnakeString (line 84) | func SnakeString(s string) string {

FILE: cmd/hz/util/tool_install.go
  constant ThriftgoMiniVersion (line 32) | ThriftgoMiniVersion = "v0.2.0"
  function QueryVersion (line 35) | func QueryVersion(exe string) (version string, err error) {
  function ShouldUpdate (line 57) | func ShouldUpdate(current, latest string) bool {
  function InstallAndCheckThriftgo (line 71) | func InstallAndCheckThriftgo() error {
  function CheckCompiler (line 113) | func CheckCompiler(tool string) (bool, error) {
  function CheckAndUpdateThriftgo (line 135) | func CheckAndUpdateThriftgo() error {

FILE: cmd/hz/util/tool_install_test.go
  function TestQueryVersion (line 21) | func TestQueryVersion(t *testing.T) {

FILE: examples/html_rendering/main.go
  function formatAsDate (line 31) | func formatAsDate(t time.Time) string {
  function main (line 36) | func main() {

FILE: examples/standard/main.go
  type Test (line 29) | type Test struct
  function main (line 34) | func main() {

FILE: internal/bytesconv/bytesconv.go
  constant upperhex (line 53) | upperhex = "0123456789ABCDEF"
  constant lowerhex (line 54) | lowerhex = "0123456789abcdef"
  function LowercaseBytes (line 57) | func LowercaseBytes(b []byte) {
  function B2s (line 69) | func B2s(b []byte) string {
  type sliceHeader (line 73) | type sliceHeader struct
  function S2b (line 83) | func S2b(s string) (b []byte) {
  function EncodedIntHexLen (line 89) | func EncodedIntHexLen(n uint64) int {
  function AppendIntHex (line 101) | func AppendIntHex(b []byte, n uint64) []byte {
  function ReadHexInt (line 115) | func ReadHexInt(r network.Reader) (int, error) {
  function ParseUintBuf (line 150) | func ParseUintBuf(b []byte) (int, int, error) {
  function AppendUint (line 176) | func AppendUint(dst []byte, n int) []byte {
  function AppendHTTPDate (line 200) | func AppendHTTPDate(dst []byte, date time.Time) []byte {
  function AppendQuotedPath (line 204) | func AppendQuotedPath(dst, src []byte) []byte {
  function AppendQuotedArg (line 221) | func AppendQuotedArg(dst, src []byte) []byte {
  function ParseHTTPDate (line 236) | func ParseHTTPDate(date []byte) (time.Time, error) {
  function ParseUint (line 241) | func ParseUint(buf []byte) (int, error) {

FILE: internal/bytesconv/bytesconv_32.go
  constant maxHexIntChars (line 47) | maxHexIntChars = 7

FILE: internal/bytesconv/bytesconv_32_test.go
  function TestReadHexInt (line 53) | func TestReadHexInt(t *testing.T) {
  function TestParseUint (line 73) | func TestParseUint(t *testing.T) {
  function TestParseUintError (line 93) | func TestParseUintError(t *testing.T) {
  function TestAppendUint (line 116) | func TestAppendUint(t *testing.T) {

FILE: internal/bytesconv/bytesconv_64.go
  constant maxHexIntChars (line 47) | maxHexIntChars = 15

FILE: internal/bytesconv/bytesconv_64_test.go
  function TestReadHexInt (line 53) | func TestReadHexInt(t *testing.T) {
  function TestParseUint (line 74) | func TestParseUint(t *testing.T) {
  function TestParseUintError (line 95) | func TestParseUintError(t *testing.T) {
  function TestAppendUint (line 118) | func TestAppendUint(t *testing.T) {

FILE: internal/bytesconv/bytesconv_table.go
  constant Hex2intTable (line 48) | Hex2intTable                = "\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\...
  constant ToLowerTable (line 49) | ToLowerTable                = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\...
  constant ToUpperTable (line 50) | ToUpperTable                = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\...
  constant QuotedArgShouldEscapeTable (line 51) | QuotedArgShouldEscapeTable  = "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\...
  constant QuotedPathShouldEscapeTable (line 52) | QuotedPathShouldEscapeTable = "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\...
  constant ValidCookieValueTable (line 53) | ValidCookieValueTable       = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\...
  constant ValidHeaderFieldValueTable (line 54) | ValidHeaderFieldValueTable  = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\...
  constant ValidHeaderFieldNameTable (line 55) | ValidHeaderFieldNameTable   = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\...

FILE: internal/bytesconv/bytesconv_table_gen.go
  constant toLower (line 55) | toLower = 'a' - 'A'
  function main (line 58) | func main() {
  constant pre (line 250) | pre = `/*

FILE: internal/bytesconv/bytesconv_test.go
  function TestAppendDate (line 28) | func TestAppendDate(t *testing.T) {
  function TestLowercaseBytes (line 56) | func TestLowercaseBytes(t *testing.T) {
  function TestB2s (line 72) | func TestB2s(t *testing.T) {
  function TestS2b (line 88) | func TestS2b(t *testing.T) {
  function TestAppendIntHex (line 103) | func TestAppendIntHex(t *testing.T) {
  function testReadHexInt (line 136) | func testReadHexInt(t *testing.T, s string, expectedN int) {
  function TestAppendQuotedPath (line 145) | func TestAppendQuotedPath(t *testing.T) {
  function TestAppendQuotedArg (line 169) | func TestAppendQuotedArg(t *testing.T) {
  function TestParseHTTPDate (line 182) | func TestParseHTTPDate(t *testing.T) {

FILE: internal/bytesconv/bytesconv_timing_test.go
  function BenchmarkValidHeaderFiledValueTableHertz (line 39) | func BenchmarkValidHeaderFiledValueTableHertz(b *testing.B) {

FILE: internal/nocopy/nocopy.go
  type NoCopy (line 26) | type NoCopy struct
    method Lock (line 28) | func (*NoCopy) Lock()   {}
    method Unlock (line 29) | func (*NoCopy) Unlock() {}

FILE: internal/stats/stats_util.go
  function Record (line 25) | func Record(ti traceinfo.TraceInfo, event stats.Event, err error) {
  function CalcEventCostUs (line 37) | func CalcEventCostUs(start, end traceinfo.Event) uint64 {

FILE: internal/stats/stats_util_test.go
  function TestUtil (line 28) | func TestUtil(t *testing.T) {

FILE: internal/stats/tracer.go
  type Controller (line 30) | type Controller struct
    method Append (line 35) | func (ctl *Controller) Append(col tracer.Tracer) {
    method DoStart (line 40) | func (ctl *Controller) DoStart(ctx context.Context, c *app.RequestCont...
    method DoFinish (line 51) | func (ctl *Controller) DoFinish(ctx context.Context, c *app.RequestCon...
    method HasTracer (line 64) | func (ctl *Controller) HasTracer() bool {
    method tryRecover (line 68) | func (ctl *Controller) tryRecover() {

FILE: internal/stats/tracer_test.go
  type mockTracer (line 30) | type mockTracer struct
    method Start (line 37) | func (mt *mockTracer) Start(ctx context.Context, c *app.RequestContext...
    method Finish (line 45) | func (mt *mockTracer) Finish(ctx context.Context, c *app.RequestContex...
  function TestOrder (line 52) | func TestOrder(t *testing.T) {
  function TestPanic (line 70) | func TestPanic(t *testing.T) {

FILE: internal/tagexpr/example_test.go
  function Example (line 23) | func Example() {

FILE: internal/tagexpr/expr.go
  type variableKeyType (line 22) | type variableKeyType
  constant variableKey (line 24) | variableKey variableKeyType = "__ENV_KEY__"
  type Expr (line 27) | type Expr struct
    method parseExprNode (line 46) | func (p *Expr) parseExprNode(expr *string, e ExprNode) error {
    method parseOperand (line 93) | func (p *Expr) parseOperand(expr *string) (e ExprNode) {
    method parseOperator (line 117) | func (*Expr) parseOperator(expr *string) (e ExprNode) {
    method run (line 173) | func (p *Expr) run(field string, tagExpr *TagExpr) interface{} {
    method runWithEnv (line 177) | func (p *Expr) runWithEnv(field string, tagExpr *TagExpr, env map[stri...
  function parseExpr (line 32) | func parseExpr(expr string) (*Expr, error) {
  function sortPriority (line 193) | func sortPriority(e ExprNode) {
  function subSortPriority (line 198) | func subSortPriority(e ExprNode, isLeft bool) bool {
  function leftOperandToParent (line 211) | func leftOperandToParent(e ExprNode, isLeft bool) {
  function getPriority (line 231) | func getPriority(e ExprNode) (i int) {
  type ExprNode (line 254) | type ExprNode interface
  type exprBackground (line 267) | type exprBackground struct
    method SetParent (line 273) | func (eb *exprBackground) SetParent(e ExprNode) {
    method Parent (line 277) | func (eb *exprBackground) Parent() ExprNode {
    method LeftOperand (line 281) | func (eb *exprBackground) LeftOperand() ExprNode {
    method RightOperand (line 285) | func (eb *exprBackground) RightOperand() ExprNode {
    method SetLeftOperand (line 289) | func (eb *exprBackground) SetLeftOperand(left ExprNode) {
    method SetRightOperand (line 293) | func (eb *exprBackground) SetRightOperand(right ExprNode) {
    method Run (line 297) | func (*exprBackground) Run(context.Context, string, *TagExpr) interfac...

FILE: internal/tagexpr/expr_test.go
  function TestExpr (line 23) | func TestExpr(t *testing.T) {
  function TestExprWithEnv (line 134) | func TestExprWithEnv(t *testing.T) {
  function TestPriority (line 164) | func TestPriority(t *testing.T) {
  function TestBuiltInFunc (line 192) | func TestBuiltInFunc(t *testing.T) {
  function TestSyntaxIncorrect (line 228) | func TestSyntaxIncorrect(t *testing.T) {

FILE: internal/tagexpr/handler.go
  type FieldHandler (line 20) | type FieldHandler struct
    method StringSelector (line 35) | func (f *FieldHandler) StringSelector() string {
    method FieldSelector (line 40) | func (f *FieldHandler) FieldSelector() FieldSelector {
    method Value (line 48) | func (f *FieldHandler) Value(initZero bool) reflect.Value {
    method EvalFuncs (line 53) | func (f *FieldHandler) EvalFuncs() map[ExprSelector]func() interface{} {
    method StructField (line 67) | func (f *FieldHandler) StructField() reflect.StructField {
  function newFieldHandler (line 26) | func newFieldHandler(expr *TagExpr, fieldSelector string, field *fieldVM...
  type ExprHandler (line 72) | type ExprHandler struct
    method TagExpr (line 90) | func (e *ExprHandler) TagExpr() *TagExpr {
    method StringSelector (line 95) | func (e *ExprHandler) StringSelector() string {
    method ExprSelector (line 100) | func (e *ExprHandler) ExprSelector() ExprSelector {
    method Path (line 105) | func (e *ExprHandler) Path() string {
    method Eval (line 120) | func (e *ExprHandler) Eval() interface{} {
    method EvalFloat (line 128) | func (e *ExprHandler) EvalFloat() float64 {
    method EvalString (line 137) | func (e *ExprHandler) EvalString() string {
    method EvalBool (line 146) | func (e *ExprHandler) EvalBool() bool {
  function newExprHandler (line 80) | func newExprHandler(te, tte *TagExpr, base, es string) *ExprHandler {

FILE: internal/tagexpr/selector.go
  constant FieldSeparator (line 24) | FieldSeparator = "."
  constant ExprNameSeparator (line 27) | ExprNameSeparator = "@"
  constant DefaultExprName (line 29) | DefaultExprName = ExprNameSeparator
  type FieldSelector (line 33) | type FieldSelector
    method Name (line 36) | func (f FieldSelector) Name() string {
    method Split (line 46) | func (f FieldSelector) Split() (paths []string, name string) {
    method Parent (line 57) | func (f FieldSelector) Parent() (string, bool) {
    method String (line 67) | func (f FieldSelector) String() string {
  type ExprSelector (line 72) | type ExprSelector
    method Name (line 75) | func (e ExprSelector) Name() string {
    method Field (line 85) | func (e ExprSelector) Field() string {
    method ParentField (line 95) | func (e ExprSelector) ParentField() (string, bool) {
    method Split (line 100) | func (e ExprSelector) Split() (field FieldSelector, name string) {
    method String (line 110) | func (e ExprSelector) String() string {

FILE: internal/tagexpr/selector_test.go
  function TestExprSelector (line 21) | func TestExprSelector(t *testing.T) {

FILE: internal/tagexpr/spec_func.go
  function MustRegFunc (line 37) | func MustRegFunc(funcName string, fn func(...interface{}) interface{}, f...
  function RegFunc (line 51) | func RegFunc(funcName string, fn func(...interface{}) interface{}, force...
  method parseFuncSign (line 62) | func (p *Expr) parseFuncSign(funcName string, expr *string) (boolOpposit...
  function newFunc (line 99) | func newFunc(funcName string, fn func(...interface{}) interface{}) func(...
  type funcExprNode (line 114) | type funcExprNode struct
    method String (line 122) | func (f *funcExprNode) String() string {
    method Run (line 126) | func (f *funcExprNode) Run(ctx context.Context, currField string, tagE...
  function init (line 138) | func init() {
  type regexpFuncExprNode (line 201) | type regexpFuncExprNode struct
    method String (line 207) | func (re *regexpFuncExprNode) String() string {
    method Run (line 260) | func (re *regexpFuncExprNode) Run(ctx context.Context, currField strin...
  function readRegexpFuncExprNode (line 211) | func readRegexpFuncExprNode(p *Expr, expr *string) ExprNode {
  type sprintfFuncExprNode (line 283) | type sprintfFuncExprNode struct
    method String (line 289) | func (se *sprintfFuncExprNode) String() string {
    method Run (line 333) | func (se *sprintfFuncExprNode) Run(ctx context.Context, currField stri...
  function readSprintfFuncExprNode (line 293) | func readSprintfFuncExprNode(p *Expr, expr *string) ExprNode {

FILE: internal/tagexpr/spec_func_test.go
  function TestFunc (line 25) | func TestFunc(t *testing.T) {
  function TestRangeIn (line 89) | func TestRangeIn(t *testing.T) {

FILE: internal/tagexpr/spec_operand.go
  type groupExprNode (line 28) | type groupExprNode struct
    method String (line 47) | func (ge *groupExprNode) String() string {
    method Run (line 51) | func (ge *groupExprNode) Run(ctx context.Context, currField string, ta...
  function newGroupExprNode (line 34) | func newGroupExprNode() ExprNode { return &groupExprNode{} }
  function readGroupExprNode (line 36) | func readGroupExprNode(expr *string) (grp ExprNode, subExprNode *string) {
  type boolExprNode (line 58) | type boolExprNode struct
    method String (line 63) | func (be *boolExprNode) String() string {
    method Run (line 88) | func (be *boolExprNode) Run(ctx context.Context, currField string, tag...
  function readBoolExprNode (line 69) | func readBoolExprNode(expr *string) ExprNode {
  type stringExprNode (line 92) | type stringExprNode struct
    method String (line 97) | func (se *stringExprNode) String() string {
    method Run (line 112) | func (se *stringExprNode) Run(ctx context.Context, currField string, t...
  function readStringExprNode (line 101) | func readStringExprNode(expr *string) ExprNode {
  type digitalExprNode (line 116) | type digitalExprNode struct
    method String (line 121) | func (de *digitalExprNode) String() string {
    method Run (line 141) | func (de *digitalExprNode) Run(ctx context.Context, currField string, ...
  function readDigitalExprNode (line 127) | func readDigitalExprNode(expr *string) ExprNode {
  type nilExprNode (line 145) | type nilExprNode struct
    method String (line 150) | func (ne *nilExprNode) String() string {
    method Run (line 166) | func (ne *nilExprNode) Run(ctx context.Context, currField string, tagE...
  function readNilExprNode (line 156) | func readNilExprNode(expr *string) ExprNode {
  type variableExprNode (line 170) | type variableExprNode struct
    method String (line 176) | func (ve *variableExprNode) String() string {
    method Run (line 180) | func (ve *variableExprNode) Run(ctx context.Context, variableName stri...
  function readVariableExprNode (line 200) | func readVariableExprNode(expr *string) ExprNode {
  function getBoolAndSignOpposite (line 215) | func getBoolAndSignOpposite(expr *string) (last string, boolOpposite *bo...
  function getOpposite (line 223) | func getOpposite(expr *string, cutset string) (string, *bool) {
  function toString (line 233) | func toString(i interface{}, enforce bool) (string, bool) {
  function toFloat64 (line 255) | func toFloat64(i interface{}, tryParse bool) (float64, bool) {
  function realValue (line 308) | func realValue(v interface{}, boolOpposite *bool, signOpposite *bool) in...

FILE: internal/tagexpr/spec_operator.go
  type additionExprNode (line 24) | type additionExprNode struct
    method String (line 26) | func (ae *additionExprNode) String() string {
    method Run (line 32) | func (ae *additionExprNode) Run(ctx context.Context, currField string,...
  function newAdditionExprNode (line 30) | func newAdditionExprNode() ExprNode { return &additionExprNode{} }
  type multiplicationExprNode (line 47) | type multiplicationExprNode struct
    method String (line 49) | func (ae *multiplicationExprNode) String() string {
    method Run (line 55) | func (ae *multiplicationExprNode) Run(ctx context.Context, currField s...
  function newMultiplicationExprNode (line 53) | func newMultiplicationExprNode() ExprNode { return &multiplicationExprNo...
  type divisionExprNode (line 61) | type divisionExprNode struct
    method String (line 63) | func (de *divisionExprNode) String() string {
    method Run (line 69) | func (de *divisionExprNode) Run(ctx context.Context, currField string,...
  function newDivisionExprNode (line 67) | func newDivisionExprNode() ExprNode { return &divisionExprNode{} }
  type subtractionExprNode (line 78) | type subtractionExprNode struct
    method String (line 80) | func (de *subtractionExprNode) String() string {
    method Run (line 86) | func (de *subtractionExprNode) Run(ctx context.Context, currField stri...
  function newSubtractionExprNode (line 84) | func newSubtractionExprNode() ExprNode { return &subtractionExprNode{} }
  type remainderExprNode (line 92) | type remainderExprNode struct
    method String (line 94) | func (re *remainderExprNode) String() string {
    method Run (line 100) | func (re *remainderExprNode) Run(ctx context.Context, currField string...
  function newRemainderExprNode (line 98) | func newRemainderExprNode() ExprNode { return &remainderExprNode{} }
  type equalExprNode (line 109) | type equalExprNode struct
    method String (line 111) | func (ee *equalExprNode) String() string {
    method Run (line 117) | func (ee *equalExprNode) Run(ctx context.Context, currField string, ta...
  function newEqualExprNode (line 115) | func newEqualExprNode() ExprNode { return &equalExprNode{} }
  type notEqualExprNode (line 146) | type notEqualExprNode struct
    method String (line 148) | func (ne *notEqualExprNode) String() string {
    method Run (line 154) | func (ne *notEqualExprNode) Run(ctx context.Context, currField string,...
  function newNotEqualExprNode (line 152) | func newNotEqualExprNode() ExprNode { return &notEqualExprNode{} }
  type greaterExprNode (line 158) | type greaterExprNode struct
    method String (line 160) | func (ge *greaterExprNode) String() string {
    method Run (line 166) | func (ge *greaterExprNode) Run(ctx context.Context, currField string, ...
  function newGreaterExprNode (line 164) | func newGreaterExprNode() ExprNode { return &greaterExprNode{} }
  type greaterEqualExprNode (line 183) | type greaterEqualExprNode struct
    method String (line 185) | func (ge *greaterEqualExprNode) String() string {
    method Run (line 191) | func (ge *greaterEqualExprNode) Run(ctx context.Context, currField str...
  function newGreaterEqualExprNode (line 189) | func newGreaterEqualExprNode() ExprNode { return &greaterEqualExprNode{} }
  type lessExprNode (line 208) | type lessExprNode struct
    method String (line 210) | func (le *lessExprNode) String() string {
    method Run (line 216) | func (le *lessExprNode) Run(ctx context.Context, currField string, tag...
  function newLessExprNode (line 214) | func newLessExprNode() ExprNode { return &lessExprNode{} }
  type lessEqualExprNode (line 233) | type lessEqualExprNode struct
    method String (line 235) | func (le *lessEqualExprNode) String() string {
    method Run (line 241) | func (le *lessEqualExprNode) Run(ctx context.Context, currField string...
  function newLessEqualExprNode (line 239) | func newLessEqualExprNode() ExprNode { return &lessEqualExprNode{} }
  type andExprNode (line 258) | type andExprNode struct
    method String (line 260) | func (ae *andExprNode) String() string {
    method Run (line 266) | func (ae *andExprNode) Run(ctx context.Context, currField string, tagE...
  function newAndExprNode (line 264) | func newAndExprNode() ExprNode { return &andExprNode{} }
  type orExprNode (line 275) | type orExprNode struct
    method String (line 277) | func (oe *orExprNode) String() string {
    method Run (line 283) | func (oe *orExprNode) Run(ctx context.Context, currField string, tagEx...
  function newOrExprNode (line 281) | func newOrExprNode() ExprNode { return &orExprNode{} }

FILE: internal/tagexpr/spec_range.go
  type rangeCtxKey (line 23) | type rangeCtxKey
  constant rangeKey (line 26) | rangeKey   rangeCtxKey = "#k"
  constant rangeValue (line 27) | rangeValue rangeCtxKey = "#v"
  constant rangeLen (line 28) | rangeLen   rangeCtxKey = "##"
  type rangeKvExprNode (line 31) | type rangeKvExprNode struct
    method String (line 38) | func (re *rangeKvExprNode) String() string {
    method Run (line 77) | func (re *rangeKvExprNode) Run(ctx context.Context, _ string, _ *TagEx...
  method readRangeKvExprNode (line 42) | func (p *Expr) readRangeKvExprNode(expr *string) ExprNode {
  function findRangeKv (line 58) | func findRangeKv(expr *string) (name string, boolOpposite, signOpposite ...
  type rangeFuncExprNode (line 91) | type rangeFuncExprNode struct
    method String (line 99) | func (e *rangeFuncExprNode) String() string {
    method Run (line 121) | func (e *rangeFuncExprNode) Run(ctx context.Context, currField string,...
  function readRangeFuncExprNode (line 105) | func readRangeFuncExprNode(p *Expr, expr *string) ExprNode {

FILE: internal/tagexpr/spec_range_test.go
  function TestIssue12 (line 24) | func TestIssue12(t *testing.T) {

FILE: internal/tagexpr/spec_selector.go
  type selectorExprNode (line 24) | type selectorExprNode struct
    method String (line 32) | func (se *selectorExprNode) String() string {
    method Run (line 95) | func (se *selectorExprNode) Run(ctx context.Context, currField string,...
  method readSelectorExprNode (line 36) | func (p *Expr) readSelectorExprNode(expr *string) ExprNode {
  function findSelector (line 62) | func findSelector(expr *string) (field string, name string, subSelector ...

FILE: internal/tagexpr/spec_test.go
  function TestReadPairedSymbol (line 23) | func TestReadPairedSymbol(t *testing.T) {
  function TestReadBoolExprNode (line 46) | func TestReadBoolExprNode(t *testing.T) {
  function TestReadDigitalExprNode (line 70) | func TestReadDigitalExprNode(t *testing.T) {
  function TestFindSelector (line 99) | func TestFindSelector(t *testing.T) {

FILE: internal/tagexpr/tagexpr.go
  type VM (line 37) | type VM struct
    method MustRun (line 90) | func (vm *VM) MustRun(structOrStructPtrOrReflectValue interface{}) *Ta...
    method Run (line 112) | func (vm *VM) Run(structPtrOrReflectValue interface{}) (*TagExpr, erro...
    method RunAny (line 158) | func (vm *VM) RunAny(v interface{}, fn func(*TagExpr, error) error) er...
    method subRunAll (line 174) | func (vm *VM) subRunAll(omitNil bool, tePath string, value reflect.Val...
    method subRun (line 249) | func (vm *VM) subRun(path string, t reflect.Type, tid uintptr, ptr uns...
    method registerStructLocked (line 272) | func (vm *VM) registerStructLocked(structType reflect.Type) (*structVM...
    method registerIndirectStructLocked (line 343) | func (vm *VM) registerIndirectStructLocked(field *fieldVM) error {
    method newStructVM (line 418) | func (vm *VM) newStructVM() *structVM {
    method getStructType (line 728) | func (vm *VM) getStructType(t reflect.Type) (reflect.Type, error) {
  type structVM (line 44) | type structVM struct
    method newFieldVM (line 429) | func (s *structVM) newFieldVM(structField reflect.StructField) (*field...
    method mergeSubStructVM (line 492) | func (s *structVM) mergeSubStructVM(field *fieldVM, sub *structVM) {
    method newChildField (line 531) | func (s *structVM) newChildField(parent *fieldVM, child *fieldVM, toBi...
    method setIfaceTagExprGetter (line 622) | func (s *structVM) setIfaceTagExprGetter(f *fieldVM) {
    method newTagExpr (line 739) | func (s *structVM) newTagExpr(ptr unsafe.Pointer, path string) *TagExpr {
  type fieldVM (line 57) | type fieldVM struct
    method ensureInit (line 476) | func (f *fieldVM) ensureInit(v reflect.Value) {
    method getElemPtr (line 606) | func (f *fieldVM) getElemPtr(ptr unsafe.Pointer) unsafe.Pointer {
    method packRawFrom (line 614) | func (f *fieldVM) packRawFrom(ptr unsafe.Pointer) reflect.Value {
    method packElemFrom (line 618) | func (f *fieldVM) packElemFrom(ptr unsafe.Pointer) reflect.Value {
    method setFloatGetter (line 641) | func (f *fieldVM) setFloatGetter() {
    method setBoolGetter (line 661) | func (f *fieldVM) setBoolGetter() {
    method setStringGetter (line 681) | func (f *fieldVM) setStringGetter() {
    method setLengthGetter (line 701) | func (f *fieldVM) setLengthGetter() {
    method setUnsupportedGetter (line 711) | func (f *fieldVM) setUnsupportedGetter() {
  function New (line 79) | func New(tagName ...string) *VM {
  function checkStructMapAddr (line 167) | func checkStructMapAddr(v reflect.Value) error {
  function appendDistinct (line 404) | func appendDistinct(a []*fieldVM, i *fieldVM) []*fieldVM {
  type TagExpr (line 750) | type TagExpr struct
    method EvalFloat (line 761) | func (t *TagExpr) EvalFloat(exprSelector string) float64 {
    method EvalString (line 770) | func (t *TagExpr) EvalString(exprSelector string) string {
    method EvalBool (line 779) | func (t *TagExpr) EvalBool(exprSelector string) bool {
    method Field (line 831) | func (t *TagExpr) Field(fieldSelector string) (fh *FieldHandler, found...
    method RangeFields (line 841) | func (t *TagExpr) RangeFields(fn func(*FieldHandler) bool) bool {
    method Eval (line 858) | func (t *TagExpr) Eval(exprSelector string) interface{} {
    method EvalWithEnv (line 886) | func (t *TagExpr) EvalWithEnv(exprSelector string, env map[string]inte...
    method Range (line 914) | func (t *TagExpr) Range(fn func(*ExprHandler) error) error {
    method subRange (line 1019) | func (t *TagExpr) subRange(omitNil bool, path string, value reflect.Va...
    method checkout (line 1033) | func (t *TagExpr) checkout(fs string) (*TagExpr, error) {
    method getValue (line 1058) | func (t *TagExpr) getValue(fieldSelector string, subFields []interface...
  function FakeBool (line 784) | func FakeBool(v interface{}) bool {
  function safeConvert (line 1126) | func safeConvert(v reflect.Value, t reflect.Type) reflect.Value {
  function splitFieldSelector (line 1131) | func splitFieldSelector(selector string) (dir, base string) {
  function getFloat64 (line 1143) | func getFloat64(kind reflect.Kind, p unsafe.Pointer) interface{} {
  function anyValueGetter (line 1175) | func anyValueGetter(raw, elem reflect.Value) interface{} {
  function safeIsNil (line 1206) | func safeIsNil(v reflect.Value) bool {
  function ptrElem (line 1219) | func ptrElem(ptr unsafe.Pointer) unsafe.Pointer {
  function derefType (line 1223) | func derefType(t reflect.Type) reflect.Type {
  function derefValue (line 1230) | func derefValue(v reflect.Value) reflect.Value {

FILE: internal/tagexpr/tagexpr_test.go
  function assertEqual (line 30) | func assertEqual(t *testing.T, v1, v2 interface{}, msgs ...interface{}) {
  function BenchmarkTagExpr (line 38) | func BenchmarkTagExpr(b *testing.B) {
  function BenchmarkReflect (line 58) | func BenchmarkReflect(b *testing.B) {
  function Test (line 82) | func Test(t *testing.T) {
  function TestFieldNotInit (line 254) | func TestFieldNotInit(t *testing.T) {
  function TestFieldInitZero (line 357) | func TestFieldInitZero(t *testing.T) {
  function TestOperator (line 450) | func TestOperator(t *testing.T) {
  function TestStruct (line 572) | func TestStruct(t *testing.T) {
  function TestStruct2 (line 602) | func TestStruct2(t *testing.T) {
  function TestStruct3 (line 626) | func TestStruct3(t *testing.T) {
  function TestNilField (line 697) | func TestNilField(t *testing.T) {
  function TestDeepNested (line 731) | func TestDeepNested(t *testing.T) {
  function TestIssue3 (line 775) | func TestIssue3(t *testing.T) {
  function TestIssue4 (line 811) | func TestIssue4(t *testing.T) {
  function TestIssue5 (line 832) | func TestIssue5(t *testing.T) {
  function TestHertzIssue1410 (line 860) | func TestHertzIssue1410(t *testing.T) {
  function TestFakeBool (line 874) | func TestFakeBool(t *testing.T) {

FILE: internal/tagexpr/tagparser.go
  constant tagOmit (line 24) | tagOmit    = "-"
  constant tagOmitNil (line 25) | tagOmitNil = "?"
  method parseExprs (line 28) | func (f *fieldVM) parseExprs(tag string) error {
  function parseTag (line 58) | func parseTag(tag string) (map[string]string, error) {
  function splitExpr (line 81) | func splitExpr(one string) (key, val string) {
  function readOneExpr (line 110) | func readOneExpr(tag *string) (string, error) {
  function trimLeftSpace (line 136) | func trimLeftSpace(p *string) *string {
  function trimRightSpace (line 141) | func trimRightSpace(p *string) *string {
  function readPairedSymbol (line 146) | func readPairedSymbol(p *string, left, right rune) *string {
  function equalRune (line 184) | func equalRune(a, b, last1, last2 rune) (real, escape bool) {

FILE: internal/tagexpr/tagparser_test.go
  function TestTagparser (line 22) | func TestTagparser(t *testing.T) {

FILE: internal/tagexpr/utils.go
  function init (line 24) | func init() {
  function dereferenceValue (line 28) | func dereferenceValue(v reflect.Value) reflect.Value {
  function dereferenceType (line 35) | func dereferenceType(t reflect.Type) reflect.Type {
  function dereferenceInterfaceValue (line 42) | func dereferenceInterfaceValue(v reflect.Value) reflect.Value {
  type rvtype (line 49) | type rvtype struct
  function rvPtr (line 54) | func rvPtr(rv reflect.Value) unsafe.Pointer {
  function rvType (line 58) | func rvType(rv reflect.Value) uintptr {
  function rtType (line 62) | func rtType(rt reflect.Type) uintptr {
  function testhack (line 71) | func testhack() {

FILE: internal/tagexpr/validator/default.go
  function Default (line 23) | func Default() *Validator {
  function Validate (line 32) | func Validate(value interface{}, checkAll ...bool) error {
  function SetErrorFactory (line 40) | func SetErrorFactory(errFactory func(fieldSelector, msg string) error) {

FILE: internal/tagexpr/validator/example_test.go
  function Example (line 23) | func Example() {

FILE: internal/tagexpr/validator/func.go
  function MustRegFunc (line 35) | func MustRegFunc(funcName string, fn func(args ...interface{}) error, fo...
  function RegFunc (line 49) | func RegFunc(funcName string, fn func(args ...interface{}) error, force ...
  function init (line 60) | func init() {
  function validatePhone (line 89) | func validatePhone(numberToParse, region string) bool {
  function init (line 93) | func init() {

FILE: internal/tagexpr/validator/validator.go
  constant MatchExprName (line 30) | MatchExprName = tagexpr.DefaultExprName
  constant ErrMsgExprName (line 33) | ErrMsgExprName = "msg"
  type Validator (line 37) | type Validator struct
    method VM (line 52) | func (v *Validator) VM() *tagexpr.VM {
    method Validate (line 60) | func (v *Validator) Validate(value interface{}, checkAll ...bool) error {
    method SetErrorFactory (line 136) | func (v *Validator) SetErrorFactory(errFactory func(failPath, msg stri...
  function New (line 43) | func New(tagName string) *Validator {
  type Error (line 145) | type Error struct
    method Error (line 150) | func (e *Error) Error() string {
  function defaultErrorFactory (line 158) | func defaultErrorFactory(failPath, msg string) error {

FILE: internal/tagexpr/validator/validator_test.go
  function assertEqualError (line 25) | func assertEqualError(t *testing.T, err error, s string) {
  function assertNoError (line 32) | func assertNoError(t *testing.T, err error) {
  function TestNil (line 39) | func TestNil(t *testing.T) {
  function TestAll (line 48) | func TestAll(t *testing.T) {
  function TestIssue1 (line 58) | func TestIssue1(t *testing.T) {
  function TestIssue2 (line 100) | func TestIssue2(t *testing.T) {
  function TestIssue3 (line 114) | func TestIssue3(t *testing.T) {
  function TestIssue4 (line 133) | func TestIssue4(t *testing.T) {
  function TestIssue5 (line 178) | func TestIssue5(t *testing.T) {
  function TestIn (line 204) | func TestIn(t *testing.T) {
  type Issue23A (line 239) | type Issue23A struct
  type Issue23B (line 243) | type Issue23B struct
  function TestIssue23 (line 249) | func TestIssue23(t *testing.T) {
  function TestIssue24 (line 255) | func TestIssue24(t *testing.T) {
  function TestStructSliceMap (line 288) | func TestStructSliceMap(t *testing.T) {
  function TestIssue30 (line 311) | func TestIssue30(t *testing.T) {
  function TestIssue31 (line 323) | func TestIssue31(t *testing.T) {
  function TestRegexp (line 332) | func TestRegexp(t *testing.T) {
  function TestRangeIn (line 342) | func TestRangeIn(t *testing.T) {

FILE: internal/test/mock/binder/binder.go
  type Binder (line 25) | type Binder struct
    method Name (line 39) | func (m *Binder) Name() string {
    method Bind (line 43) | func (m *Binder) Bind(request *protocol.Request, i interface{}, params...
    method BindAndValidate (line 47) | func (m *Binder) BindAndValidate(request *protocol.Request, i interfac...
    method BindQuery (line 51) | func (m *Binder) BindQuery(request *protocol.Request, i interface{}) e...
    method BindHeader (line 55) | func (m *Binder) BindHeader(request *protocol.Request, i interface{}) ...
    method BindPath (line 59) | func (m *Binder) BindPath(request *protocol.Request, i interface{}, pa...
    method BindForm (line 63) | func (m *Binder) BindForm(request *protocol.Request, i interface{}) er...
    method BindJSON (line 67) | func (m *Binder) BindJSON(request *protocol.Request, i interface{}) er...
    method BindProtobuf (line 71) | func (m *Binder) BindProtobuf(request *protocol.Request, i interface{}...
    method Validate (line 75) | func (m *Binder) Validate(request *protocol.Request, i interface{}) er...
  function NewBinder (line 30) | func NewBinder() *Binder {
  function NewBinderWithValidateError (line 35) | func NewBinderWithValidateError(err error) *Binder {

FILE: internal/test/mock/binder/binder_test.go
  function TestNewBinder (line 26) | func TestNewBinder(t *testing.T) {
  function TestNewBinderWithValidateError (line 43) | func TestNewBinderWithValidateError(t *testing.T) {
  function TestBinderValidate (line 49) | func TestBinderValidate(t *testing.T) {

FILE: internal/testutils/testutils.go
  type RouteEngine (line 25) | type RouteEngine interface
  function WaitEngineRunning (line 29) | func WaitEngineRunning(e RouteEngine) {
  function NewTestListener (line 42) | func NewTestListener(tb testing.TB) net.Listener {

FILE: internal/testutils/testutils_test.go
  function TestNewTestListener (line 25) | func TestNewTestListener(t *testing.T) {
  type routeEngine (line 31) | type routeEngine struct
    method IsRunning (line 35) | func (e *routeEngine) IsRunning() bool {
  function TestWaitEngineRunning (line 39) | func TestWaitEngineRunning(t *testing.T) {

FILE: pkg/app/client/client.go
  function Do (line 93) | func Do(ctx context.Context, req *protocol.Request, resp *protocol.Respo...
  function DoTimeout (line 126) | func DoTimeout(ctx context.Context, req *protocol.Request, resp *protoco...
  function DoDeadline (line 159) | func DoDeadline(ctx context.Context, req *protocol.Request, resp *protoc...
  function DoRedirects (line 182) | func DoRedirects(ctx context.Context, req *protocol.Request, resp *proto...
  function Get (line 193) | func Get(ctx context.Context, dst []byte, url string, requestOptions ......
  function GetTimeout (line 212) | func GetTimeout(ctx context.Context, dst []byte, url string, timeout tim...
  function GetDeadline (line 231) | func GetDeadline(ctx context.Context, dst []byte, url string, deadline t...
  function Post (line 243) | func Post(ctx context.Context, dst []byte, url string, postArgs *protoco...
  type Client (line 254) | type Client struct
    method GetOptions (line 282) | func (c *Client) GetOptions() *config.ClientOptions {
    method SetRetryIfFunc (line 286) | func (c *Client) SetRetryIfFunc(retryIf client.RetryIfFunc) {
    method SetRetryIf (line 291) | func (c *Client) SetRetryIf(fn func(request *protocol.Request) bool) {
    method SetProxy (line 302) | func (c *Client) SetProxy(p protocol.Proxy) {
    method Get (line 312) | func (c *Client) Get(ctx context.Context, dst []byte, url string, requ...
    method GetTimeout (line 325) | func (c *Client) GetTimeout(ctx context.Context, dst []byte, url strin...
    method GetDeadline (line 338) | func (c *Client) GetDeadline(ctx context.Context, dst []byte, url stri...
    method Post (line 350) | func (c *Client) Post(ctx context.Context, dst []byte, url string, pos...
    method DoTimeout (line 383) | func (c *Client) DoTimeout(ctx context.Context, req *protocol.Request,...
    method DoDeadline (line 410) | func (c *Client) DoDeadline(ctx context.Context, req *protocol.Request...
    method DoRedirects (line 433) | func (c *Client) DoRedirects(ctx context.Context, req *protocol.Reques...
    method Do (line 457) | func (c *Client) Do(ctx context.Context, req *protocol.Request, resp *...
    method do (line 467) | func (c *Client) do(ctx context.Context, req *protocol.Request, resp *...
    method CloseIdleConnections (line 545) | func (c *Client) CloseIdleConnections() {
    method cleaner (line 556) | func (c *Client) cleaner(isTLS bool) {
    method cleanHostClients (line 565) | func (c *Client) cleanHostClients(isTLS bool) bool {
    method SetClientFactory (line 586) | func (c *Client) SetClientFactory(cf suite.ClientFactory) {
    method GetDialerName (line 591) | func (c *Client) GetDialerName() (dName string, err error) {
    method Use (line 629) | func (c *Client) Use(mws ...Middleware) {
    method UseAsLast (line 644) | func (c *Client) UseAsLast(mw Middleware) error {
    method TakeOutLastMiddleware (line 655) | func (c *Client) TakeOutLastMiddleware() Middleware {
  function NewClient (line 615) | func NewClient(opts ...config.ClientOption) (*Client, error) {
  function newHttp1OptionFromClient (line 661) | func newHttp1OptionFromClient(c *Client) *http1.ClientOptions {

FILE: pkg/app/client/client_test.go
  function assertNil (line 89) | func assertNil(err error) {
  function waitEngineRunning (line 95) | func waitEngineRunning(e *route.Engine) {
  function newTestOptions (line 99) | func newTestOptions(t *testing.T) (*config.Options, net.Listener) {
  function fullURL (line 108) | func fullURL(ln net.Listener, p string) string {
  function TestCloseIdleConnections (line 112) | func TestCloseIdleConnections(t *testing.T) {
  function TestCloseIdleTLSConnections (line 160) | func TestCloseIdleTLSConnections(t *testing.T) {
  function TestClientInvalidURI (line 204) | func TestClientInvalidURI(t *testing.T) {
  function TestClientGetWithBody (line 235) | func TestClientGetWithBody(t *testing.T) {
  function TestClientPostBodyStream (line 267) | func TestClientPostBodyStream(t *testing.T) {
  function TestClientURLAuth (line 297) | func TestClientURLAuth(t *testing.T) {
  function TestClientNilResp (line 337) | func TestClientNilResp(t *testing.T) {
  function TestClientParseConn (line 363) | func TestClientParseConn(t *testing.T) {
  function TestClientPostArgs (line 402) | func TestClientPostArgs(t *testing.T) {
  function TestClientHeaderCase (line 439) | func TestClientHeaderCase(t *testing.T) {
  function TestClientReadTimeout (line 470) | func TestClientReadTimeout(t *testing.T) {
  function TestClientDefaultUserAgent (line 545) | func TestClientDefaultUserAgent(t *testing.T) {
  function TestClientSetUserAgent (line 575) | func TestClientSetUserAgent(t *testing.T) {
  function TestClientNoUserAgent (line 605) | func TestClientNoUserAgent(t *testing.T) {
  function TestClientDoWithCustomHeaders (line 635) | func TestClientDoWithCustomHeaders(t *testing.T) {
  function TestClientDoTimeoutDisablePathNormalizing (line 722) | func TestClientDoTimeoutDisablePathNormalizing(t *testing.T) {
  function TestHostClientPendingRequests (line 757) | func TestHostClientPendingRequests(t *testing.T) {
  function TestHostClientMaxConnsWithDeadline (line 841) | func TestHostClientMaxConnsWithDeadline(t *testing.T) {
  function TestHostClientMaxConnDuration (line 911) | func TestHostClientMaxConnDuration(t *testing.T) {
  function TestHostClientMultipleAddrs (line 956) | func TestHostClientMultipleAddrs(t *testing.T) {
  function TestClientFollowRedirects (line 1004) | func TestClientFollowRedirects(t *testing.T) {
  function TestHostClientMaxConnWaitTimeoutSuccess (line 1105) | func TestHostClientMaxConnWaitTimeoutSuccess(t *testing.T) {
  function TestHostClientMaxConnWaitTimeoutError (line 1172) | func TestHostClientMaxConnWaitTimeoutError(t *testing.T) {
  function TestNewClient (line 1246) | func TestNewClient(t *testing.T) {
  function TestUseShortConnection (line 1278) | func TestUseShortConnection(t *testing.T) {
  function TestPostWithFormData (line 1323) | func TestPostWithFormData(t *testing.T) {
  function TestPostWithMultipartField (line 1379) | func TestPostWithMultipartField(t *testing.T) {
  function TestSetFiles (line 1424) | func TestSetFiles(t *testing.T) {
  function TestSetMultipartFields (line 1477) | func TestSetMultipartFields(t *testing.T) {
  function TestClientReadResponseBodyStream (line 1543) | func TestClientReadResponseBodyStream(t *testing.T) {
  function TestWithBasicAuth (line 1593) | func TestWithBasicAuth(t *testing.T) {
  function TestClientProxyWithStandardDialer (line 1652) | func TestClientProxyWithStandardDialer(t *testing.T) {
  function TestClientProxyWithNetpollDialer (line 1792) | func TestClientProxyWithNetpollDialer(t *testing.T) {
  function TestClientMiddleware (line 1866) | func TestClientMiddleware(t *testing.T) {
  function TestClientLastMiddleware (line 1906) | func TestClientLastMiddleware(t *testing.T) {
  function TestClientReadResponseBodyStreamWithDoubleRequest (line 1975) | func TestClientReadResponseBodyStreamWithDoubleRequest(t *testing.T) {
  function TestClientReadResponseBodyStreamWithConnectionClose (line 2052) | func TestClientReadResponseBodyStreamWithConnectionClose(t *testing.T) {
  type mockDialer (line 2110) | type mockDialer struct
    method DialConnection (line 2118) | func (m *mockDialer) DialConnection(network, address string, timeout t...
  function TestClientRetry (line 2125) | func TestClientRetry(t *testing.T) {
  function TestClientHostClientConfigHookError (line 2255) | func TestClientHostClientConfigHookError(t *testing.T) {
  function TestClientHostClientConfigHook (line 2271) | func TestClientHostClientConfigHook(t *testing.T) {
  function TestClientDialerName (line 2293) | func TestClientDialerName(t *testing.T) {
  function TestClientDoWithDialFunc (line 2342) | func TestClientDoWithDialFunc(t *testing.T) {
  function TestClientState (line 2405) | func TestClientState(t *testing.T) {
  function TestClientRetryErr (line 2447) | func TestClientRetryErr(t *testing.T) {
  type mockHostClient (line 2510) | type mockHostClient struct
    method Do (line 2515) | func (m *mockHostClient) Do(ctx context.Context, req *protocol.Request...
    method SetDynamicConfig (line 2519) | func (m *mockHostClient) SetDynamicConfig(dc *client.DynamicConfig) {
    method CloseIdleConnections (line 2522) | func (m *mockHostClient) CloseIdleConnections() {
    method ShouldRemove (line 2525) | func (m *mockHostClient) ShouldRemove() bool {
    method ConnectionCount (line 2529) | func (m *mockHostClient) ConnectionCount() int {
    method Close (line 2533) | func (m *mockHostClient) Close() error {
  function TestCleanHostClients (line 2538) | func TestCleanHostClients(t *testing.T) {

FILE: pkg/app/client/client_unix_test.go
  function newMockDialerWithCustomFunc (line 30) | func newMockDialerWithCustomFunc(network, address string, timeout time.D...

FILE: pkg/app/client/client_windows_test.go
  function newMockDialerWithCustomFunc (line 28) | func newMockDialerWithCustomFunc(network, address string, timeout time.D...

FILE: pkg/app/client/discovery/discovery.go
  type TargetInfo (line 27) | type TargetInfo struct
  type Resolver (line 32) | type Resolver interface
  type SynthesizedResolver (line 44) | type SynthesizedResolver struct
    method Target (line 50) | func (sr SynthesizedResolver) Target(ctx context.Context, target *Targ...
    method Resolve (line 57) | func (sr SynthesizedResolver) Resolve(ctx context.Context, key string)...
    method Name (line 62) | func (sr SynthesizedResolver) Name() string {
  type Instance (line 70) | type Instance interface
  type instance (line 76) | type instance struct
    method Address (line 82) | func (i *instance) Address() net.Addr {
    method Weight (line 86) | func (i *instance) Weight() int {
    method Tag (line 93) | func (i *instance) Tag(key string) (value string, exist bool) {
  function NewInstance (line 99) | func NewInstance(network, address string, weight int, tags map[string]st...
  type Result (line 109) | type Result struct

FILE: pkg/app/client/discovery/discovery_test.go
  function TestInstance (line 27) | func TestInstance(t *testing.T) {
  function TestSynthesizedResolver (line 44) | func TestSynthesizedResolver(t *testing.T) {

FILE: pkg/app/client/loadbalance/lbcache.go
  type cacheResult (line 33) | type cacheResult struct
  function cacheKey (line 44) | func cacheKey(resolver, balancer string, opts Options) string {
  type BalancerFactory (line 48) | type BalancerFactory struct
    method watcher (line 86) | func (b *BalancerFactory) watcher() {
    method refresh (line 109) | func (b *BalancerFactory) refresh() {
    method GetInstance (line 127) | func (b *BalancerFactory) GetInstance(ctx context.Context, req *protoc...
    method getCacheResult (line 141) | func (b *BalancerFactory) getCacheResult(ctx context.Context, req *pro...
  type Config (line 56) | type Config struct
  function NewBalancerFactory (line 64) | func NewBalancerFactory(config Config) *BalancerFactory {
  function renameResultCacheKey (line 104) | func renameResultCacheKey(res *discovery.Result, resolverName string) {

FILE: pkg/app/client/loadbalance/lbcache_test.go
  function TestBuilder (line 32) | func TestBuilder(t *testing.T) {
  function TestBalancerCache (line 74) | func TestBalancerCache(t *testing.T) {
  function TestBalancerRefresh (line 106) | func TestBalancerRefresh(t *testing.T) {
  function TestBalancerExpires (line 140) | func TestBalancerExpires(t *testing.T) {
  function TestCacheKey (line 172) | func TestCacheKey(t *testing.T) {
  type mockLoadbalancer (line 177) | type mockLoadbalancer struct
    method Rebalance (line 185) | func (m mockLoadbalancer) Rebalance(ch discovery.Result) {
    method Delete (line 192) | func (m mockLoadbalancer) Delete(ch string) {
    method Name (line 199) | func (m mockLoadbalancer) Name() string {
    method Pick (line 207) | func (m mockLoadbalancer) Pick(d discovery.Result) discovery.Instance {

FILE: pkg/app/client/loadbalance/loadbalance.go
  type Loadbalancer (line 26) | type Loadbalancer interface
  constant DefaultRefreshInterval (line 41) | DefaultRefreshInterval = 5 * time.Second
  constant DefaultExpireInterval (line 42) | DefaultExpireInterval  = 15 * time.Second
  type Options (line 51) | type Options struct
    method Check (line 61) | func (v *Options) Check() {

FILE: pkg/app/client/loadbalance/weight_random.go
  type weightedBalancer (line 28) | type weightedBalancer struct
    method calcWeightInfo (line 45) | func (wb *weightedBalancer) calcWeightInfo(e discovery.Result) *weight...
    method Pick (line 72) | func (wb *weightedBalancer) Pick(e discovery.Result) discovery.Instance {
    method Rebalance (line 98) | func (wb *weightedBalancer) Rebalance(e discovery.Result) {
    method Delete (line 103) | func (wb *weightedBalancer) Delete(cacheKey string) {
    method Name (line 107) | func (wb *weightedBalancer) Name() string {
  type weightInfo (line 33) | type weightInfo struct
  function NewWeightedBalancer (line 40) | func NewWeightedBalancer() Loadbalancer {

FILE: pkg/app/client/loadbalance/weight_random_test.go
  function TestWeightedBalancer (line 27) | func TestWeightedBalancer(t *testing.T) {

FILE: pkg/app/client/middleware.go
  type Endpoint (line 26) | type Endpoint
  type Middleware (line 29) | type Middleware
  function chain (line 32) | func chain(mws ...Middleware) Middleware {

FILE: pkg/app/client/middleware_test.go
  function invoke (line 34) | func invoke(ctx context.Context, req *protocol.Request, resp *protocol.R...
  function mockMW0 (line 39) | func mockMW0(next Endpoint) Endpoint {
  function mockMW1 (line 51) | func mockMW1(next Endpoint) Endpoint {
  function TestChain (line 63) | func TestChain(t *testing.T) {

FILE: pkg/app/client/option.go
  function WithDialTimeout (line 32) | func WithDialTimeout(dialTimeout time.Duration) config.ClientOption {
  function WithMaxConnsPerHost (line 39) | func WithMaxConnsPerHost(mc int) config.ClientOption {
  function WithMaxIdleConnDuration (line 46) | func WithMaxIdleConnDuration(t time.Duration) config.ClientOption {
  function WithMaxConnDuration (line 53) | func WithMaxConnDuration(t time.Duration) config.ClientOption {
  function WithMaxConnWaitTimeout (line 60) | func WithMaxConnWaitTimeout(t time.Duration) config.ClientOption {
  function WithKeepAlive (line 67) | func WithKeepAlive(b bool) config.ClientOption {
  function WithClientReadTimeout (line 74) | func WithClientReadTimeout(t time.Duration) config.ClientOption {
  function WithTLSConfig (line 81) | func WithTLSConfig(cfg *tls.Config) config.ClientOption {
  function WithDialer (line 89) | func WithDialer(d network.Dialer) config.ClientOption {
  function WithResponseBodyStream (line 96) | func WithResponseBodyStream(b bool) config.ClientOption {
  function WithHostClientConfigHook (line 103) | func WithHostClientConfigHook(h func(hc interface{}) error) config.Clien...
  function WithDisableHeaderNamesNormalizing (line 110) | func WithDisableHeaderNamesNormalizing(disable bool) config.ClientOption {
  function WithName (line 117) | func WithName(name string) config.ClientOption {
  function WithNoDefaultUserAgentHeader (line 124) | func WithNoDefaultUserAgentHeader(isNoDefaultUserAgentHeader bool) confi...
  function WithDisablePathNormalizing (line 131) | func WithDisablePathNormalizing(isDisablePathNormalizing bool) config.Cl...
  function WithRetryConfig (line 137) | func WithRetryConfig(opts ...retry.Option) config.ClientOption {
  function WithWriteTimeout (line 153) | func WithWriteTimeout(t time.Duration) config.ClientOption {
  function WithConnStateObserve (line 163) | func WithConnStateObserve(hs config.HostClientStateFunc, interval ...tim...
  function WithDialFunc (line 174) | func WithDialFunc(f network.DialFunc, dialers ...network.Dialer) config....
  type customDialer (line 185) | type customDialer struct
    method DialConnection (line 190) | func (m *customDialer) DialConnection(network, address string, timeout...
  function newCustomDialerWithDialFunc (line 197) | func newCustomDialerWithDialFunc(dialer network.Dialer, dialFunc network...

FILE: pkg/app/client/option_test.go
  function TestClientOptions (line 30) | func TestClientOptions(t *testing.T) {

FILE: pkg/app/client/retry/option.go
  type Option (line 22) | type Option struct
  function WithMaxAttemptTimes (line 27) | func WithMaxAttemptTimes(maxAttemptTimes uint) Option {
  function WithInitDelay (line 34) | func WithInitDelay(delay time.Duration) Option {
  function WithMaxDelay (line 41) | func WithMaxDelay(maxDelay time.Duration) Option {
  function WithDelayPolicy (line 48) | func WithDelayPolicy(delayPolicy DelayPolicyFunc) Option {
  function WithMaxJitter (line 55) | func WithMaxJitter(maxJitter time.Duration) Option {

FILE: pkg/app/client/retry/retry.go
  type Config (line 27) | type Config struct
    method Apply (line 45) | func (o *Config) Apply(opts []Option) {
  type DelayPolicyFunc (line 53) | type DelayPolicyFunc
  function DefaultDelayPolicy (line 56) | func DefaultDelayPolicy(_ uint, _ error, _ *Config) time.Duration {
  function FixedDelayPolicy (line 61) | func FixedDelayPolicy(_ uint, _ error, retryConfig *Config) time.Duration {
  function RandomDelayPolicy (line 66) | func RandomDelayPolicy(_ uint, _ error, retryConfig *Config) time.Durati...
  function BackOffDelayPolicy (line 74) | func BackOffDelayPolicy(attempts uint, _ error, retryConfig *Config) tim...
  function CombineDelay (line 88) | func CombineDelay(delays ...DelayPolicyFunc) DelayPolicyFunc {
  function Delay (line 105) | func Delay(attempts uint, err error, retryConfig *Config) time.Duration {

FILE: pkg/app/client/retry/retry_test.go
  function TestApply (line 27) | func TestApply(t *testing.T) {
  function TestPolicy (line 45) | func TestPolicy(t *testing.T) {

FILE: pkg/app/context.go
  type Handler (line 75) | type Handler interface
  type ClientIP (line 79) | type ClientIP
  type ClientIPOptions (line 81) | type ClientIPOptions struct
  function ClientIPWithOption (line 105) | func ClientIPWithOption(opts ClientIPOptions) ClientIP {
  function isTrustedProxy (line 135) | func isTrustedProxy(trustedCIDRs []*net.IPNet, remoteIP net.IP) bool {
  function validateHeader (line 148) | func validateHeader(trustedCIDRs []*net.IPNet, header string) (clientIP ...
  function SetClientIPFunc (line 173) | func SetClientIPFunc(fn ClientIP) {
  type FormValueFunc (line 177) | type FormValueFunc
  type RequestContext (line 198) | type RequestContext struct
    method Exile (line 243) | func (ctx *RequestContext) Exile() {
    method IsExiled (line 247) | func (ctx *RequestContext) IsExiled() bool {
    method Flush (line 253) | func (ctx *RequestContext) Flush() error {
    method SetClientIPFunc (line 260) | func (ctx *RequestContext) SetClientIPFunc(f ClientIP) {
    method SetFormValueFunc (line 264) | func (ctx *RequestContext) SetFormValueFunc(f FormValueFunc) {
    method SetBinder (line 268) | func (ctx *RequestContext) SetBinder(binder binding.Binder) {
    method GetTraceInfo (line 272) | func (ctx *RequestContext) GetTraceInfo() traceinfo.TraceInfo {
    method SetTraceInfo (line 276) | func (ctx *RequestContext) SetTraceInfo(t traceinfo.TraceInfo) {
    method IsEnableTrace (line 280) | func (ctx *RequestContext) IsEnableTrace() bool {
    method SetEnableTrace (line 287) | func (ctx *RequestContext) SetEnableTrace(enable bool) {
    method ForEachKey (line 301) | func (ctx *RequestContext) ForEachKey(fn func(k string, v interface{})) {
    method SetConn (line 309) | func (ctx *RequestContext) SetConn(c network.Conn) {
    method GetConn (line 313) | func (ctx *RequestContext) GetConn() network.Conn {
    method SetHijackHandler (line 317) | func (ctx *RequestContext) SetHijackHandler(h HijackHandler) {
    method GetHijackHandler (line 321) | func (ctx *RequestContext) GetHijackHandler() HijackHandler {
    method GetReader (line 325) | func (ctx *RequestContext) GetReader() network.Reader {
    method GetWriter (line 329) | func (ctx *RequestContext) GetWriter() network.Writer {
    method GetIndex (line 333) | func (ctx *RequestContext) GetIndex() int8 {
    method SetIndex (line 339) | func (ctx *RequestContext) SetIndex(index int8) {
    method Hijack (line 445) | func (ctx *RequestContext) Hijack(handler HijackHandler) {
    method Finished (line 459) | func (ctx *RequestContext) Finished() <-chan struct{} {
    method GetRequest (line 470) | func (ctx *RequestContext) GetRequest() (dst *protocol.Request) {
    method GetResponse (line 477) | func (ctx *RequestContext) GetResponse() (dst *protocol.Response) {
    method Value (line 488) | func (ctx *RequestContext) Value(key interface{}) interface{} {
    method Hijacked (line 501) | func (ctx *RequestContext) Hijacked() bool {
    method SetBodyStream (line 516) | func (ctx *RequestContext) SetBodyStream(bodyStream io.Reader, bodySiz...
    method Host (line 523) | func (ctx *RequestContext) Host() []byte {
    method RemoteAddr (line 530) | func (ctx *RequestContext) RemoteAddr() net.Addr {
    method WriteString (line 542) | func (ctx *RequestContext) WriteString(s string) (int, error) {
    method SetContentType (line 548) | func (ctx *RequestContext) SetContentType(contentType string) {
    method Path (line 555) | func (ctx *RequestContext) Path() []byte {
    method NotModified (line 560) | func (ctx *RequestContext) NotModified() {
    method IfModifiedSince (line 569) | func (ctx *RequestContext) IfModifiedSince(lastModified time.Time) bool {
    method URI (line 585) | func (ctx *RequestContext) URI() *protocol.URI {
    method String (line 589) | func (ctx *RequestContext) String(code int, format string, values ...i...
    method FullPath (line 599) | func (ctx *RequestContext) FullPath() string {
    method SetFullPath (line 603) | func (ctx *RequestContext) SetFullPath(p string) {
    method SetStatusCode (line 608) | func (ctx *RequestContext) SetStatusCode(statusCode int) {
    method Write (line 613) | func (ctx *RequestContext) Write(p []byte) (int, error) {
    method File (line 619) | func (ctx *RequestContext) File(filepath string) {
    method FileFromFS (line 623) | func (ctx *RequestContext) FileFromFS(filepath string, fs *FS) {
    method FileAttachment (line 636) | func (ctx *RequestContext) FileAttachment(filepath, filename string) {
    method SetBodyString (line 642) | func (ctx *RequestContext) SetBodyString(body string) {
    method SetContentTypeBytes (line 649) | func (ctx *RequestContext) SetContentTypeBytes(contentType []byte) {
    method FormFile (line 654) | func (ctx *RequestContext) FormFile(name string) (*multipart.FileHeade...
    method FormValue (line 674) | func (ctx *RequestContext) FormValue(key string) []byte {
    method multipartFormValue (line 681) | func (ctx *RequestContext) multipartFormValue(key string) (string, boo...
    method multipartFormValueArray (line 692) | func (ctx *RequestContext) multipartFormValueArray(key string) ([]stri...
    method RequestBodyStream (line 703) | func (ctx *RequestContext) RequestBodyStream() io.Reader {
    method MultipartForm (line 721) | func (ctx *RequestContext) MultipartForm() (*multipart.Form, error) {
    method SaveUploadedFile (line 726) | func (ctx *RequestContext) SaveUploadedFile(file *multipart.FileHeader...
    method SetConnectionClose (line 744) | func (ctx *RequestContext) SetConnectionClose() {
    method IsGet (line 749) | func (ctx *RequestContext) IsGet() bool {
    method IsHead (line 754) | func (ctx *RequestContext) IsHead() bool {
    method IsPost (line 759) | func (ctx *RequestContext) IsPost() bool {
    method Method (line 766) | func (ctx *RequestContext) Method() []byte {
    method NotFound (line 771) | func (ctx *RequestContext) NotFound() {
    method redirect (line 777) | func (ctx *RequestContext) redirect(uri []byte, statusCode int) {
    method Copy (line 797) | func (ctx *RequestContext) Copy() *RequestContext {
    method Next (line 824) | func (ctx *RequestContext) Next(c context.Context) {
    method Handler (line 833) | func (ctx *RequestContext) Handler() HandlerFunc {
    method Handlers (line 838) | func (ctx *RequestContext) Handlers() HandlersChain {
    method SetHandlers (line 842) | func (ctx *RequestContext) SetHandlers(hc HandlersChain) {
    method HandlerName (line 849) | func (ctx *RequestContext) HandlerName() string {
    method ResetWithoutConn (line 853) | func (ctx *RequestContext) ResetWithoutConn() {
    method Reset (line 876) | func (ctx *RequestContext) Reset() {
    method Redirect (line 888) | func (ctx *RequestContext) Redirect(statusCode int, uri []byte) {
    method Header (line 895) | func (ctx *RequestContext) Header(key, value string) {
    method Set (line 905) | func (ctx *RequestContext) Set(key string, value interface{}) {
    method Get (line 917) | func (ctx *RequestContext) Get(key string) (value interface{}, exists ...
    method MustGet (line 925) | func (ctx *RequestContext) MustGet(key string) interface{} {
    method GetString (line 933) | func (ctx *RequestContext) GetString(key string) (s string) {
    method GetBool (line 941) | func (ctx *RequestContext) GetBool(key string) (b bool) {
    method GetInt (line 949) | func (ctx *RequestContext) GetInt(key string) (i int) {
    method GetInt32 (line 957) | func (ctx *RequestContext) GetInt32(key string) (i32 int32) {
    method GetInt64 (line 965) | func (ctx *RequestContext) GetInt64(key string) (i64 int64) {
    method GetUint (line 973) | func (ctx *RequestContext) GetUint(key string) (ui uint) {
    method GetUint32 (line 981) | func (ctx *RequestContext) GetUint32(key string) (ui32 uint32) {
    method GetUint64 (line 989) | func (ctx *RequestContext) GetUint64(key string) (ui64 uint64) {
    method GetFloat32 (line 997) | func (ctx *RequestContext) GetFloat32(key string) (f32 float32) {
    method GetFloat64 (line 1005) | func (ctx *RequestContext) GetFloat64(key string) (f64 float64) {
    method GetTime (line 1013) | func (ctx *RequestContext) GetTime(key string) (t time.Time) {
    method GetDuration (line 1021) | func (ctx *RequestContext) GetDuration(key string) (d time.Duration) {
    method GetStringSlice (line 1031) | func (ctx *RequestContext) GetStringSlice(key string) (ss []string) {
    method GetStringMap (line 1041) | func (ctx *RequestContext) GetStringMap(key string) (sm map[string]int...
    method GetStringMapString (line 1051) | func (ctx *RequestContext) GetStringMapString(key string) (sms map[str...
    method GetStringMapStringSlice (line 1061) | func (ctx *RequestContext) GetStringMapStringSlice(key string) (smss m...
    method Param (line 1075) | func (ctx *RequestContext) Param(key string) string {
    method Abort (line 1085) | func (ctx *RequestContext) Abort() {
    method AbortWithStatus (line 1092) | func (ctx *RequestContext) AbortWithStatus(code int) {
    method AbortWithMsg (line 1101) | func (ctx *RequestContext) AbortWithMsg(msg string, statusCode int) {
    method AbortWithStatusJSON (line 1113) | func (ctx *RequestContext) AbortWithStatusJSON(code int, jsonObj inter...
    method Render (line 1119) | func (ctx *RequestContext) Render(code int, r render.Render) {
    method ProtoBuf (line 1133) | func (ctx *RequestContext) ProtoBuf(code int, obj interface{}) {
    method JSON (line 1140) | func (ctx *RequestContext) JSON(code int, obj interface{}) {
    method PureJSON (line 1146) | func (ctx *RequestContext) PureJSON(code int, obj interface{}) {
    method IndentedJSON (line 1152) | func (ctx *RequestContext) IndentedJSON(code int, obj interface{}) {
    method HTML (line 1160) | func (ctx *RequestContext) HTML(code int, name string, obj interface{}) {
    method Data (line 1166) | func (ctx *RequestContext) Data(code int, contentType string, data []b...
    method XML (line 1176) | func (ctx *RequestContext) XML(code int, obj interface{}) {
    method AbortWithError (line 1184) | func (ctx *RequestContext) AbortWithError(code int, err error) *errors...
    method IsAborted (line 1190) | func (ctx *RequestContext) IsAborted() bool {
    method Error (line 1200) | func (ctx *RequestContext) Error(err error) *errors.Error {
    method ContentType (line 1218) | func (ctx *RequestContext) ContentType() []byte {
    method Cookie (line 1223) | func (ctx *RequestContext) Cookie(key string) []byte {
    method SetCookie (line 1245) | func (ctx *RequestContext) SetCookie(name, value string, maxAge int, p...
    method setCookie (line 1249) | func (ctx *RequestContext) setCookie(name, value string, maxAge int, p...
    method SetPartitionedCookie (line 1273) | func (ctx *RequestContext) SetPartitionedCookie(name, value string, ma...
    method UserAgent (line 1278) | func (ctx *RequestContext) UserAgent() []byte {
    method Status (line 1283) | func (ctx *RequestContext) Status(code int) {
    method GetHeader (line 1288) | func (ctx *RequestContext) GetHeader(key string) []byte {
    method GetRawData (line 1293) | func (ctx *RequestContext) GetRawData() []byte {
    method Body (line 1298) | func (ctx *RequestContext) Body() ([]byte, error) {
    method ClientIP (line 1305) | func (ctx *RequestContext) ClientIP() string {
    method QueryArgs (line 1317) | func (ctx *RequestContext) QueryArgs() *protocol.Args {
    method PostArgs (line 1326) | func (ctx *RequestContext) PostArgs() *protocol.Args {
    method Query (line 1339) | func (ctx *RequestContext) Query(key string) string {
    method DefaultQuery (line 1346) | func (ctx *RequestContext) DefaultQuery(key, defaultValue string) stri...
    method GetQuery (line 1363) | func (ctx *RequestContext) GetQuery(key string) (string, bool) {
    method PostForm (line 1369) | func (ctx *RequestContext) PostForm(key string) string {
    method PostFormArray (line 1376) | func (ctx *RequestContext) PostFormArray(key string) []string {
    method DefaultPostForm (line 1385) | func (ctx *RequestContext) DefaultPostForm(key, defaultValue string) s...
    method GetPostForm (line 1401) | func (ctx *RequestContext) GetPostForm(key string) (string, bool) {
    method GetPostFormArray (line 1417) | func (ctx *RequestContext) GetPostFormArray(key string) ([]string, boo...
    method getBinder (line 1443) | func (ctx *RequestContext) getBinder() binding.Binder {
    method BindAndValidate (line 1452) | func (ctx *RequestContext) BindAndValidate(obj interface{}) error {
    method Bind (line 1462) | func (ctx *RequestContext) Bind(obj interface{}) error {
    method Validate (line 1468) | func (ctx *RequestContext) Validate(obj interface{}) error {
    method BindQuery (line 1474) | func (ctx *RequestContext) BindQuery(obj interface{}) error {
    method BindHeader (line 1480) | func (ctx *RequestContext) BindHeader(obj interface{}) error {
    method BindPath (line 1486) | func (ctx *RequestContext) BindPath(obj interface{}) error {
    method BindForm (line 1492) | func (ctx *RequestContext) BindForm(obj interface{}) error {
    method BindJSON (line 1501) | func (ctx *RequestContext) BindJSON(obj interface{}) error {
    method BindProtobuf (line 1507) | func (ctx *RequestContext) BindProtobuf(obj interface{}) error {
    method BindByContentType (line 1513) | func (ctx *RequestContext) BindByContentType(obj interface{}) error {
    method VisitAllQueryArgs (line 1534) | func (ctx *RequestContext) VisitAllQueryArgs(f func(key, value []byte)) {
    method VisitAllPostArgs (line 1542) | func (ctx *RequestContext) VisitAllPostArgs(f func(key, value []byte)) {
    method VisitAllHeaders (line 1552) | func (ctx *RequestContext) VisitAllHeaders(f func(key, value []byte)) {
    method VisitAllCookie (line 1559) | func (ctx *RequestContext) VisitAllCookie(f func(key, value []byte)) {
  function NewContext (line 294) | func NewContext(maxParams uint16) *RequestContext {
  type HandlerFunc (line 343) | type HandlerFunc
  type HandlersChain (line 346) | type HandlersChain
    method Last (line 452) | func (c HandlersChain) Last() HandlerFunc {
  type HandlerNameOperator (line 348) | type HandlerNameOperator interface
  function SetHandlerNameOperator (line 353) | func SetHandlerNameOperator(o HandlerNameOperator) {
  type inbuiltHandlerNameOperatorStruct (line 357) | type inbuiltHandlerNameOperatorStruct struct
    method SetHandlerName (line 361) | func (o *inbuiltHandlerNameOperatorStruct) SetHandlerName(handler Hand...
    method GetHandlerName (line 365) | func (o *inbuiltHandlerNameOperatorStruct) GetHandlerName(handler Hand...
  type concurrentHandlerNameOperatorStruct (line 369) | type concurrentHandlerNameOperatorStruct struct
    method SetHandlerName (line 374) | func (o *concurrentHandlerNameOperatorStruct) SetHandlerName(handler H...
    method GetHandlerName (line 380) | func (o *concurrentHandlerNameOperatorStruct) GetHandlerName(handler H...
  function SetConcurrentHandlerNameOperator (line 386) | func SetConcurrentHandlerNameOperator() {
  function init (line 390) | func init() {
  function SetHandlerName (line 396) | func SetHandlerName(handler HandlerFunc, name string) {
  function GetHandlerName (line 400) | func GetHandlerName(handler HandlerFunc) string {
  function getFuncAddr (line 404) | func getFuncAddr(v interface{}) uintptr {
  type HijackHandler (line 419) | type HijackHandler
  function getRedirectStatusCode (line 783) | func getRedirectStatusCode(statusCode int) int {
  function bodyAllowedForStatus (line 1431) | func bodyAllowedForStatus(status int) bool {

FILE: pkg/app/context_test.go
  function TestProtobuf (line 53) | func TestProtobuf(t *testing.T) {
  function TestPureJson (line 61) | func TestPureJson(t *testing.T) {
  function TestIndentedJSON (line 71) | func TestIndentedJSON(t *testing.T) {
  function TestContext (line 82) | func TestContext(t *testing.T) {
  function TestValue (line 91) | func TestValue(t *testing.T) {
  function TestContextNotModified (line 102) | func TestContextNotModified(t *testing.T) {
  function TestIfModifiedSince (line 114) | func TestIfModifiedSince(t *testing.T) {
  function TestWrite (line 128) | func TestWrite(t *testing.T) {
  function TestSetConnectionClose (line 142) | func TestSetConnectionClose(t *testing.T) {
  function TestNotFound (line 150) | func TestNotFound(t *testing.T) {
  function TestRedirect (line 158) | func TestRedirect(t *testing.T) {
  function TestGetRedirectStatusCode (line 167) | func TestGetRedirectStatusCode(t *testing.T) {
  function TestCookie (line 175) | func TestCookie(t *testing.T) {
  function TestUserAgent (line 183) | func TestUserAgent(t *testing.T) {
  function TestStatus (line 191) | func TestStatus(t *testing.T) {
  function TestPost (line 199) | func TestPost(t *testing.T) {
  function TestGet (line 211) | func TestGet(t *testing.T) {
  function TestCopy (line 220) | func TestCopy(t *testing.T) {
  function TestQuery (line 285) | func TestQuery(t *testing.T) {
  function TestMethod (line 308) | func TestMethod(t *testing.T) {
  function makeCtxByReqString (line 316) | func makeCtxByReqString(t *testing.T, s string) *RequestContext {
  function TestPostForm (line 326) | func TestPostForm(t *testing.T) {
  function TestPostFormArray (line 370) | func TestPostFormArray(t *testing.T) {
  function TestDefaultPostForm (line 404) | func TestDefaultPostForm(t *testing.T) {
  function TestRequestContext_FormFile (line 434) | func TestRequestContext_FormFile(t *testing.T) {
  function TestContextRenderFileFromFS (line 527) | func TestContextRenderFileFromFS(t *testing.T) {
  function TestContextRenderFile (line 551) | func TestContextRenderFile(t *testing.T) {
  function TestContextRenderAttachment (line 569) | func TestContextRenderAttachment(t *testing.T) {
  function TestRequestContext_Header (line 588) | func TestRequestContext_Header(t *testing.T) {
  function TestRequestContext_Keys (line 611) | func TestRequestContext_Keys(t *testing.T) {
  function testFunc (line 621) | func testFunc(c context.Context, ctx *RequestContext) {
  function testFunc2 (line 625) | func testFunc2(c context.Context, ctx *RequestContext) {
  function TestRequestContext_Handler (line 629) | func TestRequestContext_Handler(t *testing.T) {
  function TestRequestContext_Handlers (line 644) | func TestRequestContext_Handlers(t *testing.T) {
  function TestRequestContext_HandlerName (line 655) | func TestRequestContext_HandlerName(t *testing.T) {
  function TestNext (line 664) | func TestNext(t *testing.T) {
  function TestContextError (line 682) | func TestContextError(t *testing.T) {
  function TestContextAbortWithError (line 717) | func TestContextAbortWithError(t *testing.T) {
  function TestRender (line 727) | func TestRender(t *testing.T) {
  function TestHTML (line 763) | func TestHTML(t *testing.T) {
  type xmlmap (line 779) | type xmlmap
    method MarshalXML (line 782) | func (h xmlmap) MarshalXML(e *xml.Encoder, start xml.StartElement) err...
  function TestXML (line 803) | func TestXML(t *testing.T) {
  function TestJSON (line 810) | func TestJSON(t *testing.T) {
  function TestDATA (line 817) | func TestDATA(t *testing.T) {
  function TestContextReset (line 824) | func TestContextReset(t *testing.T) {
  function TestContextContentType (line 845) | func TestContextContentType(t *testing.T) {
  type MockConn (line 851) | type MockConn struct
    method RemoteAddr (line 857) | func (c *MockConn) RemoteAddr() net.Addr {
  function newContextClientIPTest (line 861) | func newContextClientIPTest() *RequestContext {
  function TestClientIP (line 871) | func TestClientIP(t *testing.T) {
  function TestSetClientIPFunc (line 916) | func TestSetClientIPFunc(t *testing.T) {
  function TestGetQuery (line 924) | func TestGetQuery(t *testing.T) {
  function TestGetPostForm (line 932) | func TestGetPostForm(t *testing.T) {
  function TestGetPostFormArray (line 941) | func TestGetPostFormArray(t *testing.T) {
  function TestRemoteAddr (line 949) | func TestRemoteAddr(t *testing.T) {
  function TestRequestBodyStream (line 956) | func TestRequestBodyStream(t *testing.T) {
  function TestContextIsAborted (line 966) | func TestContextIsAborted(t *testing.T) {
  function TestContextAbortWithStatus (line 980) | func TestContextAbortWithStatus(t *testing.T) {
  type testJSONAbortMsg (line 991) | type testJSONAbortMsg struct
  function TestContextAbortWithStatusJSON (line 996) | func TestContextAbortWithStatusJSON(t *testing.T) {
  function TestRequestCtxFormValue (line 1017) | func TestRequestCtxFormValue(t *testing.T) {
  function TestSetCustomFormValueFunc (line 1062) | func TestSetCustomFormValueFunc(t *testing.T) {
  function TestContextSetGet (line 1093) | func TestContextSetGet(t *testing.T) {
  function TestContextSetGetValues (line 1109) | func TestContextSetGetValues(t *testing.T) {
  function TestContextGetString (line 1131) | func TestContextGetString(t *testing.T) {
  function TestContextSetGetBool (line 1139) | func TestContextSetGetBool(t *testing.T) {
  function TestContextGetInt (line 1147) | func TestContextGetInt(t *testing.T) {
  function TestContextGetInt32 (line 1155) | func TestContextGetInt32(t *testing.T) {
  function TestContextGetInt64 (line 1163) | func TestContextGetInt64(t *testing.T) {
  function TestContextGetUint (line 1171) | func TestContextGetUint(t *testing.T) {
  function TestContextGetUint32 (line 1179) | func TestContextGetUint32(t *testing.T) {
  function TestContextGetUint64 (line 1187) | func TestContextGetUint64(t *testing.T) {
  function TestContextGetFloat32 (line 1195) | func TestContextGetFloat32(t *testing.T) {
  function TestContextGetFloat64 (line 1203) | func TestContextGetFloat64(t *testing.T) {
  function TestContextGetTime (line 1211) | func TestContextGetTime(t *testing.T) {
  function TestContextGetDuration (line 1220) | func TestContextGetDuration(t *testing.T) {
  function TestContextGetStringSlice (line 1228) | func TestContextGetStringSlice(t *testing.T) {
  function TestContextGetStringMap (line 1237) | func TestContextGetStringMap(t *testing.T) {
  function TestContextGetStringMapString (line 1251) | func TestContextGetStringMapString(t *testing.T) {
  function TestContextGetStringMapStringSlice (line 1265) | func TestContextGetStringMapStringSlice(t *testing.T) {
  function TestContextTraceInfo (line 1279) | func TestContextTraceInfo(t *testing.T) {
  function TestEnableTrace (line 1288) | func TestEnableTrace(t *testing.T) {
  function TestForEachKey (line 1295) | func TestForEachKey(t *testing.T) {
  function TestFlush (line 1308) | func TestFlush(t *testing.T) {
  function TestConn (line 1314) | func TestConn(t *testing.T) {
  function TestHijackHandler (line 1327) | func TestHijackHandler(t *testing.T) {
  function TestGetReader (line 1340) | func TestGetReader(t *testing.T) {
  function TestGetWriter (line 1353) | func TestGetWriter(t *testing.T) {
  function TestIndex (line 1366) | func TestIndex(t *testing.T) {
  function TestConcurrentHandlerName (line 1378) | func TestConcurrentHandlerName(t *testing.T) {
  function TestHandlerName (line 1402) | func TestHandlerName(t *testing.T) {
  function TestHijack (line 1409) | func TestHijack(t *testing.T) {
  function TestFinished (line 1416) | func TestFinished(t *testing.T) {
  function TestString (line 1433) | func TestString(t *testing.T) {
  function TestFullPath (line 1439) | func TestFullPath(t *testing.T) {
  function TestReset (line 1447) | func TestReset(t *testing.T) {
  function TestGetHeader (line 1459) | func TestGetHeader(t *testing.T) {
  function TestGetRawData (line 1466) | func TestGetRawData(t *testing.T) {
  function TestRequestContext_GetRequest (line 1477) | func TestRequestContext_GetRequest(t *testing.T) {
  function TestRequestContext_GetResponse (line 1490) | func TestRequestContext_GetResponse(t *testing.T) {
  function TestBindAndValidate (line 1503) | func TestBindAndValidate(t *testing.T) {
  function TestBindForm (line 1544) | func TestBindForm(t *testing.T) {
  function TestSetBinder (line 1570) | func TestSetBinder(t *testing.T) {
  function TestRequestContext_SetCookie (line 1594) | func TestRequestContext_SetCookie(t *testing.T) {
  function TestRequestContext_SetPartitionedCookie (line 1600) | func TestRequestContext_SetPartitionedCookie(t *testing.T) {
  function TestRequestContext_SetCookiePathEmpty (line 1606) | func TestRequestContext_SetCookiePathEmpty(t *testing.T) {
  function TestRequestContext_VisitAll (line 1612) | func TestRequestContext_VisitAll(t *testing.T) {
  function BenchmarkInbuiltHandlerNameOperator (line 1666) | func BenchmarkInbuiltHandlerNameOperator(b *testing.B) {
  function BenchmarkConcurrentHandlerNameOperator (line 1675) | func BenchmarkConcurrentHandlerNameOperator(b *testing.B) {

FILE: pkg/app/fs.go
  type PathRewriteFunc (line 99) | type PathRewriteFunc
  type FS (line 105) | type FS struct
    method NewRequestHandler (line 305) | func (fs *FS) NewRequestHandler() HandlerFunc {
    method initRequestHandler (line 310) | func (fs *FS) initRequestHandler() {
  type byteRangeUpdater (line 178) | type byteRangeUpdater interface
  type fsSmallFileReader (line 182) | type fsSmallFileReader struct
    method Close (line 188) | func (r *fsSmallFileReader) Close() error {
    method UpdateByteRange (line 198) | func (r *fsSmallFileReader) UpdateByteRange(startPos, endPos int) error {
    method Read (line 204) | func (r *fsSmallFileReader) Read(p []byte) (int, error) {
    method WriteTo (line 225) | func (r *fsSmallFileReader) WriteTo(w io.Writer) (int64, error) {
  function ServeFile (line 279) | func ServeFile(ctx *RequestContext, path string) {
  type fsHandler (line 357) | type fsHandler struct
    method cleanCache (line 427) | func (h *fsHandler) cleanCache(pendingFiles []*fsFile) []*fsFile {
    method compressAndOpenFSFile (line 456) | func (h *fsHandler) compressAndOpenFSFile(filePath string) (*fsFile, e...
    method newCompressedFSFile (line 494) | func (h *fsHandler) newCompressedFSFile(filePath string) (*fsFile, err...
    method compressFileNolock (line 507) | func (h *fsHandler) compressFileNolock(f *os.File, fileInfo os.FileInf...
    method openFSFile (line 551) | func (h *fsHandler) openFSFile(filePath string, mustCompress bool) (*f...
    method newFSFile (line 598) | func (h *fsHandler) newFSFile(f *os.File, fileInfo os.FileInfo, compre...
    method createDirIndex (line 632) | func (h *fsHandler) createDirIndex(base *protocol.URI, dirPath string,...
    method openIndexFile (line 713) | func (h *fsHandler) openIndexFile(ctx *RequestContext, dirPath string,...
    method handleRequest (line 796) | func (h *fsHandler) handleRequest(c context.Context, ctx *RequestConte...
  type bigFileReader (line 377) | type bigFileReader struct
    method UpdateByteRange (line 384) | func (r *bigFileReader) UpdateByteRange(startPos, endPos int) error {
    method Read (line 394) | func (r *bigFileReader) Read(p []byte) (int, error) {
    method WriteTo (line 398) | func (r *bigFileReader) WriteTo(w io.Writer) (int64, error) {
    method Close (line 408) | func (r *bigFileReader) Close() error {
  type fsFile (line 951) | type fsFile struct
    method decReadersCount (line 732) | func (ff *fsFile) decReadersCount() {
    method bigFileReader (line 741) | func (ff *fsFile) bigFileReader() (io.Reader, error) {
    method NewReader (line 771) | func (ff *fsFile) NewReader() (io.Reader, error) {
    method smallFileReader (line 782) | func (ff *fsFile) smallFileReader() io.Reader {
    method Release (line 969) | func (ff *fsFile) Release() {
    method isBig (line 983) | func (ff *fsFile) isBig() bool {
  function cleanCacheNolock (line 987) | func cleanCacheNolock(cache map[string]*fsFile, pendingFiles, filesToRel...
  function stripTrailingSlashes (line 1005) | func stripTrailingSlashes(path []byte) []byte {
  function isFileCompressible (line 1012) | func isFileCompressible(f *os.File, minCompressRatio float64) bool {
  function getFileLock (line 1041) | func getFileLock(absPath string) *sync.Mutex {
  function fileExtension (line 1052) | func fileExtension(path string, compressed bool, compressedFileSuffix st...
  function readFileHeader (line 1063) | func readFileHeader(f *os.File, compressed bool) ([]byte, error) {
  function fsModTime (line 1090) | func fsModTime(t time.Time) time.Time {
  function ParseByteRange (line 1097) | func ParseByteRange(byteRange []byte, contentLength int) (startPos, endP...
  function NewVHostPathRewriter (line 1161) | func NewVHostPathRewriter(slashesCount int) PathRewriteFunc {
  function stripLeadingSlashes (line 1182) | func stripLeadingSlashes(path []byte, stripSlashes int) []byte {
  function ServeFileUncompressed (line 1205) | func ServeFileUncompressed(ctx *RequestContext, path string) {
  function NewPathSlashesStripper (line 1220) | func NewPathSlashesStripper(slashesCount int) PathRewriteFunc {

FILE: pkg/app/fs_test.go
  function TestNewVHostPathRewriter (line 63) | func TestNewVHostPathRewriter(t *testing.T) {
  function TestNewVHostPathRewriterMaliciousHost (line 89) | func TestNewVHostPathRewriterMaliciousHost(t *testing.T) {
  function testPathNotFound (line 104) | func testPathNotFound(t *testing.T, pathNotFoundFunc HandlerFunc) {
  function TestPathNotFound (line 131) | func TestPathNotFound(t *testing.T) {
  function TestPathNotFoundFunc (line 137) | func TestPathNotFoundFunc(t *testing.T) {
  function TestServeFileHead (line 145) | func TestServeFileHead(t *testing.T) {
  function TestServeFileSmallNoReadFrom (line 184) | func TestServeFileSmallNoReadFrom(t *testing.T) {
  type pureWriter (line 255) | type pureWriter struct
    method Write (line 259) | func (pw pureWriter) Write(p []byte) (nn int, err error) {
  function TestServeFileCompressed (line 263) | func TestServeFileCompressed(t *testing.T) {
  function TestServeFileUncompressed (line 298) | func TestServeFileUncompressed(t *testing.T) {
  function TestFSByteRangeConcurrent (line 331) | func TestFSByteRangeConcurrent(t *testing.T) {
  function TestFSByteRangeSingleThread (line 360) | func TestFSByteRangeSingleThread(t *testing.T) {
  function testFSByteRange (line 372) | func testFSByteRange(t *testing.T, h HandlerFunc, filePath string) {
  function getFileContents (line 422) | func getFileContents(path string) ([]byte, error) {
  function TestParseByteRangeSuccess (line 432) | func TestParseByteRangeSuccess(t *testing.T) {
  function testParseByteRangeSuccess (line 452) | func testParseByteRangeSuccess(t *testing.T, v string, contentLength, st...
  function TestParseByteRangeError (line 465) | func TestParseByteRangeError(t *testing.T) {
  function testParseByteRangeError (line 492) | func testParseByteRangeError(t *testing.T, v string, contentLength int) {
  function TestFSCompressConcurrent (line 499) | func TestFSCompressConcurrent(t *testing.T) {
  function TestFSCompressSingleThread (line 530) | func TestFSCompressSingleThread(t *testing.T) {
  function testFSCompress (line 544) | func testFSCompress(t *testing.T, h HandlerFunc, filePath string) {
  function TestFileLock (line 595) | func TestFileLock(t *testing.T) {
  function TestStripPathSlashes (line 615) | func TestStripPathSlashes(t *testing.T) {
  function testStripPathSlashes (line 636) | func testStripPathSlashes(t *testing.T, path string, stripSlashes int, e...
  function TestFileExtension (line 644) | func TestFileExtension(t *testing.T) {
  function testFileExtension (line 660) | func testFileExtension(t *testing.T, path string, compressed bool, compr...
  function TestServeFileContentType (line 667) | func TestServeFileContentType(t *testing.T) {
  function TestFileSmallUpdateByteRange (line 691) | func TestFileSmallUpdateByteRange(t *testing.T) {

FILE: pkg/app/middlewares/client/sd/discovery.go
  function Discovery (line 29) | func Discovery(resolver discovery.Resolver, opts ...ServiceDiscoveryOpti...

FILE: pkg/app/middlewares/client/sd/discovery_test.go
  function TestDiscovery (line 29) | func TestDiscovery(t *testing.T) {

FILE: pkg/app/middlewares/client/sd/options.go
  type ServiceDiscoveryOptions (line 31) | type ServiceDiscoveryOptions struct
    method Apply (line 42) | func (o *ServiceDiscoveryOptions) Apply(opts []ServiceDiscoveryOption) {
  type ServiceDiscoveryOption (line 48) | type ServiceDiscoveryOption struct
  function WithCustomizedAddrs (line 54) | func WithCustomizedAddrs(addrs ...string) ServiceDiscoveryOption {
  function WithLoadBalanceOptions (line 91) | func WithLoadBalanceOptions(lb loadbalance.Loadbalancer, options loadbal...

FILE: pkg/app/middlewares/client/sd/options_test.go
  function TestWithCustomizedAddrs (line 27) | func TestWithCustomizedAddrs(t *testing.T) {
  function TestWithLoadBalanceOptions (line 39) | func TestWithLoadBalanceOptions(t *testing.T) {

FILE: pkg/app/middlewares/server/basic_auth/basic_auth.go
  type Accounts (line 54) | type Accounts
  type pairs (line 57) | type pairs
    method findValue (line 59) | func (p pairs) findValue(needle string) (v string, ok bool) {
  function constructPairs (line 64) | func constructPairs(accounts Accounts) pairs {
  function BasicAuthForRealm (line 78) | func BasicAuthForRealm(accounts Accounts, realm, userKey string) app.Han...
  function BasicAuth (line 99) | func BasicAuth(accounts Accounts) app.HandlerFunc {

FILE: pkg/app/middlewares/server/basic_auth/basic_auth_test.go
  function TestPairs (line 53) | func TestPairs(t *testing.T) {
  function TestBasicAuth (line 71) | func TestBasicAuth(t *testing.T) {

FILE: pkg/app/middlewares/server/recovery/option.go
  type options (line 28) | type options struct
  type Option (line 32) | type Option
  function defaultRecoveryHandler (line 35) | func defaultRecoveryHandler(c context.Context, ctx *app.RequestContext, ...
  function newOptions (line 40) | func newOptions(opts ...Option) *options {
  function WithRecoveryHandler (line 52) | func WithRecoveryHandler(f func(c context.Context, ctx *app.RequestConte...

FILE: pkg/app/middlewares/server/recovery/option_test.go
  function TestDefaultOption (line 31) | func TestDefaultOption(t *testing.T) {
  function newRecoveryHandler (line 36) | func newRecoveryHandler(c context.Context, ctx *app.RequestContext, err ...
  function TestOption (line 42) | func TestOption(t *testing.T) {

FILE: pkg/app/middlewares/server/recovery/recovery.go
  function Recovery (line 39) | func Recovery(opts ...Option) app.HandlerFunc {
  function stack (line 55) | func stack(skip int) []byte {
  function source (line 82) | func source(lines [][]byte, n int) []byte {
  function function (line 91) | func function(pc uintptr) []byte {

FILE: pkg/app/middlewares/server/recovery/recovery_test.go
  function TestRecovery (line 29) | func TestRecovery(t *testing.T) {
  function TestWithRecoveryHandler (line 45) | func TestWithRecoveryHandler(t *testing.T) {

FILE: pkg/app/server/binding/binder.go
  type Binder (line 48) | type Binder interface

FILE: pkg/app/server/binding/binder_test.go
  type mockRequest (line 63) | type mockRequest struct
    method SetRequestURI (line 73) | func (m *mockRequest) SetRequestURI(uri string) *mockRequest {
    method SetFile (line 78) | func (m *mockRequest) SetFile(param, fileName string) *mockRequest {
    method SetHeader (line 83) | func (m *mockRequest) SetHeader(key, value string) *mockRequest {
    method SetHeaders (line 88) | func (m *mockRequest) SetHeaders(key, value string) *mockRequest {
    method SetPostArg (line 93) | func (m *mockRequest) SetPostArg(key, value string) *mockRequest {
    method SetUrlEncodeContentType (line 98) | func (m *mockRequest) SetUrlEncodeContentType() *mockRequest {
    method SetJSONContentType (line 103) | func (m *mockRequest) SetJSONContentType() *mockRequest {
    method SetProtobufContentType (line 108) | func (m *mockRequest) SetProtobufContentType() *mockRequest {
    method SetBody (line 113) | func (m *mockRequest) SetBody(data []byte) *mockRequest {
  function newMockRequest (line 67) | func newMockRequest() *mockRequest {
  function TestBind_BaseType (line 119) | func TestBind_BaseType(t *testing.T) {
  function TestBind_SliceType (line 150) | func TestBind_SliceType(t *testing.T) {
  function TestBind_StructType (line 187) | func TestBind_StructType(t *testing.T) {
  function TestBind_PointerType (line 224) | func TestBind_PointerType(t *testing.T) {
  function TestBind_NestedStruct (line 269) | func TestBind_NestedStruct(t *testing.T) {
  function TestBind_SliceStruct (line 292) | func TestBind_SliceStruct(t *testing.T) {
  function TestBind_MapType (line 315) | func TestBind_MapType(t *testing.T) {
  function TestBind_MapFieldType (line 329) | func TestBind_MapFieldType(t *testing.T) {
  function TestBind_UnexportedField (line 365) | func TestBind_UnexportedField(t *testing.T) {
  function TestBind_NoTagField (line 380) | func TestBind_NoTagField(t *testing.T) {
  function TestBind_ZeroValueBind (line 405) | func TestBind_ZeroValueBind(t *testing.T) {
  function TestBind_DefaultValueBind (line 424) | func TestBind_DefaultValueBind(t *testing.T) {
  function TestBind_RequiredBind (line 470) | func TestBind_RequiredBind(t *testing.T) {
  function TestBind_TypedefType (line 497) | func TestBind_TypedefType(t *testing.T) {
  type EnumType (line 521) | type EnumType
    method String (line 528) | func (p EnumType) String() string {
  constant EnumType_TWEET (line 524) | EnumType_TWEET   EnumType = 0
  constant EnumType_RETWEET (line 525) | EnumType_RETWEET EnumType = 2
  function TestBind_EnumBind (line 538) | func TestBind_EnumBind(t *testing.T) {
  type CustomizedDecode (line 551) | type CustomizedDecode struct
  function TestBind_CustomizedTypeDecode (line 555) | func TestBind_CustomizedTypeDecode(t *testing.T) {
  function TestBind_CustomizedTypeDecodeForPanic (line 597) | func TestBind_CustomizedTypeDecodeForPanic(t *testing.T) {
  function TestBind_JSON (line 610) | func TestBind_JSON(t *testing.T) {
  function TestBind_ResetJSONUnmarshal (line 639) | func TestBind_ResetJSONUnmarshal(t *testing.T) {
  function TestBind_FileBind (line 670) | func TestBind_FileBind(t *testing.T) {
  function TestBind_FileBindWithNoFile (line 701) | func TestBind_FileBindWithNoFile(t *testing.T) {
  function TestBind_FileSliceBind (line 726) | func TestBind_FileSliceBind(t *testing.T) {
  function TestBind_AnonymousField (line 770) | func TestBind_AnonymousField(t *testing.T) {
  function TestBind_IgnoreField (line 795) | func TestBind_IgnoreField(t *testing.T) {
  function TestBind_DefaultTag (line 826) | func TestBind_DefaultTag(t *testing.T) {
  function TestBind_StructFieldResolve (line 873) | func TestBind_StructFieldResolve(t *testing.T) {
  function TestBind_JSONRequiredField (line 911) | func TestBind_JSONRequiredField(t *testing.T) {
  function TestValidate_MultipleValidate (line 969) | func TestValidate_MultipleValidate(t *testing.T) {
  function TestBind_BindQuery (line 982) | func TestBind_BindQuery(t *testing.T) {
  function TestBind_LooseMode (line 1008) | func TestBind_LooseMode(t *testing.T) {
  function TestBind_NonStruct (line 1038) | func TestBind_NonStruct(t *testing.T) {
  function TestBind_BindTag (line 1053) | func TestBind_BindTag(t *testing.T) {
  function TestBind_BindAndValidate (line 1118) | func TestBind_BindAndValidate(t *testing.T) {
  function TestBind_FastPath (line 1156) | func TestBind_FastPath(t *testing.T) {
  function TestBind_NonPointer (line 1181) | func TestBind_NonPointer(t *testing.T) {
  function TestBind_PreBind (line 1201) | func TestBind_PreBind(t *testing.T) {
  function TestBind_BindProtobuf (line 1224) | func TestBind_BindProtobuf(t *testing.T) {
  function TestBind_PointerStruct (line 1250) | func TestBind_PointerStruct(t *testing.T) {
  function TestBind_StructRequired (line 1283) | func TestBind_StructRequired(t *testing.T) {
  function TestBind_StructErrorToWarn (line 1316) | func TestBind_StructErrorToWarn(t *testing.T) {
  function TestBind_DisallowUnknownFieldsConfig (line 1350) | func TestBind_DisallowUnknownFieldsConfig(t *testing.T) {
  function TestBind_UseNumberConfig (line 1369) | func TestBind_UseNumberConfig(t *testing.T) {
  function TestBind_InterfaceType (line 1393) | func TestBind_InterfaceType(t *testing.T) {
  function Test_BindHeaderNormalize (line 1419) | func Test_BindHeaderNormalize(t *testing.T) {
  type ValidateError (line 1493) | type ValidateError struct
    method Error (line 1498) | func (e *ValidateError) Error() string {
  function Test_ValidatorErrorFactory (line 1505) | func Test_ValidatorErrorFactory(t *testing.T) {
  function Test_Issue964 (line 1550) | func Test_Issue964(t *testing.T) {
  type reqSameType (line 1572) | type reqSameType struct
  type reqSameType2 (line 1579) | type reqSameType2 struct
  function TestBind_Issue1015 (line 1583) | func TestBind_Issue1015(t *testing.T) {
  function TestBind_JSONWithDefault (line 1606) | func TestBind_JSONWithDefault(t *testing.T) {
  function TestBind_WithoutPreBindForTag (line 1632) | func TestBind_WithoutPreBindForTag(t *testing.T) {
  function TestBind_NormalizeContentType (line 1653) | func TestBind_NormalizeContentType(t *testing.T) {
  type TestEnumType (line 1674) | type TestEnumType
    method UnmarshalText (line 1678) | func (p *TestEnumType) UnmarshalText(v []byte) error {
  function TestBind_TextUnmarshaler (line 1690) | func TestBind_TextUnmarshaler(t *testing.T) {
  function Benchmark_Binding (line 1709) | func Benchmark_Binding(b *testing.B) {
  function TestBind_AnonymousFieldWithDefaultTag (line 1753) | func TestBind_AnonymousFieldWithDefaultTag(t *testing.T) {

FILE: pkg/app/server/binding/config.go
  type BindConfig (line 33) | type BindConfig struct
    method RegTypeUnmarshal (line 98) | func (config *BindConfig) RegTypeUnmarshal(t reflect.Type, fn inDecode...
    method MustRegTypeUnmarshal (line 117) | func (config *BindConfig) MustRegTypeUnmarshal(t reflect.Type, fn func...
    method initTypeUnmarshal (line 124) | func (config *BindConfig) initTypeUnmarshal() {
    method UseThirdPartyJSONUnmarshaler (line 141) | func (config *BindConfig) UseThirdPartyJSONUnmarshaler(fn func(data []...
    method UseStdJSONUnmarshaler (line 150) | func (config *BindConfig) UseStdJSONUnmarshaler() {
  function NewBindConfig (line 85) | func NewBindConfig() *BindConfig {
  type ValidateErrFactory (line 157) | type ValidateErrFactory
  type ValidateConfig (line 162) | type ValidateConfig struct
    method MustRegValidateFunc (line 181) | func (config *ValidateConfig) MustRegValidateFunc(funcName string, fn ...
    method SetValidatorErrorFactory (line 188) | func (config *ValidateConfig) SetValidatorErrorFactory(errFactory Vali...
    method SetValidatorTag (line 195) | func (config *ValidateConfig) SetValidatorTag(tag string) {
  function NewValidateConfig (line 170) | func NewValidateConfig() *ValidateConfig {

FILE: pkg/app/server/binding/default.go
  constant queryTag (line 85) | queryTag           = "query"
  constant headerTag (line 86) | headerTag          = "header"
  constant formTag (line 87) | formTag            = "form"
  constant pathTag (line 88) | pathTag            = "path"
  constant defaultValidateTag (line 89) | defaultValidateTag = "vd"
  type decoderInfo (line 92) | type decoderInfo struct
  function DefaultBinder (line 98) | func DefaultBinder() Binder {
  type defaultBinder (line 102) | type defaultBinder struct
    method tagCache (line 156) | func (b *defaultBinder) tagCache(tag string) *sync.Map {
    method bindTag (line 171) | func (b *defaultBinder) bindTag(req *protocol.Request, v interface{}, ...
    method BindQuery (line 211) | func (b *defaultBinder) BindQuery(req *protocol.Request, v interface{}...
    method BindHeader (line 215) | func (b *defaultBinder) BindHeader(req *protocol.Request, v interface{...
    method BindPath (line 219) | func (b *defaultBinder) BindPath(req *protocol.Request, v interface{},...
    method BindForm (line 223) | func (b *defaultBinder) BindForm(req *protocol.Request, v interface{})...
    method BindJSON (line 227) | func (b *defaultBinder) BindJSON(req *protocol.Request, v interface{})...
    method decodeJSON (line 231) | func (b *defaultBinder) decodeJSON(r io.Reader, obj interface{}) error {
    method BindProtobuf (line 243) | func (b *defaultBinder) BindProtobuf(req *protocol.Request, v interfac...
    method Name (line 251) | func (b *defaultBinder) Name() string {
    method Bind (line 255) | func (b *defaultBinder) Bind(req *protocol.Request, v interface{}, par...
    method Validate (line 259) | func (b *defaultBinder) Validate(req *protocol.Request, v interface{})...
    method preBindBody (line 264) | func (b *defaultBinder) preBindBody(req *protocol.Request, v interface...
    method bindNonStruct (line 283) | func (b *defaultBinder) bindNonStruct(req *protocol.Request, v interfa...
  function NewDefaultBinder (line 111) | func NewDefaultBinder(config *BindConfig) Binder {
  function BindAndValidate (line 132) | func BindAndValidate(req *protocol.Request, obj interface{}, pathParams ...
  function Bind (line 143) | func Bind(req *protocol.Request, obj interface{}, pathParams param.Param...
  function Validate (line 152) | func Validate(obj interface{}) error {
  type validator (line 327) | type validator struct
    method ValidateStruct (line 372) | func (v *validator) ValidateStruct(obj interface{}) error {
    method Engine (line 380) | func (v *validator) Engine() interface{} {
    method ValidateTag (line 384) | func (v *validator) ValidateTag() string {
  function NewValidator (line 336) | func NewValidator(config *ValidateConfig) StructValidator {
  type validateError (line 352) | type validateError struct
    method Error (line 357) | func (e *validateError) Error() string {
  function defaultValidateErrorFactory (line 364) | func defaultValidateErrorFactory(failPath, msg string) error {
  function DefaultValidator (line 405) | func DefaultValidator() StructValidator {

FILE: pkg/app/server/binding/internal/decoder/base_type_decoder.go
  type fieldInfo (line 51) | type fieldInfo struct
  type baseTypeFieldTextDecoder (line 60) | type baseTypeFieldTextDecoder struct
    method Decode (line 65) | func (d *baseTypeFieldTextDecoder) Decode(req *protocol.Request, param...
  function getBaseTypeTextDecoder (line 139) | func getBaseTypeTextDecoder(field reflect.StructField, index int, tagInf...

FILE: pkg/app/server/binding/internal/decoder/customized_type_decoder.go
  type CustomizeDecodeFunc (line 50) | type CustomizeDecodeFunc
  type customizedFieldTextDecoder (line 52) | type customizedFieldTextDecoder struct
    method Decode (line 57) | func (d *customizedFieldTextDecoder) Decode(req *protocol.Request, par...
  function getCustomizedFieldDecoder (line 109) | func getCustomizedFieldDecoder(field reflect.StructField, index int, tag...

FILE: pkg/app/server/binding/internal/decoder/decoder.go
  type fieldDecoder (line 52) | type fieldDecoder interface
  type Decoder (line 56) | type Decoder
  type DecodeConfig (line 58) | type DecodeConfig struct
  function GetReqDecoder (line 67) | func GetReqDecoder(rt reflect.Type, byTag string, config *DecodeConfig) ...
  type parentInfos (line 103) | type parentInfos struct
  function getFieldDecoder (line 109) | func getFieldDecoder(pInfo parentInfos, field reflect.StructField, index...
  function hasSameType (line 207) | func hasSameType(pts []reflect.Type, ft reflect.Type) bool {

FILE: pkg/app/server/binding/internal/decoder/getter.go
  type getter (line 48) | type getter
  function path (line 50) | func path(req *protocol.Request, params param.Params, key string, defaul...
  function postForm (line 61) | func postForm(req *protocol.Request, params param.Params, key string, de...
  function query (line 89) | func query(req *protocol.Request, params param.Params, key string, defau...
  function cookie (line 101) | func cookie(req *protocol.Request, params param.Params, key string, defa...
  function header (line 114) | func header(req *protocol.Request, params param.Params, key string, defa...
  function rawBody (line 127) | func rawBody(req *protocol.Request, params param.Params, key string, def...

FILE: pkg/app/server/binding/internal/decoder/gjson_required.go
  function checkRequireJSON (line 30) | func checkRequireJSON(req *protocol.Request, tagInfo TagInfo) bool {
  function keyExist (line 50) | func keyExist(req *protocol.Request, tagInfo TagInfo) bool {

FILE: pkg/app/server/binding/internal/decoder/map_type_decoder.go
  type mapTypeFieldTextDecoder (line 53) | type mapTypeFieldTextDecoder struct
    method Decode (line 57) | func (d *mapTypeFieldTextDecoder) Decode(req *protocol.Request, params...
  function getMapTypeTextDecoder (line 124) | func getMapTypeTextDecoder(field reflect.StructField, index int, tagInfo...

FILE: pkg/app/server/binding/internal/decoder/multipart_file_decoder.go
  type fileTypeDecoder (line 28) | type fileTypeDecoder struct
    method Decode (line 33) | func (d *fileTypeDecoder) Decode(req *protocol.Request, params param.P...
    method fileSliceDecode (line 78) | func (d *fileTypeDecoder) fileSliceDecode(req *protocol.Request, param...
  function getMultipartFileDecoder (line 148) | func getMultipartFileDecoder(field reflect.StructField, index int, tagIn...

FILE: pkg/app/server/binding/internal/decoder/reflect.go
  function ReferenceValue (line 48) | func ReferenceValue(v reflect.Value, ptrDepth int) reflect.Value {
  function GetNonNilReferenceValue (line 64) | func GetNonNilReferenceValue(v reflect.Value) (reflect.Value, int) {
  function GetFieldValue (line 77) | func GetFieldValue(reqValue reflect.Value, parentIndex []int) reflect.Va...
  function getElemType (line 107) | func getElemType(t reflect.Type) reflect.Type {

FILE: pkg/app/server/binding/internal/decoder/slice_getter.go
  type sliceGetter (line 49) | type sliceGetter
  function pathSlice (line 51) | func pathSlice(req *protocol.Request, params param.Params, key string, d...
  function postFormSlice (line 67) | func postFormSlice(req *protocol.Request, params param.Params, key strin...
  function querySlice (line 96) | func querySlice(req *protocol.Request, params param.Params, key string, ...
  function cookieSlice (line 110) | func cookieSlice(req *protocol.Request, params param.Params, key string,...
  function headerSlice (line 124) | func headerSlice(req *protocol.Request, params param.Params, key string,...
  function rawBodySlice (line 132) | func rawBodySlice(req *protocol.Request, params param.Params, key string...

FILE: pkg/app/server/binding/internal/decoder/slice_type_decoder.go
  type sliceTypeFieldTextDecoder (line 54) | type sliceTypeFieldTextDecoder struct
    method Decode (line 59) | func (d *sliceTypeFieldTextDecoder) Decode(req *protocol.Request, para...
  function getSliceFieldDecoder (line 176) | func getSliceFieldDecoder(field reflect.StructField, index int, tagInfos...

FILE: pkg/app/server/binding/internal/decoder/sonic_required.go
  function checkRequireJSON (line 30) | func checkRequireJSON(req *protocol.Request, tagInfo TagInfo) bool {
  function stringSliceForInterface (line 53) | func stringSliceForInterface(s string) (ret []interface{}) {
  function keyExist (line 61) | func keyExist(req *protocol.Request, tagInfo TagInfo) bool {

FILE: pkg/app/server/binding/internal/decoder/struct_type_decoder.go
  type structTypeFieldTextDecoder (line 30) | type structTypeFieldTextDecoder struct
    method Decode (line 34) | func (d *structTypeFieldTextDecoder) Decode(req *protocol.Request, par...
  function getStructTypeFieldDecoder (line 101) | func getStructTypeFieldDecoder(field reflect.StructField, index int, tag...

FILE: pkg/app/server/binding/internal/decoder/tag.go
  constant pathTag (line 25) | pathTag     = "path"
  constant formTag (line 26) | formTag     = "form"
  constant queryTag (line 27) | queryTag    = "query"
  constant cookieTag (line 28) | cookieTag   = "cookie"
  constant headerTag (line 29) | headerTag   = "header"
  constant jsonTag (line 30) | jsonTag     = "json"
  constant rawBodyTag (line 31) | rawBodyTag  = "raw_body"
  constant fileNameTag (line 32) | fileNameTag = "file_name"
  constant defaultTag (line 36) | defaultTag = "default"
  constant requiredTagOpt (line 40) | requiredTagOpt = "required"
  type TagInfo (line 43) | type TagInfo struct
  function head (line 55) | func head(str, sep string) (head, tail string) {
  function lookupFieldTags (line 63) | func lookupFieldTags(field reflect.StructField, parentJSONName string, c...
  function getDefaultFieldTags (line 119) | func getDefaultFieldTags(field reflect.StructField, parentJSONName strin...
  function getFieldTagInfoByTag (line 135) | func getFieldTagInfoByTag(field reflect.StructField, tag string) []TagIn...

FILE: pkg/app/server/binding/internal/decoder/text_decoder.go
  type TextDecoder (line 52) | type TextDecoder interface
  function SelectTextDecoder (line 56) | func SelectTextDecoder(rt reflect.Type) (TextDecoder, error) {
  type boolDecoder (line 93) | type boolDecoder struct
    method UnmarshalString (line 95) | func (d *boolDecoder) UnmarshalString(s string, fieldValue reflect.Val...
  type floatDecoder (line 107) | type floatDecoder struct
    method UnmarshalString (line 111) | func (d *floatDecoder) UnmarshalString(s string, fieldValue reflect.Va...
  type intDecoder (line 123) | type intDecoder struct
    method UnmarshalString (line 127) | func (d *intDecoder) UnmarshalString(s string, fieldValue reflect.Valu...
  type stringDecoder (line 139) | type stringDecoder struct
    method UnmarshalString (line 141) | func (d *stringDecoder) UnmarshalString(s string, fieldValue reflect.V...
  type uintDecoder (line 146) | type uintDecoder struct
    method UnmarshalString (line 150) | func (d *uintDecoder) UnmarshalString(s string, fieldValue reflect.Val...
  type interfaceDecoder (line 162) | type interfaceDecoder struct
    method UnmarshalString (line 164) | func (d *interfaceDecoder) UnmarshalString(s string, fieldValue reflec...

FILE: pkg/app/server/binding/internal/decoder/util.go
  constant specialChar (line 32) | specialChar = "\x07"
  function toDefaultValue (line 36) | func toDefaultValue(typ reflect.Type, defaultValue string) string {
  function stringToValue (line 49) | func stringToValue(elemType reflect.Type, text string, req *protocol.Req...
  function tryTextUnmarshaler (line 86) | func tryTextUnmarshaler(v reflect.Value, s string) bool {

FILE: pkg/app/server/binding/internal/decoder/util_test.go
  type testTextUnmarshaler (line 30) | type testTextUnmarshaler struct
    method UnmarshalText (line 34) | func (t *testTextUnmarshaler) UnmarshalText(text []byte) error {
  function TestStringToValue (line 41) | func TestStringToValue(t *testing.T) {
  function TestTryTextUnmarshaler (line 160) | func TestTryTextUnmarshaler(t *testing.T) {

FILE: pkg/app/server/binding/reflect.go
  function valueAndTypeID (line 49) | func valueAndTypeID(v interface{}) (reflect.Value, uintptr) {
  type emptyInterface (line 55) | type emptyInterface struct
  function checkPointer (line 60) | func checkPointer(rv reflect.Value) error {
  function dereferenceType (line 68) | func dereferenceType(t reflect.Type) reflect.Type {

FILE: pkg/app/server/binding/reflect_internal_test.go
  type foo2 (line 26) | type foo2 struct
  type fooq (line 30) | type fooq struct
  function Test_ReferenceValue (line 34) | func Test_ReferenceValue(t *testing.T) {
  function Test_GetNonNilReferenceValue (line 52) | func Test_GetNonNilReferenceValue(t *testing.T) {
  function Test_GetFieldValue (line 69) | func Test_GetFieldValue(t *testing.T) {

FILE: pkg/app/server/binding/reflect_test.go
  type foo (line 26) | type foo struct
  function TestReflect_TypeID (line 30) | func TestReflect_TypeID(t *testing.T) {
  function TestReflect_CheckPointer (line 48) | func TestReflect_CheckPointer(t *testing.T) {
  function TestReflect_DereferenceType (line 71) | func TestReflect_DereferenceType(t *testing.T) {

FILE: pkg/app/server/binding/tagexpr_bind_test.go
  function TestRawBody (line 55) | func TestRawBody(t *testing.T) {
  function TestQueryString (line 74) | func TestQueryString(t *testing.T) {
  function TestGetBody (line 112) | func TestGetBody(t *testing.T) {
  function TestQueryNum (line 127) | func TestQueryNum(t *testing.T) {
  function TestHeaderString (line 154) | func TestHeaderString(t *testing.T) {
  function TestHeaderNum (line 190) | func TestHeaderNum(t *testing.T) {
  function TestCookieString (line 225) | func TestCookieString(t *testing.T) {
  function TestCookieNum (line 261) | func TestCookieNum(t *testing.T) {
  function TestFormString (line 294) | func TestFormString(t *testing.T) {
  function TestFormNum (line 348) | func TestFormNum(t *testing.T) {
  function TestJSON (line 392) | func TestJSON(t *testing.T) {
  function TestNonstruct (line 446) | func TestNonstruct(t *testing.T) {
  function TestPath (line 488) | func TestPath(t *testing.T) {
  function TestDefault (line 542) | func TestDefault(t *testing.T) {
  function TestAuto (line 624) | func TestAuto(t *testing.T) {
  function TestTypeUnmarshal (line 679) | func TestTypeUnmarshal(t *testing.T) {
  function TestOption (line 719) | func TestOption(t *testing.T) {
  function newRequest (line 794) | func newRequest(u string, header http.Header, cookies []*http.Cookie, bo...
  function TestQueryStringIssue (line 825) | func TestQueryStringIssue(t *testing.T) {
  function TestQueryTypes (line 845) | func TestQueryTypes(t *testing.T) {
  function TestNoTagIssue (line 895) | func TestNoTagIssue(t *testing.T) {
  function TestRegTypeUnmarshal (line 916) | func TestRegTypeUnmarshal(t *testing.T) {
  function TestPathnameBUG (line 956) | func TestPathnameBUG(t *testing.T) {
  function TestPathnameBUG2 (line 1013) | func TestPathnameBUG2(t *testing.T) {
  function TestRequiredBUG (line 1071) | func TestRequiredBUG(t *testing.T) {
  function TestIssue25 (line 1119) | func TestIssue25(t *testing.T) {
  function TestIssue26 (line 1149) | func TestIssue26(t *testing.T) {
  function TestDefault2 (line 1199) | func TestDefault2(t *testing.T) {
  type files (line 1223) | type files
  type file (line 1224) | type file interface
  function newFormBody2 (line 1230) | func newFormBody2(values url.Values, files files) (contentType string, b...
  function newFile (line 1256) | func newFile(name string, bodyReader io.Reader) file {
  type fileReader (line 1261) | type fileReader struct
    method Name (line 1266) | func (f *fileReader) Name() string {
    method Read (line 1270) | func (f *fileReader) Read(p []byte) (int, error) {
  function newJSONBody (line 1274) | func newJSONBody(v interface{}) (contentType string, bodyReader io.Reade...

FILE: pkg/app/server/binding/testdata/hello.pb.go
  constant _ (line 34) | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  constant _ (line 36) | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  type HertzReq (line 39) | type HertzReq struct
    method Reset (line 47) | func (x *HertzReq) Reset() {
    method String (line 56) | func (x *HertzReq) String() string {
    method ProtoMessage (line 60) | func (*HertzReq) ProtoMessage() {}
    method ProtoReflect (line 62) | func (x *HertzReq) ProtoReflect() protoreflect.Message {
    method Descriptor (line 75) | func (*HertzReq) Descriptor() ([]byte, []int) {
    method GetName (line 79) | func (x *HertzReq) GetName() string {
  function file_hello_proto_rawDescGZIP (line 101) | func file_hello_proto_rawDescGZIP() []byte {
  function init (line 120) | func init() { file_hello_proto_init() }
  function file_hello_proto_init (line 121) | func file_hello_proto_init() {

FILE: pkg/app/server/binding/validator.go
  type ValidatorFunc (line 52) | type ValidatorFunc
  type StructValidator (line 58) | type StructValidator interface
  function MakeValidatorFunc (line 71) | func MakeValidatorFunc(s StructValidator) ValidatorFunc {
  function containsStructTag (line 99) | func containsStructTag(rt reflect.Type, tag string, checking map[reflect...

FILE: pkg/app/server/binding/validator_test.go
  function Test_ValidateStruct (line 25) | func Test_ValidateStruct(t *testing.T) {
  function Test_ValidateTag (line 39) | func Test_ValidateTag(t *testing.T) {

FILE: pkg/app/server/hertz.go
  type Hertz (line 33) | type Hertz struct
    method Spin (line 56) | func (h *Hertz) Spin() {
    method SetCustomSignalWaiter (line 84) | func (h *Hertz) SetCustomSignalWaiter(f func(err chan error) error) {
    method initOnRunHooks (line 115) | func (h *Hertz) initOnRunHooks(errChan chan error) {
  function New (line 39) | func New(opts ...config.Option) *Hertz {
  function Default (line 48) | func Default(opts ...config.Option) *Hertz {
  function waitSignal (line 90) | func waitSignal(errCh chan error) error {

FILE: pkg/app/server/hertz_test.go
  type routeEngine (line 55) | type routeEngine interface
  function waitEngineRunning (line 59) | func waitEngineRunning(e routeEngine) {
  function fullURL (line 63) | func fullURL(ln net.Listener, p string) string {
  function TestHertz_Run (line 67) | func TestHertz_Run(t *testing.T) {
  function TestHertz_GracefulShutdown (line 93) | func TestHertz_GracefulShutdown(t *testing.T) {
  function TestLoadHTMLGlob (line 171) | func TestLoadHTMLGlob(t *testing.T) {
  function TestLoadHTMLFiles (line 197) | func TestLoadHTMLFiles(t *testing.T) {
  function formatAsDate (line 225) | func formatAsDate(t time.Time) string {
  function TestServer_Use (line 236) | func TestServer_Use(t *testing.T) {
  function Test_getServerName (line 244) | func Test_getServerName(t *testing.T) {
  function TestServer_Run (line 252) | func TestServer_Run(t *testing.T) {
  function TestNotAbsolutePath (line 289) | func TestNotAbsolutePath(t *testing.T) {
  function TestNotAbsolutePathWithRawPath (line 328) | func TestNotAbsolutePathWithRawPath(t *testing.T) {
  function TestNotValidHost (line 376) | func TestNotValidHost(t *testing.T) {
  function TestWithBasePath (line 419) | func TestWithBasePath(t *testing.T) {
  function TestNotEnoughBodySize (line 440) | func TestNotEnoughBodySize(t *testing.T) {
  function TestEnoughBodySize (line 463) | func TestEnoughBodySize(t *testing.T) {
  function TestRequestCtxHijack (line 483) | func TestRequestCtxHijack(t *testing.T) {
  function verifyResponse (line 557) | func verifyResponse(t *testing.T, zr network.Reader, expectedStatusCode ...
  function verifyResponseHeader (line 569) | func verifyResponseHeader(t *testing.T, h *protocol.ResponseHeader, expe...
  function TestParamInconsist (line 584) | func TestParamInconsist(t *testing.T) {
  function TestDuplicateReleaseBodyStream (line 623) | func TestDuplicateReleaseBodyStream(t *testing.T) {
  function TestServiceRegisterFailed (line 668) | func TestServiceRegisterFailed(t *testing.T) {
  function TestServiceDeregisterFailed (line 694) | func TestServiceDeregisterFailed(t *testing.T) {
  function TestServiceRegistryInfo (line 734) | func TestServiceRegistryInfo(t *testing.T) {
  function TestServiceRegistryNoInitInfo (line 784) | func TestServiceRegistryNoInitInfo(t *testing.T) {
  type testTracer (line 826) | type testTracer struct
    method Start (line 828) | func (t testTracer) Start(ctx context.Context, c *app.RequestContext) ...
    method Finish (line 838) | func (t testTracer) Finish(ctx context.Context, c *app.RequestContext) {}
  function TestReuseCtx (line 840) | func TestReuseCtx(t *testing.T) {
  function TestOnprepare (line 857) | func TestOnprepare(t *testing.T) {
  type lockBuffer (line 917) | type lockBuffer struct
    method Write (line 922) | func (l *lockBuffer) Write(p []byte) (int, error) {
    method String (line 928) | func (l *lockBuffer) String() string {
  function TestHertzDisableHeaderNamesNormalizing (line 934) | func TestHertzDisableHeaderNamesNormalizing(t *testing.T) {
  function TestBindConfig (line 972) | func TestBindConfig(t *testing.T) {
  function TestCustomBinder (line 1021) | func TestCustomBinder(t *testing.T) {
  function TestValidateConfigRegValidateFunc (line 1048) | func TestValidateConfigRegValidateFunc(t *testing.T) {
  function TestCustomValidator (line 1077) | func TestCustomValidator(t *testing.T) {
  type ValidateError (line 1105) | type ValidateError struct
    method Error (line 1110) | func (e *ValidateError) Error() string {
  function TestValidateConfigSetSetErrorFactory (line 1117) | func TestValidateConfigSetSetErrorFactory(t *testing.T) {
  function TestValidateConfigAndBindConfig (line 1155) | func TestValidateConfigAndBindConfig(t *testing.T) {
  function TestWithDisableDefaultDate (line 1184) | func TestWithDisableDefaultDate(t *testing.T) {
  function TestWithDisableDefaultContentType (line 1200) | func TestWithDisableDefaultContentType(t *testing.T) {
  function TestServerReturns413And431OnSizeLimits (line 1216) | func TestServerReturns413And431OnSizeLimits(t *testing.T) {

FILE: pkg/app/server/hertz_unix_test.go
  function TestReusePorts (line 44) | func TestReusePorts(t *testing.T) {
  function TestHertz_Spin (line 85) | func TestHertz_Spin(t *testing.T) {
  function TestWithSenseClientDisconnection (line 146) | func TestWithSenseClientDisconnection(t *testing.T) {
  function TestWithSenseClientDisconnectionAndWithOnConnect (line 175) | func TestWithSenseClientDisconnectionAndWithOnConnect(t *testing.T) {

FILE: pkg/app/server/mocks_test.go
  type MockRegistry (line 26) | type MockRegistry struct
    method Register (line 32) | func (m MockRegistry) Register(info *registry.Info) error {
    method Deregister (line 40) | func (m MockRegistry) Deregister(info *registry.Info) error {

FILE: pkg/app/server/option.go
  function WithKeepAliveTimeout (line 38) | func WithKeepAliveTimeout(t time.Duration) config.Option {
  function WithReadTimeout (line 47) | func WithReadTimeout(t time.Duration) config.Option {
  function WithWriteTimeout (line 56) | func WithWriteTimeout(t time.Duration) config.Option {
  function WithIdleTimeout (line 66) | func WithIdleTimeout(t time.Duration) config.Option {
  function WithRedirectTrailingSlash (line 79) | func WithRedirectTrailingSlash(b bool) config.Option {
  function WithRedirectFixedPath (line 96) | func WithRedirectFixedPath(b bool) config.Option {
  function WithHandleMethodNotAllowed (line 110) | func WithHandleMethodNotAllowed(b bool) config.Option {
  function WithUseRawPath (line 119) | func WithUseRawPath(b bool) config.Option {
  function WithRemoveExtraSlash (line 130) | func WithRemoveExtraSlash(b bool) config.Option {
  function WithUnescapePathValues (line 141) | func WithUnescapePathValues(b bool) config.Option {
  function WithDisablePreParseMultipartForm (line 152) | func WithDisablePreParseMultipartForm(b bool) config.Option {
  function WithHostPorts (line 159) | func WithHostPorts(hp string) config.Option {
  function WithListener (line 176) | func WithListener(ln net.Listener) config.Option {
  function WithBasePath (line 186) | func WithBasePath(basePath string) config.Option {
  function WithMaxRequestBodySize (line 202) | func WithMaxRequestBodySize(bs int) config.Option {
  function WithMaxHeaderBytes (line 214) | func WithMaxHeaderBytes(size int) config.Option {
  function WithMaxKeepBodySize (line 224) | func WithMaxKeepBodySize(bs int) config.Option {
  function WithGetOnly (line 231) | func WithGetOnly(isOnly bool) config.Option {
  function WithKeepAlive (line 238) | func WithKeepAlive(b bool) config.Option {
  function WithStreamBody (line 249) | func WithStreamBody(b bool) config.Option {
  function WithNetwork (line 256) | func WithNetwork(nw string) config.Option {
  function WithExitWaitTime (line 266) | func WithExitWaitTime(timeout time.Duration) config.Option {
  function WithTLS (line 275) | func WithTLS(cfg *tls.Config) config.Option {
  function WithListenConfig (line 286) | func WithListenConfig(l *net.ListenConfig) config.Option {
  function WithTransport (line 293) | func WithTransport(transporter func(options *config.Options) network.Tra...
  function WithAltTransport (line 300) | func WithAltTransport(transporter func(options *config.Options) network....
  function WithH2C (line 307) | func WithH2C(enable bool) config.Option {
  function WithReadBufferSize (line 315) | func WithReadBufferSize(size int) config.Option {
  function WithALPN (line 322) | func WithALPN(enable bool) config.Option {
  function WithTracer (line 329) | func WithTracer(t tracer.Tracer) config.Option {
  function WithTraceLevel (line 336) | func WithTraceLevel(level stats.Level) config.Option {
  function WithRegistry (line 343) | func WithRegistry(r registry.Registry, info *registry.Info) config.Option {
  function WithAutoReloadRender (line 354) | func WithAutoReloadRender(b bool, interval time.Duration) config.Option {
  function WithDisablePrintRoute (line 363) | func WithDisablePrintRoute(b bool) config.Option {
  function WithOnAccept (line 371) | func WithOnAccept(fn func(conn net.Conn) context.Context) config.Option {
  function WithOnConnect (line 379) | func WithOnConnect(fn func(ctx context.Context, conn network.Conn) conte...
  function WithBindConfig (line 386) | func WithBindConfig(bc *binding.BindConfig) config.Option {
  function WithValidateConfig (line 395) | func WithValidateConfig(vc *binding.ValidateConfig) config.Option {
  function WithCustomBinder (line 416) | func WithCustomBinder(b binding.Binder) config.Option {
  function WithCustomValidator (line 425) | func WithCustomValidator(b binding.StructValidator) config.Option {
  function WithCustomValidatorFunc (line 430) | func WithCustomValidatorFunc(vf binding.ValidatorFunc) config.Option {
  function WithDisableHeaderNamesNormalizing (line 437) | func WithDisableHeaderNamesNormalizing(disable bool) config.Option {
  function WithDisableDefaultDate (line 443) | func WithDisableDefaultDate(disable bool) config.Option {
  function WithDisableDefaultContentType (line 449) | func WithDisableDefaultContentType(disable bool) config.Option {
  function WithSenseClientDisconnection (line 465) | func WithSenseClientDisconnection(b bool) config.Option {

FILE: pkg/app/server/option_test.go
  function TestOptions (line 36) | func TestOptions(t *testing.T) {
  function TestDefaultOptions (line 119) | func TestDefaultOptions(t *testing.T) {
  function TestWithListener (line 154) | func TestWithListener(t *testing.T) {
  type mockTransporter (line 177) | type mockTransporter struct
    method ListenAndServe (line 179) | func (m *mockTransporter) ListenAndServe(onData network.OnData) (err e...
    method Close (line 183) | func (m *mockTransporter) Close() error {
    method Shutdown (line 187) | func (m *mockTransporter) Shutdown(ctx context.Context) error {

FILE: pkg/app/server/registry/registry.go
  constant DefaultWeight (line 22) | DefaultWeight = 10
  type Registry (line 26) | type Registry interface
  type Info (line 33) | type Info struct
  type noopRegistry (line 48) | type noopRegistry struct
    method Register (line 50) | func (e noopRegistry) Register(*Info) error {
    method Deregister (line 54) | func (e noopRegistry) Deregister(*Info) error {

FILE: pkg/app/server/registry/registry_test.go
  function TestNoopRegistry (line 25) | func TestNoopRegistry(t *testing.T) {

FILE: pkg/app/server/render/data.go
  type Data (line 47) | type Data struct
    method Render (line 53) | func (r Data) Render(resp *protocol.Response) (err error) {
    method WriteContentType (line 60) | func (r Data) WriteContentType(resp *protocol.Response) {

FILE: pkg/app/server/render/html.go
  type Delims (line 56) | type Delims struct
  type HTMLRender (line 64) | type HTMLRender interface
  type HTMLProduction (line 71) | type HTMLProduction struct
    method Instance (line 85) | func (r HTMLProduction) Instance(name string, data interface{}) Render {
    method Close (line 93) | func (r HTMLProduction) Close() error {
  type HTML (line 76) | type HTML struct
    method Render (line 98) | func (r HTML) Render(resp *protocol.Response) error {
    method WriteContentType (line 108) | func (r HTML) WriteContentType(resp *protocol.Response) {
  type HTMLDebug (line 112) | type HTMLDebug struct
    method Instance (line 125) | func (h *HTMLDebug) Instance(name string, data interface{}) Render {
    method Close (line 143) | func (h *HTMLDebug) Close() error {
    method reload (line 150) | func (h *HTMLDebug) reload() {
    method startChecker (line 157) | func (h *HTMLDebug) startChecker() {

FILE: pkg/app/server/render/html_test.go
  function TestHTMLDebug_StartChecker_timer (line 31) | func TestHTMLDebug_StartChecker_timer(t *testing.T) {
  function TestHTMLDebug_StartChecker_fs_watcher (line 52) | func TestHTMLDebug_StartChecker_fs_watcher(t *testing.T) {
  function TestRenderHTML (line 79) | func TestRenderHTML(t *testing.T) {

FILE: pkg/app/server/render/json.go
  type JSONMarshaler (line 53) | type JSONMarshaler
  function init (line 57) | func init() {
  function ResetJSONMarshal (line 61) | func ResetJSONMarshal(fn JSONMarshaler) {
  function ResetStdJSONMarshal (line 65) | func ResetStdJSONMarshal() {
  type JSONRender (line 70) | type JSONRender struct
    method Render (line 77) | func (r JSONRender) Render(resp *protocol.Response) error {
    method WriteContentType (line 89) | func (r JSONRender) WriteContentType(resp *protocol.Response) {
  type PureJSON (line 94) | type PureJSON struct
    method Render (line 99) | func (r PureJSON) Render(resp *protocol.Response) (err error) {
    method WriteContentType (line 113) | func (r PureJSON) WriteContentType(resp *protocol.Response) {
  type IndentedJSON (line 118) | type IndentedJSON struct
    method Render (line 123) | func (r IndentedJSON) Render(resp *protocol.Response) (err error) {
    method WriteContentType (line 139) | func (r IndentedJSON) WriteContentType(resp *protocol.Response) {

FILE: pkg/app/server/render/json_test.go
  function Test_ResetStdJSONMarshal (line 49) | func Test_ResetStdJSONMarshal(t *testing.T) {
  function Test_DefaultJSONMarshal (line 64) | func Test_DefaultJSONMarshal(t *testing.T) {

FILE: pkg/app/server/render/protobuf.go
  type ProtoBuf (line 50) | type ProtoBuf struct
    method Render (line 57) | func (r ProtoBuf) Render(resp *protocol.Response) error {
    method WriteContentType (line 69) | func (r ProtoBuf) WriteContentType(resp *protocol.Response) {

FILE: pkg/app/server/render/render.go
  type Render (line 47) | type Render interface
  function writeContentType (line 61) | func writeContentType(resp *protocol.Response, value string) {

FILE: pkg/app/server/render/render_test.go
  type xmlmap (line 55) | type xmlmap
    method MarshalXML (line 58) | func (h xmlmap) MarshalXML(e *xml.Encoder, start xml.StartElement) err...
  function TestRenderJSON (line 79) | func TestRenderJSON(t *testing.T) {
  function TestRenderJSONError (line 96) | func TestRenderJSONError(t *testing.T) {
  function TestRenderPureJSON (line 105) | func TestRenderPureJSON(t *testing.T) {
  function TestRenderPureJSONError (line 123) | func TestRenderPureJSONError(t *testing.T) {
  function TestRenderProtobuf (line 132) | func TestRenderProtobuf(t *testing.T) {
  function TestRenderProtobufError (line 146) | func TestRenderProtobufError(t *testing.T) {
  function TestRenderString (line 155) | func TestRenderString(t *testing.T) {
  function TestRenderStringLenZero (line 174) | func TestRenderStringLenZero(t *testing.T) {
  function TestRenderData (line 187) | func TestRenderData(t *testing.T) {
  function TestRenderXML (line 201) | func TestRenderXML(t *testing.T) {
  function TestRenderXMLError (line 217) | func TestRenderXMLError(t *testing.T) {
  function TestRenderIndentedJSON (line 226) | func TestRenderIndentedJSON(t *testing.T) {

FILE: pkg/app/server/render/text.go
  type String (line 51) | type String struct
    method Render (line 59) | func (r String) Render(resp *protocol.Response) error {
    method WriteContentType (line 70) | func (r String) WriteContentType(resp *protocol.Response) {

FILE: pkg/app/server/render/xml.go
  type XML (line 51) | type XML struct
    method Render (line 58) | func (r XML) Render(resp *protocol.Response) error {
    method WriteContentType (line 70) | func (r XML) WriteContentType(w *protocol.Response) {

FILE: pkg/app/server/server_bench_test.go
  function BenchmarkServerHelloWorld (line 30) | func BenchmarkServerHelloWorld(b *testing.B) {

FILE: pkg/common/adaptor/handler.go
  function HertzHandler (line 36) | func HertzHandler(h http.Handler) app.HandlerFunc {
  type httpResponseWriter (line 102) | type httpResponseWriter struct
    method Header (line 116) | func (p *httpResponseWriter) Header() http.Header {
    method Write (line 125) | func (p *httpResponseWriter) Write(b []byte) (n int, err error) {
    method WriteHeader (line 143) | func (p *httpResponseWriter) WriteHeader(statusCode int) {
    method Flush (line 187) | func (p *httpResponseWriter) Flush() {
    method Hijack (line 196) | func (p *httpResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, er...
  type noopHijackWriter (line 226) | type noopHijackWriter struct
    method Write (line 230) | func (noopHijackWriter) Write(b []byte) (int, error) {
    method Flush (line 233) | func (noopHijackWriter) Flush() error    { return errConnHijacked }
    method Finalize (line 234) | func (noopHijackWriter) Finalize() error { return nil }
  type noopWriter (line 236) | type noopWriter struct
    method Write (line 240) | func (noopWriter) Write(b []byte) (int, error) { return len(b), nil }
    method Flush (line 241) | func (noopWriter) Flush() error                { return nil }
    method Finalize (line 242) | func (noopWriter) Finalize() error             { return nil }
  type hijackedConn (line 244) | type hijackedConn struct
    method Close (line 261) | func (c *hijackedConn) Close() error {
  function newHijackedConn (line 251) | func newHijackedConn(conn network.Conn) *hijackedConn {
  function hijackedConnFinalizer (line 257) | func hijackedConnFinalizer(c *hijackedConn) {

FILE: pkg/common/adaptor/handler_test.go
  function runEngine (line 44) | func runEngine(onCreate func(*route.Engine)) (string, *route.Engine) {
  function TestHertzHandler_BodyStream (line 55) | func TestHertzHandler_BodyStream(t *testing.T) {
  function TestHertzHandler_Chunked (line 90) | func TestHertzHandler_Chunked(t *testing.T) {
  function TestHertzHandler_WriteHeader (line 119) | func TestHertzHandler_WriteHeader(t *testing.T) {
  function TestHertzHandler_Hijack (line 146) | func TestHertzHandler_Hijack(t *testing.T) {
  function TestHertzHandler_HijackGC (line 193) | func TestHertzHandler_HijackGC(t *testing.T) {
  function TestHertzHandler_WriteHeader_Hijack (line 220) | func TestHertzHandler_WriteHeader_Hijack(t *testing.T) {
  function TestHertzHandler_FSEmbed (line 260) | func TestHertzHandler_FSEmbed(t *testing.T) {
  function TestHertzHandler_Multipart (line 279) | func TestHertzHandler_Multipart(t *testing.T) {
  function createMultipartBody (line 316) | func createMultipartBody(kvs map[string]string) (*bytes.Buffer, string) {
  function TestNoopHijackWriter (line 326) | func TestNoopHijackWriter(t *testing.T) {
  function TestNoopWriter (line 343) | func TestNoopWriter(t *testing.T) {

FILE: pkg/common/adaptor/request.go
  function GetCompatRequest (line 29) | func GetCompatRequest(req *protocol.Request) (*http.Request, error) {
  function CopyToHertzRequest (line 45) | func CopyToHertzRequest(req *http.Request, hreq *protocol.Request) error {

FILE: pkg/common/adaptor/request_test.go
  function fullURL (line 38) | func fullURL(ln net.Listener, p string) string {
  function TestCompatResponse_WriteHeader (line 42) | func TestCompatResponse_WriteHeader(t *testing.T) {
  function makeACall (line 81) | func makeACall(t *testing.T, method, url string, header http.Header, bod...
  function handlerAndCheck (line 118) | func handlerAndCheck(t *testing.T, writer http.ResponseWriter, request *...
  function TestCopyToHertzRequest (line 156) | func TestCopyToHertzRequest(t *testing.T) {

FILE: pkg/common/adaptor/response.go
  type compatResponse (line 26) | type compatResponse struct
    method Header (line 32) | func (c *compatResponse) Header() http.Header {
    method Write (line 40) | func (c *compatResponse) Write(b []byte) (int, error) {
    method WriteHeader (line 48) | func (c *compatResponse) WriteHeader(statusCode int) {
  function GetCompatResponseWriter (line 73) | func GetCompatResponseWriter(resp *protocol.Response) http.ResponseWriter {

FILE: pkg/common/adaptor/utils.go
  function methodstr (line 32) | func methodstr(m []byte) string {
  type bytesRWCloser (line 64) | type bytesRWCloser struct
    method Close (line 75) | func (bytesRWCloser) Close() error { return nil }
  function newBytesRWCloser (line 69) | func newBytesRWCloser(b []byte) io.ReadCloser {
  function writer2writerExt (line 77) | func writer2writerExt(w network.Writer) network.ExtWriter {
  type extWriter (line 81) | type extWriter struct
    method Write (line 85) | func (w extWriter) Write(b []byte) (int, error) {
    method Finalize (line 93) | func (w extWriter) Finalize() error {
  function reader2closer (line 97) | func reader2closer(r io.Reader) io.ReadCloser {
  function parseHTTPVersion (line 105) | func parseHTTPVersion(s string) (major, minor int, _ error) {

FILE: pkg/common/adaptor/utils_test.go
  function TestMethodStr (line 27) | func TestMethodStr(t *testing.T) {
  function TestBytesRWCloser (line 52) | func TestBytesRWCloser(t *testing.T) {
  function TestParseHTTPVersion (line 73) | func TestParseHTTPVersion(t *testing.T) {

FILE: pkg/common/bytebufferpool/bytebuffer.go
  type ByteBuffer (line 53) | type ByteBuffer struct
    method Len (line 60) | func (b *ByteBuffer) Len() int {
    method Cap (line 64) | func (b *ByteBuffer) Cap() int {
    method ReadFrom (line 71) | func (b *ByteBuffer) ReadFrom(r io.Reader) (int64, error) {
    method WriteTo (line 103) | func (b *ByteBuffer) WriteTo(w io.Writer) (int64, error) {
    method Bytes (line 111) | func (b *ByteBuffer) Bytes() []byte {
    method Write (line 116) | func (b *ByteBuffer) Write(p []byte) (int, error) {
    method WriteByte (line 126) | func (b *ByteBuffer) WriteByte(c byte) error {
    method WriteString (line 132) | func (b *ByteBuffer) WriteString(s string) (int, error) {
    method Set (line 138) | func (b *ByteBuffer) Set(p []byte) {
    method SetString (line 143) | func (b *ByteBuffer) SetString(s string) {
    method String (line 148) | func (b *ByteBuffer) String() string {
    method Reset (line 153) | func (b *ByteBuffer) Reset() {

FILE: pkg/common/bytebufferpool/bytebuffer_test.go
  function TestByteBufferReadFrom (line 54) | func TestByteBufferReadFrom(t *testing.T) {
  function TestByteBufferWriteTo (line 89) | func TestByteBufferWriteTo(t *testing.T) {
  function TestByteBufferGetPutSerial (line 114) | func TestByteBufferGetPutSerial(t *testing.T) {
  function TestByteBufferGetPutConcurrent (line 118) | func TestByteBufferGetPutConcurrent(t *testing.T) {
  function testByteBufferGetPut (line 137) | func testByteBufferGetPut(t *testing.T) {
  function testByteBufferGetString (line 150) | func testByteBufferGetString(t *testing.T) {
  function TestByteBufferGetStringSerial (line 162) | func TestByteBufferGetStringSerial(t *testing.T) {
  function TestByteBufferGetStringConcurrent (line 166) | func TestByteBufferGetStringConcurrent(t *testing.T) {

FILE: pkg/common/bytebufferpool/pool.go
  constant minBitSize (line 51) | minBitSize = 6
  constant steps (line 52) | steps      = 20
  constant minSize (line 54) | minSize = 1 << minBitSize
  constant maxSize (line 55) | maxSize = 1 << (minBitSize + steps - 1)
  constant calibrateCallsThreshold (line 57) | calibrateCallsThreshold = 42000
  constant maxPercentile (line 58) | maxPercentile           = 0.95
  type Pool (line 66) | type Pool struct
    method Get (line 89) | func (p *Pool) Get() *ByteBuffer {
    method Put (line 108) | func (p *Pool) Put(b *ByteBuffer) {
    method calibrate (line 122) | func (p *Pool) calibrate() {
  function Get (line 83) | func Get() *ByteBuffer { return defaultPool.Get() }
  function Put (line 103) | func Put(b *ByteBuffer) { defaultPool.Put(b) }
  type callSize (line 161) | type callSize struct
  type callSizes (line 166) | type callSizes
    method Len (line 168) | func (ci callSizes) Len() int {
    method Less (line 172) | func (ci callSizes) Less(i, j int) bool {
    method Swap (line 176) | func (ci callSizes) Swap(i, j int) {
  function index (line 180) | func index(n int) int {

FILE: pkg/common/bytebufferpool/pool_test.go
  function TestIndex (line 50) | func TestIndex(t *testing.T) {
  function testIndex (line 67) | func testIndex(t *testing.T, n, expectedIdx int) {
  function TestPoolCalibrate (line 74) | func TestPoolCalibrate(t *testing.T) {
  function TestPoolVariousSizesSerial (line 84) | func TestPoolVariousSizesSerial(t *testing.T) {
  function TestPoolVariousSizesConcurrent (line 88) | func TestPoolVariousSizesConcurrent(t *testing.T) {
  function testPoolVariousSizes (line 106) | func testPoolVariousSizes(t *testing.T) {
  function testGetPut (line 120) | func testGetPut(t *testing.T, n int) {
  function allocNBytes (line 129) | func allocNBytes(dst []byte, n int) []byte {

FILE: pkg/common/compress/compress.go
  constant CompressDefaultCompression (line 57) | CompressDefaultCompression = 6
  function newCompressWriterPoolMap (line 66) | func newCompressWriterPoolMap() []*sync.Pool {
  type compressCtx (line 78) | type compressCtx struct
  function AppendGunzipBytes (line 85) | func AppendGunzipBytes(dst, src []byte) ([]byte, error) {
  type byteSliceWriter (line 91) | type byteSliceWriter struct
    method Write (line 95) | func (w *byteSliceWriter) Write(p []byte) (int, error) {
  function WriteGunzip (line 102) | func WriteGunzip(w io.Writer, p []byte) (int, error) {
  type byteSliceReader (line 118) | type byteSliceReader struct
    method Read (line 122) | func (r *byteSliceReader) Read(p []byte) (int, error) {
  function AcquireGzipReader (line 131) | func AcquireGzipReader(r io.Reader) (*gzip.Reader, error) {
  function ReleaseGzipReader (line 143) | func ReleaseGzipReader(zr *gzip.Reader) {
  function AppendGzipBytes (line 149) | func AppendGzipBytes(dst, src []byte) []byte {
  function AppendGzipBytesLevel (line 163) | func AppendGzipBytesLevel(dst, src []byte, level int) []byte {
  function nonblockingWriteGzip (line 171) | func nonblockingWriteGzip(ctxv interface{}) {
  function releaseRealGzipWriter (line 183) | func releaseRealGzipWriter(zw *gzip.Writer, level int) {
  function acquireRealGzipWriter (line 190) | func acquireRealGzipWriter(w io.Writer, level int) *gzip.Writer {
  function normalizeCompressLevel (line 208) | func normalizeCompressLevel(level int) int {
  function WriteGzipLevel (line 227) | func WriteGzipLevel(w io.Writer, p []byte, level int) (int, error) {
  function AcquireStacklessGzipWriter (line 248) | func AcquireStacklessGzipWriter(w io.Writer, level int) stackless.Writer {
  function ReleaseStacklessGzipWriter (line 262) | func ReleaseStacklessGzipWriter(sw stackless.Writer, level int) {

FILE: pkg/common/compress/compress_test.go
  function TestCompressNewCompressWriterPoolMap (line 49) | func TestCompressNewCompressWriterPoolMap(t *testing.T) {
  function TestCompressAppendGunzipBytes (line 56) | func TestCompressAppendGunzipBytes(t *testing.T) {
  function TestCompressAppendGzipBytesLevel (line 94) | func TestCompressAppendGzipBytesLevel(t *testing.T) {
  function TestCompressWriteGzipLevel (line 105) | func TestCompressWriteGzipLevel(t *testing.T) {
  type defaultByteWriter (line 122) | type defaultByteWriter struct
    method Write (line 126) | func (w *defaultByteWriter) Write(p []byte) (int, error) {

FILE: pkg/common/config/client_option.go
  type ConnPoolState (line 28) | type ConnPoolState struct
  type HostClientState (line 41) | type HostClientState interface
  type HostClientStateFunc (line 45) | type HostClientStateFunc
  type ClientOption (line 48) | type ClientOption struct
  type ClientOptions (line 52) | type ClientOptions struct
    method Apply (line 151) | func (o *ClientOptions) Apply(opts []ClientOption) {
  function NewClientOptions (line 139) | func NewClientOptions(opts []ClientOption) *ClientOptions {

FILE: pkg/common/config/client_option_test.go
  function TestDefaultClientOptions (line 28) | func TestDefaultClientOptions(t *testing.T) {
  function TestCustomClientOptions (line 38) | func TestCustomClientOptions(t *testing.T) {

FILE: pkg/common/config/option.go
  type Option (line 30) | type Option struct
  constant defaultKeepAliveTimeout (line 35) | defaultKeepAliveTimeout   = 1 * time.Minute
  constant defaultReadTimeout (line 36) | defaultReadTimeout        = 3 * time.Minute
  constant defaultAddr (line 37) | defaultAddr               = ":8888"
  constant defaultNetwork (line 38) | defaultNetwork            = "tcp"
  constant defaultBasePath (line 39) | defaultBasePath           = "/"
  constant defaultMaxRequestBodySize (line 40) | defaultMaxRequestBodySize = 4 << 20
  constant defaultMaxHeaderBytes (line 41) | defaultMaxHeaderBytes     = 1 << 20
  constant defaultWaitExitTimeout (line 42) | defaultWaitExitTimeout    = time.Second * 5
  constant defaultReadBufferSize (line 43) | defaultReadBufferSize     = 4 * 1024
  type Options (line 46) | type Options struct
    method Apply (line 130) | func (o *Options) Apply(opts []Option) {
  function NewOptions (line 136) | func NewOptions(opts []Option) *Options {

FILE: pkg/common/config/option_test.go
  function TestDefaultOptions (line 28) | func TestDefaultOptions(t *testing.T) {
  function TestApplyCustomOptions (line 65) | func TestApplyCustomOptions(t *testing.T) {

FILE: pkg/common/config/request_option.go
  type RequestOptions (line 23) | type RequestOptions struct
    method Apply (line 112) | func (o *RequestOptions) Apply(opts []RequestOption) {
    method Tag (line 118) | func (o *RequestOptions) Tag(k string) string {
    method Tags (line 122) | func (o *RequestOptions) Tags() map[string]string {
    method IsSD (line 126) | func (o *RequestOptions) IsSD() bool {
    method DialTimeout (line 130) | func (o *RequestOptions) DialTimeout() time.Duration {
    method ReadTimeout (line 134) | func (o *RequestOptions) ReadTimeout() time.Duration {
    method WriteTimeout (line 138) | func (o *RequestOptions) WriteTimeout() time.Duration {
    method RequestTimeout (line 142) | func (o *RequestOptions) RequestTimeout() time.Duration {
    method StartRequest (line 149) | func (o *RequestOptions) StartRequest() {
    method StartTime (line 155) | func (o *RequestOptions) StartTime() time.Time {
    method CopyTo (line 159) | func (o *RequestOptions) CopyTo(dst *RequestOptions) {
  type RequestOption (line 37) | type RequestOption struct
  function NewRequestOptions (line 42) | func NewRequestOptions(opts []RequestOption) *RequestOptions {
  function WithTag (line 55) | func WithTag(k, v string) RequestOption {
  function WithSD (line 62) | func WithSD(b bool) RequestOption {
  function WithDialTimeout (line 76) | func WithDialTimeout(t time.Duration) RequestOption {
  function WithReadTimeout (line 86) | func WithReadTimeout(t time.Duration) RequestOption {
  function WithWriteTimeout (line 96) | func WithWriteTimeout(t time.Duration) RequestOption {
  function WithRequestTimeout (line 106) | func WithRequestTimeout(t time.Duration) RequestOption {
  function SetPreDefinedOpts (line 177) | func SetPreDefinedOpts(opts ...RequestOption) {

FILE: pkg/common/config/request_option_test.go
  function TestRequestOptions (line 27) | func TestRequestOptions(t *testing.T) {
  function TestRequestOptionsWithDefaultOpts (line 47) | func TestRequestOptionsWithDefaultOpts(t *testing.T) {
  function TestRequestOptions_CopyTo (line 68) | func TestRequestOptions_CopyTo(t *testing.T) {

FILE: pkg/common/errors/errors.go
  type ErrorType (line 80) | type ErrorType
  type Error (line 82) | type Error struct
    method SetType (line 106) | func (msg *Error) SetType(flags ErrorType) *Error {
    method Error (line 112) | func (msg *Error) Error() string {
    method Unwrap (line 130) | func (msg *Error) Unwrap() error {
    method SetMeta (line 135) | func (msg *Error) SetMeta(data interface{}) *Error {
    method IsType (line 141) | func (msg *Error) IsType(flags ErrorType) bool {
    method JSON (line 146) | func (msg *Error) JSON() interface{} {
  constant ErrorTypeBind (line 90) | ErrorTypeBind ErrorType = 1 << iota
  constant ErrorTypeRender (line 92) | ErrorTypeRender
  constant ErrorTypePrivate (line 94) | ErrorTypePrivate
  constant ErrorTypePublic (line 96) | ErrorTypePublic
  constant ErrorTypeAny (line 98) | ErrorTypeAny
  type ErrorChain (line 101) | type ErrorChain
    method String (line 116) | func (a ErrorChain) String() string {
    method Errors (line 174) | func (a ErrorChain) Errors() []string {
    method ByType (line 187) | func (a ErrorChain) ByType(typ ErrorType) ErrorChain {
    method Last (line 205) | func (a ErrorChain) Last() *Error {
    method JSON (line 212) | func (a ErrorChain) JSON() interface{} {
  function New (line 227) | func New(err error, t ErrorType, meta interface{}) *Error {
  function NewPublic (line 236) | func NewPublic(err string) *Error {
  function NewPrivate (line 240) | func NewPrivate(err string) *Error {
  function Newf (line 244) | func Newf(t ErrorType, meta interface{}, format string, v ...interface{}...
  function NewPublicf (line 248) | func NewPublicf(format string, v ...interface{}) *Error {
  function NewPrivatef (line 252) | func NewPrivatef(format string, v ...interface{}) *Error {

FILE: pkg/common/errors/errors_test.go
  function TestError (line 50) | func TestError(t *testing.T) {
  function TestErrorSlice (line 98) | func TestErrorSlice(t *testing.T) {
  function TestErrorFormat (line 134) | func TestErrorFormat(t *testing.T) {

FILE: pkg/common/hlog/consts.go
  constant systemLogPrefix (line 20) | systemLogPrefix = "HERTZ: "
  constant EngineErrorFormat (line 22) | EngineErrorFormat = "Error=%s, remoteAddr=%s"

FILE: pkg/common/hlog/default.go
  function Fatal (line 28) | func Fatal(v ...interface{}) {
  function Error (line 33) | func Error(v ...interface{}) {
  function Warn (line 38) | func Warn(v ...interface{}) {
  function Notice (line 43) | func Notice(v ...interface{}) {
  function Info (line 48) | func Info(v ...interface{}) {
  function Debug (line 53) | func Debug(v ...interface{}) {
  fu
Condensed preview — 450 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,913K chars).
[
  {
    "path": ".codecov.yml",
    "chars": 323,
    "preview": "github_checks:\n  annotations: false\n\nignore:\n  - \"images/.*\"\n  - \"examples/.*\"\n  - \"cmd/.*\"\n\ncoverage:\n  status:\n    pro"
  },
  {
    "path": ".gitattributes",
    "chars": 297,
    "preview": "# Handle line endings automatically for files detected as text\n# and leave all files detected as binary untouched.\n* tex"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 262,
    "preview": "# For more information, please refer to https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-f"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 655,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 599,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "chars": 745,
    "preview": "---\nname: Question\nabout: Ask a question, so we can help you easily\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 2044,
    "preview": "#### What type of PR is this?\n<!--\nAdd one of the following kinds:\n\nbuild: Changes that affect the build system or exter"
  },
  {
    "path": ".github/labels.json",
    "chars": 723,
    "preview": "{\n  \"labels\": {\n    \"invalid_issue\": {\n      \"name\": \"invalid issue\",\n      \"colour\": \"#CF2E1F\",\n      \"description\": \"i"
  },
  {
    "path": ".github/workflows/cmd-tests.yml",
    "chars": 1468,
    "preview": "name: Cmd Tests\n\non:\n  push:\n    paths:\n      - 'cmd/**'\n  pull_request:\n    paths:\n      - 'cmd/**'\n\njobs:\n  hz-test-un"
  },
  {
    "path": ".github/workflows/invalid_question.yml",
    "chars": 754,
    "preview": "name: \"Close Invalid Issue\"\non:\n  schedule:\n    - cron: \"0 0,8,16 * * *\"\n\npermissions:\n  contents: read\n\njobs:\n  stale:\n"
  },
  {
    "path": ".github/workflows/labeler.yml",
    "chars": 456,
    "preview": "name: \"Labeler\"\non:\n  issues:\n    types: [ opened, edited, reopened ]\n\njobs:\n  triage:\n    if: contains(github.event.iss"
  },
  {
    "path": ".github/workflows/pr-check.yml",
    "chars": 800,
    "preview": "name: Pull Request Check\n\non: [ pull_request ]\n\njobs:\n  compliant:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: a"
  },
  {
    "path": ".github/workflows/unit-tests.yml",
    "chars": 2004,
    "preview": "name: Unit Tests\n\non: [push, pull_request]\n\njobs:\n  unit-test-x64:\n    strategy:\n      matrix:\n        version: [\"1.19\","
  },
  {
    "path": ".github/workflows/vulncheck.yml",
    "chars": 640,
    "preview": "name: Run govulncheck\n\non:\n  push:\n    branches:\n      - develop\n    paths:\n      - \"**\"\n      - \"!**.md\"\n  pull_request"
  },
  {
    "path": ".gitignore",
    "chars": 137,
    "preview": ".idea\n.vscode\npkg/app/fs.go.hertz.gz\ncoverage.txt\ncoverage.out\n# OSX trash\n.DS_Store\n\n# test benchmark tmp output\ncpu.ou"
  },
  {
    "path": ".golangci.yaml",
    "chars": 541,
    "preview": "version: \"2\"\nlinters:\n  default: none\n  enable:\n    - govet\n    - ineffassign\n    - staticcheck\n    - unconvert\n    - un"
  },
  {
    "path": ".licenserc.yaml",
    "chars": 218,
    "preview": "header:\n  license:\n    spdx-id: Apache-2.0\n    copyright-owner: CloudWeGo Authors\n\n  paths:\n    - '**/*.go'\n    - '**/*."
  },
  {
    "path": ".typos.toml",
    "chars": 565,
    "preview": "# Typo check: https://github.com/crate-ci/typos\n\n[files]\nextend-exclude = [\"go.mod\", \"go.sum\"]\n\n[default.extend-identifi"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5222,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 3731,
    "preview": "# How to Contribute\n\n## Your First Pull Request\nWe use github for our codebase. You can start by reading [How To Pull Re"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Makefile",
    "chars": 991,
    "preview": "SHELL := /bin/bash\n\n.PHONY: \\\n\thelp \\\n\tcoverage \\\n\tvet \\\n\tlint \\\n\tfmt \\\n\tversion\n\nall: imports fmt lint vet errors build"
  },
  {
    "path": "NOTICE",
    "chars": 217,
    "preview": "CloudWeGo\nCopyright 2022 CloudWeGo Authors\n\nApache Thrift\nCopyright (C) 2006 - 2019, The Apache Software Foundation\n\nThi"
  },
  {
    "path": "README.md",
    "chars": 16821,
    "preview": "# Hertz\n\nEnglish | [中文](README_cn.md)\n\n[![Release](https://img.shields.io/github/v/release/cloudwego/hertz)](https://git"
  },
  {
    "path": "README_cn.md",
    "chars": 11883,
    "preview": "# Hertz\n\n[English](README.md) | 中文\n\n[![Release](https://img.shields.io/github/v/release/cloudwego/hertz)](https://github"
  },
  {
    "path": "ROADMAP.md",
    "chars": 834,
    "preview": "# Hertz RoadMap\n\nFrom 2025, instead of developing new features we will focus on optimizing core functionalities and user"
  },
  {
    "path": "cmd/hz/app/app.go",
    "chars": 14992,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/config/argument.go",
    "chars": 11657,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/config/cmd.go",
    "chars": 5329,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/doc.go",
    "chars": 843,
    "preview": "// Copyright 2022 CloudWeGo Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not"
  },
  {
    "path": "cmd/hz/generator/client.go",
    "chars": 3151,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/custom_files.go",
    "chars": 23440,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/file.go",
    "chars": 1193,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/handler.go",
    "chars": 9578,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/layout.go",
    "chars": 6261,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/layout_tpl.go",
    "chars": 4057,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/define.go",
    "chars": 3727,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/expr.go",
    "chars": 1997,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/constant.go",
    "chars": 736,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/enum.go",
    "chars": 1662,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/file.go",
    "chars": 1271,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/function.go",
    "chars": 1283,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/init.go",
    "chars": 2774,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/oneof.go",
    "chars": 1248,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/struct.go",
    "chars": 3204,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/typedef.go",
    "chars": 975,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/golang/variable.go",
    "chars": 736,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model/model.go",
    "chars": 8518,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model.go",
    "chars": 4267,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/model_test.go",
    "chars": 5321,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/package.go",
    "chars": 6162,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/package_tpl.go",
    "chars": 24001,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/router.go",
    "chars": 15149,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/router_test.go",
    "chars": 1970,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/template.go",
    "chars": 9569,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/generator/template_funcs.go",
    "chars": 1479,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/go.mod",
    "chars": 372,
    "preview": "module github.com/cloudwego/hertz/cmd/hz\n\ngo 1.16\n\nrequire (\n\tgithub.com/Masterminds/sprig/v3 v3.2.3\n\tgithub.com/cloudwe"
  },
  {
    "path": "cmd/hz/go.sum",
    "chars": 20467,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1/go."
  },
  {
    "path": "cmd/hz/main.go",
    "chars": 955,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/meta/const.go",
    "chars": 2171,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/meta/manifest.go",
    "chars": 2439,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/meta/manifest_test.go",
    "chars": 811,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/api/api.pb.go",
    "chars": 32775,
    "preview": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.30.0\n// \tprotoc        v3.21.12\n// so"
  },
  {
    "path": "cmd/hz/protobuf/api/api.proto",
    "chars": 2672,
    "preview": "syntax = \"proto2\";\n\npackage api;\n\nimport \"google/protobuf/descriptor.proto\";\n\noption go_package = \"/api\";\n\nextend google"
  },
  {
    "path": "cmd/hz/protobuf/ast.go",
    "chars": 23887,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/plugin.go",
    "chars": 19340,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/plugin_stubs.go",
    "chars": 9837,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/plugin_test.go",
    "chars": 2706,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/resolver.go",
    "chars": 13084,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/tag_test.go",
    "chars": 4615,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/tags.go",
    "chars": 12310,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/protobuf/test_data/test_tag.proto",
    "chars": 1217,
    "preview": "syntax = \"proto2\";\n\npackage test;\n\noption go_package = \"cloudwego.hertz.hz\";\n\nimport \"api.proto\";\n\nmessage MultiTagReq {"
  },
  {
    "path": "cmd/hz/test_hz_unix.sh",
    "chars": 2671,
    "preview": "#! /usr/bin/env bash\n\n\nset -e\n\n# const value define\nmoduleName=\"github.com/cloudwego/hertz/cmd/hz/test\"\ncurDir=`pwd`\nthr"
  },
  {
    "path": "cmd/hz/test_hz_windows.sh",
    "chars": 2327,
    "preview": "#! /usr/bin/env bash\n\nset -e\n\n# const value define\nmoduleName=\"github.com/cloudwego/hertz/cmd/hz/test\"\ncurDir=`pwd`\nthri"
  },
  {
    "path": "cmd/hz/testdata/protobuf2/api.proto",
    "chars": 2377,
    "preview": "syntax = \"proto2\";\n\npackage api;\n\nimport \"google/protobuf/descriptor.proto\";\n\noption go_package = \"github.com/cloudwego/"
  },
  {
    "path": "cmd/hz/testdata/protobuf2/other/other.proto",
    "chars": 260,
    "preview": "syntax = \"proto2\";\n\npackage hertz.other;\n\nimport \"other/other_base.proto\";\n\noption go_package = \"github.com/cloudwego/he"
  },
  {
    "path": "cmd/hz/testdata/protobuf2/other/other_base.proto",
    "chars": 193,
    "preview": "syntax = \"proto2\";\n\npackage hertz.other;\n\noption go_package = \"github.com/cloudwego/hertz/cmd/hz/test/hertz_model/other\""
  },
  {
    "path": "cmd/hz/testdata/protobuf2/psm/base.proto",
    "chars": 217,
    "preview": "syntax = \"proto2\";\n\npackage base;\n\noption go_package = \"github.com/cloudwego/hertz/cmd/hz/test/hertz_model/psm\";\n\nmessag"
  },
  {
    "path": "cmd/hz/testdata/protobuf2/psm/psm.proto",
    "chars": 4444,
    "preview": "syntax = \"proto2\";\n\npackage psm;\n\noption go_package = \"github.com/cloudwego/hertz/cmd/hz/test/hertz_model/psm\";\n\nimport "
  },
  {
    "path": "cmd/hz/testdata/protobuf3/api.proto",
    "chars": 2377,
    "preview": "syntax = \"proto2\";\n\npackage api;\n\nimport \"google/protobuf/descriptor.proto\";\n\noption go_package = \"github.com/cloudwego/"
  },
  {
    "path": "cmd/hz/testdata/protobuf3/other/other.proto",
    "chars": 260,
    "preview": "syntax = \"proto2\";\n\npackage hertz.other;\n\nimport \"other/other_base.proto\";\n\noption go_package = \"github.com/cloudwego/he"
  },
  {
    "path": "cmd/hz/testdata/protobuf3/other/other_base.proto",
    "chars": 193,
    "preview": "syntax = \"proto2\";\n\npackage hertz.other;\n\noption go_package = \"github.com/cloudwego/hertz/cmd/hz/test/hertz_model/other\""
  },
  {
    "path": "cmd/hz/testdata/protobuf3/psm/base.proto",
    "chars": 166,
    "preview": "syntax = \"proto2\";\n\npackage base;\n\noption go_package = \"github.com/cloudwego/hertz/cmd/hz/test/hertz_model/psm\";\n\nmessag"
  },
  {
    "path": "cmd/hz/testdata/protobuf3/psm/psm.proto",
    "chars": 3618,
    "preview": "syntax = \"proto3\";\n\npackage psm;\n\noption go_package = \"github.com/cloudwego/hertz/cmd/hz/test/hertz_model/psm\";\n\nimport "
  },
  {
    "path": "cmd/hz/testdata/thrift/common.thrift",
    "chars": 249,
    "preview": "namespace go toutiao.middleware.hertz\n\nstruct CommonType {\n    1: required string IsCommonString;\n    2: optional string"
  },
  {
    "path": "cmd/hz/testdata/thrift/data/basic_data.thrift",
    "chars": 110,
    "preview": "namespace go toutiao.middleware.hertz_data\n\nstruct BasicDataType {\n    1: optional string IsBasicDataString;\n}"
  },
  {
    "path": "cmd/hz/testdata/thrift/data/data.thrift",
    "chars": 147,
    "preview": "include \"basic_data.thrift\"\n\nnamespace go toutiao.middleware.hertz_data\n\nstruct DataType {\n    1: optional basic_data.Ba"
  },
  {
    "path": "cmd/hz/testdata/thrift/psm.thrift",
    "chars": 5076,
    "preview": "include \"common.thrift\"\ninclude \"data/data.thrift\"\n\nnamespace go toutiao.middleware.hertz\n\nconst string STRING_CONST = \""
  },
  {
    "path": "cmd/hz/thrift/ast.go",
    "chars": 27552,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/thrift/plugin.go",
    "chars": 12443,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/thrift/plugin_test.go",
    "chars": 2713,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/thrift/resolver.go",
    "chars": 14656,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/thrift/tag_test.go",
    "chars": 3170,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/thrift/tags.go",
    "chars": 8360,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/thrift/test_data/test_tag.thrift",
    "chars": 1038,
    "preview": "namespace go cloudwego.hertz.hz\n\nstruct MultiTagReq {\n    // basic feature\n    1: string DefaultQueryTag (api.query=\"que"
  },
  {
    "path": "cmd/hz/thrift/thriftgo_util.go",
    "chars": 823,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/ast.go",
    "chars": 1882,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/ast_test.go",
    "chars": 1596,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/data.go",
    "chars": 10481,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/data_test.go",
    "chars": 1862,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/env.go",
    "chars": 3187,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/fs.go",
    "chars": 1101,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/logs/api.go",
    "chars": 1870,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/logs/std.go",
    "chars": 3211,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/string.go",
    "chars": 2348,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/tool_install.go",
    "chars": 4085,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "cmd/hz/util/tool_install_test.go",
    "chars": 990,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "examples/html_rendering/index.tmpl",
    "chars": 44,
    "preview": "<html>\n<h1>\n    {[{ .title }]}\n</h1>\n</html>"
  },
  {
    "path": "examples/html_rendering/main.go",
    "chars": 1606,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "examples/html_rendering/template.html",
    "chars": 40,
    "preview": "<h1>Date: {[{.now | formatAsDate}]}</h1>"
  },
  {
    "path": "examples/standard/main.go",
    "chars": 1593,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "go.mod",
    "chars": 1047,
    "preview": "module github.com/cloudwego/hertz\n\ngo 1.19\n\nrequire (\n\tgithub.com/bytedance/gopkg v0.1.3\n\tgithub.com/bytedance/sonic v1."
  },
  {
    "path": "go.sum",
    "chars": 9865,
    "preview": "github.com/bytedance/gopkg v0.1.1/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=\ngithub.com/bytedance/gopkg v0.1"
  },
  {
    "path": "internal/bytesconv/bytesconv.go",
    "chars": 5767,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/bytesconv/bytesconv_32.go",
    "chars": 2040,
    "preview": "//go:build !amd64 && !arm64 && !ppc64\n\n/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, V"
  },
  {
    "path": "internal/bytesconv/bytesconv_32_test.go",
    "chars": 3441,
    "preview": "//go:build !amd64 && !arm64 && !ppc64\n\n/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, V"
  },
  {
    "path": "internal/bytesconv/bytesconv_64.go",
    "chars": 2038,
    "preview": "//go:build amd64 || arm64 || ppc64\n\n/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Vers"
  },
  {
    "path": "internal/bytesconv/bytesconv_64_test.go",
    "chars": 3582,
    "preview": "//go:build amd64 || arm64 || ppc64\n\n/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Vers"
  },
  {
    "path": "internal/bytesconv/bytesconv_table.go",
    "chars": 9966,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/bytesconv/bytesconv_table_gen.go",
    "chars": 8260,
    "preview": "//go:build ignore\n\n/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"Lic"
  },
  {
    "path": "internal/bytesconv/bytesconv_test.go",
    "chars": 5862,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/bytesconv/bytesconv_timing_test.go",
    "chars": 1432,
    "preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/bytesconv/doc.go",
    "chars": 1056,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/bytesconv/errors.go",
    "chars": 2408,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/bytestr/bytes.go",
    "chars": 4787,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/nocopy/nocopy.go",
    "chars": 1059,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/stats/stats_util.go",
    "chars": 1309,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/stats/stats_util_test.go",
    "chars": 1856,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/stats/tracer.go",
    "chars": 2093,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/stats/tracer_test.go",
    "chars": 2482,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/tagexpr/LICENSE",
    "chars": 11344,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "internal/tagexpr/README.md",
    "chars": 77,
    "preview": "# go-tagexpr\n\noriginally from https://github.com/bytedance/go-tagexpr v2.9.2\n"
  },
  {
    "path": "internal/tagexpr/example_test.go",
    "chars": 2093,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/expr.go",
    "chars": 6329,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/expr_test.go",
    "chars": 7255,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/handler.go",
    "chars": 3897,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/selector.go",
    "chars": 2868,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/selector_test.go",
    "chars": 826,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_func.go",
    "chars": 8168,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_func_test.go",
    "chars": 2341,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_operand.go",
    "chars": 8101,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_operator.go",
    "chars": 7700,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_range.go",
    "chars": 3935,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_range_test.go",
    "chars": 1930,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_selector.go",
    "chars": 2871,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/spec_test.go",
    "chars": 5757,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/tagexpr.go",
    "chars": 31315,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/tagexpr_test.go",
    "chars": 20697,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/tagparser.go",
    "chars": 4208,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/tagparser_test.go",
    "chars": 2115,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/utils.go",
    "chars": 2550,
    "preview": "/*\n * Copyright 2024 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/tagexpr/validator/README.md",
    "chars": 76,
    "preview": "# validator\n\noriginally from https://github.com/bytedance/go-tagexpr v2.9.2\n"
  },
  {
    "path": "internal/tagexpr/validator/default.go",
    "chars": 1366,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/validator/example_test.go",
    "chars": 3546,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/validator/func.go",
    "chars": 3726,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/tagexpr/validator/validator.go",
    "chars": 3904,
    "preview": "// Package validator is a powerful validator that supports struct tag expression.\n//\n// Copyright 2019 Bytedance Inc. Al"
  },
  {
    "path": "internal/tagexpr/validator/validator_test.go",
    "chars": 10109,
    "preview": "// Copyright 2019 Bytedance Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License"
  },
  {
    "path": "internal/test/mock/binder/binder.go",
    "chars": 2172,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/test/mock/binder/binder_test.go",
    "chars": 1787,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/testutils/testutils.go",
    "chars": 1274,
    "preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "internal/testutils/testutils_test.go",
    "chars": 1058,
    "preview": "/*\n * Copyright 2025 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "licenses/LICENSE-echo.txt",
    "chars": 1521,
    "preview": "BSD 3-Clause License\n\nCopyright (c) 2013, Julien Schmidt\nAll rights reserved.\n\nRedistribution and use in source and bina"
  },
  {
    "path": "licenses/LICENSE-fasthttp.txt",
    "chars": 1074,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2021 LabStack\n\nPermission is hereby granted, free of charge, to any person obtainin"
  },
  {
    "path": "licenses/LICENSE-fsnotify",
    "chars": 1528,
    "preview": "Copyright © 2012 The Go Authors. All rights reserved.\nCopyright © fsnotify Authors. All rights reserved.\n\nRedistribution"
  },
  {
    "path": "licenses/LICENSE-gin.txt",
    "chars": 1089,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2014 Manuel Martínez-Almeida\n\nPermission is hereby granted, free of charge, to any "
  },
  {
    "path": "licenses/LICENSE-go-version.txt",
    "chars": 15883,
    "preview": "Mozilla Public License, version 2.0\n\n1. Definitions\n\n1.1. “Contributor”\n\n     means each individual or legal entity that"
  },
  {
    "path": "licenses/LICENSE-protobuf.txt",
    "chars": 1479,
    "preview": "Copyright (c) 2018 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or with"
  },
  {
    "path": "licenses/LICENSE-protoreflect.txt",
    "chars": 11358,
    "preview": "\n\n                                 Apache License\n                           Version 2.0, January 2004\n                 "
  },
  {
    "path": "licenses/LICENSE-sprig.txt",
    "chars": 1059,
    "preview": "Copyright (C) 2013-2020 Masterminds\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof thi"
  },
  {
    "path": "licenses/LICENSE-yaml.txt",
    "chars": 11356,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "pkg/app/client/client.go",
    "chars": 25133,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/client_test.go",
    "chars": 73584,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/client_unix_test.go",
    "chars": 1327,
    "preview": "// Copyright 2023 CloudWeGo Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not"
  },
  {
    "path": "pkg/app/client/client_windows_test.go",
    "chars": 1135,
    "preview": "// Copyright 2023 CloudWeGo Authors\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not"
  },
  {
    "path": "pkg/app/client/discovery/discovery.go",
    "chars": 2945,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/discovery/discovery_test.go",
    "chars": 2174,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/loadbalance/lbcache.go",
    "chars": 5045,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/loadbalance/lbcache_test.go",
    "chars": 6924,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/loadbalance/loadbalance.go",
    "chars": 1855,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/loadbalance/weight_random.go",
    "chars": 2727,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/loadbalance/weight_random_test.go",
    "chars": 2845,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/middleware.go",
    "chars": 1162,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/middleware_test.go",
    "chars": 1928,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/option.go",
    "chars": 6783,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/option_test.go",
    "chars": 3023,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/retry/option.go",
    "chars": 1566,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/retry/retry.go",
    "chars": 3855,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/client/retry/retry_test.go",
    "chars": 2775,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/context.go",
    "chars": 49531,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/context_test.go",
    "chars": 47433,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/fs.go",
    "chars": 33329,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/fs_test.go",
    "chars": 19680,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/client/sd/discovery.go",
    "chars": 1710,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/client/sd/discovery_test.go",
    "chars": 1903,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/client/sd/options.go",
    "chars": 2936,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/client/sd/options_test.go",
    "chars": 1633,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/server/basic_auth/basic_auth.go",
    "chars": 4007,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/server/basic_auth/basic_auth_test.go",
    "chars": 3348,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/server/basic_auth/doc.go",
    "chars": 1031,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  },
  {
    "path": "pkg/app/middlewares/server/recovery/option.go",
    "chars": 1512,
    "preview": "/*\n * Copyright 2022 CloudWeGo Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may "
  }
]

// ... and 250 more files (download for full content)

About this extraction

This page contains the full source code of the cloudwego/hertz GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 450 files (2.5 MB), approximately 688.4k tokens, and a symbol index with 4647 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!