From ca8e215cfa238f29b137b2ff93b704ca8db2f16f Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 13 Nov 2021 20:18:06 +0100 Subject: [PATCH] Migrate to Xorm (#474) close #234 * Migrate store * Migrate tests * Rewrite migrations * Init fresh DB in on step * Rm old stuff (meddler, sql files, dead code, ...) --- Makefile | 2 +- agent/runner.go | 3 +- cli/exec/exec.go | 6 +- cmd/server/server.go | 5 + cmd/server/setup.go | 30 +- go.mod | 10 +- go.sum | 306 +- pipeline/frontend/metadata.go | 10 +- server/api/build.go | 24 +- server/api/file.go | 4 +- server/api/hook.go | 2 +- server/api/stream.go | 2 +- server/model/{build_test.go => agent.go} | 34 +- server/model/build.go | 79 +- server/model/cc.go | 2 +- server/model/config.go | 17 +- server/model/environ.go | 7 +- server/model/feed.go | 39 +- server/model/file.go | 29 +- .../ddl/mysql/ddl.go => model/log.go} | 10 +- server/model/perm.go | 23 +- server/model/proc.go | 36 +- server/model/queue.go | 17 +- server/model/registry.go | 15 +- server/model/repo.go | 53 +- server/model/secret.go | 22 +- server/model/sender.go | 22 +- server/model/task.go | 36 + server/model/user.go | 30 +- .../{datastore/sql/mysql/sql.go => common.go} | 10 +- server/store/datastore/build.go | 123 + .../{builds_test.go => build_test.go} | 124 +- server/store/datastore/builds.go | 229 - server/store/datastore/config.go | 79 +- server/store/datastore/config_test.go | 86 +- server/store/datastore/ddl/migrate.go | 115 - server/store/datastore/ddl/mysql/ddl_gen.go | 783 --- .../mysql/files/001_create_table_users.sql | 16 - .../mysql/files/002_create_table_repos.sql | 26 - .../mysql/files/003_create_table_builds.sql | 44 - .../mysql/files/004_create_table_procs.sql | 24 - .../ddl/mysql/files/005_create_table_logs.sql | 9 - .../mysql/files/006_create_table_files.sql | 22 - .../mysql/files/007_create_table_secets.sql | 18 - .../mysql/files/008_create_table_registry.sql | 17 - .../mysql/files/009_create_table_config.sql | 10 - .../mysql/files/010_create_table_tasks.sql | 7 - .../mysql/files/011_create_table_agents.sql | 12 - .../mysql/files/012_create_table_senders.sql | 15 - .../files/013_add_column_repo_visibility.sql | 11 - .../mysql/files/014_add_column_repo_seq.sql | 16 - .../files/015_add_column_repo_active.sql | 7 - .../files/016_add_column_user_synced.sql | 7 - .../mysql/files/017_create_table_perms.sql | 19 - .../mysql/files/018_add_column_file_pid.sql | 22 - .../files/019_create_table_build_config.sql | 9 - .../files/020_add_column_config_name.sql | 7 - .../mysql/files/021_populate_build_config.sql | 4 - .../ddl/mysql/files/022_add_task_columns.sql | 6 - .../files/023_add_repo_fallback_column.sql | 5 - .../files/024_add_repo_fallback_column.sql | 2 - .../025_add_builds_changed_files_column.sql | 5 - .../files/026_drop_repo_fallback_column.sql | 2 - ...op_allow_push_tags_deployments_columns.sql | 2 - ...able_set_users_token_and_secret_length.sql | 3 - .../store/datastore/ddl/postgres/ddl_gen.go | 786 --- .../postgres/files/001_create_table_users.sql | 16 - .../postgres/files/002_create_table_repos.sql | 26 - .../files/003_create_table_builds.sql | 44 - .../postgres/files/004_create_table_procs.sql | 24 - .../postgres/files/005_create_table_logs.sql | 9 - .../postgres/files/006_create_table_files.sql | 22 - .../files/007_create_table_secets.sql | 18 - .../files/008_create_table_registry.sql | 17 - .../files/009_create_table_config.sql | 10 - .../postgres/files/010_create_table_tasks.sql | 7 - .../files/011_create_table_agents.sql | 12 - .../files/012_create_table_senders.sql | 15 - .../files/013_add_column_repo_visibility.sql | 11 - .../files/014_add_column_repo_seq.sql | 17 - .../files/015_add_column_repo_active.sql | 7 - .../files/016_add_column_user_synced.sql | 7 - .../postgres/files/017_create_table_perms.sql | 19 - .../files/018_add_column_file_pid.sql | 23 - .../files/019_create_table_build_config.sql | 9 - .../files/020_add_column_config_name.sql | 7 - .../files/021_populate_build_config.sql | 4 - .../postgres/files/022_add_task_columns.sql | 6 - .../files/023_add_repo_fallback_column.sql | 5 - .../files/024_add_repo_fallback_column.sql | 2 - .../025_add_builds_changed_files_column.sql | 5 - .../files/026_drop_repo_fallback_column.sql | 2 - ...op_allow_push_tags_deployments_columns.sql | 2 - ...able_set_users_token_and_secret_length.sql | 4 - server/store/datastore/ddl/sqlite/ddl_gen.go | 884 --- .../sqlite/files/001_create_table_users.sql | 15 - .../sqlite/files/002_create_table_repos.sql | 25 - .../sqlite/files/003_create_table_builds.sql | 48 - .../sqlite/files/004_create_table_procs.sql | 23 - .../sqlite/files/005_create_table_logs.sql | 8 - .../sqlite/files/006_create_table_files.sql | 21 - .../sqlite/files/007_create_table_secets.sql | 17 - .../files/008_create_table_registry.sql | 17 - .../sqlite/files/009_create_table_config.sql | 9 - .../sqlite/files/010_create_table_tasks.sql | 7 - .../sqlite/files/011_create_table_agents.sql | 12 - .../sqlite/files/012_create_table_senders.sql | 15 - .../files/013_add_column_repo_visibility.sql | 11 - .../sqlite/files/014_add_column_repo_seq.sql | 16 - .../files/015_add_column_repo_active.sql | 7 - .../files/016_add_column_user_synced.sql | 7 - .../sqlite/files/017_create_table_perms.sql | 19 - .../sqlite/files/018_add_column_file_pid.sql | 22 - .../files/019_create_table_build_config.sql | 9 - .../files/020_add_column_config_name.sql | 7 - .../files/021_populate_build_config.sql | 4 - .../ddl/sqlite/files/022_add_task_columns.sql | 6 - .../files/023_add_repo_fallback_column.sql | 5 - .../files/024_add_repo_fallback_column.sql | 2 - .../025_add_builds_changed_files_column.sql | 5 - .../files/026_drop_repo_fallback_column.sql | 56 - ...op_allow_push_tags_deployments_columns.sql | 48 - ...able_set_users_token_and_secret_length.sql | 3 - server/store/datastore/engine.go | 56 + .../{store_test.go => engine_test.go} | 47 +- server/store/datastore/feed.go | 126 + server/store/datastore/feed_test.go | 104 + server/store/datastore/file.go | 56 + .../datastore/{files_test.go => file_test.go} | 130 +- server/store/datastore/files.go | 85 - .../{ddl/sqlite/ddl.go => helper.go} | 19 +- server/store/datastore/init.go | 15 + server/store/datastore/init_cgo.go | 16 + server/store/datastore/log.go | 65 + .../datastore/{logs_test.go => log_test.go} | 24 +- server/store/datastore/logs.go | 51 - .../datastore/migration/000_legacy_to_xorm.go | 149 + .../001_repos_drop_fallback.go} | 15 +- ...002_repos_drop_allow_deploys_allow_tags.go | 29 + server/store/datastore/migration/common.go | 206 + server/store/datastore/migration/migration.go | 144 + server/store/datastore/permission.go | 93 + .../{perms_test.go => permission_test.go} | 52 +- server/store/datastore/perms.go | 64 - server/store/datastore/proc.go | 86 + .../datastore/{procs_test.go => proc_test.go} | 106 +- server/store/datastore/procs.go | 74 - server/store/datastore/registry.go | 48 +- server/store/datastore/registry_test.go | 54 +- server/store/datastore/repo.go | 111 + .../datastore/{repos_test.go => repo_test.go} | 248 +- server/store/datastore/repos.go | 117 - server/store/datastore/secret.go | 48 +- server/store/datastore/secret_test.go | 77 +- server/store/datastore/sender.go | 48 +- server/store/datastore/sender_test.go | 64 +- server/store/datastore/sql/lookup.go | 41 - .../datastore/sql/mysql/files/config.sql | 35 - .../datastore/sql/mysql/files/counts.sql | 15 - .../store/datastore/sql/mysql/files/feed.sql | 63 - .../store/datastore/sql/mysql/files/files.sql | 57 - .../store/datastore/sql/mysql/files/logs.sql | 9 - .../store/datastore/sql/mysql/files/perms.sql | 58 - .../store/datastore/sql/mysql/files/procs.sql | 87 - .../datastore/sql/mysql/files/registry.sql | 34 - .../store/datastore/sql/mysql/files/repos.sql | 90 - .../datastore/sql/mysql/files/secret.sql | 32 - .../datastore/sql/mysql/files/sender.sql | 30 - .../store/datastore/sql/mysql/files/task.sql | 13 - .../store/datastore/sql/mysql/files/users.sql | 53 - server/store/datastore/sql/mysql/sql_gen.go | 644 --- .../datastore/sql/postgres/files/config.sql | 35 - .../datastore/sql/postgres/files/counts.sql | 15 - .../datastore/sql/postgres/files/feed.sql | 61 - .../datastore/sql/postgres/files/files.sql | 57 - .../datastore/sql/postgres/files/logs.sql | 9 - .../datastore/sql/postgres/files/perms.sql | 63 - .../datastore/sql/postgres/files/procs.sql | 87 - .../datastore/sql/postgres/files/registry.sql | 34 - .../datastore/sql/postgres/files/repos.sql | 92 - .../datastore/sql/postgres/files/secret.sql | 32 - .../datastore/sql/postgres/files/sender.sql | 30 - .../datastore/sql/postgres/files/tasks.sql | 13 - .../datastore/sql/postgres/files/users.sql | 53 - server/store/datastore/sql/postgres/sql.go | 17 - .../store/datastore/sql/postgres/sql_gen.go | 649 --- .../datastore/sql/sqlite/files/config.sql | 35 - .../datastore/sql/sqlite/files/counts.sql | 15 - .../store/datastore/sql/sqlite/files/feed.sql | 63 - .../datastore/sql/sqlite/files/files.sql | 57 - .../store/datastore/sql/sqlite/files/logs.sql | 9 - .../datastore/sql/sqlite/files/perms.sql | 58 - .../datastore/sql/sqlite/files/procs.sql | 87 - .../datastore/sql/sqlite/files/registry.sql | 34 - .../datastore/sql/sqlite/files/repos.sql | 90 - .../datastore/sql/sqlite/files/secret.sql | 32 - .../datastore/sql/sqlite/files/sender.sql | 30 - .../store/datastore/sql/sqlite/files/task.sql | 13 - .../store/datastore/sql/sqlite/files/user.sql | 53 - server/store/datastore/sql/sqlite/sql.go | 17 - server/store/datastore/sql/sqlite/sql_gen.go | 644 --- server/store/datastore/store.go | 116 - server/store/datastore/task.go | 28 +- server/store/datastore/task_test.go | 19 +- server/store/datastore/user.go | 55 + server/store/datastore/users.go | 70 - server/store/datastore/users_test.go | 99 +- server/store/datastore/utils.go | 49 - server/store/store.go | 24 +- tools.go | 1 - vendor/github.com/goccy/go-json/.codecov.yml | 32 + vendor/github.com/goccy/go-json/.gitignore | 2 + vendor/github.com/goccy/go-json/.golangci.yml | 75 + vendor/github.com/goccy/go-json/CHANGELOG.md | 236 + .../{urfave/cli => goccy/go-json}/LICENSE | 2 +- vendor/github.com/goccy/go-json/Makefile | 39 + vendor/github.com/goccy/go-json/README.md | 529 ++ vendor/github.com/goccy/go-json/color.go | 68 + vendor/github.com/goccy/go-json/decode.go | 232 + vendor/github.com/goccy/go-json/encode.go | 323 ++ vendor/github.com/goccy/go-json/error.go | 39 + vendor/github.com/goccy/go-json/go.mod | 3 + vendor/github.com/goccy/go-json/go.sum | 0 .../internal/decoder/anonymous_field.go | 37 + .../goccy/go-json/internal/decoder/array.go | 169 + .../goccy/go-json/internal/decoder/bool.go | 78 + .../goccy/go-json/internal/decoder/bytes.go | 177 + .../goccy/go-json/internal/decoder/compile.go | 510 ++ .../internal/decoder/compile_norace.go | 28 + .../go-json/internal/decoder/compile_race.go | 36 + .../goccy/go-json/internal/decoder/context.go | 254 + .../goccy/go-json/internal/decoder/float.go | 158 + .../goccy/go-json/internal/decoder/func.go | 141 + .../goccy/go-json/internal/decoder/int.go | 242 + .../go-json/internal/decoder/interface.go | 458 ++ .../goccy/go-json/internal/decoder/map.go | 173 + .../goccy/go-json/internal/decoder/number.go | 108 + .../goccy/go-json/internal/decoder/option.go | 15 + .../goccy/go-json/internal/decoder/ptr.go | 87 + .../goccy/go-json/internal/decoder/slice.go | 294 + .../goccy/go-json/internal/decoder/stream.go | 554 ++ .../goccy/go-json/internal/decoder/string.go | 361 ++ .../goccy/go-json/internal/decoder/struct.go | 819 +++ .../goccy/go-json/internal/decoder/type.go | 29 + .../goccy/go-json/internal/decoder/uint.go | 190 + .../internal/decoder/unmarshal_json.go | 91 + .../internal/decoder/unmarshal_text.go | 280 + .../internal/decoder/wrapped_string.go | 68 + .../goccy/go-json/internal/encoder/compact.go | 286 + .../go-json/internal/encoder/compiler.go | 1569 +++++ .../internal/encoder/compiler_norace.go | 56 + .../go-json/internal/encoder/compiler_race.go | 65 + .../goccy/go-json/internal/encoder/context.go | 141 + .../goccy/go-json/internal/encoder/encoder.go | 551 ++ .../goccy/go-json/internal/encoder/indent.go | 211 + .../goccy/go-json/internal/encoder/int.go | 130 + .../goccy/go-json/internal/encoder/map112.go | 8 + .../goccy/go-json/internal/encoder/map113.go | 8 + .../goccy/go-json/internal/encoder/opcode.go | 766 +++ .../goccy/go-json/internal/encoder/option.go | 41 + .../goccy/go-json/internal/encoder/optype.go | 934 +++ .../goccy/go-json/internal/encoder/string.go | 640 +++ .../go-json/internal/encoder/vm/debug_vm.go | 34 + .../goccy/go-json/internal/encoder/vm/hack.go | 9 + .../goccy/go-json/internal/encoder/vm/util.go | 182 + .../goccy/go-json/internal/encoder/vm/vm.go | 5041 +++++++++++++++++ .../internal/encoder/vm_color/debug_vm.go | 34 + .../go-json/internal/encoder/vm_color/hack.go | 9 + .../go-json/internal/encoder/vm_color/util.go | 246 + .../go-json/internal/encoder/vm_color/vm.go | 5041 +++++++++++++++++ .../encoder/vm_color_indent/debug_vm.go | 34 + .../internal/encoder/vm_color_indent/util.go | 267 + .../internal/encoder/vm_color_indent/vm.go | 5041 +++++++++++++++++ .../internal/encoder/vm_indent/debug_vm.go | 34 + .../internal/encoder/vm_indent/hack.go | 9 + .../internal/encoder/vm_indent/util.go | 204 + .../go-json/internal/encoder/vm_indent/vm.go | 5041 +++++++++++++++++ .../goccy/go-json/internal/errors/error.go | 157 + .../goccy/go-json/internal/runtime/rtype.go | 263 + .../go-json/internal/runtime/struct_field.go | 87 + .../goccy/go-json/internal/runtime/type.go | 100 + vendor/github.com/goccy/go-json/json.go | 366 ++ vendor/github.com/goccy/go-json/option.go | 46 + vendor/github.com/golang/snappy/.gitignore | 16 + vendor/github.com/golang/snappy/AUTHORS | 15 + vendor/github.com/golang/snappy/CONTRIBUTORS | 37 + vendor/github.com/golang/snappy/LICENSE | 27 + vendor/github.com/golang/snappy/README | 107 + vendor/github.com/golang/snappy/decode.go | 237 + .../github.com/golang/snappy/decode_amd64.go | 14 + .../github.com/golang/snappy/decode_amd64.s | 490 ++ .../github.com/golang/snappy/decode_other.go | 101 + vendor/github.com/golang/snappy/encode.go | 285 + .../github.com/golang/snappy/encode_amd64.go | 29 + .../github.com/golang/snappy/encode_amd64.s | 730 +++ .../github.com/golang/snappy/encode_other.go | 238 + vendor/github.com/golang/snappy/snappy.go | 98 + .../hashicorp/go-retryablehttp/client.go | 2 +- .../hashicorp/go-version/CHANGELOG.md | 25 - .../hashicorp/go-version/version.go | 8 - vendor/github.com/json-iterator/go/README.md | 2 + vendor/github.com/json-iterator/go/go.mod | 2 +- vendor/github.com/json-iterator/go/go.sum | 5 +- vendor/github.com/mattn/go-isatty/.travis.yml | 14 + vendor/github.com/mattn/go-isatty/go.mod | 2 +- .../github.com/mattn/go-isatty/isatty_bsd.go | 1 - .../mattn/go-isatty/isatty_others.go | 3 +- .../mattn/go-isatty/isatty_plan9.go | 1 - .../mattn/go-isatty/isatty_solaris.go | 9 +- .../mattn/go-isatty/isatty_tcgets.go | 3 +- .../mattn/go-isatty/isatty_windows.go | 6 +- .../github.com/mattn/go-isatty/renovate.json | 8 + .../github.com/modern-go/reflect2/.travis.yml | 2 +- .../github.com/modern-go/reflect2/Gopkg.lock | 8 +- .../github.com/modern-go/reflect2/Gopkg.toml | 4 + vendor/github.com/modern-go/reflect2/go.mod | 3 - .../modern-go/reflect2/go_above_118.go | 23 - .../modern-go/reflect2/go_above_17.go | 8 + .../modern-go/reflect2/go_above_19.go | 3 - .../modern-go/reflect2/go_below_118.go | 21 - .../modern-go/reflect2/go_below_17.go | 9 + .../modern-go/reflect2/go_below_19.go | 14 + .../github.com/modern-go/reflect2/reflect2.go | 20 +- vendor/github.com/modern-go/reflect2/test.sh | 12 + .../github.com/modern-go/reflect2/type_map.go | 51 +- .../modern-go/reflect2/unsafe_link.go | 26 +- .../modern-go/reflect2/unsafe_map.go | 8 + vendor/github.com/russross/meddler/.gitignore | 1 - .../github.com/russross/meddler/.travis.yml | 19 - vendor/github.com/russross/meddler/LICENSE | 9 - vendor/github.com/russross/meddler/README.md | 372 -- vendor/github.com/russross/meddler/doc.go | 16 - vendor/github.com/russross/meddler/go.mod | 5 - vendor/github.com/russross/meddler/go.sum | 2 - .../github.com/russross/meddler/loadsave.go | 247 - vendor/github.com/russross/meddler/mapper.go | 33 - vendor/github.com/russross/meddler/meddler.go | 368 -- vendor/github.com/russross/meddler/scan.go | 580 -- vendor/github.com/syndtr/goleveldb/LICENSE | 24 + .../syndtr/goleveldb/leveldb/batch.go | 349 ++ .../syndtr/goleveldb/leveldb/cache/cache.go | 704 +++ .../syndtr/goleveldb/leveldb/cache/lru.go | 195 + .../syndtr/goleveldb/leveldb/comparer.go | 67 + .../leveldb/comparer/bytes_comparer.go | 51 + .../goleveldb/leveldb/comparer/comparer.go | 57 + .../github.com/syndtr/goleveldb/leveldb/db.go | 1179 ++++ .../syndtr/goleveldb/leveldb/db_compaction.go | 854 +++ .../syndtr/goleveldb/leveldb/db_iter.go | 360 ++ .../syndtr/goleveldb/leveldb/db_snapshot.go | 187 + .../syndtr/goleveldb/leveldb/db_state.go | 239 + .../goleveldb/leveldb/db_transaction.go | 329 ++ .../syndtr/goleveldb/leveldb/db_util.go | 102 + .../syndtr/goleveldb/leveldb/db_write.go | 464 ++ .../syndtr/goleveldb/leveldb/doc.go | 92 + .../syndtr/goleveldb/leveldb/errors.go | 20 + .../syndtr/goleveldb/leveldb/errors/errors.go | 78 + .../syndtr/goleveldb/leveldb/filter.go | 31 + .../syndtr/goleveldb/leveldb/filter/bloom.go | 116 + .../syndtr/goleveldb/leveldb/filter/filter.go | 60 + .../goleveldb/leveldb/iterator/array_iter.go | 184 + .../leveldb/iterator/indexed_iter.go | 242 + .../syndtr/goleveldb/leveldb/iterator/iter.go | 132 + .../goleveldb/leveldb/iterator/merged_iter.go | 304 + .../goleveldb/leveldb/journal/journal.go | 524 ++ .../syndtr/goleveldb/leveldb/key.go | 143 + .../syndtr/goleveldb/leveldb/memdb/memdb.go | 479 ++ .../syndtr/goleveldb/leveldb/opt/options.go | 697 +++ .../syndtr/goleveldb/leveldb/options.go | 107 + .../syndtr/goleveldb/leveldb/session.go | 210 + .../goleveldb/leveldb/session_compaction.go | 302 + .../goleveldb/leveldb/session_record.go | 323 ++ .../syndtr/goleveldb/leveldb/session_util.go | 271 + .../syndtr/goleveldb/leveldb/storage.go | 63 + .../goleveldb/leveldb/storage/file_storage.go | 671 +++ .../leveldb/storage/file_storage_nacl.go | 34 + .../leveldb/storage/file_storage_plan9.go | 63 + .../leveldb/storage/file_storage_solaris.go | 81 + .../leveldb/storage/file_storage_unix.go | 98 + .../leveldb/storage/file_storage_windows.go | 78 + .../goleveldb/leveldb/storage/mem_storage.go | 222 + .../goleveldb/leveldb/storage/storage.go | 187 + .../syndtr/goleveldb/leveldb/table.go | 531 ++ .../syndtr/goleveldb/leveldb/table/reader.go | 1139 ++++ .../syndtr/goleveldb/leveldb/table/table.go | 177 + .../syndtr/goleveldb/leveldb/table/writer.go | 375 ++ .../syndtr/goleveldb/leveldb/util.go | 98 + .../syndtr/goleveldb/leveldb/util/buffer.go | 293 + .../goleveldb/leveldb/util/buffer_pool.go | 239 + .../syndtr/goleveldb/leveldb/util/crc32.go | 30 + .../syndtr/goleveldb/leveldb/util/hash.go | 48 + .../syndtr/goleveldb/leveldb/util/range.go | 32 + .../syndtr/goleveldb/leveldb/util/util.go | 73 + .../syndtr/goleveldb/leveldb/version.go | 528 ++ vendor/github.com/urfave/cli/.flake8 | 2 - vendor/github.com/urfave/cli/.gitignore | 4 - .../github.com/urfave/cli/CODE_OF_CONDUCT.md | 74 - vendor/github.com/urfave/cli/README.md | 70 - vendor/github.com/urfave/cli/app.go | 531 -- vendor/github.com/urfave/cli/appveyor.yml | 28 - vendor/github.com/urfave/cli/category.go | 44 - vendor/github.com/urfave/cli/cli.go | 22 - vendor/github.com/urfave/cli/command.go | 378 -- vendor/github.com/urfave/cli/context.go | 348 -- vendor/github.com/urfave/cli/docs.go | 148 - vendor/github.com/urfave/cli/errors.go | 115 - vendor/github.com/urfave/cli/fish.go | 194 - vendor/github.com/urfave/cli/flag.go | 346 -- vendor/github.com/urfave/cli/flag_bool.go | 109 - vendor/github.com/urfave/cli/flag_bool_t.go | 110 - vendor/github.com/urfave/cli/flag_duration.go | 106 - vendor/github.com/urfave/cli/flag_float64.go | 106 - vendor/github.com/urfave/cli/flag_generic.go | 110 - vendor/github.com/urfave/cli/flag_int.go | 105 - vendor/github.com/urfave/cli/flag_int64.go | 106 - .../github.com/urfave/cli/flag_int64_slice.go | 199 - .../github.com/urfave/cli/flag_int_slice.go | 198 - vendor/github.com/urfave/cli/flag_string.go | 98 - .../urfave/cli/flag_string_slice.go | 184 - vendor/github.com/urfave/cli/flag_uint.go | 106 - vendor/github.com/urfave/cli/flag_uint64.go | 106 - vendor/github.com/urfave/cli/funcs.go | 44 - vendor/github.com/urfave/cli/go.mod | 9 - vendor/github.com/urfave/cli/go.sum | 14 - vendor/github.com/urfave/cli/help.go | 363 -- vendor/github.com/urfave/cli/parse.go | 94 - vendor/github.com/urfave/cli/sort.go | 29 - vendor/github.com/urfave/cli/template.go | 121 - .../github.com/woodpecker-ci/togo/.gitignore | 1 - .../github.com/woodpecker-ci/togo/README.md | 35 - .../woodpecker-ci/togo/action_ddl.go | 104 - .../woodpecker-ci/togo/action_http.go | 144 - .../woodpecker-ci/togo/action_httptest.go | 174 - .../woodpecker-ci/togo/action_i18n.go | 90 - .../woodpecker-ci/togo/action_sql.go | 78 - .../woodpecker-ci/togo/action_tmpl.go | 103 - vendor/github.com/woodpecker-ci/togo/go.mod | 10 - vendor/github.com/woodpecker-ci/togo/go.sum | 25 - vendor/github.com/woodpecker-ci/togo/main.go | 28 - .../woodpecker-ci/togo/parser/parser.go | 83 - .../woodpecker-ci/togo/template/format.go | 20 - .../woodpecker-ci/togo/template/funcs.go | 48 - .../woodpecker-ci/togo/template/template.go | 61 - .../togo/template/template_gen.go | 770 --- vendor/modules.txt | 70 +- vendor/xorm.io/builder/.drone.yml | 21 + vendor/xorm.io/builder/.gitignore | 1 + vendor/xorm.io/builder/LICENSE | 27 + vendor/xorm.io/builder/README.md | 206 + vendor/xorm.io/builder/builder.go | 321 ++ vendor/xorm.io/builder/builder_delete.go | 27 + vendor/xorm.io/builder/builder_insert.go | 149 + vendor/xorm.io/builder/builder_join.go | 42 + vendor/xorm.io/builder/builder_limit.go | 103 + vendor/xorm.io/builder/builder_select.go | 158 + .../xorm.io/builder/builder_set_operations.go | 51 + vendor/xorm.io/builder/builder_update.go | 57 + vendor/xorm.io/builder/cond.go | 38 + vendor/xorm.io/builder/cond_and.go | 61 + vendor/xorm.io/builder/cond_between.go | 65 + vendor/xorm.io/builder/cond_compare.go | 160 + vendor/xorm.io/builder/cond_eq.go | 117 + vendor/xorm.io/builder/cond_expr.go | 43 + vendor/xorm.io/builder/cond_if.go | 49 + vendor/xorm.io/builder/cond_in.go | 237 + vendor/xorm.io/builder/cond_like.go | 41 + vendor/xorm.io/builder/cond_neq.go | 94 + vendor/xorm.io/builder/cond_not.go | 77 + vendor/xorm.io/builder/cond_notin.go | 234 + vendor/xorm.io/builder/cond_null.go | 59 + vendor/xorm.io/builder/cond_or.go | 69 + vendor/xorm.io/builder/doc.go | 120 + vendor/xorm.io/builder/error.go | 40 + vendor/xorm.io/builder/go.mod | 8 + vendor/xorm.io/builder/go.sum | 9 + vendor/xorm.io/builder/sql.go | 168 + vendor/xorm.io/builder/writer.go | 42 + vendor/xorm.io/xorm/.changelog.yml | 53 + vendor/xorm.io/xorm/.drone.yml | 401 ++ vendor/xorm.io/xorm/.gitignore | 40 + vendor/xorm.io/xorm/.revive.toml | 29 + vendor/xorm.io/xorm/CHANGELOG.md | 344 ++ vendor/xorm.io/xorm/CONTRIBUTING.md | 87 + vendor/xorm.io/xorm/LICENSE | 27 + vendor/xorm.io/xorm/Makefile | 258 + vendor/xorm.io/xorm/README.md | 488 ++ vendor/xorm.io/xorm/README_CN.md | 480 ++ vendor/xorm.io/xorm/caches/cache.go | 99 + vendor/xorm.io/xorm/caches/encode.go | 65 + vendor/xorm.io/xorm/caches/leveldb.go | 99 + vendor/xorm.io/xorm/caches/lru.go | 282 + vendor/xorm.io/xorm/caches/manager.go | 60 + vendor/xorm.io/xorm/caches/memory_store.go | 49 + vendor/xorm.io/xorm/contexts/context_cache.go | 30 + vendor/xorm.io/xorm/contexts/hook.go | 81 + vendor/xorm.io/xorm/convert/bool.go | 51 + vendor/xorm.io/xorm/convert/conversion.go | 391 ++ vendor/xorm.io/xorm/convert/float.go | 142 + vendor/xorm.io/xorm/convert/int.go | 178 + vendor/xorm.io/xorm/convert/interface.go | 49 + vendor/xorm.io/xorm/convert/scanner.go | 19 + vendor/xorm.io/xorm/convert/string.go | 75 + vendor/xorm.io/xorm/convert/time.go | 117 + vendor/xorm.io/xorm/core/db.go | 308 + vendor/xorm.io/xorm/core/error.go | 14 + vendor/xorm.io/xorm/core/interface.go | 22 + vendor/xorm.io/xorm/core/rows.go | 346 ++ vendor/xorm.io/xorm/core/scan.go | 70 + vendor/xorm.io/xorm/core/stmt.go | 213 + vendor/xorm.io/xorm/core/tx.go | 238 + vendor/xorm.io/xorm/dialects/dialect.go | 330 ++ vendor/xorm.io/xorm/dialects/driver.go | 85 + vendor/xorm.io/xorm/dialects/filter.go | 76 + vendor/xorm.io/xorm/dialects/gen_reserved.sh | 6 + vendor/xorm.io/xorm/dialects/mssql.go | 727 +++ vendor/xorm.io/xorm/dialects/mysql.go | 814 +++ vendor/xorm.io/xorm/dialects/oracle.go | 928 +++ vendor/xorm.io/xorm/dialects/pg_reserved.txt | 746 +++ vendor/xorm.io/xorm/dialects/postgres.go | 1495 +++++ vendor/xorm.io/xorm/dialects/quote.go | 15 + vendor/xorm.io/xorm/dialects/sqlite3.go | 572 ++ vendor/xorm.io/xorm/dialects/table_name.go | 89 + vendor/xorm.io/xorm/dialects/time.go | 61 + vendor/xorm.io/xorm/doc.go | 234 + vendor/xorm.io/xorm/engine.go | 1328 +++++ vendor/xorm.io/xorm/engine_group.go | 267 + vendor/xorm.io/xorm/engine_group_policy.go | 118 + vendor/xorm.io/xorm/error.go | 26 + vendor/xorm.io/xorm/go.mod | 19 + vendor/xorm.io/xorm/go.sum | 573 ++ vendor/xorm.io/xorm/interface.go | 133 + vendor/xorm.io/xorm/internal/json/gojson.go | 28 + vendor/xorm.io/xorm/internal/json/json.go | 31 + vendor/xorm.io/xorm/internal/json/jsoniter.go | 28 + .../xorm.io/xorm/internal/statements/cache.go | 81 + .../xorm/internal/statements/column_map.go | 66 + .../xorm.io/xorm/internal/statements/expr.go | 94 + .../xorm/internal/statements/insert.go | 260 + vendor/xorm.io/xorm/internal/statements/pk.go | 98 + .../xorm.io/xorm/internal/statements/query.go | 462 ++ .../xorm/internal/statements/statement.go | 1032 ++++ .../internal/statements/statement_args.go | 134 + .../xorm/internal/statements/update.go | 308 + .../xorm/internal/statements/values.go | 171 + vendor/xorm.io/xorm/internal/utils/name.go | 14 + vendor/xorm.io/xorm/internal/utils/new.go | 25 + vendor/xorm.io/xorm/internal/utils/reflect.go | 14 + vendor/xorm.io/xorm/internal/utils/slice.go | 22 + vendor/xorm.io/xorm/internal/utils/sql.go | 20 + vendor/xorm.io/xorm/internal/utils/strings.go | 32 + vendor/xorm.io/xorm/internal/utils/zero.go | 151 + vendor/xorm.io/xorm/log/logger.go | 208 + vendor/xorm.io/xorm/log/logger_context.go | 116 + vendor/xorm.io/xorm/log/syslogger.go | 87 + vendor/xorm.io/xorm/names/mapper.go | 281 + vendor/xorm.io/xorm/names/table_name.go | 57 + vendor/xorm.io/xorm/processors.go | 144 + vendor/xorm.io/xorm/rows.go | 149 + vendor/xorm.io/xorm/scan.go | 320 ++ vendor/xorm.io/xorm/schemas/column.go | 110 + vendor/xorm.io/xorm/schemas/index.go | 72 + vendor/xorm.io/xorm/schemas/pk.go | 46 + vendor/xorm.io/xorm/schemas/quote.go | 242 + vendor/xorm.io/xorm/schemas/table.go | 178 + vendor/xorm.io/xorm/schemas/type.go | 353 ++ vendor/xorm.io/xorm/schemas/version.go | 12 + vendor/xorm.io/xorm/session.go | 745 +++ vendor/xorm.io/xorm/session_cols.go | 143 + vendor/xorm.io/xorm/session_cond.go | 55 + vendor/xorm.io/xorm/session_delete.go | 268 + vendor/xorm.io/xorm/session_exist.go | 32 + vendor/xorm.io/xorm/session_find.go | 482 ++ vendor/xorm.io/xorm/session_get.go | 376 ++ vendor/xorm.io/xorm/session_insert.go | 671 +++ vendor/xorm.io/xorm/session_iterate.go | 105 + vendor/xorm.io/xorm/session_query.go | 154 + vendor/xorm.io/xorm/session_raw.go | 128 + vendor/xorm.io/xorm/session_schema.go | 508 ++ vendor/xorm.io/xorm/session_stats.go | 81 + vendor/xorm.io/xorm/session_tx.go | 91 + vendor/xorm.io/xorm/session_update.go | 551 ++ vendor/xorm.io/xorm/tags/parser.go | 332 ++ vendor/xorm.io/xorm/tags/tag.go | 400 ++ 582 files changed, 81745 insertions(+), 17600 deletions(-) rename server/model/{build_test.go => agent.go} (51%) rename server/{store/datastore/ddl/mysql/ddl.go => model/log.go} (74%) create mode 100644 server/model/task.go rename server/store/{datastore/sql/mysql/sql.go => common.go} (78%) create mode 100644 server/store/datastore/build.go rename server/store/datastore/{builds_test.go => build_test.go} (72%) delete mode 100644 server/store/datastore/builds.go delete mode 100644 server/store/datastore/ddl/migrate.go delete mode 100644 server/store/datastore/ddl/mysql/ddl_gen.go delete mode 100644 server/store/datastore/ddl/mysql/files/001_create_table_users.sql delete mode 100644 server/store/datastore/ddl/mysql/files/002_create_table_repos.sql delete mode 100644 server/store/datastore/ddl/mysql/files/003_create_table_builds.sql delete mode 100644 server/store/datastore/ddl/mysql/files/004_create_table_procs.sql delete mode 100644 server/store/datastore/ddl/mysql/files/005_create_table_logs.sql delete mode 100644 server/store/datastore/ddl/mysql/files/006_create_table_files.sql delete mode 100644 server/store/datastore/ddl/mysql/files/007_create_table_secets.sql delete mode 100644 server/store/datastore/ddl/mysql/files/008_create_table_registry.sql delete mode 100644 server/store/datastore/ddl/mysql/files/009_create_table_config.sql delete mode 100644 server/store/datastore/ddl/mysql/files/010_create_table_tasks.sql delete mode 100644 server/store/datastore/ddl/mysql/files/011_create_table_agents.sql delete mode 100644 server/store/datastore/ddl/mysql/files/012_create_table_senders.sql delete mode 100644 server/store/datastore/ddl/mysql/files/013_add_column_repo_visibility.sql delete mode 100644 server/store/datastore/ddl/mysql/files/014_add_column_repo_seq.sql delete mode 100644 server/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql delete mode 100644 server/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql delete mode 100644 server/store/datastore/ddl/mysql/files/017_create_table_perms.sql delete mode 100644 server/store/datastore/ddl/mysql/files/018_add_column_file_pid.sql delete mode 100644 server/store/datastore/ddl/mysql/files/019_create_table_build_config.sql delete mode 100644 server/store/datastore/ddl/mysql/files/020_add_column_config_name.sql delete mode 100644 server/store/datastore/ddl/mysql/files/021_populate_build_config.sql delete mode 100644 server/store/datastore/ddl/mysql/files/022_add_task_columns.sql delete mode 100644 server/store/datastore/ddl/mysql/files/023_add_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/mysql/files/024_add_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/mysql/files/025_add_builds_changed_files_column.sql delete mode 100644 server/store/datastore/ddl/mysql/files/026_drop_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/mysql/files/027_drop_allow_push_tags_deployments_columns.sql delete mode 100644 server/store/datastore/ddl/mysql/files/028_update_table_set_users_token_and_secret_length.sql delete mode 100644 server/store/datastore/ddl/postgres/ddl_gen.go delete mode 100644 server/store/datastore/ddl/postgres/files/001_create_table_users.sql delete mode 100644 server/store/datastore/ddl/postgres/files/002_create_table_repos.sql delete mode 100644 server/store/datastore/ddl/postgres/files/003_create_table_builds.sql delete mode 100644 server/store/datastore/ddl/postgres/files/004_create_table_procs.sql delete mode 100644 server/store/datastore/ddl/postgres/files/005_create_table_logs.sql delete mode 100644 server/store/datastore/ddl/postgres/files/006_create_table_files.sql delete mode 100644 server/store/datastore/ddl/postgres/files/007_create_table_secets.sql delete mode 100644 server/store/datastore/ddl/postgres/files/008_create_table_registry.sql delete mode 100644 server/store/datastore/ddl/postgres/files/009_create_table_config.sql delete mode 100644 server/store/datastore/ddl/postgres/files/010_create_table_tasks.sql delete mode 100644 server/store/datastore/ddl/postgres/files/011_create_table_agents.sql delete mode 100644 server/store/datastore/ddl/postgres/files/012_create_table_senders.sql delete mode 100644 server/store/datastore/ddl/postgres/files/013_add_column_repo_visibility.sql delete mode 100644 server/store/datastore/ddl/postgres/files/014_add_column_repo_seq.sql delete mode 100644 server/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql delete mode 100644 server/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql delete mode 100644 server/store/datastore/ddl/postgres/files/017_create_table_perms.sql delete mode 100644 server/store/datastore/ddl/postgres/files/018_add_column_file_pid.sql delete mode 100644 server/store/datastore/ddl/postgres/files/019_create_table_build_config.sql delete mode 100644 server/store/datastore/ddl/postgres/files/020_add_column_config_name.sql delete mode 100644 server/store/datastore/ddl/postgres/files/021_populate_build_config.sql delete mode 100644 server/store/datastore/ddl/postgres/files/022_add_task_columns.sql delete mode 100644 server/store/datastore/ddl/postgres/files/023_add_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/postgres/files/024_add_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/postgres/files/025_add_builds_changed_files_column.sql delete mode 100644 server/store/datastore/ddl/postgres/files/026_drop_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/postgres/files/027_drop_allow_push_tags_deployments_columns.sql delete mode 100644 server/store/datastore/ddl/postgres/files/028_update_table_set_users_token_and_secret_length.sql delete mode 100644 server/store/datastore/ddl/sqlite/ddl_gen.go delete mode 100644 server/store/datastore/ddl/sqlite/files/001_create_table_users.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/002_create_table_repos.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/003_create_table_builds.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/004_create_table_procs.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/005_create_table_logs.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/006_create_table_files.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/007_create_table_secets.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/008_create_table_registry.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/009_create_table_config.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/010_create_table_tasks.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/011_create_table_agents.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/012_create_table_senders.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/013_add_column_repo_visibility.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/014_add_column_repo_seq.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/015_add_column_repo_active.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/016_add_column_user_synced.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/017_create_table_perms.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/018_add_column_file_pid.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/019_create_table_build_config.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/020_add_column_config_name.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/021_populate_build_config.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/022_add_task_columns.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/023_add_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/024_add_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/025_add_builds_changed_files_column.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/026_drop_repo_fallback_column.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/027_drop_allow_push_tags_deployments_columns.sql delete mode 100644 server/store/datastore/ddl/sqlite/files/028_update_table_set_users_token_and_secret_length.sql create mode 100644 server/store/datastore/engine.go rename server/store/datastore/{store_test.go => engine_test.go} (60%) create mode 100644 server/store/datastore/feed.go create mode 100644 server/store/datastore/feed_test.go create mode 100644 server/store/datastore/file.go rename server/store/datastore/{files_test.go => file_test.go} (62%) delete mode 100644 server/store/datastore/files.go rename server/store/datastore/{ddl/sqlite/ddl.go => helper.go} (63%) create mode 100644 server/store/datastore/log.go rename server/store/datastore/{logs_test.go => log_test.go} (83%) delete mode 100644 server/store/datastore/logs.go create mode 100644 server/store/datastore/migration/000_legacy_to_xorm.go rename server/store/datastore/{ddl/postgres/ddl.go => migration/001_repos_drop_fallback.go} (67%) create mode 100644 server/store/datastore/migration/002_repos_drop_allow_deploys_allow_tags.go create mode 100644 server/store/datastore/migration/common.go create mode 100644 server/store/datastore/migration/migration.go create mode 100644 server/store/datastore/permission.go rename server/store/datastore/{perms_test.go => permission_test.go} (80%) delete mode 100644 server/store/datastore/perms.go create mode 100644 server/store/datastore/proc.go rename server/store/datastore/{procs_test.go => proc_test.go} (62%) delete mode 100644 server/store/datastore/procs.go create mode 100644 server/store/datastore/repo.go rename server/store/datastore/{repos_test.go => repo_test.go} (57%) delete mode 100644 server/store/datastore/repos.go delete mode 100644 server/store/datastore/sql/lookup.go delete mode 100644 server/store/datastore/sql/mysql/files/config.sql delete mode 100644 server/store/datastore/sql/mysql/files/counts.sql delete mode 100644 server/store/datastore/sql/mysql/files/feed.sql delete mode 100644 server/store/datastore/sql/mysql/files/files.sql delete mode 100644 server/store/datastore/sql/mysql/files/logs.sql delete mode 100644 server/store/datastore/sql/mysql/files/perms.sql delete mode 100644 server/store/datastore/sql/mysql/files/procs.sql delete mode 100644 server/store/datastore/sql/mysql/files/registry.sql delete mode 100644 server/store/datastore/sql/mysql/files/repos.sql delete mode 100644 server/store/datastore/sql/mysql/files/secret.sql delete mode 100644 server/store/datastore/sql/mysql/files/sender.sql delete mode 100644 server/store/datastore/sql/mysql/files/task.sql delete mode 100644 server/store/datastore/sql/mysql/files/users.sql delete mode 100644 server/store/datastore/sql/mysql/sql_gen.go delete mode 100644 server/store/datastore/sql/postgres/files/config.sql delete mode 100644 server/store/datastore/sql/postgres/files/counts.sql delete mode 100644 server/store/datastore/sql/postgres/files/feed.sql delete mode 100644 server/store/datastore/sql/postgres/files/files.sql delete mode 100644 server/store/datastore/sql/postgres/files/logs.sql delete mode 100644 server/store/datastore/sql/postgres/files/perms.sql delete mode 100644 server/store/datastore/sql/postgres/files/procs.sql delete mode 100644 server/store/datastore/sql/postgres/files/registry.sql delete mode 100644 server/store/datastore/sql/postgres/files/repos.sql delete mode 100644 server/store/datastore/sql/postgres/files/secret.sql delete mode 100644 server/store/datastore/sql/postgres/files/sender.sql delete mode 100644 server/store/datastore/sql/postgres/files/tasks.sql delete mode 100644 server/store/datastore/sql/postgres/files/users.sql delete mode 100644 server/store/datastore/sql/postgres/sql.go delete mode 100644 server/store/datastore/sql/postgres/sql_gen.go delete mode 100644 server/store/datastore/sql/sqlite/files/config.sql delete mode 100644 server/store/datastore/sql/sqlite/files/counts.sql delete mode 100644 server/store/datastore/sql/sqlite/files/feed.sql delete mode 100644 server/store/datastore/sql/sqlite/files/files.sql delete mode 100644 server/store/datastore/sql/sqlite/files/logs.sql delete mode 100644 server/store/datastore/sql/sqlite/files/perms.sql delete mode 100644 server/store/datastore/sql/sqlite/files/procs.sql delete mode 100644 server/store/datastore/sql/sqlite/files/registry.sql delete mode 100644 server/store/datastore/sql/sqlite/files/repos.sql delete mode 100644 server/store/datastore/sql/sqlite/files/secret.sql delete mode 100644 server/store/datastore/sql/sqlite/files/sender.sql delete mode 100644 server/store/datastore/sql/sqlite/files/task.sql delete mode 100644 server/store/datastore/sql/sqlite/files/user.sql delete mode 100644 server/store/datastore/sql/sqlite/sql.go delete mode 100644 server/store/datastore/sql/sqlite/sql_gen.go delete mode 100644 server/store/datastore/store.go create mode 100644 server/store/datastore/user.go delete mode 100644 server/store/datastore/users.go delete mode 100644 server/store/datastore/utils.go create mode 100644 vendor/github.com/goccy/go-json/.codecov.yml create mode 100644 vendor/github.com/goccy/go-json/.gitignore create mode 100644 vendor/github.com/goccy/go-json/.golangci.yml create mode 100644 vendor/github.com/goccy/go-json/CHANGELOG.md rename vendor/github.com/{urfave/cli => goccy/go-json}/LICENSE (95%) create mode 100644 vendor/github.com/goccy/go-json/Makefile create mode 100644 vendor/github.com/goccy/go-json/README.md create mode 100644 vendor/github.com/goccy/go-json/color.go create mode 100644 vendor/github.com/goccy/go-json/decode.go create mode 100644 vendor/github.com/goccy/go-json/encode.go create mode 100644 vendor/github.com/goccy/go-json/error.go create mode 100644 vendor/github.com/goccy/go-json/go.mod create mode 100644 vendor/github.com/goccy/go-json/go.sum create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/array.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bool.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/bytes.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/compile_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/float.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/func.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/interface.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/map.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/number.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/ptr.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/slice.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/stream.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/struct.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/type.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/uint.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go create mode 100644 vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compact.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/context.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/encoder.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/indent.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/int.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map112.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/map113.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/opcode.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/option.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/optype.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/string.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go create mode 100644 vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go create mode 100644 vendor/github.com/goccy/go-json/internal/errors/error.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/rtype.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/struct_field.go create mode 100644 vendor/github.com/goccy/go-json/internal/runtime/type.go create mode 100644 vendor/github.com/goccy/go-json/json.go create mode 100644 vendor/github.com/goccy/go-json/option.go create mode 100644 vendor/github.com/golang/snappy/.gitignore create mode 100644 vendor/github.com/golang/snappy/AUTHORS create mode 100644 vendor/github.com/golang/snappy/CONTRIBUTORS create mode 100644 vendor/github.com/golang/snappy/LICENSE create mode 100644 vendor/github.com/golang/snappy/README create mode 100644 vendor/github.com/golang/snappy/decode.go create mode 100644 vendor/github.com/golang/snappy/decode_amd64.go create mode 100644 vendor/github.com/golang/snappy/decode_amd64.s create mode 100644 vendor/github.com/golang/snappy/decode_other.go create mode 100644 vendor/github.com/golang/snappy/encode.go create mode 100644 vendor/github.com/golang/snappy/encode_amd64.go create mode 100644 vendor/github.com/golang/snappy/encode_amd64.s create mode 100644 vendor/github.com/golang/snappy/encode_other.go create mode 100644 vendor/github.com/golang/snappy/snappy.go delete mode 100644 vendor/github.com/hashicorp/go-version/CHANGELOG.md create mode 100644 vendor/github.com/mattn/go-isatty/.travis.yml create mode 100644 vendor/github.com/mattn/go-isatty/renovate.json delete mode 100644 vendor/github.com/modern-go/reflect2/go.mod delete mode 100644 vendor/github.com/modern-go/reflect2/go_above_118.go create mode 100644 vendor/github.com/modern-go/reflect2/go_above_17.go delete mode 100644 vendor/github.com/modern-go/reflect2/go_below_118.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_17.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_19.go create mode 100644 vendor/github.com/modern-go/reflect2/test.sh delete mode 100644 vendor/github.com/russross/meddler/.gitignore delete mode 100644 vendor/github.com/russross/meddler/.travis.yml delete mode 100644 vendor/github.com/russross/meddler/LICENSE delete mode 100644 vendor/github.com/russross/meddler/README.md delete mode 100644 vendor/github.com/russross/meddler/doc.go delete mode 100644 vendor/github.com/russross/meddler/go.mod delete mode 100644 vendor/github.com/russross/meddler/go.sum delete mode 100644 vendor/github.com/russross/meddler/loadsave.go delete mode 100644 vendor/github.com/russross/meddler/mapper.go delete mode 100644 vendor/github.com/russross/meddler/meddler.go delete mode 100644 vendor/github.com/russross/meddler/scan.go create mode 100644 vendor/github.com/syndtr/goleveldb/LICENSE create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/batch.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/cache/cache.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/cache/lru.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/comparer.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/comparer/bytes_comparer.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/comparer/comparer.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_compaction.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_iter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_snapshot.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_state.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_transaction.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_util.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/db_write.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/doc.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/errors.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/errors/errors.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/filter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/filter/bloom.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/filter/filter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/iterator/array_iter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/iterator/indexed_iter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/iterator/iter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/iterator/merged_iter.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/journal/journal.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/key.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/opt/options.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/options.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/session.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/session_compaction.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/session_record.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/session_util.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_nacl.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_plan9.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_solaris.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/file_storage_windows.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/mem_storage.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/storage/storage.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/table.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/table/reader.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/table/table.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/table/writer.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util/buffer.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util/buffer_pool.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util/crc32.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util/hash.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util/range.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/util/util.go create mode 100644 vendor/github.com/syndtr/goleveldb/leveldb/version.go delete mode 100644 vendor/github.com/urfave/cli/.flake8 delete mode 100644 vendor/github.com/urfave/cli/.gitignore delete mode 100644 vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md delete mode 100644 vendor/github.com/urfave/cli/README.md delete mode 100644 vendor/github.com/urfave/cli/app.go delete mode 100644 vendor/github.com/urfave/cli/appveyor.yml delete mode 100644 vendor/github.com/urfave/cli/category.go delete mode 100644 vendor/github.com/urfave/cli/cli.go delete mode 100644 vendor/github.com/urfave/cli/command.go delete mode 100644 vendor/github.com/urfave/cli/context.go delete mode 100644 vendor/github.com/urfave/cli/docs.go delete mode 100644 vendor/github.com/urfave/cli/errors.go delete mode 100644 vendor/github.com/urfave/cli/fish.go delete mode 100644 vendor/github.com/urfave/cli/flag.go delete mode 100644 vendor/github.com/urfave/cli/flag_bool.go delete mode 100644 vendor/github.com/urfave/cli/flag_bool_t.go delete mode 100644 vendor/github.com/urfave/cli/flag_duration.go delete mode 100644 vendor/github.com/urfave/cli/flag_float64.go delete mode 100644 vendor/github.com/urfave/cli/flag_generic.go delete mode 100644 vendor/github.com/urfave/cli/flag_int.go delete mode 100644 vendor/github.com/urfave/cli/flag_int64.go delete mode 100644 vendor/github.com/urfave/cli/flag_int64_slice.go delete mode 100644 vendor/github.com/urfave/cli/flag_int_slice.go delete mode 100644 vendor/github.com/urfave/cli/flag_string.go delete mode 100644 vendor/github.com/urfave/cli/flag_string_slice.go delete mode 100644 vendor/github.com/urfave/cli/flag_uint.go delete mode 100644 vendor/github.com/urfave/cli/flag_uint64.go delete mode 100644 vendor/github.com/urfave/cli/funcs.go delete mode 100644 vendor/github.com/urfave/cli/go.mod delete mode 100644 vendor/github.com/urfave/cli/go.sum delete mode 100644 vendor/github.com/urfave/cli/help.go delete mode 100644 vendor/github.com/urfave/cli/parse.go delete mode 100644 vendor/github.com/urfave/cli/sort.go delete mode 100644 vendor/github.com/urfave/cli/template.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/.gitignore delete mode 100644 vendor/github.com/woodpecker-ci/togo/README.md delete mode 100644 vendor/github.com/woodpecker-ci/togo/action_ddl.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/action_http.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/action_httptest.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/action_i18n.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/action_sql.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/action_tmpl.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/go.mod delete mode 100644 vendor/github.com/woodpecker-ci/togo/go.sum delete mode 100644 vendor/github.com/woodpecker-ci/togo/main.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/parser/parser.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/template/format.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/template/funcs.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/template/template.go delete mode 100644 vendor/github.com/woodpecker-ci/togo/template/template_gen.go create mode 100644 vendor/xorm.io/builder/.drone.yml create mode 100644 vendor/xorm.io/builder/.gitignore create mode 100644 vendor/xorm.io/builder/LICENSE create mode 100644 vendor/xorm.io/builder/README.md create mode 100644 vendor/xorm.io/builder/builder.go create mode 100644 vendor/xorm.io/builder/builder_delete.go create mode 100644 vendor/xorm.io/builder/builder_insert.go create mode 100644 vendor/xorm.io/builder/builder_join.go create mode 100644 vendor/xorm.io/builder/builder_limit.go create mode 100644 vendor/xorm.io/builder/builder_select.go create mode 100644 vendor/xorm.io/builder/builder_set_operations.go create mode 100644 vendor/xorm.io/builder/builder_update.go create mode 100644 vendor/xorm.io/builder/cond.go create mode 100644 vendor/xorm.io/builder/cond_and.go create mode 100644 vendor/xorm.io/builder/cond_between.go create mode 100644 vendor/xorm.io/builder/cond_compare.go create mode 100644 vendor/xorm.io/builder/cond_eq.go create mode 100644 vendor/xorm.io/builder/cond_expr.go create mode 100644 vendor/xorm.io/builder/cond_if.go create mode 100644 vendor/xorm.io/builder/cond_in.go create mode 100644 vendor/xorm.io/builder/cond_like.go create mode 100644 vendor/xorm.io/builder/cond_neq.go create mode 100644 vendor/xorm.io/builder/cond_not.go create mode 100644 vendor/xorm.io/builder/cond_notin.go create mode 100644 vendor/xorm.io/builder/cond_null.go create mode 100644 vendor/xorm.io/builder/cond_or.go create mode 100644 vendor/xorm.io/builder/doc.go create mode 100644 vendor/xorm.io/builder/error.go create mode 100644 vendor/xorm.io/builder/go.mod create mode 100644 vendor/xorm.io/builder/go.sum create mode 100644 vendor/xorm.io/builder/sql.go create mode 100644 vendor/xorm.io/builder/writer.go create mode 100644 vendor/xorm.io/xorm/.changelog.yml create mode 100644 vendor/xorm.io/xorm/.drone.yml create mode 100644 vendor/xorm.io/xorm/.gitignore create mode 100644 vendor/xorm.io/xorm/.revive.toml create mode 100644 vendor/xorm.io/xorm/CHANGELOG.md create mode 100644 vendor/xorm.io/xorm/CONTRIBUTING.md create mode 100644 vendor/xorm.io/xorm/LICENSE create mode 100644 vendor/xorm.io/xorm/Makefile create mode 100644 vendor/xorm.io/xorm/README.md create mode 100644 vendor/xorm.io/xorm/README_CN.md create mode 100644 vendor/xorm.io/xorm/caches/cache.go create mode 100644 vendor/xorm.io/xorm/caches/encode.go create mode 100644 vendor/xorm.io/xorm/caches/leveldb.go create mode 100644 vendor/xorm.io/xorm/caches/lru.go create mode 100644 vendor/xorm.io/xorm/caches/manager.go create mode 100644 vendor/xorm.io/xorm/caches/memory_store.go create mode 100644 vendor/xorm.io/xorm/contexts/context_cache.go create mode 100644 vendor/xorm.io/xorm/contexts/hook.go create mode 100644 vendor/xorm.io/xorm/convert/bool.go create mode 100644 vendor/xorm.io/xorm/convert/conversion.go create mode 100644 vendor/xorm.io/xorm/convert/float.go create mode 100644 vendor/xorm.io/xorm/convert/int.go create mode 100644 vendor/xorm.io/xorm/convert/interface.go create mode 100644 vendor/xorm.io/xorm/convert/scanner.go create mode 100644 vendor/xorm.io/xorm/convert/string.go create mode 100644 vendor/xorm.io/xorm/convert/time.go create mode 100644 vendor/xorm.io/xorm/core/db.go create mode 100644 vendor/xorm.io/xorm/core/error.go create mode 100644 vendor/xorm.io/xorm/core/interface.go create mode 100644 vendor/xorm.io/xorm/core/rows.go create mode 100644 vendor/xorm.io/xorm/core/scan.go create mode 100644 vendor/xorm.io/xorm/core/stmt.go create mode 100644 vendor/xorm.io/xorm/core/tx.go create mode 100644 vendor/xorm.io/xorm/dialects/dialect.go create mode 100644 vendor/xorm.io/xorm/dialects/driver.go create mode 100644 vendor/xorm.io/xorm/dialects/filter.go create mode 100644 vendor/xorm.io/xorm/dialects/gen_reserved.sh create mode 100644 vendor/xorm.io/xorm/dialects/mssql.go create mode 100644 vendor/xorm.io/xorm/dialects/mysql.go create mode 100644 vendor/xorm.io/xorm/dialects/oracle.go create mode 100644 vendor/xorm.io/xorm/dialects/pg_reserved.txt create mode 100644 vendor/xorm.io/xorm/dialects/postgres.go create mode 100644 vendor/xorm.io/xorm/dialects/quote.go create mode 100644 vendor/xorm.io/xorm/dialects/sqlite3.go create mode 100644 vendor/xorm.io/xorm/dialects/table_name.go create mode 100644 vendor/xorm.io/xorm/dialects/time.go create mode 100644 vendor/xorm.io/xorm/doc.go create mode 100644 vendor/xorm.io/xorm/engine.go create mode 100644 vendor/xorm.io/xorm/engine_group.go create mode 100644 vendor/xorm.io/xorm/engine_group_policy.go create mode 100644 vendor/xorm.io/xorm/error.go create mode 100644 vendor/xorm.io/xorm/go.mod create mode 100644 vendor/xorm.io/xorm/go.sum create mode 100644 vendor/xorm.io/xorm/interface.go create mode 100644 vendor/xorm.io/xorm/internal/json/gojson.go create mode 100644 vendor/xorm.io/xorm/internal/json/json.go create mode 100644 vendor/xorm.io/xorm/internal/json/jsoniter.go create mode 100644 vendor/xorm.io/xorm/internal/statements/cache.go create mode 100644 vendor/xorm.io/xorm/internal/statements/column_map.go create mode 100644 vendor/xorm.io/xorm/internal/statements/expr.go create mode 100644 vendor/xorm.io/xorm/internal/statements/insert.go create mode 100644 vendor/xorm.io/xorm/internal/statements/pk.go create mode 100644 vendor/xorm.io/xorm/internal/statements/query.go create mode 100644 vendor/xorm.io/xorm/internal/statements/statement.go create mode 100644 vendor/xorm.io/xorm/internal/statements/statement_args.go create mode 100644 vendor/xorm.io/xorm/internal/statements/update.go create mode 100644 vendor/xorm.io/xorm/internal/statements/values.go create mode 100644 vendor/xorm.io/xorm/internal/utils/name.go create mode 100644 vendor/xorm.io/xorm/internal/utils/new.go create mode 100644 vendor/xorm.io/xorm/internal/utils/reflect.go create mode 100644 vendor/xorm.io/xorm/internal/utils/slice.go create mode 100644 vendor/xorm.io/xorm/internal/utils/sql.go create mode 100644 vendor/xorm.io/xorm/internal/utils/strings.go create mode 100644 vendor/xorm.io/xorm/internal/utils/zero.go create mode 100644 vendor/xorm.io/xorm/log/logger.go create mode 100644 vendor/xorm.io/xorm/log/logger_context.go create mode 100644 vendor/xorm.io/xorm/log/syslogger.go create mode 100644 vendor/xorm.io/xorm/names/mapper.go create mode 100644 vendor/xorm.io/xorm/names/table_name.go create mode 100644 vendor/xorm.io/xorm/processors.go create mode 100644 vendor/xorm.io/xorm/rows.go create mode 100644 vendor/xorm.io/xorm/scan.go create mode 100644 vendor/xorm.io/xorm/schemas/column.go create mode 100644 vendor/xorm.io/xorm/schemas/index.go create mode 100644 vendor/xorm.io/xorm/schemas/pk.go create mode 100644 vendor/xorm.io/xorm/schemas/quote.go create mode 100644 vendor/xorm.io/xorm/schemas/table.go create mode 100644 vendor/xorm.io/xorm/schemas/type.go create mode 100644 vendor/xorm.io/xorm/schemas/version.go create mode 100644 vendor/xorm.io/xorm/session.go create mode 100644 vendor/xorm.io/xorm/session_cols.go create mode 100644 vendor/xorm.io/xorm/session_cond.go create mode 100644 vendor/xorm.io/xorm/session_delete.go create mode 100644 vendor/xorm.io/xorm/session_exist.go create mode 100644 vendor/xorm.io/xorm/session_find.go create mode 100644 vendor/xorm.io/xorm/session_get.go create mode 100644 vendor/xorm.io/xorm/session_insert.go create mode 100644 vendor/xorm.io/xorm/session_iterate.go create mode 100644 vendor/xorm.io/xorm/session_query.go create mode 100644 vendor/xorm.io/xorm/session_raw.go create mode 100644 vendor/xorm.io/xorm/session_schema.go create mode 100644 vendor/xorm.io/xorm/session_stats.go create mode 100644 vendor/xorm.io/xorm/session_tx.go create mode 100644 vendor/xorm.io/xorm/session_update.go create mode 100644 vendor/xorm.io/xorm/tags/parser.go create mode 100644 vendor/xorm.io/xorm/tags/tag.go diff --git a/Makefile b/Makefile index f0f71e0c7..b5432602f 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ test-lib: test: test-lib test-agent test-server build-frontend: - (cd web/; yarn; yarn build) + (cd web/; yarn install --frozen-lockfile; yarn build) build-server: build-frontend $(DOCKER_RUN) go build -o dist/woodpecker-server github.com/woodpecker-ci/woodpecker/cmd/server diff --git a/agent/runner.go b/agent/runner.go index 518843bff..43bdda012 100644 --- a/agent/runner.go +++ b/agent/runner.go @@ -60,8 +60,7 @@ func NewRunner(workEngine rpc.Peer, f rpc.Filter, h string, state *State, backen } func (r *Runner) Run(ctx context.Context) error { - log.Debug(). - Msg("request next execution") + log.Debug().Msg("request next execution") meta, _ := metadata.FromOutgoingContext(ctx) ctxmeta := metadata.NewOutgoingContext(context.Background(), meta) diff --git a/cli/exec/exec.go b/cli/exec/exec.go index 3fcff7fa6..460e526e7 100644 --- a/cli/exec/exec.go +++ b/cli/exec/exec.go @@ -188,8 +188,8 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) frontend.Metadata { Private: c.Bool("repo-private"), }, Curr: frontend.Build{ - Number: c.Int("build-number"), - Parent: c.Int("parent-build-number"), + Number: c.Int64("build-number"), + Parent: c.Int64("parent-build-number"), Created: c.Int64("build-created"), Started: c.Int64("build-started"), Finished: c.Int64("build-finished"), @@ -211,7 +211,7 @@ func metadataFromContext(c *cli.Context, axis matrix.Axis) frontend.Metadata { }, }, Prev: frontend.Build{ - Number: c.Int("prev-build-number"), + Number: c.Int64("prev-build-number"), Created: c.Int64("prev-build-created"), Started: c.Int64("prev-build-started"), Finished: c.Int64("prev-build-finished"), diff --git a/cmd/server/server.go b/cmd/server/server.go index c4dc55c07..b93bce85b 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -108,6 +108,11 @@ func loop(c *cli.Context) error { if err != nil { log.Fatal().Err(err).Msg("") } + defer func() { + if err := store_.Close(); err != nil { + log.Error().Err(err).Msg("could not close store") + } + }() setupEvilGlobals(c, store_, remote_) diff --git a/cmd/server/setup.go b/cmd/server/setup.go index 794a33165..8e2e745e8 100644 --- a/cmd/server/setup.go +++ b/cmd/server/setup.go @@ -17,7 +17,6 @@ package main import ( "fmt" "os" - "strings" "time" "github.com/gin-gonic/gin" @@ -50,7 +49,19 @@ func setupStore(c *cli.Context) (store.Store, error) { datasource := c.String("datasource") driver := c.String("driver") - if strings.ToLower(driver) == "sqlite3" { + if driver == "sqlite3" { + if datastore.SupportedDriver("sqlite3") { + log.Debug().Msgf("server has sqlite3 support") + } else { + log.Debug().Msgf("server was build with no sqlite3 support!") + } + } + + if !datastore.SupportedDriver(driver) { + log.Fatal().Msgf("database driver '%s' not supported", driver) + } + + if driver == "sqlite3" { if new, err := fallbackSqlite3File(datasource); err != nil { log.Fatal().Err(err).Msg("fallback to old sqlite3 file failed") } else { @@ -58,12 +69,21 @@ func setupStore(c *cli.Context) (store.Store, error) { } } - opts := &datastore.Opts{ + opts := &store.Opts{ Driver: driver, Config: datasource, } - log.Trace().Msgf("setup datastore: %#v", opts) - return datastore.New(opts) + log.Trace().Msgf("setup datastore: %#v", *opts) + store, err := datastore.NewEngine(opts) + if err != nil { + log.Fatal().Err(err).Msg("could not open datastore") + } + + if err := store.Migrate(); err != nil { + log.Fatal().Err(err).Msg("could not migrate datastore") + } + + return store, nil } // TODO: convert it to a check and fail hard only function in v0.16.0 to be able to remove it in v0.17.0 diff --git a/go.mod b/go.mod index f7f775e65..b60fe2098 100644 --- a/go.mod +++ b/go.mod @@ -24,16 +24,11 @@ require ( github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/golang-jwt/jwt/v4 v4.1.0 github.com/google/go-github/v39 v39.2.0 - github.com/gorilla/mux v1.7.3 // indirect github.com/gorilla/securecookie v1.1.1 github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.0 // indirect - github.com/hashicorp/go-version v1.3.0 // indirect github.com/joho/godotenv v1.4.0 - github.com/json-iterator/go v1.1.12 // indirect github.com/kr/pretty v0.3.0 github.com/lib/pq v1.10.3 - github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-sqlite3 v1.14.9 github.com/moby/moby v20.10.10+incompatible github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 @@ -41,14 +36,12 @@ require ( github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 github.com/prometheus/client_golang v1.11.0 github.com/rs/zerolog v1.25.0 - github.com/russross/meddler v1.0.1 github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/testify v1.7.0 github.com/tevino/abool v1.2.0 github.com/ugorji/go v1.2.6 // indirect github.com/urfave/cli/v2 v2.3.0 github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 - github.com/woodpecker-ci/togo v0.0.0-20211018210511-a36120f299b0 github.com/xanzy/go-gitlab v0.51.1 github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonschema v1.2.0 @@ -62,5 +55,8 @@ require ( google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca // indirect google.golang.org/grpc v1.41.0 google.golang.org/protobuf v1.27.1 + gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b + xorm.io/builder v0.3.9 + xorm.io/xorm v1.2.5 ) diff --git a/go.sum b/go.sum index 288865d1b..51c952987 100644 --- a/go.sum +++ b/go.sum @@ -35,6 +35,8 @@ code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFj code.gitea.io/sdk/gitea v0.15.0 h1:tsNhxDM/2N1Ohv1Xq5UWrht/esg0WmtRj4wsHVHriTg= code.gitea.io/sdk/gitea v0.15.0/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= +gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= @@ -51,6 +53,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= @@ -76,6 +80,10 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -83,9 +91,18 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -104,6 +121,8 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7 github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -119,12 +138,15 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= @@ -218,6 +240,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -240,6 +263,7 @@ github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7h github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= @@ -270,9 +294,14 @@ github.com/drone/envsubst v1.0.3 h1:PCIBwNDYjs50AsLZPYdfhSATKaRg/FJmDc2D6+C2x8g= github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9bFiJ2g= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -285,10 +314,13 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf h1:NrF81UtW8gG2LBGkXFQFqlfNnvMt9WdB46sfdJY4oqc= github.com/franela/goblin v0.0.0-20211003143422-0a4f594942bf/go.mod h1:VzmDKDJVZI3aJmnRI9VjAn9nJ8qPPsN1fqzr9dqInIo= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= @@ -305,6 +337,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -329,19 +362,26 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A= github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-json v0.7.4 h1:B44qRUFwz/vxPKPISQ1KhvzRi9kZ28RAf6YtjriBZ5k= +github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:04sojTxgYxu1L4Hn7Tgf7UVtIosVa6CuHtvNY+7T1K4= github.com/gogits/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:cY2AIrMgHm6oOHmR7jY+9TtjzSjQ3iG7tURJG3Y6XH0= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -350,6 +390,7 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.1.0 h1:XUgk2Ex5veyVFVeLm0xhusUTQybEbexJXrvPNOKkSY0= github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -380,6 +421,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -390,6 +433,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= @@ -419,7 +463,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -435,6 +481,8 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -442,18 +490,30 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs= github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= -github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw= -github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -461,25 +521,76 @@ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.8.1/go.mod h1:JV6m6b6jhjdmzchES0drzCcYcAHS1OPD5xu3OZ/lE2g= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.7.0/go.mod h1:ZnHF+rMePVqDKaOfJVI4Q8IVvAQMryDlDkZnKOI75BE= +github.com/jackc/pgtype v1.8.0/go.mod h1:PqDKcEBtllAtk/2p6z6SHdXW5UB+MhE75tUol2OKexE= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.11.0/go.mod h1:i62xJgdrtVDsnL3U8ekyrQXEwGNTRoG7/8r+CIdYfcc= +github.com/jackc/pgx/v4 v4.12.0/go.mod h1:fE547h6VulLPA3kySjfnSG/e2D861g/50JlVUa/ub60= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -497,35 +608,59 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= @@ -541,9 +676,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 h1:j2kD3MT1z4PXCiUllUJF9mWUESr9TWKS7iEKsQ/IipM= @@ -554,23 +688,37 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/nicksnyder/go-i18n v1.10.1/go.mod h1:e4Di5xjP9oTVrC6y3C7C0HoSYXjSbhh/dU0eUV32nB4= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1 h1:mFwc4LvZ0xpSvDZ3E+k8Yte0hLOMxXUlP+yXtJqkYfQ= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -596,42 +744,65 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -643,23 +814,33 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/rs/zerolog v1.25.0 h1:Rj7XygbUHKUlDPcVdoLyR91fJBsduXj5fRxyqIQj/II= github.com/rs/zerolog v1.25.0/go.mod h1:7KHcEGe0QZPOm2IE4Kpb5rTh6n1h2hIgS5OOnu1rUaI= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/meddler v1.0.1 h1:JLR7Z4M4iGm1nr7DIURBq18UW8cTrm+qArUFgOhELo8= -github.com/russross/meddler v1.0.1/go.mod h1:GzGDChbFHuzxlFwt8gnJMRRNyFSQDSudmy2kHh7GYnQ= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= @@ -672,7 +853,9 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -688,6 +871,9 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -705,6 +891,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= @@ -720,9 +908,8 @@ github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxW github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -735,8 +922,6 @@ github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 h1:9zBOoKSR9CBeYoKQv6LFIuImg8lorCjh8XzK72bJMRg= github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915/go.mod h1:PbzlZ93HrA1cf16OUP1vckAPq57gtF+ccnwZeDkmC9s= -github.com/woodpecker-ci/togo v0.0.0-20211018210511-a36120f299b0 h1:jP4WIdiQAwP72PPJpVY5gpJtH/u4g0R+2erPR8l5Fa8= -github.com/woodpecker-ci/togo v0.0.0-20211018210511-a36120f299b0/go.mod h1:L34A0IDEjrqlTTuxfKhRsY8S1drgpLh1O7GtHAnt8Xg= github.com/xanzy/go-gitlab v0.51.1 h1:wWKLalwx4omxFoHh3PLs9zDgAD4GXDP/uoxwMRCSiWM= github.com/xanzy/go-gitlab v0.51.1/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -757,11 +942,16 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -770,21 +960,36 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= @@ -825,9 +1030,12 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -885,13 +1093,18 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -906,6 +1119,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -917,6 +1131,7 @@ golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -948,6 +1163,7 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -960,10 +1176,10 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -983,6 +1199,7 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -992,6 +1209,7 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1000,8 +1218,11 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1009,6 +1230,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -1029,15 +1251,19 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1055,6 +1281,7 @@ google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1070,6 +1297,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1100,10 +1328,13 @@ google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca h1:+e+aQDO4/c9KaG8PXWHTc6/+Du6kz+BKcXCSnV4SSTE= google.golang.org/genproto v0.0.0-20211027162914-98a5263abeca/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= @@ -1146,14 +1377,18 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1172,6 +1407,7 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1204,6 +1440,33 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= +lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= +modernc.org/cc/v3 v3.33.6 h1:r63dgSzVzRxUpAJFPQWHy1QeZeY1ydNENUDaBx1GqYc= +modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/ccgo/v3 v3.9.5 h1:dEuUSf8WN51rDkprFuAqjfchKEzN0WttP/Py3enBwjk= +modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= +modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= +modernc.org/libc v1.9.11 h1:QUxZMs48Ahg2F7SN41aERvMfGLY2HU/ADnB9DC4Yts8= +modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= +modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.4.0 h1:GCjoRaBew8ECCKINQA2nYjzvufFW9YiEuuB+rQ9bn2E= +modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM= +modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= +modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.11.2 h1:ShWQpeD3ag/bmx6TqidBlIWonWmQaSQKls3aenCbt+w= +modernc.org/sqlite v1.11.2/go.mod h1:+mhs/P1ONd+6G7hcAs6irwDi/bjTQ7nLW6LHRBsEa3A= +modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= +modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= +modernc.org/tcl v1.5.5/go.mod h1:ADkaTUuwukkrlhqwERyq0SM8OvyXo7+TjFz7yAF56EI= +modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= @@ -1213,3 +1476,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +xorm.io/builder v0.3.9 h1:Sd65/LdWyO7LR8+Cbd+e7mm3sK/7U9k0jS3999IDHMc= +xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= +xorm.io/xorm v1.2.5 h1:tqN7OhN8P9xi52qBb76I8m5maAJMz/SSbgK2RGPCPbo= +xorm.io/xorm v1.2.5/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0= diff --git a/pipeline/frontend/metadata.go b/pipeline/frontend/metadata.go index d5570247f..d7a320d3b 100644 --- a/pipeline/frontend/metadata.go +++ b/pipeline/frontend/metadata.go @@ -38,7 +38,7 @@ type ( // Build defines runtime metadata for a build. Build struct { - Number int `json:"number,omitempty"` + Number int64 `json:"number,omitempty"` Created int64 `json:"created,omitempty"` Started int64 `json:"started,omitempty"` Finished int64 `json:"finished,omitempty"` @@ -49,7 +49,7 @@ type ( Target string `json:"target,omitempty"` Trusted bool `json:"trusted,omitempty"` Commit Commit `json:"commit,omitempty"` - Parent int `json:"parent,omitempty"` + Parent int64 `json:"parent,omitempty"` } // Commit defines runtime metadata for a commit. @@ -103,8 +103,8 @@ func (m *Metadata) Environ() map[string]string { "CI_REPO_REMOTE": m.Repo.Remote, "CI_REMOTE_URL": m.Repo.Remote, "CI_REPO_PRIVATE": strconv.FormatBool(m.Repo.Private), - "CI_BUILD_NUMBER": strconv.Itoa(m.Curr.Number), - "CI_PARENT_BUILD_NUMBER": strconv.Itoa(m.Curr.Parent), + "CI_BUILD_NUMBER": strconv.FormatInt(m.Curr.Number, 10), + "CI_PARENT_BUILD_NUMBER": strconv.FormatInt(m.Curr.Parent, 10), "CI_BUILD_CREATED": strconv.FormatInt(m.Curr.Created, 10), "CI_BUILD_STARTED": strconv.FormatInt(m.Curr.Started, 10), "CI_BUILD_FINISHED": strconv.FormatInt(m.Curr.Finished, 10), @@ -121,7 +121,7 @@ func (m *Metadata) Environ() map[string]string { "CI_COMMIT_AUTHOR_NAME": m.Curr.Commit.Author.Name, "CI_COMMIT_AUTHOR_EMAIL": m.Curr.Commit.Author.Email, "CI_COMMIT_AUTHOR_AVATAR": m.Curr.Commit.Author.Avatar, - "CI_PREV_BUILD_NUMBER": strconv.Itoa(m.Prev.Number), + "CI_PREV_BUILD_NUMBER": strconv.FormatInt(m.Prev.Number, 10), "CI_PREV_BUILD_CREATED": strconv.FormatInt(m.Prev.Created, 10), "CI_PREV_BUILD_STARTED": strconv.FormatInt(m.Prev.Started, 10), "CI_PREV_BUILD_FINISHED": strconv.FormatInt(m.Prev.Finished, 10), diff --git a/server/api/build.go b/server/api/build.go index 1fa3621d5..7928d53a3 100644 --- a/server/api/build.go +++ b/server/api/build.go @@ -62,7 +62,7 @@ func GetBuild(c *gin.Context) { } repo := session.Repo(c) - num, err := strconv.Atoi(c.Param("number")) + num, err := strconv.ParseInt(c.Param("number"), 10, 64) if err != nil { c.AbortWithError(http.StatusBadRequest, err) return @@ -103,7 +103,7 @@ func GetBuildLogs(c *gin.Context) { // parse the build number and job sequence number from // the request parameter. - num, _ := strconv.Atoi(c.Params.ByName("number")) + num, _ := strconv.ParseInt(c.Params.ByName("number"), 10, 64) ppid, _ := strconv.Atoi(c.Params.ByName("pid")) name := c.Params.ByName("proc") @@ -137,7 +137,7 @@ func GetProcLogs(c *gin.Context) { // parse the build number and job sequence number from // the request parameter. - num, _ := strconv.Atoi(c.Params.ByName("number")) + num, _ := strconv.ParseInt(c.Params.ByName("number"), 10, 64) pid, _ := strconv.Atoi(c.Params.ByName("pid")) build, err := store_.GetBuildNumber(repo, num) @@ -168,7 +168,7 @@ func GetProcLogs(c *gin.Context) { func DeleteBuild(c *gin.Context) { store_ := store.FromContext(c) repo := session.Repo(c) - num, _ := strconv.Atoi(c.Params.ByName("number")) + num, _ := strconv.ParseInt(c.Params.ByName("number"), 10, 64) build, err := store_.GetBuildNumber(repo, num) if err != nil { @@ -250,9 +250,7 @@ func PostApproval(c *gin.Context) { store_ = store.FromContext(c) repo = session.Repo(c) user = session.User(c) - num, _ = strconv.Atoi( - c.Params.ByName("number"), - ) + num, _ = strconv.ParseInt(c.Params.ByName("number"), 10, 64) ) build, err := store_.GetBuildNumber(repo, num) @@ -307,7 +305,7 @@ func PostApproval(c *gin.Context) { var yamls []*remote.FileMeta for _, y := range configs { - yamls = append(yamls, &remote.FileMeta{Data: []byte(y.Data), Name: y.Name}) + yamls = append(yamls, &remote.FileMeta{Data: y.Data, Name: y.Name}) } b := shared.ProcBuilder{ @@ -360,9 +358,7 @@ func PostDecline(c *gin.Context) { repo = session.Repo(c) user = session.User(c) - num, _ = strconv.Atoi( - c.Params.ByName("number"), - ) + num, _ = strconv.ParseInt(c.Params.ByName("number"), 10, 64) ) build, err := store_.GetBuildNumber(repo, num) @@ -404,7 +400,7 @@ func PostBuild(c *gin.Context) { store_ := store.FromContext(c) repo := session.Repo(c) - num, err := strconv.Atoi(c.Param("number")) + num, err := strconv.ParseInt(c.Param("number"), 10, 64) if err != nil { c.AbortWithError(http.StatusBadRequest, err) return @@ -519,7 +515,7 @@ func PostBuild(c *gin.Context) { var yamls []*remote.FileMeta for _, y := range configs { - yamls = append(yamls, &remote.FileMeta{Data: []byte(y.Data), Name: y.Name}) + yamls = append(yamls, &remote.FileMeta{Data: y.Data, Name: y.Name}) } b := shared.ProcBuilder{ @@ -565,7 +561,7 @@ func DeleteBuildLogs(c *gin.Context) { repo := session.Repo(c) user := session.User(c) - num, _ := strconv.Atoi(c.Params.ByName("number")) + num, _ := strconv.ParseInt(c.Params.ByName("number"), 10, 64) build, err := store_.GetBuildNumber(repo, num) if err != nil { diff --git a/server/api/file.go b/server/api/file.go index 57ac5e2f6..51bb9503b 100644 --- a/server/api/file.go +++ b/server/api/file.go @@ -29,7 +29,7 @@ import ( // FileList gets a list file by build. func FileList(c *gin.Context) { store_ := store.FromContext(c) - num, err := strconv.Atoi(c.Param("number")) + num, err := strconv.ParseInt(c.Param("number"), 10, 64) if err != nil { c.AbortWithError(http.StatusBadRequest, err) return @@ -63,7 +63,7 @@ func FileGet(c *gin.Context) { }() ) - num, err := strconv.Atoi(c.Param("number")) + num, err := strconv.ParseInt(c.Param("number"), 10, 64) if err != nil { c.AbortWithError(http.StatusBadRequest, err) return diff --git a/server/api/hook.go b/server/api/hook.go index f380ac12d..061ee07a8 100644 --- a/server/api/hook.go +++ b/server/api/hook.go @@ -340,7 +340,7 @@ func findOrPersistPipelineConfig(repo *model.Repo, build *model.Build, remoteYam if err != nil { conf = &model.Config{ RepoID: build.RepoID, - Data: string(remoteYamlConfig.Data), + Data: remoteYamlConfig.Data, Hash: sha, Name: shared.SanitizePath(remoteYamlConfig.Name), } diff --git a/server/api/stream.go b/server/api/stream.go index 8233e0170..c8e714641 100644 --- a/server/api/stream.go +++ b/server/api/stream.go @@ -138,7 +138,7 @@ func LogStreamSSE(c *gin.Context) { // // parse the build number and job sequence number from // // the repquest parameter. - buildn, _ := strconv.Atoi(c.Param("build")) + buildn, _ := strconv.ParseInt(c.Param("build"), 10, 64) jobn, _ := strconv.Atoi(c.Param("number")) build, err := store_.GetBuildNumber(repo, buildn) diff --git a/server/model/build_test.go b/server/model/agent.go similarity index 51% rename from server/model/build_test.go rename to server/model/agent.go index 9220ac3d3..02a3fe700 100644 --- a/server/model/build_test.go +++ b/server/model/agent.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,24 +14,18 @@ package model -import ( - "crypto/rand" - "fmt" - "testing" -) +// TODO: check if it is actually used or just some relict from the past -func TestBuildTrim(t *testing.T) { - d := make([]byte, 2000) - rand.Read(d) - - b := Build{} - b.Message = fmt.Sprintf("%X", d) - - if len(b.Message) != 4000 { - t.Errorf("Failed to generate 4000 byte test string") - } - b.Trim() - if len(b.Message) != 2000 { - t.Errorf("Failed to trim text string to 2000 bytes") - } +type Agent struct { + ID int64 `xorm:"pk autoincr 'agent_id'"` + Addr string `xorm:"UNIQUE VARCHAR(250) 'agent_addr'"` + Platform string `xorm:"VARCHAR(500) 'agent_platform'"` + Capacity int64 `xorm:"agent_capacity"` + Created int64 `xorm:"created 'agent_created'"` + Updated int64 `xorm:"updated 'agent_updated'"` +} + +// TableName return database table name for xorm +func (Agent) TableName() string { + return "agents" } diff --git a/server/model/build.go b/server/model/build.go index 4dc6235cc..ae31e6077 100644 --- a/server/model/build.go +++ b/server/model/build.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,48 +17,42 @@ package model // swagger:model build type Build struct { - ID int64 `json:"id" meddler:"build_id,pk"` - RepoID int64 `json:"-" meddler:"build_repo_id"` - ConfigID int64 `json:"-" meddler:"build_config_id"` - Number int `json:"number" meddler:"build_number"` - Parent int `json:"parent" meddler:"build_parent"` - Event string `json:"event" meddler:"build_event"` - Status string `json:"status" meddler:"build_status"` - Error string `json:"error" meddler:"build_error"` - Enqueued int64 `json:"enqueued_at" meddler:"build_enqueued"` - Created int64 `json:"created_at" meddler:"build_created"` - Started int64 `json:"started_at" meddler:"build_started"` - Finished int64 `json:"finished_at" meddler:"build_finished"` - Deploy string `json:"deploy_to" meddler:"build_deploy"` - Commit string `json:"commit" meddler:"build_commit"` - Branch string `json:"branch" meddler:"build_branch"` - Ref string `json:"ref" meddler:"build_ref"` - Refspec string `json:"refspec" meddler:"build_refspec"` - Remote string `json:"remote" meddler:"build_remote"` - Title string `json:"title" meddler:"build_title"` - Message string `json:"message" meddler:"build_message"` - Timestamp int64 `json:"timestamp" meddler:"build_timestamp"` - Sender string `json:"sender" meddler:"build_sender"` - Author string `json:"author" meddler:"build_author"` - Avatar string `json:"author_avatar" meddler:"build_avatar"` - Email string `json:"author_email" meddler:"build_email"` - Link string `json:"link_url" meddler:"build_link"` - Signed bool `json:"signed" meddler:"build_signed"` // deprecate - Verified bool `json:"verified" meddler:"build_verified"` // deprecate - Reviewer string `json:"reviewed_by" meddler:"build_reviewer"` - Reviewed int64 `json:"reviewed_at" meddler:"build_reviewed"` - Procs []*Proc `json:"procs,omitempty" meddler:"-"` - Files []*File `json:"files,omitempty" meddler:"-"` - ChangedFiles []string `json:"changed_files,omitempty" meddler:"changed_files,json"` + ID int64 `json:"id" xorm:"pk autoincr 'build_id'"` + RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX 'build_repo_id'"` + Number int64 `json:"number" xorm:"UNIQUE(s) 'build_number'"` + Author string `json:"author" xorm:"INDEX 'build_author'"` + ConfigID int64 `json:"-" xorm:"build_config_id"` + Parent int64 `json:"parent" xorm:"build_parent"` + Event string `json:"event" xorm:"build_event"` + Status string `json:"status" xorm:"INDEX 'build_status'"` + Error string `json:"error" xorm:"build_error"` + Enqueued int64 `json:"enqueued_at" xorm:"build_enqueued"` + Created int64 `json:"created_at" xorm:"build_created"` + Started int64 `json:"started_at" xorm:"build_started"` + Finished int64 `json:"finished_at" xorm:"build_finished"` + Deploy string `json:"deploy_to" xorm:"build_deploy"` + Commit string `json:"commit" xorm:"build_commit"` + Branch string `json:"branch" xorm:"build_branch"` + Ref string `json:"ref" xorm:"build_ref"` + Refspec string `json:"refspec" xorm:"build_refspec"` + Remote string `json:"remote" xorm:"build_remote"` + Title string `json:"title" xorm:"build_title"` + Message string `json:"message" xorm:"build_message"` + Timestamp int64 `json:"timestamp" xorm:"build_timestamp"` + Sender string `json:"sender" xorm:"build_sender"` + Avatar string `json:"author_avatar" xorm:"build_avatar"` + Email string `json:"author_email" xorm:"build_email"` + Link string `json:"link_url" xorm:"build_link"` + Signed bool `json:"signed" xorm:"build_signed"` // deprecate + Verified bool `json:"verified" xorm:"build_verified"` // deprecate + Reviewer string `json:"reviewed_by" xorm:"build_reviewer"` + Reviewed int64 `json:"reviewed_at" xorm:"build_reviewed"` + Procs []*Proc `json:"procs,omitempty" xorm:"-"` + Files []*File `json:"files,omitempty" xorm:"-"` + ChangedFiles []string `json:"changed_files,omitempty" xorm:"json 'changed_files'"` } -// Trim trims string values that would otherwise exceed -// the database column sizes and fail to insert. -func (b *Build) Trim() { - if len(b.Title) > 1000 { - b.Title = b.Title[:1000] - } - if len(b.Message) > 2000 { - b.Message = b.Message[:2000] - } +// TableName return database table name for xorm +func (Build) TableName() string { + return "builds" } diff --git a/server/model/cc.go b/server/model/cc.go index f78b8076b..cb3296571 100644 --- a/server/model/cc.go +++ b/server/model/cc.go @@ -50,7 +50,7 @@ func NewCC(r *Repo, b *Build, link string) *CCProjects { b.Status != StatusRunning { proj.Activity = "Sleeping" proj.LastBuildTime = time.Unix(b.Started, 0).Format(time.RFC3339) - proj.LastBuildLabel = strconv.Itoa(b.Number) + proj.LastBuildLabel = strconv.FormatInt(b.Number, 10) } // ensure the last build Status accepts a valid diff --git a/server/model/config.go b/server/model/config.go index 05aa587ac..4db63e99e 100644 --- a/server/model/config.go +++ b/server/model/config.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,7 +18,7 @@ package model // ConfigStore persists pipeline configuration to storage. type ConfigStore interface { ConfigsForBuild(buildID int64) ([]*Config, error) - ConfigFindIdentical(repoID int64, sha string) (*Config, error) + ConfigFindIdentical(repoID int64, hash string) (*Config, error) ConfigFindApproved(*Config) (bool, error) ConfigCreate(*Config) error BuildConfigCreate(*BuildConfig) error @@ -25,15 +26,15 @@ type ConfigStore interface { // Config represents a pipeline configuration. type Config struct { - ID int64 `json:"-" meddler:"config_id,pk"` - RepoID int64 `json:"-" meddler:"config_repo_id"` - Data string `json:"data" meddler:"config_data"` - Hash string `json:"hash" meddler:"config_hash"` - Name string `json:"name" meddler:"config_name"` + ID int64 `json:"-" xorm:"pk autoincr 'config_id'"` + RepoID int64 `json:"-" xorm:"UNIQUE(s) 'config_repo_id'"` + Hash string `json:"hash" xorm:"UNIQUE(s) INDEX 'config_hash'"` + Name string `json:"name" xorm:"config_name"` + Data []byte `json:"data" xorm:"config_data"` } // BuildConfig is the n:n relation between Build and Config type BuildConfig struct { - ConfigID int64 `json:"-" meddler:"config_id"` - BuildID int64 `json:"-" meddler:"build_id"` + ConfigID int64 `json:"-" xorm:"UNIQUE(s) NOT NULL 'config_id'"` + BuildID int64 `json:"-" xorm:"UNIQUE(s) NOT NULL 'build_id'"` } diff --git a/server/model/environ.go b/server/model/environ.go index ee2d0d5f5..92670aa97 100644 --- a/server/model/environ.go +++ b/server/model/environ.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,9 +37,9 @@ type EnvironStore interface { // Environ represents an environment variable. // swagger:model environ type Environ struct { - ID int64 `json:"id" meddler:"env_id,pk"` - Name string `json:"name" meddler:"env_name"` - Value string `json:"value,omitempty" meddler:"env_value"` + ID int64 `json:"id"` + Name string `json:"name"` + Value string `json:"value,omitempty"` } // Validate validates the required fields and formats. diff --git a/server/model/feed.go b/server/model/feed.go index 35d7b9bac..02863f407 100644 --- a/server/model/feed.go +++ b/server/model/feed.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,24 +19,24 @@ package model // // swagger:model feed type Feed struct { - Owner string `json:"owner" meddler:"repo_owner"` - Name string `json:"name" meddler:"repo_name"` - FullName string `json:"full_name" meddler:"repo_full_name"` + Owner string `json:"owner" xorm:"repo_owner"` + Name string `json:"name" xorm:"repo_name"` + FullName string `json:"full_name" xorm:"repo_full_name"` - Number int `json:"number,omitempty" meddler:"build_number,zeroisnull"` - Event string `json:"event,omitempty" meddler:"build_event,zeroisnull"` - Status string `json:"status,omitempty" meddler:"build_status,zeroisnull"` - Created int64 `json:"created_at,omitempty" meddler:"build_created,zeroisnull"` - Started int64 `json:"started_at,omitempty" meddler:"build_started,zeroisnull"` - Finished int64 `json:"finished_at,omitempty" meddler:"build_finished,zeroisnull"` - Commit string `json:"commit,omitempty" meddler:"build_commit,zeroisnull"` - Branch string `json:"branch,omitempty" meddler:"build_branch,zeroisnull"` - Ref string `json:"ref,omitempty" meddler:"build_ref,zeroisnull"` - Refspec string `json:"refspec,omitempty" meddler:"build_refspec,zeroisnull"` - Remote string `json:"remote,omitempty" meddler:"build_remote,zeroisnull"` - Title string `json:"title,omitempty" meddler:"build_title,zeroisnull"` - Message string `json:"message,omitempty" meddler:"build_message,zeroisnull"` - Author string `json:"author,omitempty" meddler:"build_author,zeroisnull"` - Avatar string `json:"author_avatar,omitempty" meddler:"build_avatar,zeroisnull"` - Email string `json:"author_email,omitempty" meddler:"build_email,zeroisnull"` + Number int64 `json:"number,omitempty" xorm:"build_number"` + Event string `json:"event,omitempty" xorm:"build_event"` + Status string `json:"status,omitempty" xorm:"build_status"` + Created int64 `json:"created_at,omitempty" xorm:"build_created"` + Started int64 `json:"started_at,omitempty" xorm:"build_started"` + Finished int64 `json:"finished_at,omitempty" xorm:"build_finished"` + Commit string `json:"commit,omitempty" xorm:"build_commit"` + Branch string `json:"branch,omitempty" xorm:"build_branch"` + Ref string `json:"ref,omitempty" xorm:"build_ref"` + Refspec string `json:"refspec,omitempty" xorm:"build_refspec"` + Remote string `json:"remote,omitempty" xorm:"build_remote"` + Title string `json:"title,omitempty" xorm:"build_title"` + Message string `json:"message,omitempty" xorm:"build_message"` + Author string `json:"author,omitempty" xorm:"build_author"` + Avatar string `json:"author_avatar,omitempty" xorm:"build_avatar"` + Email string `json:"author_email,omitempty" xorm:"build_email"` } diff --git a/server/model/file.go b/server/model/file.go index 3bf52a5ee..a74e34aaf 100644 --- a/server/model/file.go +++ b/server/model/file.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,15 +27,21 @@ type FileStore interface { // File represents a pipeline artifact. type File struct { - ID int64 `json:"id" meddler:"file_id,pk"` - BuildID int64 `json:"-" meddler:"file_build_id"` - ProcID int64 `json:"proc_id" meddler:"file_proc_id"` - PID int `json:"pid" meddler:"file_pid"` - Name string `json:"name" meddler:"file_name"` - Size int `json:"size" meddler:"file_size"` - Mime string `json:"mime" meddler:"file_mime"` - Time int64 `json:"time" meddler:"file_time"` - Passed int `json:"passed" meddler:"file_meta_passed"` - Failed int `json:"failed" meddler:"file_meta_failed"` - Skipped int `json:"skipped" meddler:"file_meta_skipped"` + ID int64 `json:"id" xorm:"pk autoincr 'file_id'"` + BuildID int64 `json:"-" xorm:"INDEX 'file_build_id'"` + ProcID int64 `json:"proc_id" xorm:"UNIQUE(s) INDEX 'file_proc_id'"` + PID int `json:"pid" xorm:"file_pid"` + Name string `json:"name" xorm:"UNIQUE(s) file_name"` + Size int `json:"size" xorm:"file_size"` + Mime string `json:"mime" xorm:"file_mime"` + Time int64 `json:"time" xorm:"file_time"` + Passed int `json:"passed" xorm:"file_meta_passed"` + Failed int `json:"failed" xorm:"file_meta_failed"` + Skipped int `json:"skipped" xorm:"file_meta_skipped"` + Data []byte `json:"-" xorm:"file_data"` // TODO: dont store in db but object storage? +} + +// TableName return database table name for xorm +func (File) TableName() string { + return "files" } diff --git a/server/store/datastore/ddl/mysql/ddl.go b/server/model/log.go similarity index 74% rename from server/store/datastore/ddl/mysql/ddl.go rename to server/model/log.go index ac3c09491..3fea5396a 100644 --- a/server/store/datastore/ddl/mysql/ddl.go +++ b/server/model/log.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package mysql +package model -//go:generate togo ddl -package mysql -dialect mysql +type Logs struct { + ID int64 `xorm:"pk autoincr 'log_id'"` + ProcID int64 `xorm:"UNIQUE 'log_job_id'"` + Data []byte `xorm:"log_data"` +} diff --git a/server/model/perm.go b/server/model/perm.go index 03ba29350..513c5efd0 100644 --- a/server/model/perm.go +++ b/server/model/perm.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,11 +26,19 @@ type PermStore interface { // Perm defines a repository permission for an individual user. type Perm struct { - UserID int64 `json:"-" meddler:"perm_user_id"` - RepoID int64 `json:"-" meddler:"perm_repo_id"` - Repo string `json:"-" meddler:"-"` - Pull bool `json:"pull" meddler:"perm_pull"` - Push bool `json:"push" meddler:"perm_push"` - Admin bool `json:"admin" meddler:"perm_admin"` - Synced int64 `json:"synced" meddler:"perm_synced"` + UserID int64 `json:"-" xorm:"UNIQUE(s) INDEX NOT NULL 'perm_user_id'"` + RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX NOT NULL 'perm_repo_id'"` + Repo string `json:"-" xorm:"-"` // TODO: better caching (use type *Repo) + Pull bool `json:"pull" xorm:"perm_pull"` + Push bool `json:"push" xorm:"perm_push"` + Admin bool `json:"admin" xorm:"perm_admin"` + Synced int64 `json:"synced" xorm:"perm_synced"` + // TODO: after xorm switch make followup pull that utilize created & updated + // Created int64 `json:"created" xorm:"created"` + // Updated int64 `json:"updated" xorm:"updated"` +} + +// TableName return database table name for xorm +func (Perm) TableName() string { + return "perms" } diff --git a/server/model/proc.go b/server/model/proc.go index 8740c0737..aca90be4f 100644 --- a/server/model/proc.go +++ b/server/model/proc.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,21 +31,26 @@ type ProcStore interface { // Proc represents a process in the build pipeline. // swagger:model proc type Proc struct { - ID int64 `json:"id" meddler:"proc_id,pk"` - BuildID int64 `json:"build_id" meddler:"proc_build_id"` - PID int `json:"pid" meddler:"proc_pid"` - PPID int `json:"ppid" meddler:"proc_ppid"` - PGID int `json:"pgid" meddler:"proc_pgid"` - Name string `json:"name" meddler:"proc_name"` - State string `json:"state" meddler:"proc_state"` - Error string `json:"error,omitempty" meddler:"proc_error"` - ExitCode int `json:"exit_code" meddler:"proc_exit_code"` - Started int64 `json:"start_time,omitempty" meddler:"proc_started"` - Stopped int64 `json:"end_time,omitempty" meddler:"proc_stopped"` - Machine string `json:"machine,omitempty" meddler:"proc_machine"` - Platform string `json:"platform,omitempty" meddler:"proc_platform"` - Environ map[string]string `json:"environ,omitempty" meddler:"proc_environ,json"` - Children []*Proc `json:"children,omitempty" meddler:"-"` + ID int64 `json:"id" xorm:"pk autoincr 'proc_id'"` + BuildID int64 `json:"build_id" xorm:"UNIQUE(s) INDEX 'proc_build_id'"` + PID int `json:"pid" xorm:"UNIQUE(s) 'proc_pid'"` + PPID int `json:"ppid" xorm:"proc_ppid"` + PGID int `json:"pgid" xorm:"proc_pgid"` + Name string `json:"name" xorm:"proc_name"` + State string `json:"state" xorm:"proc_state"` + Error string `json:"error,omitempty" xorm:"VARCHAR(500) proc_error"` + ExitCode int `json:"exit_code" xorm:"proc_exit_code"` + Started int64 `json:"start_time,omitempty" xorm:"proc_started"` + Stopped int64 `json:"end_time,omitempty" xorm:"proc_stopped"` + Machine string `json:"machine,omitempty" xorm:"proc_machine"` + Platform string `json:"platform,omitempty" xorm:"proc_platform"` + Environ map[string]string `json:"environ,omitempty" xorm:"json 'proc_environ'"` + Children []*Proc `json:"children,omitempty" xorm:"-"` +} + +// TableName return database table name for xorm +func (Proc) TableName() string { + return "procs" } // Running returns true if the process state is pending or running. diff --git a/server/model/queue.go b/server/model/queue.go index 33361cacf..94ead8724 100644 --- a/server/model/queue.go +++ b/server/model/queue.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,21 +23,7 @@ import ( "github.com/woodpecker-ci/woodpecker/server/queue" ) -// Task defines scheduled pipeline Task. -type Task struct { - ID string `meddler:"task_id"` - Data []byte `meddler:"task_data"` - Labels map[string]string `meddler:"task_labels,json"` - Dependencies []string `meddler:"task_dependencies,json"` - RunOn []string `meddler:"task_run_on,json"` -} - -// TaskStore defines storage for scheduled Tasks. -type TaskStore interface { - TaskList() ([]*Task, error) - TaskInsert(*Task) error - TaskDelete(string) error -} +// TODO: move code to "github.com/woodpecker-ci/woodpecker/server/queue" // WithTaskStore returns a queue that is backed by the TaskStore. This // ensures the task Queue can be restored when the system starts. diff --git a/server/model/registry.go b/server/model/registry.go index 49f7f7e94..7644b9376 100644 --- a/server/model/registry.go +++ b/server/model/registry.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,13 +50,13 @@ type RegistryStore interface { // Registry represents a docker registry with credentials. // swagger:model registry type Registry struct { - ID int64 `json:"id" meddler:"registry_id,pk"` - RepoID int64 `json:"-" meddler:"registry_repo_id"` - Address string `json:"address" meddler:"registry_addr"` - Username string `json:"username" meddler:"registry_username"` - Password string `json:"password" meddler:"registry_password"` - Email string `json:"email" meddler:"registry_email"` - Token string `json:"token" meddler:"registry_token"` + ID int64 `json:"id" xorm:"pk autoincr 'registry_id'"` + RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX 'registry_repo_id'"` + Address string `json:"address" xorm:"UNIQUE(s) INDEX 'registry_addr'"` + Username string `json:"username" xorm:"varchar(2000) 'registry_username'"` + Password string `json:"password" xorm:"TEXT 'registry_password'"` + Token string `json:"token" xorm:"TEXT 'registry_token'"` + Email string `json:"email" xorm:"varchar(500) 'registry_email'"` } // Validate validates the registry information. diff --git a/server/model/repo.go b/server/model/repo.go index f4916eb90..4f725c4ea 100644 --- a/server/model/repo.go +++ b/server/model/repo.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,28 +24,34 @@ import ( // // swagger:model repo type Repo struct { - ID int64 `json:"id,omitempty" meddler:"repo_id,pk"` - UserID int64 `json:"-" meddler:"repo_user_id"` - Owner string `json:"owner" meddler:"repo_owner"` - Name string `json:"name" meddler:"repo_name"` - FullName string `json:"full_name" meddler:"repo_full_name"` - Avatar string `json:"avatar_url,omitempty" meddler:"repo_avatar"` - Link string `json:"link_url,omitempty" meddler:"repo_link"` - Kind string `json:"scm,omitempty" meddler:"repo_scm"` - Clone string `json:"clone_url,omitempty" meddler:"repo_clone"` - Branch string `json:"default_branch,omitempty" meddler:"repo_branch"` - Timeout int64 `json:"timeout,omitempty" meddler:"repo_timeout"` - Visibility string `json:"visibility" meddler:"repo_visibility"` - IsPrivate bool `json:"private" meddler:"repo_private"` - IsTrusted bool `json:"trusted" meddler:"repo_trusted"` - IsStarred bool `json:"starred,omitempty" meddler:"-"` - IsGated bool `json:"gated" meddler:"repo_gated"` - IsActive bool `json:"active" meddler:"repo_active"` - AllowPull bool `json:"allow_pr" meddler:"repo_allow_pr"` - Counter int `json:"last_build" meddler:"repo_counter"` - Config string `json:"config_file" meddler:"repo_config_path"` - Hash string `json:"-" meddler:"repo_hash"` - Perm *Perm `json:"-" meddler:"-"` + ID int64 `json:"id,omitempty" xorm:"pk autoincr 'repo_id'"` + UserID int64 `json:"-" xorm:"repo_user_id"` + Owner string `json:"owner" xorm:"UNIQUE(name) 'repo_owner'"` + Name string `json:"name" xorm:"UNIQUE(name) 'repo_name'"` + FullName string `json:"full_name" xorm:"UNIQUE 'repo_full_name'"` + Avatar string `json:"avatar_url,omitempty" xorm:"varchar(500) 'repo_avatar'"` + Link string `json:"link_url,omitempty" xorm:"varchar(1000) 'repo_link'"` + Clone string `json:"clone_url,omitempty" xorm:"varchar(1000) 'repo_clone'"` + Branch string `json:"default_branch,omitempty" xorm:"varchar(500) 'repo_branch'"` + Kind string `json:"scm,omitempty" xorm:"varchar(50) 'repo_scm'"` // TODO: rename to `SCMKind` + Timeout int64 `json:"timeout,omitempty" xorm:"repo_timeout"` + Visibility string `json:"visibility" xorm:"varchar(10) 'repo_visibility'"` + IsPrivate bool `json:"private" xorm:"repo_private"` // TODO: Rename to `IsSCMPrivate` + IsTrusted bool `json:"trusted" xorm:"repo_trusted"` + IsStarred bool `json:"starred,omitempty" xorm:"-"` + IsGated bool `json:"gated" xorm:"repo_gated"` + IsActive bool `json:"active" xorm:"repo_active"` + AllowPull bool `json:"allow_pr" xorm:"repo_allow_pr"` + // Counter is used as index to determine new build numbers + Counter int64 `json:"last_build" xorm:"NOT NULL DEFAULT 0 'repo_counter'"` + Config string `json:"config_file" xorm:"varchar(500) 'repo_config_path'"` + Hash string `json:"-" xorm:"varchar(500) 'repo_hash'"` + Perm *Perm `json:"-" xorm:"-"` +} + +// TableName return database table name for xorm +func (Repo) TableName() string { + return "repos" } func (r *Repo) ResetVisibility() { @@ -91,5 +98,5 @@ type RepoPatch struct { Timeout *int64 `json:"timeout,omitempty"` Visibility *string `json:"visibility,omitempty"` AllowPull *bool `json:"allow_pr,omitempty"` - BuildCounter *int `json:"build_counter,omitempty"` + BuildCounter *int64 `json:"build_counter,omitempty"` } diff --git a/server/model/secret.go b/server/model/secret.go index 4135b2387..9fb82c2e1 100644 --- a/server/model/secret.go +++ b/server/model/secret.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -46,14 +47,19 @@ type SecretStore interface { // Secret represents a secret variable, such as a password or token. // swagger:model registry type Secret struct { - ID int64 `json:"id" meddler:"secret_id,pk"` - RepoID int64 `json:"-" meddler:"secret_repo_id"` - Name string `json:"name" meddler:"secret_name"` - Value string `json:"value,omitempty" meddler:"secret_value"` - Images []string `json:"image" meddler:"secret_images,json"` - Events []string `json:"event" meddler:"secret_events,json"` - SkipVerify bool `json:"-" meddler:"secret_skip_verify"` - Conceal bool `json:"-" meddler:"secret_conceal"` + ID int64 `json:"id" xorm:"pk autoincr 'secret_id'"` + RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX 'secret_repo_id'"` + Name string `json:"name" xorm:"UNIQUE(s) INDEX 'secret_name'"` + Value string `json:"value,omitempty" xorm:"TEXT 'secret_value'"` + Images []string `json:"image" xorm:"json 'secret_images'"` + Events []string `json:"event" xorm:"json 'secret_events'"` + SkipVerify bool `json:"-" xorm:"secret_skip_verify"` + Conceal bool `json:"-" xorm:"secret_conceal"` +} + +// TableName return database table name for xorm +func (Secret) TableName() string { + return "secrets" } // Match returns true if an image and event match the restricted list. diff --git a/server/model/sender.go b/server/model/sender.go index e3bef4e5c..e3be289ea 100644 --- a/server/model/sender.go +++ b/server/model/sender.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,12 +32,17 @@ type SenderStore interface { } type Sender struct { - ID int64 `json:"-" meddler:"sender_id,pk"` - RepoID int64 `json:"-" meddler:"sender_repo_id"` - Login string `json:"login" meddler:"sender_login"` - Allow bool `json:"allow" meddler:"sender_allow"` - Block bool `json:"block" meddler:"sender_block"` - Branch []string `json:"branch" meddler:"-"` - Deploy []string `json:"deploy" meddler:"-"` - Event []string `json:"event" meddler:"-"` + ID int64 `json:"-" xorm:"pk autoincr 'sender_id'"` + RepoID int64 `json:"-" xorm:"UNIQUE(s) INDEX 'sender_repo_id'"` + Login string `json:"login" xorm:"UNIQUE(s) 'sender_login'"` + Allow bool `json:"allow" xorm:"sender_allow"` + Block bool `json:"block" xorm:"sender_block"` + Branch []string `json:"branch" xorm:"-"` + Deploy []string `json:"deploy" xorm:"-"` + Event []string `json:"event" xorm:"-"` +} + +// TableName return database table name for xorm +func (Sender) TableName() string { + return "senders" } diff --git a/server/model/task.go b/server/model/task.go new file mode 100644 index 000000000..49aa5aeb6 --- /dev/null +++ b/server/model/task.go @@ -0,0 +1,36 @@ +// Copyright 2021 Woodpecker 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 + +// TaskStore defines storage for scheduled Tasks. +type TaskStore interface { + TaskList() ([]*Task, error) + TaskInsert(*Task) error + TaskDelete(string) error +} + +// Task defines scheduled pipeline Task. +type Task struct { + ID string `xorm:"PK UNIQUE 'task_id'"` + Data []byte `xorm:"'task_data'"` + Labels map[string]string `xorm:"json 'task_labels'"` + Dependencies []string `xorm:"json 'task_dependencies'"` + RunOn []string `xorm:"json 'task_run_on'"` +} + +// TableName return database table name for xorm +func (Task) TableName() string { + return "tasks" +} diff --git a/server/model/user.go b/server/model/user.go index c56296850..4e1520816 100644 --- a/server/model/user.go +++ b/server/model/user.go @@ -1,3 +1,4 @@ +// Copyright 2021 Woodpecker Authors // Copyright 2018 Drone.IO Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,47 +32,52 @@ type User struct { // the id for this user. // // required: true - ID int64 `json:"id" meddler:"user_id,pk"` + ID int64 `json:"id" xorm:"pk autoincr 'user_id'"` // Login is the username for this user. // // required: true - Login string `json:"login" meddler:"user_login"` + Login string `json:"login" xorm:"UNIQUE 'user_login'"` // Token is the oauth2 token. - Token string `json:"-" meddler:"user_token"` + Token string `json:"-" xorm:"TEXT 'user_token'"` // Secret is the oauth2 token secret. - Secret string `json:"-" meddler:"user_secret"` + Secret string `json:"-" xorm:"TEXT 'user_secret'"` // Expiry is the token and secret expiration timestamp. - Expiry int64 `json:"-" meddler:"user_expiry"` + Expiry int64 `json:"-" xorm:"user_expiry"` // Email is the email address for this user. // // required: true - Email string `json:"email" meddler:"user_email"` + Email string `json:"email" xorm:" varchar(500) 'user_email'"` // the avatar url for this user. - Avatar string `json:"avatar_url" meddler:"user_avatar"` + Avatar string `json:"avatar_url" xorm:" varchar(500) 'user_avatar'"` // Activate indicates the user is active in the system. - Active bool `json:"active" meddler:"user_active"` + Active bool `json:"active" xorm:"user_active"` // Synced is the timestamp when the user was synced with the remote system. - Synced int64 `json:"synced" meddler:"user_synced"` + Synced int64 `json:"synced" xorm:"user_synced"` // Admin indicates the user is a system administrator. // // NOTE: This is sourced from the WOODPECKER_ADMINS environment variable and is no // longer persisted in the database. - Admin bool `json:"admin,omitempty" meddler:"-"` + Admin bool `json:"admin,omitempty" xorm:"-"` // Hash is a unique token used to sign tokens. - Hash string `json:"-" meddler:"user_hash"` + Hash string `json:"-" xorm:"UNIQUE varchar(500) 'user_hash'"` // DEPRECATED Admin indicates the user is a system administrator. - XAdmin bool `json:"-" meddler:"user_admin"` + XAdmin bool `json:"-" xorm:"user_admin"` +} + +// TableName return database table name for xorm +func (User) TableName() string { + return "users" } // Validate validates the required fields and formats. diff --git a/server/store/datastore/sql/mysql/sql.go b/server/store/common.go similarity index 78% rename from server/store/datastore/sql/mysql/sql.go rename to server/store/common.go index 64fba52d4..7d984f435 100644 --- a/server/store/datastore/sql/mysql/sql.go +++ b/server/store/common.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -package mysql +package store -//go:generate togo sql --package=mysql +// Opts are options for a new database connection +type Opts struct { + Driver string + Config string +} diff --git a/server/store/datastore/build.go b/server/store/datastore/build.go new file mode 100644 index 000000000..b32ef14d9 --- /dev/null +++ b/server/store/datastore/build.go @@ -0,0 +1,123 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "time" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) GetBuild(id int64) (*model.Build, error) { + build := &model.Build{} + return build, wrapGet(s.engine.ID(id).Get(build)) +} + +func (s storage) GetBuildNumber(repo *model.Repo, num int64) (*model.Build, error) { + build := &model.Build{ + RepoID: repo.ID, + Number: num, + } + return build, wrapGet(s.engine.Get(build)) +} + +func (s storage) GetBuildRef(repo *model.Repo, ref string) (*model.Build, error) { + build := &model.Build{ + RepoID: repo.ID, + Ref: ref, + } + return build, wrapGet(s.engine.Get(build)) +} + +func (s storage) GetBuildCommit(repo *model.Repo, sha, branch string) (*model.Build, error) { + build := &model.Build{ + RepoID: repo.ID, + Branch: branch, + Commit: sha, + } + return build, wrapGet(s.engine.Get(build)) +} + +func (s storage) GetBuildLast(repo *model.Repo, branch string) (*model.Build, error) { + build := &model.Build{ + RepoID: repo.ID, + Branch: branch, + Event: "push", + } + return build, wrapGet(s.engine.Desc("build_number").Get(build)) +} + +func (s storage) GetBuildLastBefore(repo *model.Repo, branch string, num int64) (*model.Build, error) { + build := &model.Build{ + RepoID: repo.ID, + Branch: branch, + } + return build, wrapGet(s.engine. + Desc("build_number"). + Where("build_id < ?", num). + Get(build)) +} + +func (s storage) GetBuildList(repo *model.Repo, page int) ([]*model.Build, error) { + builds := make([]*model.Build, 0, perPage) + return builds, s.engine.Where("build_repo_id = ?", repo.ID). + Desc("build_number"). + Limit(perPage, perPage*(page-1)). + Find(&builds) +} + +func (s storage) GetBuildCount() (int64, error) { + return s.engine.Count(new(model.Build)) +} + +func (s storage) CreateBuild(build *model.Build, procList ...*model.Proc) error { + sess := s.engine.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + // increment counter + if _, err := sess.ID(build.RepoID).Incr("repo_counter").Update(new(model.Repo)); err != nil { + return err + } + + repo := new(model.Repo) + if err := wrapGet(sess.ID(build.RepoID).Get(repo)); err != nil { + return err + } + + build.Number = repo.Counter + build.Created = time.Now().UTC().Unix() + build.Enqueued = build.Created + // only Insert set auto created ID back to object + if _, err := sess.Insert(build); err != nil { + return err + } + + for i := range procList { + // only Insert set auto created ID back to object + if _, err := sess.Insert(procList[i]); err != nil { + return err + } + } + + return sess.Commit() +} + +func (s storage) UpdateBuild(build *model.Build) error { + _, err := s.engine.ID(build.ID).AllCols().Update(build) + return err +} diff --git a/server/store/datastore/builds_test.go b/server/store/datastore/build_test.go similarity index 72% rename from server/store/datastore/builds_test.go rename to server/store/datastore/build_test.go index 382eca203..f1c8a7f8b 100644 --- a/server/store/datastore/builds_test.go +++ b/server/store/datastore/build_test.go @@ -31,24 +31,28 @@ func TestBuilds(t *testing.T) { Name: "test", } - s := newTest() - defer s.Close() + store, closer := newTestStore(t, new(model.Repo), new(model.Proc), new(model.Build)) + defer closer() g := goblin.Goblin(t) g.Describe("Builds", func() { g.Before(func() { - s.Exec("DELETE FROM repos") - s.CreateRepo(repo) + _, err := store.engine.Exec("DELETE FROM repos") + g.Assert(err).IsNil() + g.Assert(store.CreateRepo(repo)).IsNil() }) g.After(func() { - s.Exec("DELETE FROM repos") + _, err := store.engine.Exec("DELETE FROM repos") + g.Assert(err).IsNil() }) // before each test be sure to purge the package // table data from the database. g.BeforeEach(func() { - s.Exec("DELETE FROM builds") - s.Exec("DELETE FROM procs") + _, err := store.engine.Exec("DELETE FROM builds") + g.Assert(err).IsNil() + _, err = store.engine.Exec("DELETE FROM procs") + g.Assert(err).IsNil() }) g.It("Should Post a Build", func() { @@ -57,13 +61,13 @@ func TestBuilds(t *testing.T) { Status: model.StatusSuccess, Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac", } - err := s.CreateBuild(&build) + err := store.CreateBuild(&build) g.Assert(err).IsNil() g.Assert(build.ID != 0).IsTrue() - g.Assert(build.Number).Equal(1) + g.Assert(build.Number).Equal(int64(1)) g.Assert(build.Commit).Equal("85f8c029b902ed9400bc600bac301a0aadb144ac") - count, err := s.GetBuildCount() + count, err := store.GetBuildCount() g.Assert(err).IsNil() g.Assert(count > 0).IsTrue() fmt.Println("GOT COUNT", count) @@ -76,10 +80,11 @@ func TestBuilds(t *testing.T) { Status: model.StatusSuccess, Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac", } - s.CreateBuild(&build) + err := store.CreateBuild(&build) + g.Assert(err).IsNil() build.Status = model.StatusRunning - err1 := s.UpdateBuild(&build) - getbuild, err2 := s.GetBuild(build.ID) + err1 := store.UpdateBuild(&build) + getbuild, err2 := store.GetBuild(build.ID) g.Assert(err1).IsNil() g.Assert(err2).IsNil() g.Assert(build.ID).Equal(getbuild.ID) @@ -93,8 +98,9 @@ func TestBuilds(t *testing.T) { RepoID: repo.ID, Status: model.StatusSuccess, } - s.CreateBuild(&build, []*model.Proc{}...) - getbuild, err := s.GetBuild(build.ID) + err := store.CreateBuild(&build, []*model.Proc{}...) + g.Assert(err).IsNil() + getbuild, err := store.GetBuild(build.ID) g.Assert(err).IsNil() g.Assert(build.ID).Equal(getbuild.ID) g.Assert(build.RepoID).Equal(getbuild.RepoID) @@ -110,11 +116,11 @@ func TestBuilds(t *testing.T) { RepoID: repo.ID, Status: model.StatusPending, } - err1 := s.CreateBuild(build1, []*model.Proc{}...) - err2 := s.CreateBuild(build2, []*model.Proc{}...) - getbuild, err3 := s.GetBuildNumber(&model.Repo{ID: 1}, build2.Number) + err1 := store.CreateBuild(build1, []*model.Proc{}...) g.Assert(err1).IsNil() + err2 := store.CreateBuild(build2, []*model.Proc{}...) g.Assert(err2).IsNil() + getbuild, err3 := store.GetBuildNumber(&model.Repo{ID: 1}, build2.Number) g.Assert(err3).IsNil() g.Assert(build2.ID).Equal(getbuild.ID) g.Assert(build2.RepoID).Equal(getbuild.RepoID) @@ -132,11 +138,11 @@ func TestBuilds(t *testing.T) { Status: model.StatusPending, Ref: "refs/pull/6", } - err1 := s.CreateBuild(build1, []*model.Proc{}...) - err2 := s.CreateBuild(build2, []*model.Proc{}...) - getbuild, err3 := s.GetBuildRef(&model.Repo{ID: 1}, "refs/pull/6") + err1 := store.CreateBuild(build1, []*model.Proc{}...) g.Assert(err1).IsNil() + err2 := store.CreateBuild(build2, []*model.Proc{}...) g.Assert(err2).IsNil() + getbuild, err3 := store.GetBuildRef(&model.Repo{ID: 1}, "refs/pull/6") g.Assert(err3).IsNil() g.Assert(build2.ID).Equal(getbuild.ID) g.Assert(build2.RepoID).Equal(getbuild.RepoID) @@ -155,11 +161,11 @@ func TestBuilds(t *testing.T) { Status: model.StatusPending, Ref: "refs/pull/6", } - err1 := s.CreateBuild(build1, []*model.Proc{}...) - err2 := s.CreateBuild(build2, []*model.Proc{}...) - getbuild, err3 := s.GetBuildRef(&model.Repo{ID: 1}, "refs/pull/6") + err1 := store.CreateBuild(build1, []*model.Proc{}...) g.Assert(err1).IsNil() + err2 := store.CreateBuild(build2, []*model.Proc{}...) g.Assert(err2).IsNil() + getbuild, err3 := store.GetBuildRef(&model.Repo{ID: 1}, "refs/pull/6") g.Assert(err3).IsNil() g.Assert(build2.ID).Equal(getbuild.ID) g.Assert(build2.RepoID).Equal(getbuild.RepoID) @@ -180,11 +186,11 @@ func TestBuilds(t *testing.T) { Branch: "dev", Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa", } - err1 := s.CreateBuild(build1, []*model.Proc{}...) - err2 := s.CreateBuild(build2, []*model.Proc{}...) - getbuild, err3 := s.GetBuildCommit(&model.Repo{ID: 1}, build2.Commit, build2.Branch) + err1 := store.CreateBuild(build1, []*model.Proc{}...) g.Assert(err1).IsNil() + err2 := store.CreateBuild(build2, []*model.Proc{}...) g.Assert(err2).IsNil() + getbuild, err3 := store.GetBuildCommit(&model.Repo{ID: 1}, build2.Commit, build2.Branch) g.Assert(err3).IsNil() g.Assert(build2.ID).Equal(getbuild.ID) g.Assert(build2.RepoID).Equal(getbuild.RepoID) @@ -208,9 +214,9 @@ func TestBuilds(t *testing.T) { Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa", Event: model.EventPush, } - err1 := s.CreateBuild(build1, []*model.Proc{}...) - err2 := s.CreateBuild(build2, []*model.Proc{}...) - getbuild, err3 := s.GetBuildLast(&model.Repo{ID: 1}, build2.Branch) + err1 := store.CreateBuild(build1, []*model.Proc{}...) + err2 := store.CreateBuild(build2, []*model.Proc{}...) + getbuild, err3 := store.GetBuildLast(&model.Repo{ID: 1}, build2.Branch) g.Assert(err1).IsNil() g.Assert(err2).IsNil() g.Assert(err3).IsNil() @@ -241,13 +247,13 @@ func TestBuilds(t *testing.T) { Branch: "master", Commit: "85f8c029b902ed9400bc600bac301a0aadb144aa", } - err1 := s.CreateBuild(build1, []*model.Proc{}...) - err2 := s.CreateBuild(build2, []*model.Proc{}...) - err3 := s.CreateBuild(build3, []*model.Proc{}...) - getbuild, err4 := s.GetBuildLastBefore(&model.Repo{ID: 1}, build3.Branch, build3.ID) + err1 := store.CreateBuild(build1, []*model.Proc{}...) g.Assert(err1).IsNil() + err2 := store.CreateBuild(build2, []*model.Proc{}...) g.Assert(err2).IsNil() + err3 := store.CreateBuild(build3, []*model.Proc{}...) g.Assert(err3).IsNil() + getbuild, err4 := store.GetBuildLastBefore(&model.Repo{ID: 1}, build3.Branch, build3.ID) g.Assert(err4).IsNil() g.Assert(build2.ID).Equal(getbuild.ID) g.Assert(build2.RepoID).Equal(getbuild.RepoID) @@ -266,10 +272,12 @@ func TestBuilds(t *testing.T) { RepoID: repo.ID, Status: model.StatusSuccess, } - s.CreateBuild(build1, []*model.Proc{}...) - s.CreateBuild(build2, []*model.Proc{}...) - builds, err := s.GetBuildList(&model.Repo{ID: 1}, 1) - g.Assert(err).IsNil() + err1 := store.CreateBuild(build1, []*model.Proc{}...) + g.Assert(err1).IsNil() + err2 := store.CreateBuild(build2, []*model.Proc{}...) + g.Assert(err2).IsNil() + builds, err3 := store.GetBuildList(&model.Repo{ID: 1}, 1) + g.Assert(err3).IsNil() g.Assert(len(builds)).Equal(2) g.Assert(builds[0].ID).Equal(build2.ID) g.Assert(builds[0].RepoID).Equal(build2.RepoID) @@ -279,12 +287,8 @@ func TestBuilds(t *testing.T) { } func TestBuildIncrement(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from builds") - s.Close() - }() + store, closer := newTestStore(t, new(model.Build), new(model.Repo)) + defer closer() repo := &model.Repo{ UserID: 1, @@ -292,43 +296,25 @@ func TestBuildIncrement(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - if err := s.CreateRepo(repo); err != nil { + if err := store.CreateRepo(repo); err != nil { t.Error(err) } - num, err := s.incrementRepo(repo.ID, 0, 1) - if err != nil { + if err := store.CreateBuild(&model.Build{RepoID: repo.ID}); err != nil { t.Error(err) } + repo, _ = store.GetRepo(repo.ID) - if got, want := num, 1; got != want { + if got, want := repo.Counter, int64(1); got != want { t.Errorf("Want repository counter incremented to %d, got %d", want, got) } - num, err = s.incrementRepo(repo.ID, 1, 2) - if err != nil { + if err := store.CreateBuild(&model.Build{RepoID: repo.ID}); err != nil { t.Error(err) } + repo, _ = store.GetRepo(repo.ID) - if got, want := num, 2; got != want { - t.Errorf("Want repository counter incremented to %d, got %d", want, got) - } - - // this block tests incrementing the repository counter - // should fail when attempting to increment the counter - // from a stale base. - num, _ = s.incrementRepo(repo.ID, 1, 2) - if num != 0 { - t.Errorf("Want error when trying to increment stale number") - } - - // this block tests incrementing the repository counter - // using the given repository id with backoff. - num, err = s.incrementRepoRetry(repo.ID) - if err != nil { - t.Error(err) - } - if got, want := num, 3; got != want { + if got, want := repo.Counter, int64(2); got != want { t.Errorf("Want repository counter incremented to %d, got %d", want, got) } } diff --git a/server/store/datastore/builds.go b/server/store/datastore/builds.go deleted file mode 100644 index bdb223552..000000000 --- a/server/store/datastore/builds.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "fmt" - "time" - - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) GetBuild(id int64) (*model.Build, error) { - var build = new(model.Build) - var err = meddler.Load(db, buildTable, build, id) - return build, err -} - -func (db *datastore) GetBuildNumber(repo *model.Repo, num int) (*model.Build, error) { - var build = new(model.Build) - var err = meddler.QueryRow(db, build, rebind(buildNumberQuery), repo.ID, num) - return build, err -} - -func (db *datastore) GetBuildRef(repo *model.Repo, ref string) (*model.Build, error) { - var build = new(model.Build) - var err = meddler.QueryRow(db, build, rebind(buildRefQuery), repo.ID, ref) - return build, err -} - -func (db *datastore) GetBuildCommit(repo *model.Repo, sha, branch string) (*model.Build, error) { - var build = new(model.Build) - var err = meddler.QueryRow(db, build, rebind(buildCommitQuery), repo.ID, sha, branch) - return build, err -} - -func (db *datastore) GetBuildLast(repo *model.Repo, branch string) (*model.Build, error) { - var build = new(model.Build) - var err = meddler.QueryRow(db, build, rebind(buildLastQuery), repo.ID, branch) - return build, err -} - -func (db *datastore) GetBuildLastBefore(repo *model.Repo, branch string, num int64) (*model.Build, error) { - var build = new(model.Build) - var err = meddler.QueryRow(db, build, rebind(buildLastBeforeQuery), repo.ID, branch, num) - return build, err -} - -func (db *datastore) GetBuildList(repo *model.Repo, page int) ([]*model.Build, error) { - var builds = []*model.Build{} - var err = meddler.QueryAll(db, &builds, rebind(buildListQuery), repo.ID, 50*(page-1)) - return builds, err -} - -func (db *datastore) GetBuildQueue() ([]*model.Feed, error) { - feed := []*model.Feed{} - err := meddler.QueryAll(db, &feed, buildQueueList) - return feed, err -} - -func (db *datastore) CreateBuild(build *model.Build, procs ...*model.Proc) error { - build.Trim() - id, err := db.incrementRepoRetry(build.RepoID) - if err != nil { - return err - } - build.Number = id - build.Created = time.Now().UTC().Unix() - build.Enqueued = build.Created - err = meddler.Insert(db, buildTable, build) - if err != nil { - return err - } - for _, proc := range procs { - proc.BuildID = build.ID - err = meddler.Insert(db, "procs", proc) - if err != nil { - return err - } - } - return nil -} - -func (db *datastore) incrementRepoRetry(id int64) (int, error) { - repo, err := db.GetRepo(id) - if err != nil { - return 0, fmt.Errorf("database: cannot fetch repository: %s", err) - } - for i := 0; i < 10; i++ { - seq, err := db.incrementRepo(repo.ID, repo.Counter+i, repo.Counter+i+1) - if err != nil { - return 0, err - } - if seq == 0 { - continue - } - return seq, nil - } - return 0, fmt.Errorf("cannot increment next build number") -} - -func (db *datastore) incrementRepo(id int64, old, new int) (int, error) { - results, err := db.Exec(sql.Lookup(db.driver, "repo-update-counter"), new, old, id) - if err != nil { - return 0, fmt.Errorf("database: update repository counter: %s", err) - } - updated, err := results.RowsAffected() - if err != nil { - return 0, fmt.Errorf("database: update repository counter: %s", err) - } - if updated == 0 { - return 0, nil - } - return new, nil -} - -func (db *datastore) UpdateBuild(build *model.Build) error { - return meddler.Update(db, buildTable, build) -} - -func (db *datastore) GetBuildCount() (count int, err error) { - err = db.QueryRow( - sql.Lookup(db.driver, "count-builds"), - ).Scan(&count) - return -} - -const buildTable = "builds" - -const buildListQuery = ` -SELECT * -FROM builds -WHERE build_repo_id = ? -ORDER BY build_number DESC -LIMIT 50 OFFSET ? -` - -const buildNumberQuery = ` -SELECT * -FROM builds -WHERE build_repo_id = ? - AND build_number = ? -LIMIT 1; -` - -const buildLastQuery = ` -SELECT * -FROM builds -WHERE build_repo_id = ? - AND build_branch = ? - AND build_event = 'push' -ORDER BY build_number DESC -LIMIT 1 -` - -const buildLastBeforeQuery = ` -SELECT * -FROM builds -WHERE build_repo_id = ? - AND build_branch = ? - AND build_id < ? -ORDER BY build_number DESC -LIMIT 1 -` - -const buildCommitQuery = ` -SELECT * -FROM builds -WHERE build_repo_id = ? - AND build_commit = ? - AND build_branch = ? -LIMIT 1 -` - -const buildRefQuery = ` -SELECT * -FROM builds -WHERE build_repo_id = ? - AND build_ref = ? -LIMIT 1 -` - -const buildNumberLast = ` -SELECT MAX(build_number) -FROM builds -WHERE build_repo_id = ? -` - -const buildQueueList = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM - builds b -,repos r -WHERE b.build_repo_id = r.repo_id - AND b.build_status IN ('pending','running') -` diff --git a/server/store/datastore/config.go b/server/store/datastore/config.go index 1a0fca4bc..485831fc3 100644 --- a/server/store/datastore/config.go +++ b/server/store/datastore/config.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,44 +15,61 @@ package datastore import ( - gosql "database/sql" - - "github.com/russross/meddler" - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" ) -func (db *datastore) ConfigsForBuild(buildID int64) ([]*model.Config, error) { - stmt := sql.Lookup(db.driver, "config-find-id") - var configs = []*model.Config{} - err := meddler.QueryAll(db, &configs, stmt, buildID) - return configs, err +func (s storage) ConfigsForBuild(buildID int64) ([]*model.Config, error) { + configs := make([]*model.Config, 0, perPage) + return configs, s.engine. + Table("config"). + Join("LEFT", "build_config", "config.config_id = build_config.config_id"). + Where("build_config.build_id = ?", buildID). + Find(&configs) } -func (db *datastore) ConfigFindIdentical(repoID int64, hash string) (*model.Config, error) { - stmt := sql.Lookup(db.driver, "config-find-repo-hash") - conf := new(model.Config) - err := meddler.QueryRow(db, conf, stmt, repoID, hash) - return conf, err -} - -func (db *datastore) ConfigFindApproved(config *model.Config) (bool, error) { - var dest int64 - stmt := sql.Lookup(db.driver, "config-find-approved") - err := db.DB.QueryRow(stmt, config.RepoID, config.ID).Scan(&dest) - if err == gosql.ErrNoRows { - return false, nil - } else if err != nil { - return false, err +func (s storage) ConfigFindIdentical(repoID int64, hash string) (*model.Config, error) { + conf := &model.Config{ + RepoID: repoID, + Hash: hash, } - return true, nil + if err := wrapGet(s.engine.Get(conf)); err != nil { + return nil, err + } + return conf, nil } -func (db *datastore) ConfigCreate(config *model.Config) error { - return meddler.Insert(db, "config", config) +func (s storage) ConfigFindApproved(config *model.Config) (bool, error) { + /* TODO: use builder (do not behave same as pure sql, fix that) + return s.engine.Table(new(model.Build)). + Join("INNER", "build_config", "builds.build_id = build_config.build_id" ). + Where(builder.Eq{"builds.build_repo_id": config.RepoID}). + And(builder.Eq{"build_config.config_id": config.ID}). + And(builder.In("builds.build_status", "blocked", "pending")). + Exist(new(model.Build)) + */ + + c, err := s.engine.SQL(` +SELECT build_id FROM builds +WHERE build_repo_id = ? +AND build_id in ( + SELECT build_id + FROM build_config + WHERE build_config.config_id = ? + ) +AND build_status NOT IN ('blocked', 'pending') +LIMIT 1 +`, config.RepoID, config.ID).Count() + return c > 0, err } -func (db *datastore) BuildConfigCreate(buildConfig *model.BuildConfig) error { - return meddler.Insert(db, "build_config", buildConfig) +func (s storage) ConfigCreate(config *model.Config) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(config) + return err +} + +func (s storage) BuildConfigCreate(config *model.BuildConfig) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(config) + return err } diff --git a/server/store/datastore/config_test.go b/server/store/datastore/config_test.go index 984148d53..638f3d566 100644 --- a/server/store/datastore/config_test.go +++ b/server/store/datastore/config_test.go @@ -17,18 +17,14 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestConfig(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from builds") - s.Exec("delete from procs") - s.Exec("delete from config") - s.Close() - }() + store, closer := newTestStore(t, new(model.Config), new(model.BuildConfig), new(model.Build), new(model.Repo)) + defer closer() var ( data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]" @@ -41,18 +37,18 @@ func TestConfig(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - if err := s.CreateRepo(repo); err != nil { + if err := store.CreateRepo(repo); err != nil { t.Errorf("Unexpected error: insert repo: %s", err) return } config := &model.Config{ RepoID: repo.ID, - Data: data, + Data: []byte(data), Hash: hash, Name: "default", } - if err := s.ConfigCreate(config); err != nil { + if err := store.ConfigCreate(config); err != nil { t.Errorf("Unexpected error: insert config: %s", err) return } @@ -62,12 +58,12 @@ func TestConfig(t *testing.T) { Status: model.StatusRunning, Commit: "85f8c029b902ed9400bc600bac301a0aadb144ac", } - if err := s.CreateBuild(build); err != nil { + if err := store.CreateBuild(build); err != nil { t.Errorf("Unexpected error: insert build: %s", err) return } - if err := s.BuildConfigCreate( + if err := store.BuildConfigCreate( &model.BuildConfig{ ConfigID: config.ID, BuildID: build.ID, @@ -77,7 +73,7 @@ func TestConfig(t *testing.T) { return } - config, err := s.ConfigFindIdentical(repo.ID, hash) + config, err := store.ConfigFindIdentical(repo.ID, hash) if err != nil { t.Error(err) return @@ -88,7 +84,7 @@ func TestConfig(t *testing.T) { if got, want := config.RepoID, repo.ID; got != want { t.Errorf("Want config repo id %d, got %d", want, got) } - if got, want := config.Data, data; got != want { + if got, want := string(config.Data), data; got != want { t.Errorf("Want config data %s, got %s", want, got) } if got, want := config.Hash, hash; got != want { @@ -98,7 +94,7 @@ func TestConfig(t *testing.T) { t.Errorf("Want config name %s, got %s", want, got) } - loaded, err := s.ConfigsForBuild(build.ID) + loaded, err := store.ConfigsForBuild(build.ID) if err != nil { t.Errorf("Want config by id, got error %q", err) return @@ -109,14 +105,8 @@ func TestConfig(t *testing.T) { } func TestConfigApproved(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from builds") - s.Exec("delete from procs") - s.Exec("delete from config") - s.Close() - }() + store, closer := newTestStore(t, new(model.Config), new(model.BuildConfig), new(model.Build), new(model.Repo)) + defer closer() repo := &model.Repo{ UserID: 1, @@ -124,7 +114,7 @@ func TestConfigApproved(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - if err := s.CreateRepo(repo); err != nil { + if err := store.CreateRepo(repo); err != nil { t.Errorf("Unexpected error: insert repo: %s", err) return } @@ -149,20 +139,20 @@ func TestConfigApproved(t *testing.T) { } ) - if err := s.CreateBuild(buildBlocked); err != nil { + if err := store.CreateBuild(buildBlocked); err != nil { t.Errorf("Unexpected error: insert build: %s", err) return } - if err := s.CreateBuild(buildPending); err != nil { + if err := store.CreateBuild(buildPending); err != nil { t.Errorf("Unexpected error: insert build: %s", err) return } conf := &model.Config{ RepoID: repo.ID, - Data: data, + Data: []byte(data), Hash: hash, } - if err := s.ConfigCreate(conf); err != nil { + if err := store.ConfigCreate(conf); err != nil { t.Errorf("Unexpected error: insert config: %s", err) return } @@ -170,23 +160,27 @@ func TestConfigApproved(t *testing.T) { ConfigID: conf.ID, BuildID: buildBlocked.ID, } - if err := s.BuildConfigCreate(buildConfig); err != nil { + if err := store.BuildConfigCreate(buildConfig); err != nil { t.Errorf("Unexpected error: insert build_config: %s", err) return } - if approved, err := s.ConfigFindApproved(conf); approved != false || err != nil { - t.Errorf("Want config not approved, when blocked or pending. %v", err) + approved, err := store.ConfigFindApproved(conf) + if !assert.NoError(t, err) { + return + } + if approved != false { + t.Errorf("Want config not approved, when blocked or pending.") return } - s.CreateBuild(buildRunning) + assert.NoError(t, store.CreateBuild(buildRunning)) conf2 := &model.Config{ RepoID: repo.ID, - Data: data, + Data: []byte(data), Hash: "xxx", } - if err := s.ConfigCreate(conf2); err != nil { + if err := store.ConfigCreate(conf2); err != nil { t.Errorf("Unexpected error: insert config: %s", err) return } @@ -194,36 +188,30 @@ func TestConfigApproved(t *testing.T) { ConfigID: conf2.ID, BuildID: buildRunning.ID, } - if err := s.BuildConfigCreate(buildConfig2); err != nil { + if err := store.BuildConfigCreate(buildConfig2); err != nil { t.Errorf("Unexpected error: insert config: %s", err) return } - if approved, err := s.ConfigFindApproved(conf2); approved != true || err != nil { + if approved, err := store.ConfigFindApproved(conf2); approved != true || err != nil { t.Errorf("Want config approved, when running. %v", err) return } } func TestConfigIndexes(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from builds") - s.Exec("delete from procs") - s.Exec("delete from config") - s.Close() - }() + store, closer := newTestStore(t, new(model.Config), new(model.Proc), new(model.Build), new(model.Repo)) + defer closer() var ( data = "pipeline: [ { image: golang, commands: [ go build, go test ] } ]" hash = "8d8647c9aa90d893bfb79dddbe901f03e258588121e5202632f8ae5738590b26" ) - if err := s.ConfigCreate( + if err := store.ConfigCreate( &model.Config{ RepoID: 2, - Data: data, + Data: []byte(data), Hash: hash, }, ); err != nil { @@ -232,10 +220,10 @@ func TestConfigIndexes(t *testing.T) { } // fail due to duplicate sha - if err := s.ConfigCreate( + if err := store.ConfigCreate( &model.Config{ RepoID: 2, - Data: data, + Data: []byte(data), Hash: hash, }, ); err == nil { diff --git a/server/store/datastore/ddl/migrate.go b/server/store/datastore/ddl/migrate.go deleted file mode 100644 index d93ed13f6..000000000 --- a/server/store/datastore/ddl/migrate.go +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 ddl - -import ( - "database/sql" - "errors" - - "github.com/woodpecker-ci/woodpecker/server/store/datastore/ddl/mysql" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/ddl/postgres" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/ddl/sqlite" -) - -// Supported database drivers -const ( - DriverSqlite = "sqlite3" - DriverMysql = "mysql" - DriverPostgres = "postgres" -) - -// Migrate performs the database migration. If the migration fails -// and error is returned. -func Migrate(driver string, db *sql.DB) error { - if err := checkPriorMigration(db); err != nil { - return err - } - switch driver { - case DriverMysql: - return mysql.Migrate(db) - case DriverPostgres: - return postgres.Migrate(db) - default: - return sqlite.Migrate(db) - } -} - -// we need to check and see if there was a previous migration -// for drone 0.6 or prior and migrate to the new migration -// system. Attempting to migrate from 0.5 or below to 0.7 or -// above will result in an error. -// -// this can be removed once we get to 1.0 with the reasonable -// expectation that people are no longer using 0.5. -func checkPriorMigration(db *sql.DB) error { - var none int - if err := db.QueryRow(legacyMigrationsExist).Scan(&none); err != nil { - // if no legacy migrations exist, this is a fresh install - // and we can proceed as normal. - return nil - } - if err := db.QueryRow(legacyMigrationsCurrent).Scan(&none); err != nil { - // this indicates an attempted upgrade from 0.5 or lower to - // version 0.7 or higher and will fail. - return errors.New("Please upgrade to 0.6 before upgrading to 0.7+") - } - db.Exec(createMigrationsTable) - db.Exec(legacyMigrationsImport) - return nil -} - -var legacyMigrationsExist = ` -SELECT 1 -FROM gorp_migrations -LIMIT 1 -` - -var legacyMigrationsCurrent = ` -SELECT 1 -FROM gorp_migrations -WHERE id = '16.sql' -LIMIT 1 -` - -var legacyMigrationsImport = ` -INSERT INTO migrations (name) VALUES - ('create-table-users') -,('create-table-repos') -,('create-table-builds') -,('create-index-builds-repo') -,('create-index-builds-author') -,('create-table-procs') -,('create-index-procs-build') -,('create-table-logs') -,('create-table-files') -,('create-index-files-builds') -,('create-index-files-procs') -,('create-table-secrets') -,('create-index-secrets-repo') -,('create-table-registry') -,('create-index-registry-repo') -,('create-table-config') -,('create-table-tasks') -,('create-table-agents') -,('create-table-senders') -,('create-index-sender-repos') -` - -var createMigrationsTable = ` -CREATE TABLE migrations ( - name VARCHAR(255) -,UNIQUE(name) -) -` diff --git a/server/store/datastore/ddl/mysql/ddl_gen.go b/server/store/datastore/ddl/mysql/ddl_gen.go deleted file mode 100644 index 77788962c..000000000 --- a/server/store/datastore/ddl/mysql/ddl_gen.go +++ /dev/null @@ -1,783 +0,0 @@ -package mysql - -import ( - "database/sql" -) - -var migrations = []struct { - name string - stmt string -}{ - { - name: "create-table-users", - stmt: createTableUsers, - }, - { - name: "create-table-repos", - stmt: createTableRepos, - }, - { - name: "create-table-builds", - stmt: createTableBuilds, - }, - { - name: "create-index-builds-repo", - stmt: createIndexBuildsRepo, - }, - { - name: "create-index-builds-author", - stmt: createIndexBuildsAuthor, - }, - { - name: "create-table-procs", - stmt: createTableProcs, - }, - { - name: "create-index-procs-build", - stmt: createIndexProcsBuild, - }, - { - name: "create-table-logs", - stmt: createTableLogs, - }, - { - name: "create-table-files", - stmt: createTableFiles, - }, - { - name: "create-index-files-builds", - stmt: createIndexFilesBuilds, - }, - { - name: "create-index-files-procs", - stmt: createIndexFilesProcs, - }, - { - name: "create-table-secrets", - stmt: createTableSecrets, - }, - { - name: "create-index-secrets-repo", - stmt: createIndexSecretsRepo, - }, - { - name: "create-table-registry", - stmt: createTableRegistry, - }, - { - name: "create-index-registry-repo", - stmt: createIndexRegistryRepo, - }, - { - name: "create-table-config", - stmt: createTableConfig, - }, - { - name: "create-table-tasks", - stmt: createTableTasks, - }, - { - name: "create-table-agents", - stmt: createTableAgents, - }, - { - name: "create-table-senders", - stmt: createTableSenders, - }, - { - name: "create-index-sender-repos", - stmt: createIndexSenderRepos, - }, - { - name: "alter-table-add-repo-visibility", - stmt: alterTableAddRepoVisibility, - }, - { - name: "update-table-set-repo-visibility", - stmt: updateTableSetRepoVisibility, - }, - { - name: "alter-table-add-repo-seq", - stmt: alterTableAddRepoSeq, - }, - { - name: "update-table-set-repo-seq", - stmt: updateTableSetRepoSeq, - }, - { - name: "update-table-set-repo-seq-default", - stmt: updateTableSetRepoSeqDefault, - }, - { - name: "alter-table-add-repo-active", - stmt: alterTableAddRepoActive, - }, - { - name: "update-table-set-repo-active", - stmt: updateTableSetRepoActive, - }, - { - name: "alter-table-add-user-synced", - stmt: alterTableAddUserSynced, - }, - { - name: "update-table-set-user-synced", - stmt: updateTableSetUserSynced, - }, - { - name: "create-table-perms", - stmt: createTablePerms, - }, - { - name: "create-index-perms-repo", - stmt: createIndexPermsRepo, - }, - { - name: "create-index-perms-user", - stmt: createIndexPermsUser, - }, - { - name: "alter-table-add-file-pid", - stmt: alterTableAddFilePid, - }, - { - name: "alter-table-add-file-meta-passed", - stmt: alterTableAddFileMetaPassed, - }, - { - name: "alter-table-add-file-meta-failed", - stmt: alterTableAddFileMetaFailed, - }, - { - name: "alter-table-add-file-meta-skipped", - stmt: alterTableAddFileMetaSkipped, - }, - { - name: "alter-table-update-file-meta", - stmt: alterTableUpdateFileMeta, - }, - { - name: "create-table-build-config", - stmt: createTableBuildConfig, - }, - { - name: "alter-table-add-config-name", - stmt: alterTableAddConfigName, - }, - { - name: "update-table-set-config-name", - stmt: updateTableSetConfigName, - }, - { - name: "populate-build-config", - stmt: populateBuildConfig, - }, - { - name: "alter-table-add-task-dependencies", - stmt: alterTableAddTaskDependencies, - }, - { - name: "alter-table-add-task-run-on", - stmt: alterTableAddTaskRunOn, - }, - { - name: "alter-table-add-repo-fallback", - stmt: alterTableAddRepoFallback, - }, - { - name: "update-table-set-repo-fallback", - stmt: updateTableSetRepoFallback, - }, - { - name: "update-table-set-repo-fallback-again", - stmt: updateTableSetRepoFallbackAgain, - }, - { - name: "add-builds-changed_files-column", - stmt: addBuildsChangedfilesColumn, - }, - { - name: "update-builds-set-changed_files", - stmt: updateBuildsSetChangedfiles, - }, - { - name: "alter-table-drop-repo-fallback", - stmt: alterTableDropRepoFallback, - }, - { - name: "drop-allow-push-tags-deploys-columns", - stmt: dropAllowPushTagsDeploysColumns, - }, - { - name: "update-table-set-users-token-and-secret-length", - stmt: updateTableSetUsersTokenAndSecretLength, - }, -} - -// Migrate performs the database migration. If the migration fails -// and error is returned. -func Migrate(db *sql.DB) error { - if err := createTable(db); err != nil { - return err - } - completed, err := selectCompleted(db) - if err != nil && err != sql.ErrNoRows { - return err - } - for _, migration := range migrations { - if _, ok := completed[migration.name]; ok { - - continue - } - - if _, err := db.Exec(migration.stmt); err != nil { - return err - } - if err := insertMigration(db, migration.name); err != nil { - return err - } - - } - return nil -} - -func createTable(db *sql.DB) error { - _, err := db.Exec(migrationTableCreate) - return err -} - -func insertMigration(db *sql.DB, name string) error { - _, err := db.Exec(migrationInsert, name) - return err -} - -func selectCompleted(db *sql.DB) (map[string]struct{}, error) { - migrations := map[string]struct{}{} - rows, err := db.Query(migrationSelect) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - var name string - if err := rows.Scan(&name); err != nil { - return nil, err - } - migrations[name] = struct{}{} - } - return migrations, nil -} - -// -// migration table ddl and sql -// - -var migrationTableCreate = ` -CREATE TABLE IF NOT EXISTS migrations ( - name VARCHAR(255) -,UNIQUE(name) -) -` - -var migrationInsert = ` -INSERT INTO migrations (name) VALUES (?) -` - -var migrationSelect = ` -SELECT name FROM migrations -` - -// -// 001_create_table_users.sql -// - -var createTableUsers = ` -CREATE TABLE IF NOT EXISTS users ( - user_id INTEGER PRIMARY KEY AUTO_INCREMENT -,user_login VARCHAR(250) -,user_token VARCHAR(500) -,user_secret VARCHAR(500) -,user_expiry INTEGER -,user_email VARCHAR(500) -,user_avatar VARCHAR(500) -,user_active BOOLEAN -,user_admin BOOLEAN -,user_hash VARCHAR(500) - -,UNIQUE(user_login) -); -` - -// -// 002_create_table_repos.sql -// - -var createTableRepos = ` -CREATE TABLE IF NOT EXISTS repos ( - repo_id INTEGER PRIMARY KEY AUTO_INCREMENT -,repo_user_id INTEGER -,repo_owner VARCHAR(250) -,repo_name VARCHAR(250) -,repo_full_name VARCHAR(250) -,repo_avatar VARCHAR(500) -,repo_link VARCHAR(1000) -,repo_clone VARCHAR(1000) -,repo_branch VARCHAR(500) -,repo_timeout INTEGER -,repo_private BOOLEAN -,repo_trusted BOOLEAN -,repo_allow_pr BOOLEAN -,repo_allow_push BOOLEAN -,repo_allow_deploys BOOLEAN -,repo_allow_tags BOOLEAN -,repo_hash VARCHAR(500) -,repo_scm VARCHAR(50) -,repo_config_path VARCHAR(500) -,repo_gated BOOLEAN - -,UNIQUE(repo_full_name) -); -` - -// -// 003_create_table_builds.sql -// - -var createTableBuilds = ` -CREATE TABLE IF NOT EXISTS builds ( - build_id INTEGER PRIMARY KEY AUTO_INCREMENT -,build_repo_id INTEGER -,build_number INTEGER -,build_event VARCHAR(500) -,build_status VARCHAR(500) -,build_enqueued INTEGER -,build_created INTEGER -,build_started INTEGER -,build_finished INTEGER -,build_commit VARCHAR(500) -,build_branch VARCHAR(500) -,build_ref VARCHAR(500) -,build_refspec VARCHAR(1000) -,build_remote VARCHAR(500) -,build_title VARCHAR(1000) -,build_message VARCHAR(2000) -,build_timestamp INTEGER -,build_author VARCHAR(500) -,build_avatar VARCHAR(1000) -,build_email VARCHAR(500) -,build_link VARCHAR(1000) -,build_deploy VARCHAR(500) -,build_signed BOOLEAN -,build_verified BOOLEAN -,build_parent INTEGER -,build_error VARCHAR(500) -,build_reviewer VARCHAR(250) -,build_reviewed INTEGER -,build_sender VARCHAR(250) -,build_config_id INTEGER - -,UNIQUE(build_number, build_repo_id) -); -` - -var createIndexBuildsRepo = ` -CREATE INDEX ix_build_repo ON builds (build_repo_id); -` - -var createIndexBuildsAuthor = ` -CREATE INDEX ix_build_author ON builds (build_author); -` - -// -// 004_create_table_procs.sql -// - -var createTableProcs = ` -CREATE TABLE IF NOT EXISTS procs ( - proc_id INTEGER PRIMARY KEY AUTO_INCREMENT -,proc_build_id INTEGER -,proc_pid INTEGER -,proc_ppid INTEGER -,proc_pgid INTEGER -,proc_name VARCHAR(250) -,proc_state VARCHAR(250) -,proc_error VARCHAR(500) -,proc_exit_code INTEGER -,proc_started INTEGER -,proc_stopped INTEGER -,proc_machine VARCHAR(250) -,proc_platform VARCHAR(250) -,proc_environ VARCHAR(2000) - -,UNIQUE(proc_build_id, proc_pid) -); -` - -var createIndexProcsBuild = ` -CREATE INDEX proc_build_ix ON procs (proc_build_id); -` - -// -// 005_create_table_logs.sql -// - -var createTableLogs = ` -CREATE TABLE IF NOT EXISTS logs ( - log_id INTEGER PRIMARY KEY AUTO_INCREMENT -,log_job_id INTEGER -,log_data MEDIUMBLOB - -,UNIQUE(log_job_id) -); -` - -// -// 006_create_table_files.sql -// - -var createTableFiles = ` -CREATE TABLE IF NOT EXISTS files ( - file_id INTEGER PRIMARY KEY AUTO_INCREMENT -,file_build_id INTEGER -,file_proc_id INTEGER -,file_name VARCHAR(250) -,file_mime VARCHAR(250) -,file_size INTEGER -,file_time INTEGER -,file_data MEDIUMBLOB - -,UNIQUE(file_proc_id,file_name) -); -` - -var createIndexFilesBuilds = ` -CREATE INDEX file_build_ix ON files (file_build_id); -` - -var createIndexFilesProcs = ` -CREATE INDEX file_proc_ix ON files (file_proc_id); -` - -// -// 007_create_table_secets.sql -// - -var createTableSecrets = ` -CREATE TABLE IF NOT EXISTS secrets ( - secret_id INTEGER PRIMARY KEY AUTO_INCREMENT -,secret_repo_id INTEGER -,secret_name VARCHAR(250) -,secret_value MEDIUMBLOB -,secret_images VARCHAR(2000) -,secret_events VARCHAR(2000) -,secret_skip_verify BOOLEAN -,secret_conceal BOOLEAN - -,UNIQUE(secret_name, secret_repo_id) -); -` - -var createIndexSecretsRepo = ` -CREATE INDEX ix_secrets_repo ON secrets (secret_repo_id); -` - -// -// 008_create_table_registry.sql -// - -var createTableRegistry = ` -CREATE TABLE IF NOT EXISTS registry ( - registry_id INTEGER PRIMARY KEY AUTO_INCREMENT -,registry_repo_id INTEGER -,registry_addr VARCHAR(250) -,registry_email VARCHAR(500) -,registry_username VARCHAR(2000) -,registry_password VARCHAR(8000) -,registry_token VARCHAR(2000) - -,UNIQUE(registry_addr, registry_repo_id) -); -` - -var createIndexRegistryRepo = ` -CREATE INDEX ix_registry_repo ON registry (registry_repo_id); -` - -// -// 009_create_table_config.sql -// - -var createTableConfig = ` -CREATE TABLE IF NOT EXISTS config ( - config_id INTEGER PRIMARY KEY AUTO_INCREMENT -,config_repo_id INTEGER -,config_hash VARCHAR(250) -,config_data MEDIUMBLOB - -,UNIQUE(config_hash, config_repo_id) -); -` - -// -// 010_create_table_tasks.sql -// - -var createTableTasks = ` -CREATE TABLE IF NOT EXISTS tasks ( - task_id VARCHAR(250) PRIMARY KEY -,task_data MEDIUMBLOB -,task_labels MEDIUMBLOB -); -` - -// -// 011_create_table_agents.sql -// - -var createTableAgents = ` -CREATE TABLE IF NOT EXISTS agents ( - agent_id INTEGER PRIMARY KEY AUTO_INCREMENT -,agent_addr VARCHAR(250) -,agent_platform VARCHAR(500) -,agent_capacity INTEGER -,agent_created INTEGER -,agent_updated INTEGER - -,UNIQUE(agent_addr) -); -` - -// -// 012_create_table_senders.sql -// - -var createTableSenders = ` -CREATE TABLE IF NOT EXISTS senders ( - sender_id INTEGER PRIMARY KEY AUTO_INCREMENT -,sender_repo_id INTEGER -,sender_login VARCHAR(250) -,sender_allow BOOLEAN -,sender_block BOOLEAN - -,UNIQUE(sender_repo_id,sender_login) -); -` - -var createIndexSenderRepos = ` -CREATE INDEX sender_repo_ix ON senders (sender_repo_id); -` - -// -// 013_add_column_repo_visibility.sql -// - -var alterTableAddRepoVisibility = ` -ALTER TABLE repos ADD COLUMN repo_visibility VARCHAR(50) -` - -var updateTableSetRepoVisibility = ` -UPDATE repos -SET repo_visibility = CASE - WHEN repo_private = false THEN 'public' - ELSE 'private' - END -` - -// -// 014_add_column_repo_seq.sql -// - -var alterTableAddRepoSeq = ` -ALTER TABLE repos ADD COLUMN repo_counter INTEGER; -` - -var updateTableSetRepoSeq = ` -UPDATE repos SET repo_counter = ( - SELECT max(build_number) - FROM builds - WHERE builds.build_repo_id = repos.repo_id -) -` - -var updateTableSetRepoSeqDefault = ` -UPDATE repos SET repo_counter = 0 -WHERE repo_counter IS NULL -` - -// -// 015_add_column_repo_active.sql -// - -var alterTableAddRepoActive = ` -ALTER TABLE repos ADD COLUMN repo_active BOOLEAN -` - -var updateTableSetRepoActive = ` -UPDATE repos SET repo_active = true -` - -// -// 016_add_column_user_synced.sql -// - -var alterTableAddUserSynced = ` -ALTER TABLE users ADD COLUMN user_synced INTEGER; -` - -var updateTableSetUserSynced = ` -UPDATE users SET user_synced = 0 -` - -// -// 017_create_table_perms.sql -// - -var createTablePerms = ` -CREATE TABLE IF NOT EXISTS perms ( - perm_user_id INTEGER NOT NULL -,perm_repo_id INTEGER NOT NULL -,perm_pull BOOLEAN -,perm_push BOOLEAN -,perm_admin BOOLEAN -,perm_synced INTEGER -,UNIQUE(perm_user_id, perm_repo_id) -); -` - -var createIndexPermsRepo = ` -CREATE INDEX ix_perms_repo ON perms (perm_repo_id); -` - -var createIndexPermsUser = ` -CREATE INDEX ix_perms_user ON perms (perm_user_id); -` - -// -// 018_add_column_file_pid.sql -// - -var alterTableAddFilePid = ` -ALTER TABLE files ADD COLUMN file_pid INTEGER -` - -var alterTableAddFileMetaPassed = ` -ALTER TABLE files ADD COLUMN file_meta_passed INTEGER -` - -var alterTableAddFileMetaFailed = ` -ALTER TABLE files ADD COLUMN file_meta_failed INTEGER -` - -var alterTableAddFileMetaSkipped = ` -ALTER TABLE files ADD COLUMN file_meta_skipped INTEGER -` - -var alterTableUpdateFileMeta = ` -UPDATE files SET - file_meta_passed=0 -,file_meta_failed=0 -,file_meta_skipped=0 -` - -// -// 019_create_table_build_config.sql -// - -var createTableBuildConfig = ` -CREATE TABLE IF NOT EXISTS build_config ( - config_id INTEGER NOT NULL -,build_id INTEGER NOT NULL -,PRIMARY KEY (config_id, build_id) -,FOREIGN KEY (config_id) REFERENCES config (config_id) -,FOREIGN KEY (build_id) REFERENCES builds (build_id) -); -` - -// -// 020_add_column_config_name.sql -// - -var alterTableAddConfigName = ` -ALTER TABLE config ADD COLUMN config_name TEXT -` - -var updateTableSetConfigName = ` -UPDATE config SET config_name = "drone" -` - -// -// 021_populate_build_config.sql -// - -var populateBuildConfig = ` -INSERT INTO build_config (config_id, build_id) -SELECT build_config_id, build_id FROM builds -` - -// -// 022_add_task_columns.sql -// - -var alterTableAddTaskDependencies = ` -ALTER TABLE tasks ADD COLUMN task_dependencies MEDIUMBLOB -` - -var alterTableAddTaskRunOn = ` -ALTER TABLE tasks ADD COLUMN task_run_on MEDIUMBLOB -` - -// -// 023_add_repo_fallback_column.sql -// - -var alterTableAddRepoFallback = ` -ALTER TABLE repos ADD COLUMN repo_fallback BOOLEAN -` - -var updateTableSetRepoFallback = ` -UPDATE repos SET repo_fallback='false' -` - -// -// 024_add_repo_fallback_column.sql -// - -var updateTableSetRepoFallbackAgain = ` -UPDATE repos SET repo_fallback='false' -` - -// -// 025_add_builds_changed_files_column.sql -// - -var addBuildsChangedfilesColumn = ` -ALTER TABLE builds ADD COLUMN changed_files TEXT -` - -var updateBuildsSetChangedfiles = ` -UPDATE builds SET changed_files='[]' -` - -// -// 026_drop_repo_fallback_column.sql -// - -var alterTableDropRepoFallback = ` -ALTER TABLE repos DROP COLUMN repo_fallback -` - -// -// 027_drop_allow_push_tags_deployments_columns.sql -// - -var dropAllowPushTagsDeploysColumns = ` -ALTER TABLE repos DROP COLUMN repo_allow_push, DROP COLUMN repo_allow_deploys, DROP COLUMN repo_allow_tags -` - -// -// 028_update_table_set_users_token_and_secret_length.sql -// - -var updateTableSetUsersTokenAndSecretLength = ` -ALTER TABLE users MODIFY user_token varchar(1000), MODIFY user_secret varchar(1000); -` diff --git a/server/store/datastore/ddl/mysql/files/001_create_table_users.sql b/server/store/datastore/ddl/mysql/files/001_create_table_users.sql deleted file mode 100644 index d54a8c690..000000000 --- a/server/store/datastore/ddl/mysql/files/001_create_table_users.sql +++ /dev/null @@ -1,16 +0,0 @@ --- name: create-table-users - -CREATE TABLE IF NOT EXISTS users ( - user_id INTEGER PRIMARY KEY AUTO_INCREMENT -,user_login VARCHAR(250) -,user_token VARCHAR(500) -,user_secret VARCHAR(500) -,user_expiry INTEGER -,user_email VARCHAR(500) -,user_avatar VARCHAR(500) -,user_active BOOLEAN -,user_admin BOOLEAN -,user_hash VARCHAR(500) - -,UNIQUE(user_login) -); diff --git a/server/store/datastore/ddl/mysql/files/002_create_table_repos.sql b/server/store/datastore/ddl/mysql/files/002_create_table_repos.sql deleted file mode 100644 index 52e8b8465..000000000 --- a/server/store/datastore/ddl/mysql/files/002_create_table_repos.sql +++ /dev/null @@ -1,26 +0,0 @@ --- name: create-table-repos - -CREATE TABLE IF NOT EXISTS repos ( - repo_id INTEGER PRIMARY KEY AUTO_INCREMENT -,repo_user_id INTEGER -,repo_owner VARCHAR(250) -,repo_name VARCHAR(250) -,repo_full_name VARCHAR(250) -,repo_avatar VARCHAR(500) -,repo_link VARCHAR(1000) -,repo_clone VARCHAR(1000) -,repo_branch VARCHAR(500) -,repo_timeout INTEGER -,repo_private BOOLEAN -,repo_trusted BOOLEAN -,repo_allow_pr BOOLEAN -,repo_allow_push BOOLEAN -,repo_allow_deploys BOOLEAN -,repo_allow_tags BOOLEAN -,repo_hash VARCHAR(500) -,repo_scm VARCHAR(50) -,repo_config_path VARCHAR(500) -,repo_gated BOOLEAN - -,UNIQUE(repo_full_name) -); diff --git a/server/store/datastore/ddl/mysql/files/003_create_table_builds.sql b/server/store/datastore/ddl/mysql/files/003_create_table_builds.sql deleted file mode 100644 index 39959b4ab..000000000 --- a/server/store/datastore/ddl/mysql/files/003_create_table_builds.sql +++ /dev/null @@ -1,44 +0,0 @@ --- name: create-table-builds - -CREATE TABLE IF NOT EXISTS builds ( - build_id INTEGER PRIMARY KEY AUTO_INCREMENT -,build_repo_id INTEGER -,build_number INTEGER -,build_event VARCHAR(500) -,build_status VARCHAR(500) -,build_enqueued INTEGER -,build_created INTEGER -,build_started INTEGER -,build_finished INTEGER -,build_commit VARCHAR(500) -,build_branch VARCHAR(500) -,build_ref VARCHAR(500) -,build_refspec VARCHAR(1000) -,build_remote VARCHAR(500) -,build_title VARCHAR(1000) -,build_message VARCHAR(2000) -,build_timestamp INTEGER -,build_author VARCHAR(500) -,build_avatar VARCHAR(1000) -,build_email VARCHAR(500) -,build_link VARCHAR(1000) -,build_deploy VARCHAR(500) -,build_signed BOOLEAN -,build_verified BOOLEAN -,build_parent INTEGER -,build_error VARCHAR(500) -,build_reviewer VARCHAR(250) -,build_reviewed INTEGER -,build_sender VARCHAR(250) -,build_config_id INTEGER - -,UNIQUE(build_number, build_repo_id) -); - --- name: create-index-builds-repo - -CREATE INDEX ix_build_repo ON builds (build_repo_id); - --- name: create-index-builds-author - -CREATE INDEX ix_build_author ON builds (build_author); diff --git a/server/store/datastore/ddl/mysql/files/004_create_table_procs.sql b/server/store/datastore/ddl/mysql/files/004_create_table_procs.sql deleted file mode 100644 index 784ef18e4..000000000 --- a/server/store/datastore/ddl/mysql/files/004_create_table_procs.sql +++ /dev/null @@ -1,24 +0,0 @@ --- name: create-table-procs - -CREATE TABLE IF NOT EXISTS procs ( - proc_id INTEGER PRIMARY KEY AUTO_INCREMENT -,proc_build_id INTEGER -,proc_pid INTEGER -,proc_ppid INTEGER -,proc_pgid INTEGER -,proc_name VARCHAR(250) -,proc_state VARCHAR(250) -,proc_error VARCHAR(500) -,proc_exit_code INTEGER -,proc_started INTEGER -,proc_stopped INTEGER -,proc_machine VARCHAR(250) -,proc_platform VARCHAR(250) -,proc_environ VARCHAR(2000) - -,UNIQUE(proc_build_id, proc_pid) -); - --- name: create-index-procs-build - -CREATE INDEX proc_build_ix ON procs (proc_build_id); diff --git a/server/store/datastore/ddl/mysql/files/005_create_table_logs.sql b/server/store/datastore/ddl/mysql/files/005_create_table_logs.sql deleted file mode 100644 index d1e898c49..000000000 --- a/server/store/datastore/ddl/mysql/files/005_create_table_logs.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: create-table-logs - -CREATE TABLE IF NOT EXISTS logs ( - log_id INTEGER PRIMARY KEY AUTO_INCREMENT -,log_job_id INTEGER -,log_data MEDIUMBLOB - -,UNIQUE(log_job_id) -); diff --git a/server/store/datastore/ddl/mysql/files/006_create_table_files.sql b/server/store/datastore/ddl/mysql/files/006_create_table_files.sql deleted file mode 100644 index f76f8c90e..000000000 --- a/server/store/datastore/ddl/mysql/files/006_create_table_files.sql +++ /dev/null @@ -1,22 +0,0 @@ --- name: create-table-files - -CREATE TABLE IF NOT EXISTS files ( - file_id INTEGER PRIMARY KEY AUTO_INCREMENT -,file_build_id INTEGER -,file_proc_id INTEGER -,file_name VARCHAR(250) -,file_mime VARCHAR(250) -,file_size INTEGER -,file_time INTEGER -,file_data MEDIUMBLOB - -,UNIQUE(file_proc_id,file_name) -); - --- name: create-index-files-builds - -CREATE INDEX file_build_ix ON files (file_build_id); - --- name: create-index-files-procs - -CREATE INDEX file_proc_ix ON files (file_proc_id); diff --git a/server/store/datastore/ddl/mysql/files/007_create_table_secets.sql b/server/store/datastore/ddl/mysql/files/007_create_table_secets.sql deleted file mode 100644 index 6193fa9e7..000000000 --- a/server/store/datastore/ddl/mysql/files/007_create_table_secets.sql +++ /dev/null @@ -1,18 +0,0 @@ --- name: create-table-secrets - -CREATE TABLE IF NOT EXISTS secrets ( - secret_id INTEGER PRIMARY KEY AUTO_INCREMENT -,secret_repo_id INTEGER -,secret_name VARCHAR(250) -,secret_value MEDIUMBLOB -,secret_images VARCHAR(2000) -,secret_events VARCHAR(2000) -,secret_skip_verify BOOLEAN -,secret_conceal BOOLEAN - -,UNIQUE(secret_name, secret_repo_id) -); - --- name: create-index-secrets-repo - -CREATE INDEX ix_secrets_repo ON secrets (secret_repo_id); diff --git a/server/store/datastore/ddl/mysql/files/008_create_table_registry.sql b/server/store/datastore/ddl/mysql/files/008_create_table_registry.sql deleted file mode 100644 index ea06afff8..000000000 --- a/server/store/datastore/ddl/mysql/files/008_create_table_registry.sql +++ /dev/null @@ -1,17 +0,0 @@ --- name: create-table-registry - -CREATE TABLE IF NOT EXISTS registry ( - registry_id INTEGER PRIMARY KEY AUTO_INCREMENT -,registry_repo_id INTEGER -,registry_addr VARCHAR(250) -,registry_email VARCHAR(500) -,registry_username VARCHAR(2000) -,registry_password VARCHAR(8000) -,registry_token VARCHAR(2000) - -,UNIQUE(registry_addr, registry_repo_id) -); - --- name: create-index-registry-repo - -CREATE INDEX ix_registry_repo ON registry (registry_repo_id); diff --git a/server/store/datastore/ddl/mysql/files/009_create_table_config.sql b/server/store/datastore/ddl/mysql/files/009_create_table_config.sql deleted file mode 100644 index f907a23b3..000000000 --- a/server/store/datastore/ddl/mysql/files/009_create_table_config.sql +++ /dev/null @@ -1,10 +0,0 @@ --- name: create-table-config - -CREATE TABLE IF NOT EXISTS config ( - config_id INTEGER PRIMARY KEY AUTO_INCREMENT -,config_repo_id INTEGER -,config_hash VARCHAR(250) -,config_data MEDIUMBLOB - -,UNIQUE(config_hash, config_repo_id) -); diff --git a/server/store/datastore/ddl/mysql/files/010_create_table_tasks.sql b/server/store/datastore/ddl/mysql/files/010_create_table_tasks.sql deleted file mode 100644 index 40f908b79..000000000 --- a/server/store/datastore/ddl/mysql/files/010_create_table_tasks.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: create-table-tasks - -CREATE TABLE IF NOT EXISTS tasks ( - task_id VARCHAR(250) PRIMARY KEY -,task_data MEDIUMBLOB -,task_labels MEDIUMBLOB -); diff --git a/server/store/datastore/ddl/mysql/files/011_create_table_agents.sql b/server/store/datastore/ddl/mysql/files/011_create_table_agents.sql deleted file mode 100644 index 5a91b2e10..000000000 --- a/server/store/datastore/ddl/mysql/files/011_create_table_agents.sql +++ /dev/null @@ -1,12 +0,0 @@ --- name: create-table-agents - -CREATE TABLE IF NOT EXISTS agents ( - agent_id INTEGER PRIMARY KEY AUTO_INCREMENT -,agent_addr VARCHAR(250) -,agent_platform VARCHAR(500) -,agent_capacity INTEGER -,agent_created INTEGER -,agent_updated INTEGER - -,UNIQUE(agent_addr) -); diff --git a/server/store/datastore/ddl/mysql/files/012_create_table_senders.sql b/server/store/datastore/ddl/mysql/files/012_create_table_senders.sql deleted file mode 100644 index 02e5bd8e2..000000000 --- a/server/store/datastore/ddl/mysql/files/012_create_table_senders.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: create-table-senders - -CREATE TABLE IF NOT EXISTS senders ( - sender_id INTEGER PRIMARY KEY AUTO_INCREMENT -,sender_repo_id INTEGER -,sender_login VARCHAR(250) -,sender_allow BOOLEAN -,sender_block BOOLEAN - -,UNIQUE(sender_repo_id,sender_login) -); - --- name: create-index-sender-repos - -CREATE INDEX sender_repo_ix ON senders (sender_repo_id); diff --git a/server/store/datastore/ddl/mysql/files/013_add_column_repo_visibility.sql b/server/store/datastore/ddl/mysql/files/013_add_column_repo_visibility.sql deleted file mode 100644 index e9ee9af9d..000000000 --- a/server/store/datastore/ddl/mysql/files/013_add_column_repo_visibility.sql +++ /dev/null @@ -1,11 +0,0 @@ --- name: alter-table-add-repo-visibility - -ALTER TABLE repos ADD COLUMN repo_visibility VARCHAR(50) - --- name: update-table-set-repo-visibility - -UPDATE repos -SET repo_visibility = CASE - WHEN repo_private = false THEN 'public' - ELSE 'private' - END diff --git a/server/store/datastore/ddl/mysql/files/014_add_column_repo_seq.sql b/server/store/datastore/ddl/mysql/files/014_add_column_repo_seq.sql deleted file mode 100644 index a0be87dda..000000000 --- a/server/store/datastore/ddl/mysql/files/014_add_column_repo_seq.sql +++ /dev/null @@ -1,16 +0,0 @@ --- name: alter-table-add-repo-seq - -ALTER TABLE repos ADD COLUMN repo_counter INTEGER; - --- name: update-table-set-repo-seq - -UPDATE repos SET repo_counter = ( - SELECT max(build_number) - FROM builds - WHERE builds.build_repo_id = repos.repo_id -) - --- name: update-table-set-repo-seq-default - -UPDATE repos SET repo_counter = 0 -WHERE repo_counter IS NULL diff --git a/server/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql b/server/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql deleted file mode 100644 index 4dca2dd1e..000000000 --- a/server/store/datastore/ddl/mysql/files/015_add_column_repo_active.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-repo-active - -ALTER TABLE repos ADD COLUMN repo_active BOOLEAN - --- name: update-table-set-repo-active - -UPDATE repos SET repo_active = true diff --git a/server/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql b/server/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql deleted file mode 100644 index 43db914e7..000000000 --- a/server/store/datastore/ddl/mysql/files/016_add_column_user_synced.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-user-synced - -ALTER TABLE users ADD COLUMN user_synced INTEGER; - --- name: update-table-set-user-synced - -UPDATE users SET user_synced = 0 diff --git a/server/store/datastore/ddl/mysql/files/017_create_table_perms.sql b/server/store/datastore/ddl/mysql/files/017_create_table_perms.sql deleted file mode 100644 index c40dc7f4b..000000000 --- a/server/store/datastore/ddl/mysql/files/017_create_table_perms.sql +++ /dev/null @@ -1,19 +0,0 @@ --- name: create-table-perms - -CREATE TABLE IF NOT EXISTS perms ( - perm_user_id INTEGER NOT NULL -,perm_repo_id INTEGER NOT NULL -,perm_pull BOOLEAN -,perm_push BOOLEAN -,perm_admin BOOLEAN -,perm_synced INTEGER -,UNIQUE(perm_user_id, perm_repo_id) -); - --- name: create-index-perms-repo - -CREATE INDEX ix_perms_repo ON perms (perm_repo_id); - --- name: create-index-perms-user - -CREATE INDEX ix_perms_user ON perms (perm_user_id); diff --git a/server/store/datastore/ddl/mysql/files/018_add_column_file_pid.sql b/server/store/datastore/ddl/mysql/files/018_add_column_file_pid.sql deleted file mode 100644 index 0ad11ac78..000000000 --- a/server/store/datastore/ddl/mysql/files/018_add_column_file_pid.sql +++ /dev/null @@ -1,22 +0,0 @@ --- name: alter-table-add-file-pid - -ALTER TABLE files ADD COLUMN file_pid INTEGER - --- name: alter-table-add-file-meta-passed - -ALTER TABLE files ADD COLUMN file_meta_passed INTEGER - --- name: alter-table-add-file-meta-failed - -ALTER TABLE files ADD COLUMN file_meta_failed INTEGER - --- name: alter-table-add-file-meta-skipped - -ALTER TABLE files ADD COLUMN file_meta_skipped INTEGER - --- name: alter-table-update-file-meta - -UPDATE files SET - file_meta_passed=0 -,file_meta_failed=0 -,file_meta_skipped=0 diff --git a/server/store/datastore/ddl/mysql/files/019_create_table_build_config.sql b/server/store/datastore/ddl/mysql/files/019_create_table_build_config.sql deleted file mode 100644 index be5d58718..000000000 --- a/server/store/datastore/ddl/mysql/files/019_create_table_build_config.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: create-table-build-config - -CREATE TABLE IF NOT EXISTS build_config ( - config_id INTEGER NOT NULL -,build_id INTEGER NOT NULL -,PRIMARY KEY (config_id, build_id) -,FOREIGN KEY (config_id) REFERENCES config (config_id) -,FOREIGN KEY (build_id) REFERENCES builds (build_id) -); diff --git a/server/store/datastore/ddl/mysql/files/020_add_column_config_name.sql b/server/store/datastore/ddl/mysql/files/020_add_column_config_name.sql deleted file mode 100644 index 0140b4035..000000000 --- a/server/store/datastore/ddl/mysql/files/020_add_column_config_name.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-config-name - -ALTER TABLE config ADD COLUMN config_name TEXT - --- name: update-table-set-config-name - -UPDATE config SET config_name = "drone" \ No newline at end of file diff --git a/server/store/datastore/ddl/mysql/files/021_populate_build_config.sql b/server/store/datastore/ddl/mysql/files/021_populate_build_config.sql deleted file mode 100644 index e004b81c9..000000000 --- a/server/store/datastore/ddl/mysql/files/021_populate_build_config.sql +++ /dev/null @@ -1,4 +0,0 @@ --- name: populate-build-config - -INSERT INTO build_config (config_id, build_id) -SELECT build_config_id, build_id FROM builds diff --git a/server/store/datastore/ddl/mysql/files/022_add_task_columns.sql b/server/store/datastore/ddl/mysql/files/022_add_task_columns.sql deleted file mode 100644 index b98a2180a..000000000 --- a/server/store/datastore/ddl/mysql/files/022_add_task_columns.sql +++ /dev/null @@ -1,6 +0,0 @@ --- name: alter-table-add-task-dependencies -ALTER TABLE tasks ADD COLUMN task_dependencies MEDIUMBLOB - --- name: alter-table-add-task-run-on - -ALTER TABLE tasks ADD COLUMN task_run_on MEDIUMBLOB \ No newline at end of file diff --git a/server/store/datastore/ddl/mysql/files/023_add_repo_fallback_column.sql b/server/store/datastore/ddl/mysql/files/023_add_repo_fallback_column.sql deleted file mode 100644 index 3e3384854..000000000 --- a/server/store/datastore/ddl/mysql/files/023_add_repo_fallback_column.sql +++ /dev/null @@ -1,5 +0,0 @@ --- name: alter-table-add-repo-fallback -ALTER TABLE repos ADD COLUMN repo_fallback BOOLEAN - --- name: update-table-set-repo-fallback -UPDATE repos SET repo_fallback='false' diff --git a/server/store/datastore/ddl/mysql/files/024_add_repo_fallback_column.sql b/server/store/datastore/ddl/mysql/files/024_add_repo_fallback_column.sql deleted file mode 100644 index 0a663b4e1..000000000 --- a/server/store/datastore/ddl/mysql/files/024_add_repo_fallback_column.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: update-table-set-repo-fallback-again -UPDATE repos SET repo_fallback='false' diff --git a/server/store/datastore/ddl/mysql/files/025_add_builds_changed_files_column.sql b/server/store/datastore/ddl/mysql/files/025_add_builds_changed_files_column.sql deleted file mode 100644 index 2ff3c14be..000000000 --- a/server/store/datastore/ddl/mysql/files/025_add_builds_changed_files_column.sql +++ /dev/null @@ -1,5 +0,0 @@ --- name: add-builds-changed_files-column -ALTER TABLE builds ADD COLUMN changed_files TEXT - --- name: update-builds-set-changed_files -UPDATE builds SET changed_files='[]' \ No newline at end of file diff --git a/server/store/datastore/ddl/mysql/files/026_drop_repo_fallback_column.sql b/server/store/datastore/ddl/mysql/files/026_drop_repo_fallback_column.sql deleted file mode 100644 index 9cd766ffc..000000000 --- a/server/store/datastore/ddl/mysql/files/026_drop_repo_fallback_column.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: alter-table-drop-repo-fallback -ALTER TABLE repos DROP COLUMN repo_fallback diff --git a/server/store/datastore/ddl/mysql/files/027_drop_allow_push_tags_deployments_columns.sql b/server/store/datastore/ddl/mysql/files/027_drop_allow_push_tags_deployments_columns.sql deleted file mode 100644 index bae5a3b37..000000000 --- a/server/store/datastore/ddl/mysql/files/027_drop_allow_push_tags_deployments_columns.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: drop-allow-push-tags-deploys-columns -ALTER TABLE repos DROP COLUMN repo_allow_push, DROP COLUMN repo_allow_deploys, DROP COLUMN repo_allow_tags diff --git a/server/store/datastore/ddl/mysql/files/028_update_table_set_users_token_and_secret_length.sql b/server/store/datastore/ddl/mysql/files/028_update_table_set_users_token_and_secret_length.sql deleted file mode 100644 index 68f72ed71..000000000 --- a/server/store/datastore/ddl/mysql/files/028_update_table_set_users_token_and_secret_length.sql +++ /dev/null @@ -1,3 +0,0 @@ --- name: update-table-set-users-token-and-secret-length - -ALTER TABLE users MODIFY user_token varchar(1000), MODIFY user_secret varchar(1000); diff --git a/server/store/datastore/ddl/postgres/ddl_gen.go b/server/store/datastore/ddl/postgres/ddl_gen.go deleted file mode 100644 index 1d9c0bf2c..000000000 --- a/server/store/datastore/ddl/postgres/ddl_gen.go +++ /dev/null @@ -1,786 +0,0 @@ -package postgres - -import ( - "database/sql" -) - -var migrations = []struct { - name string - stmt string -}{ - { - name: "create-table-users", - stmt: createTableUsers, - }, - { - name: "create-table-repos", - stmt: createTableRepos, - }, - { - name: "create-table-builds", - stmt: createTableBuilds, - }, - { - name: "create-index-builds-repo", - stmt: createIndexBuildsRepo, - }, - { - name: "create-index-builds-author", - stmt: createIndexBuildsAuthor, - }, - { - name: "create-table-procs", - stmt: createTableProcs, - }, - { - name: "create-index-procs-build", - stmt: createIndexProcsBuild, - }, - { - name: "create-table-logs", - stmt: createTableLogs, - }, - { - name: "create-table-files", - stmt: createTableFiles, - }, - { - name: "create-index-files-builds", - stmt: createIndexFilesBuilds, - }, - { - name: "create-index-files-procs", - stmt: createIndexFilesProcs, - }, - { - name: "create-table-secrets", - stmt: createTableSecrets, - }, - { - name: "create-index-secrets-repo", - stmt: createIndexSecretsRepo, - }, - { - name: "create-table-registry", - stmt: createTableRegistry, - }, - { - name: "create-index-registry-repo", - stmt: createIndexRegistryRepo, - }, - { - name: "create-table-config", - stmt: createTableConfig, - }, - { - name: "create-table-tasks", - stmt: createTableTasks, - }, - { - name: "create-table-agents", - stmt: createTableAgents, - }, - { - name: "create-table-senders", - stmt: createTableSenders, - }, - { - name: "create-index-sender-repos", - stmt: createIndexSenderRepos, - }, - { - name: "alter-table-add-repo-visibility", - stmt: alterTableAddRepoVisibility, - }, - { - name: "update-table-set-repo-visibility", - stmt: updateTableSetRepoVisibility, - }, - { - name: "alter-table-add-repo-seq", - stmt: alterTableAddRepoSeq, - }, - { - name: "update-table-set-repo-seq", - stmt: updateTableSetRepoSeq, - }, - { - name: "update-table-set-repo-seq-default", - stmt: updateTableSetRepoSeqDefault, - }, - { - name: "alter-table-add-repo-active", - stmt: alterTableAddRepoActive, - }, - { - name: "update-table-set-repo-active", - stmt: updateTableSetRepoActive, - }, - { - name: "alter-table-add-user-synced", - stmt: alterTableAddUserSynced, - }, - { - name: "update-table-set-user-synced", - stmt: updateTableSetUserSynced, - }, - { - name: "create-table-perms", - stmt: createTablePerms, - }, - { - name: "create-index-perms-repo", - stmt: createIndexPermsRepo, - }, - { - name: "create-index-perms-user", - stmt: createIndexPermsUser, - }, - { - name: "alter-table-add-file-pid", - stmt: alterTableAddFilePid, - }, - { - name: "alter-table-add-file-meta-passed", - stmt: alterTableAddFileMetaPassed, - }, - { - name: "alter-table-add-file-meta-failed", - stmt: alterTableAddFileMetaFailed, - }, - { - name: "alter-table-add-file-meta-skipped", - stmt: alterTableAddFileMetaSkipped, - }, - { - name: "alter-table-update-file-meta", - stmt: alterTableUpdateFileMeta, - }, - { - name: "create-table-build-config", - stmt: createTableBuildConfig, - }, - { - name: "alter-table-add-config-name", - stmt: alterTableAddConfigName, - }, - { - name: "update-table-set-config-name", - stmt: updateTableSetConfigName, - }, - { - name: "populate-build-config", - stmt: populateBuildConfig, - }, - { - name: "alter-table-add-task-dependencies", - stmt: alterTableAddTaskDependencies, - }, - { - name: "alter-table-add-task-run-on", - stmt: alterTableAddTaskRunOn, - }, - { - name: "alter-table-add-repo-fallback", - stmt: alterTableAddRepoFallback, - }, - { - name: "update-table-set-repo-fallback", - stmt: updateTableSetRepoFallback, - }, - { - name: "update-table-set-repo-fallback-again", - stmt: updateTableSetRepoFallbackAgain, - }, - { - name: "add-builds-changed_files-column", - stmt: addBuildsChangedfilesColumn, - }, - { - name: "update-builds-set-changed_files", - stmt: updateBuildsSetChangedfiles, - }, - { - name: "alter-table-drop-repo-fallback", - stmt: alterTableDropRepoFallback, - }, - { - name: "drop-allow-push-tags-deploys-columns", - stmt: dropAllowPushTagsDeploysColumns, - }, - { - name: "update-table-set-users-token-and-secret-length", - stmt: updateTableSetUsersTokenAndSecretLength, - }, -} - -// Migrate performs the database migration. If the migration fails -// and error is returned. -func Migrate(db *sql.DB) error { - if err := createTable(db); err != nil { - return err - } - completed, err := selectCompleted(db) - if err != nil && err != sql.ErrNoRows { - return err - } - for _, migration := range migrations { - if _, ok := completed[migration.name]; ok { - - continue - } - - if _, err := db.Exec(migration.stmt); err != nil { - return err - } - if err := insertMigration(db, migration.name); err != nil { - return err - } - - } - return nil -} - -func createTable(db *sql.DB) error { - _, err := db.Exec(migrationTableCreate) - return err -} - -func insertMigration(db *sql.DB, name string) error { - _, err := db.Exec(migrationInsert, name) - return err -} - -func selectCompleted(db *sql.DB) (map[string]struct{}, error) { - migrations := map[string]struct{}{} - rows, err := db.Query(migrationSelect) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - var name string - if err := rows.Scan(&name); err != nil { - return nil, err - } - migrations[name] = struct{}{} - } - return migrations, nil -} - -// -// migration table ddl and sql -// - -var migrationTableCreate = ` -CREATE TABLE IF NOT EXISTS migrations ( - name VARCHAR(255) -,UNIQUE(name) -) -` - -var migrationInsert = ` -INSERT INTO migrations (name) VALUES ($1) -` - -var migrationSelect = ` -SELECT name FROM migrations -` - -// -// 001_create_table_users.sql -// - -var createTableUsers = ` -CREATE TABLE IF NOT EXISTS users ( - user_id SERIAL PRIMARY KEY -,user_login VARCHAR(250) -,user_token VARCHAR(500) -,user_secret VARCHAR(500) -,user_expiry INTEGER -,user_email VARCHAR(500) -,user_avatar VARCHAR(500) -,user_active BOOLEAN -,user_admin BOOLEAN -,user_hash VARCHAR(500) - -,UNIQUE(user_login) -); -` - -// -// 002_create_table_repos.sql -// - -var createTableRepos = ` -CREATE TABLE IF NOT EXISTS repos ( - repo_id SERIAL PRIMARY KEY -,repo_user_id INTEGER -,repo_owner VARCHAR(250) -,repo_name VARCHAR(250) -,repo_full_name VARCHAR(250) -,repo_avatar VARCHAR(500) -,repo_link VARCHAR(1000) -,repo_clone VARCHAR(1000) -,repo_branch VARCHAR(500) -,repo_timeout INTEGER -,repo_private BOOLEAN -,repo_trusted BOOLEAN -,repo_allow_pr BOOLEAN -,repo_allow_push BOOLEAN -,repo_allow_deploys BOOLEAN -,repo_allow_tags BOOLEAN -,repo_hash VARCHAR(500) -,repo_scm VARCHAR(50) -,repo_config_path VARCHAR(500) -,repo_gated BOOLEAN - -,UNIQUE(repo_full_name) -); -` - -// -// 003_create_table_builds.sql -// - -var createTableBuilds = ` -CREATE TABLE IF NOT EXISTS builds ( - build_id SERIAL PRIMARY KEY -,build_repo_id INTEGER -,build_number INTEGER -,build_event VARCHAR(500) -,build_status VARCHAR(500) -,build_enqueued INTEGER -,build_created INTEGER -,build_started INTEGER -,build_finished INTEGER -,build_commit VARCHAR(500) -,build_branch VARCHAR(500) -,build_ref VARCHAR(500) -,build_refspec VARCHAR(1000) -,build_remote VARCHAR(500) -,build_title VARCHAR(1000) -,build_message VARCHAR(2000) -,build_timestamp INTEGER -,build_author VARCHAR(500) -,build_avatar VARCHAR(1000) -,build_email VARCHAR(500) -,build_link VARCHAR(1000) -,build_deploy VARCHAR(500) -,build_signed BOOLEAN -,build_verified BOOLEAN -,build_parent INTEGER -,build_error VARCHAR(500) -,build_reviewer VARCHAR(250) -,build_reviewed INTEGER -,build_sender VARCHAR(250) -,build_config_id INTEGER - -,UNIQUE(build_number, build_repo_id) -); -` - -var createIndexBuildsRepo = ` -CREATE INDEX IF NOT EXISTS ix_build_repo ON builds (build_repo_id); -` - -var createIndexBuildsAuthor = ` -CREATE INDEX IF NOT EXISTS ix_build_author ON builds (build_author); -` - -// -// 004_create_table_procs.sql -// - -var createTableProcs = ` -CREATE TABLE IF NOT EXISTS procs ( - proc_id SERIAL PRIMARY KEY -,proc_build_id INTEGER -,proc_pid INTEGER -,proc_ppid INTEGER -,proc_pgid INTEGER -,proc_name VARCHAR(250) -,proc_state VARCHAR(250) -,proc_error VARCHAR(500) -,proc_exit_code INTEGER -,proc_started INTEGER -,proc_stopped INTEGER -,proc_machine VARCHAR(250) -,proc_platform VARCHAR(250) -,proc_environ VARCHAR(2000) - -,UNIQUE(proc_build_id, proc_pid) -); -` - -var createIndexProcsBuild = ` -CREATE INDEX IF NOT EXISTS proc_build_ix ON procs (proc_build_id); -` - -// -// 005_create_table_logs.sql -// - -var createTableLogs = ` -CREATE TABLE IF NOT EXISTS logs ( - log_id SERIAL PRIMARY KEY -,log_job_id INTEGER -,log_data BYTEA - -,UNIQUE(log_job_id) -); -` - -// -// 006_create_table_files.sql -// - -var createTableFiles = ` -CREATE TABLE IF NOT EXISTS files ( - file_id SERIAL PRIMARY KEY -,file_build_id INTEGER -,file_proc_id INTEGER -,file_name VARCHAR(250) -,file_mime VARCHAR(250) -,file_size INTEGER -,file_time INTEGER -,file_data BYTEA - -,UNIQUE(file_proc_id,file_name) -); -` - -var createIndexFilesBuilds = ` -CREATE INDEX IF NOT EXISTS file_build_ix ON files (file_build_id); -` - -var createIndexFilesProcs = ` -CREATE INDEX IF NOT EXISTS file_proc_ix ON files (file_proc_id); -` - -// -// 007_create_table_secets.sql -// - -var createTableSecrets = ` -CREATE TABLE IF NOT EXISTS secrets ( - secret_id SERIAL PRIMARY KEY -,secret_repo_id INTEGER -,secret_name VARCHAR(250) -,secret_value BYTEA -,secret_images VARCHAR(2000) -,secret_events VARCHAR(2000) -,secret_skip_verify BOOLEAN -,secret_conceal BOOLEAN - -,UNIQUE(secret_name, secret_repo_id) -); -` - -var createIndexSecretsRepo = ` -CREATE INDEX IF NOT EXISTS ix_secrets_repo ON secrets (secret_repo_id); -` - -// -// 008_create_table_registry.sql -// - -var createTableRegistry = ` -CREATE TABLE IF NOT EXISTS registry ( - registry_id SERIAL PRIMARY KEY -,registry_repo_id INTEGER -,registry_addr VARCHAR(250) -,registry_email VARCHAR(500) -,registry_username VARCHAR(2000) -,registry_password VARCHAR(8000) -,registry_token VARCHAR(2000) - -,UNIQUE(registry_addr, registry_repo_id) -); -` - -var createIndexRegistryRepo = ` -CREATE INDEX IF NOT EXISTS ix_registry_repo ON registry (registry_repo_id); -` - -// -// 009_create_table_config.sql -// - -var createTableConfig = ` -CREATE TABLE IF NOT EXISTS config ( - config_id SERIAL PRIMARY KEY -,config_repo_id INTEGER -,config_hash VARCHAR(250) -,config_data BYTEA - -,UNIQUE(config_hash, config_repo_id) -); -` - -// -// 010_create_table_tasks.sql -// - -var createTableTasks = ` -CREATE TABLE IF NOT EXISTS tasks ( - task_id VARCHAR(250) PRIMARY KEY -,task_data BYTEA -,task_labels BYTEA -); -` - -// -// 011_create_table_agents.sql -// - -var createTableAgents = ` -CREATE TABLE IF NOT EXISTS agents ( - agent_id SERIAL PRIMARY KEY -,agent_addr VARCHAR(250) -,agent_platform VARCHAR(500) -,agent_capacity INTEGER -,agent_created INTEGER -,agent_updated INTEGER - -,UNIQUE(agent_addr) -); -` - -// -// 012_create_table_senders.sql -// - -var createTableSenders = ` -CREATE TABLE IF NOT EXISTS senders ( - sender_id SERIAL PRIMARY KEY -,sender_repo_id INTEGER -,sender_login VARCHAR(250) -,sender_allow BOOLEAN -,sender_block BOOLEAN - -,UNIQUE(sender_repo_id,sender_login) -); -` - -var createIndexSenderRepos = ` -CREATE INDEX IF NOT EXISTS sender_repo_ix ON senders (sender_repo_id); -` - -// -// 013_add_column_repo_visibility.sql -// - -var alterTableAddRepoVisibility = ` -ALTER TABLE repos ADD COLUMN repo_visibility VARCHAR(50); -` - -var updateTableSetRepoVisibility = ` -UPDATE repos -SET repo_visibility = (CASE - WHEN repo_private = false THEN 'public' - ELSE 'private' - END); -` - -// -// 014_add_column_repo_seq.sql -// - -var alterTableAddRepoSeq = ` -ALTER TABLE repos ADD COLUMN repo_counter INTEGER; -` - -var updateTableSetRepoSeq = ` -UPDATE repos SET repo_counter = ( - SELECT max(build_number) - FROM builds - WHERE builds.build_repo_id = repos.repo_id -); -` - -var updateTableSetRepoSeqDefault = ` -UPDATE repos SET repo_counter = 0 -WHERE repo_counter IS NULL -; -` - -// -// 015_add_column_repo_active.sql -// - -var alterTableAddRepoActive = ` -ALTER TABLE repos ADD COLUMN repo_active BOOLEAN; -` - -var updateTableSetRepoActive = ` -UPDATE repos SET repo_active = true; -` - -// -// 016_add_column_user_synced.sql -// - -var alterTableAddUserSynced = ` -ALTER TABLE users ADD COLUMN user_synced INTEGER; -` - -var updateTableSetUserSynced = ` -UPDATE users SET user_synced = 0; -` - -// -// 017_create_table_perms.sql -// - -var createTablePerms = ` -CREATE TABLE IF NOT EXISTS perms ( - perm_user_id INTEGER NOT NULL -,perm_repo_id INTEGER NOT NULL -,perm_pull BOOLEAN -,perm_push BOOLEAN -,perm_admin BOOLEAN -,perm_synced INTEGER -,UNIQUE(perm_user_id, perm_repo_id) -); -` - -var createIndexPermsRepo = ` -CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id); -` - -var createIndexPermsUser = ` -CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id); -` - -// -// 018_add_column_file_pid.sql -// - -var alterTableAddFilePid = ` -ALTER TABLE files ADD COLUMN file_pid INTEGER; -` - -var alterTableAddFileMetaPassed = ` -ALTER TABLE files ADD COLUMN file_meta_passed INTEGER; -` - -var alterTableAddFileMetaFailed = ` -ALTER TABLE files ADD COLUMN file_meta_failed INTEGER; -` - -var alterTableAddFileMetaSkipped = ` -ALTER TABLE files ADD COLUMN file_meta_skipped INTEGER; -` - -var alterTableUpdateFileMeta = ` -UPDATE files SET - file_meta_passed=0 -,file_meta_failed=0 -,file_meta_skipped=0 -; -` - -// -// 019_create_table_build_config.sql -// - -var createTableBuildConfig = ` -CREATE TABLE IF NOT EXISTS build_config ( - config_id INTEGER NOT NULL -,build_id INTEGER NOT NULL -,PRIMARY KEY (config_id, build_id) -,FOREIGN KEY (config_id) REFERENCES config (config_id) -,FOREIGN KEY (build_id) REFERENCES builds (build_id) -); -` - -// -// 020_add_column_config_name.sql -// - -var alterTableAddConfigName = ` -ALTER TABLE config ADD COLUMN config_name TEXT -` - -var updateTableSetConfigName = ` -UPDATE config SET config_name = 'drone' -` - -// -// 021_populate_build_config.sql -// - -var populateBuildConfig = ` -INSERT INTO build_config (config_id, build_id) -SELECT build_config_id, build_id FROM builds -` - -// -// 022_add_task_columns.sql -// - -var alterTableAddTaskDependencies = ` -ALTER TABLE tasks ADD COLUMN task_dependencies BYTEA -` - -var alterTableAddTaskRunOn = ` -ALTER TABLE tasks ADD COLUMN task_run_on BYTEA -` - -// -// 023_add_repo_fallback_column.sql -// - -var alterTableAddRepoFallback = ` -ALTER TABLE repos ADD COLUMN repo_fallback BOOLEAN -` - -var updateTableSetRepoFallback = ` -UPDATE repos SET repo_fallback='false' -` - -// -// 024_add_repo_fallback_column.sql -// - -var updateTableSetRepoFallbackAgain = ` -UPDATE repos SET repo_fallback='false' -` - -// -// 025_add_builds_changed_files_column.sql -// - -var addBuildsChangedfilesColumn = ` -ALTER TABLE builds ADD COLUMN changed_files TEXT; -` - -var updateBuildsSetChangedfiles = ` -UPDATE builds SET changed_files='[]' -` - -// -// 026_drop_repo_fallback_column.sql -// - -var alterTableDropRepoFallback = ` -ALTER TABLE repos DROP COLUMN repo_fallback -` - -// -// 027_drop_allow_push_tags_deployments_columns.sql -// - -var dropAllowPushTagsDeploysColumns = ` -ALTER TABLE repos DROP COLUMN repo_allow_push, DROP COLUMN repo_allow_deploys, DROP COLUMN repo_allow_tags -` - -// -// 028_update_table_set_users_token_and_secret_length.sql -// - -var updateTableSetUsersTokenAndSecretLength = ` -ALTER TABLE users ALTER COLUMN user_token TYPE varchar(1000); -ALTER TABLE users ALTER COLUMN user_secret TYPE varchar(1000); -` diff --git a/server/store/datastore/ddl/postgres/files/001_create_table_users.sql b/server/store/datastore/ddl/postgres/files/001_create_table_users.sql deleted file mode 100644 index 963cf6317..000000000 --- a/server/store/datastore/ddl/postgres/files/001_create_table_users.sql +++ /dev/null @@ -1,16 +0,0 @@ --- name: create-table-users - -CREATE TABLE IF NOT EXISTS users ( - user_id SERIAL PRIMARY KEY -,user_login VARCHAR(250) -,user_token VARCHAR(500) -,user_secret VARCHAR(500) -,user_expiry INTEGER -,user_email VARCHAR(500) -,user_avatar VARCHAR(500) -,user_active BOOLEAN -,user_admin BOOLEAN -,user_hash VARCHAR(500) - -,UNIQUE(user_login) -); diff --git a/server/store/datastore/ddl/postgres/files/002_create_table_repos.sql b/server/store/datastore/ddl/postgres/files/002_create_table_repos.sql deleted file mode 100644 index 1578c2d05..000000000 --- a/server/store/datastore/ddl/postgres/files/002_create_table_repos.sql +++ /dev/null @@ -1,26 +0,0 @@ --- name: create-table-repos - -CREATE TABLE IF NOT EXISTS repos ( - repo_id SERIAL PRIMARY KEY -,repo_user_id INTEGER -,repo_owner VARCHAR(250) -,repo_name VARCHAR(250) -,repo_full_name VARCHAR(250) -,repo_avatar VARCHAR(500) -,repo_link VARCHAR(1000) -,repo_clone VARCHAR(1000) -,repo_branch VARCHAR(500) -,repo_timeout INTEGER -,repo_private BOOLEAN -,repo_trusted BOOLEAN -,repo_allow_pr BOOLEAN -,repo_allow_push BOOLEAN -,repo_allow_deploys BOOLEAN -,repo_allow_tags BOOLEAN -,repo_hash VARCHAR(500) -,repo_scm VARCHAR(50) -,repo_config_path VARCHAR(500) -,repo_gated BOOLEAN - -,UNIQUE(repo_full_name) -); diff --git a/server/store/datastore/ddl/postgres/files/003_create_table_builds.sql b/server/store/datastore/ddl/postgres/files/003_create_table_builds.sql deleted file mode 100644 index 81ded7600..000000000 --- a/server/store/datastore/ddl/postgres/files/003_create_table_builds.sql +++ /dev/null @@ -1,44 +0,0 @@ --- name: create-table-builds - -CREATE TABLE IF NOT EXISTS builds ( - build_id SERIAL PRIMARY KEY -,build_repo_id INTEGER -,build_number INTEGER -,build_event VARCHAR(500) -,build_status VARCHAR(500) -,build_enqueued INTEGER -,build_created INTEGER -,build_started INTEGER -,build_finished INTEGER -,build_commit VARCHAR(500) -,build_branch VARCHAR(500) -,build_ref VARCHAR(500) -,build_refspec VARCHAR(1000) -,build_remote VARCHAR(500) -,build_title VARCHAR(1000) -,build_message VARCHAR(2000) -,build_timestamp INTEGER -,build_author VARCHAR(500) -,build_avatar VARCHAR(1000) -,build_email VARCHAR(500) -,build_link VARCHAR(1000) -,build_deploy VARCHAR(500) -,build_signed BOOLEAN -,build_verified BOOLEAN -,build_parent INTEGER -,build_error VARCHAR(500) -,build_reviewer VARCHAR(250) -,build_reviewed INTEGER -,build_sender VARCHAR(250) -,build_config_id INTEGER - -,UNIQUE(build_number, build_repo_id) -); - --- name: create-index-builds-repo - -CREATE INDEX IF NOT EXISTS ix_build_repo ON builds (build_repo_id); - --- name: create-index-builds-author - -CREATE INDEX IF NOT EXISTS ix_build_author ON builds (build_author); diff --git a/server/store/datastore/ddl/postgres/files/004_create_table_procs.sql b/server/store/datastore/ddl/postgres/files/004_create_table_procs.sql deleted file mode 100644 index ac6d0ac79..000000000 --- a/server/store/datastore/ddl/postgres/files/004_create_table_procs.sql +++ /dev/null @@ -1,24 +0,0 @@ --- name: create-table-procs - -CREATE TABLE IF NOT EXISTS procs ( - proc_id SERIAL PRIMARY KEY -,proc_build_id INTEGER -,proc_pid INTEGER -,proc_ppid INTEGER -,proc_pgid INTEGER -,proc_name VARCHAR(250) -,proc_state VARCHAR(250) -,proc_error VARCHAR(500) -,proc_exit_code INTEGER -,proc_started INTEGER -,proc_stopped INTEGER -,proc_machine VARCHAR(250) -,proc_platform VARCHAR(250) -,proc_environ VARCHAR(2000) - -,UNIQUE(proc_build_id, proc_pid) -); - --- name: create-index-procs-build - -CREATE INDEX IF NOT EXISTS proc_build_ix ON procs (proc_build_id); diff --git a/server/store/datastore/ddl/postgres/files/005_create_table_logs.sql b/server/store/datastore/ddl/postgres/files/005_create_table_logs.sql deleted file mode 100644 index b0cb852f1..000000000 --- a/server/store/datastore/ddl/postgres/files/005_create_table_logs.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: create-table-logs - -CREATE TABLE IF NOT EXISTS logs ( - log_id SERIAL PRIMARY KEY -,log_job_id INTEGER -,log_data BYTEA - -,UNIQUE(log_job_id) -); diff --git a/server/store/datastore/ddl/postgres/files/006_create_table_files.sql b/server/store/datastore/ddl/postgres/files/006_create_table_files.sql deleted file mode 100644 index ba0da0624..000000000 --- a/server/store/datastore/ddl/postgres/files/006_create_table_files.sql +++ /dev/null @@ -1,22 +0,0 @@ --- name: create-table-files - -CREATE TABLE IF NOT EXISTS files ( - file_id SERIAL PRIMARY KEY -,file_build_id INTEGER -,file_proc_id INTEGER -,file_name VARCHAR(250) -,file_mime VARCHAR(250) -,file_size INTEGER -,file_time INTEGER -,file_data BYTEA - -,UNIQUE(file_proc_id,file_name) -); - --- name: create-index-files-builds - -CREATE INDEX IF NOT EXISTS file_build_ix ON files (file_build_id); - --- name: create-index-files-procs - -CREATE INDEX IF NOT EXISTS file_proc_ix ON files (file_proc_id); diff --git a/server/store/datastore/ddl/postgres/files/007_create_table_secets.sql b/server/store/datastore/ddl/postgres/files/007_create_table_secets.sql deleted file mode 100644 index 233eb691b..000000000 --- a/server/store/datastore/ddl/postgres/files/007_create_table_secets.sql +++ /dev/null @@ -1,18 +0,0 @@ --- name: create-table-secrets - -CREATE TABLE IF NOT EXISTS secrets ( - secret_id SERIAL PRIMARY KEY -,secret_repo_id INTEGER -,secret_name VARCHAR(250) -,secret_value BYTEA -,secret_images VARCHAR(2000) -,secret_events VARCHAR(2000) -,secret_skip_verify BOOLEAN -,secret_conceal BOOLEAN - -,UNIQUE(secret_name, secret_repo_id) -); - --- name: create-index-secrets-repo - -CREATE INDEX IF NOT EXISTS ix_secrets_repo ON secrets (secret_repo_id); diff --git a/server/store/datastore/ddl/postgres/files/008_create_table_registry.sql b/server/store/datastore/ddl/postgres/files/008_create_table_registry.sql deleted file mode 100644 index d33754ba2..000000000 --- a/server/store/datastore/ddl/postgres/files/008_create_table_registry.sql +++ /dev/null @@ -1,17 +0,0 @@ --- name: create-table-registry - -CREATE TABLE IF NOT EXISTS registry ( - registry_id SERIAL PRIMARY KEY -,registry_repo_id INTEGER -,registry_addr VARCHAR(250) -,registry_email VARCHAR(500) -,registry_username VARCHAR(2000) -,registry_password VARCHAR(8000) -,registry_token VARCHAR(2000) - -,UNIQUE(registry_addr, registry_repo_id) -); - --- name: create-index-registry-repo - -CREATE INDEX IF NOT EXISTS ix_registry_repo ON registry (registry_repo_id); diff --git a/server/store/datastore/ddl/postgres/files/009_create_table_config.sql b/server/store/datastore/ddl/postgres/files/009_create_table_config.sql deleted file mode 100644 index ec115f896..000000000 --- a/server/store/datastore/ddl/postgres/files/009_create_table_config.sql +++ /dev/null @@ -1,10 +0,0 @@ --- name: create-table-config - -CREATE TABLE IF NOT EXISTS config ( - config_id SERIAL PRIMARY KEY -,config_repo_id INTEGER -,config_hash VARCHAR(250) -,config_data BYTEA - -,UNIQUE(config_hash, config_repo_id) -); diff --git a/server/store/datastore/ddl/postgres/files/010_create_table_tasks.sql b/server/store/datastore/ddl/postgres/files/010_create_table_tasks.sql deleted file mode 100644 index 9cc4c5f69..000000000 --- a/server/store/datastore/ddl/postgres/files/010_create_table_tasks.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: create-table-tasks - -CREATE TABLE IF NOT EXISTS tasks ( - task_id VARCHAR(250) PRIMARY KEY -,task_data BYTEA -,task_labels BYTEA -); diff --git a/server/store/datastore/ddl/postgres/files/011_create_table_agents.sql b/server/store/datastore/ddl/postgres/files/011_create_table_agents.sql deleted file mode 100644 index 575dc2996..000000000 --- a/server/store/datastore/ddl/postgres/files/011_create_table_agents.sql +++ /dev/null @@ -1,12 +0,0 @@ --- name: create-table-agents - -CREATE TABLE IF NOT EXISTS agents ( - agent_id SERIAL PRIMARY KEY -,agent_addr VARCHAR(250) -,agent_platform VARCHAR(500) -,agent_capacity INTEGER -,agent_created INTEGER -,agent_updated INTEGER - -,UNIQUE(agent_addr) -); diff --git a/server/store/datastore/ddl/postgres/files/012_create_table_senders.sql b/server/store/datastore/ddl/postgres/files/012_create_table_senders.sql deleted file mode 100644 index b15f3d6d2..000000000 --- a/server/store/datastore/ddl/postgres/files/012_create_table_senders.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: create-table-senders - -CREATE TABLE IF NOT EXISTS senders ( - sender_id SERIAL PRIMARY KEY -,sender_repo_id INTEGER -,sender_login VARCHAR(250) -,sender_allow BOOLEAN -,sender_block BOOLEAN - -,UNIQUE(sender_repo_id,sender_login) -); - --- name: create-index-sender-repos - -CREATE INDEX IF NOT EXISTS sender_repo_ix ON senders (sender_repo_id); diff --git a/server/store/datastore/ddl/postgres/files/013_add_column_repo_visibility.sql b/server/store/datastore/ddl/postgres/files/013_add_column_repo_visibility.sql deleted file mode 100644 index 03b73f888..000000000 --- a/server/store/datastore/ddl/postgres/files/013_add_column_repo_visibility.sql +++ /dev/null @@ -1,11 +0,0 @@ --- name: alter-table-add-repo-visibility - -ALTER TABLE repos ADD COLUMN repo_visibility VARCHAR(50); - --- name: update-table-set-repo-visibility - -UPDATE repos -SET repo_visibility = (CASE - WHEN repo_private = false THEN 'public' - ELSE 'private' - END); diff --git a/server/store/datastore/ddl/postgres/files/014_add_column_repo_seq.sql b/server/store/datastore/ddl/postgres/files/014_add_column_repo_seq.sql deleted file mode 100644 index 2c45f95b6..000000000 --- a/server/store/datastore/ddl/postgres/files/014_add_column_repo_seq.sql +++ /dev/null @@ -1,17 +0,0 @@ --- name: alter-table-add-repo-seq - -ALTER TABLE repos ADD COLUMN repo_counter INTEGER; - --- name: update-table-set-repo-seq - -UPDATE repos SET repo_counter = ( - SELECT max(build_number) - FROM builds - WHERE builds.build_repo_id = repos.repo_id -); - --- name: update-table-set-repo-seq-default - -UPDATE repos SET repo_counter = 0 -WHERE repo_counter IS NULL -; \ No newline at end of file diff --git a/server/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql b/server/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql deleted file mode 100644 index 627ffda0c..000000000 --- a/server/store/datastore/ddl/postgres/files/015_add_column_repo_active.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-repo-active - -ALTER TABLE repos ADD COLUMN repo_active BOOLEAN; - --- name: update-table-set-repo-active - -UPDATE repos SET repo_active = true; diff --git a/server/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql b/server/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql deleted file mode 100644 index efe2d9bed..000000000 --- a/server/store/datastore/ddl/postgres/files/016_add_column_user_synced.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-user-synced - -ALTER TABLE users ADD COLUMN user_synced INTEGER; - --- name: update-table-set-user-synced - -UPDATE users SET user_synced = 0; diff --git a/server/store/datastore/ddl/postgres/files/017_create_table_perms.sql b/server/store/datastore/ddl/postgres/files/017_create_table_perms.sql deleted file mode 100644 index 23da6223a..000000000 --- a/server/store/datastore/ddl/postgres/files/017_create_table_perms.sql +++ /dev/null @@ -1,19 +0,0 @@ --- name: create-table-perms - -CREATE TABLE IF NOT EXISTS perms ( - perm_user_id INTEGER NOT NULL -,perm_repo_id INTEGER NOT NULL -,perm_pull BOOLEAN -,perm_push BOOLEAN -,perm_admin BOOLEAN -,perm_synced INTEGER -,UNIQUE(perm_user_id, perm_repo_id) -); - --- name: create-index-perms-repo - -CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id); - --- name: create-index-perms-user - -CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id); diff --git a/server/store/datastore/ddl/postgres/files/018_add_column_file_pid.sql b/server/store/datastore/ddl/postgres/files/018_add_column_file_pid.sql deleted file mode 100644 index a8ee163c1..000000000 --- a/server/store/datastore/ddl/postgres/files/018_add_column_file_pid.sql +++ /dev/null @@ -1,23 +0,0 @@ --- name: alter-table-add-file-pid - -ALTER TABLE files ADD COLUMN file_pid INTEGER; - --- name: alter-table-add-file-meta-passed - -ALTER TABLE files ADD COLUMN file_meta_passed INTEGER; - --- name: alter-table-add-file-meta-failed - -ALTER TABLE files ADD COLUMN file_meta_failed INTEGER; - --- name: alter-table-add-file-meta-skipped - -ALTER TABLE files ADD COLUMN file_meta_skipped INTEGER; - --- name: alter-table-update-file-meta - -UPDATE files SET - file_meta_passed=0 -,file_meta_failed=0 -,file_meta_skipped=0 -; \ No newline at end of file diff --git a/server/store/datastore/ddl/postgres/files/019_create_table_build_config.sql b/server/store/datastore/ddl/postgres/files/019_create_table_build_config.sql deleted file mode 100644 index be5d58718..000000000 --- a/server/store/datastore/ddl/postgres/files/019_create_table_build_config.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: create-table-build-config - -CREATE TABLE IF NOT EXISTS build_config ( - config_id INTEGER NOT NULL -,build_id INTEGER NOT NULL -,PRIMARY KEY (config_id, build_id) -,FOREIGN KEY (config_id) REFERENCES config (config_id) -,FOREIGN KEY (build_id) REFERENCES builds (build_id) -); diff --git a/server/store/datastore/ddl/postgres/files/020_add_column_config_name.sql b/server/store/datastore/ddl/postgres/files/020_add_column_config_name.sql deleted file mode 100644 index b1581d11d..000000000 --- a/server/store/datastore/ddl/postgres/files/020_add_column_config_name.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-config-name - -ALTER TABLE config ADD COLUMN config_name TEXT - --- name: update-table-set-config-name - -UPDATE config SET config_name = 'drone' \ No newline at end of file diff --git a/server/store/datastore/ddl/postgres/files/021_populate_build_config.sql b/server/store/datastore/ddl/postgres/files/021_populate_build_config.sql deleted file mode 100644 index e004b81c9..000000000 --- a/server/store/datastore/ddl/postgres/files/021_populate_build_config.sql +++ /dev/null @@ -1,4 +0,0 @@ --- name: populate-build-config - -INSERT INTO build_config (config_id, build_id) -SELECT build_config_id, build_id FROM builds diff --git a/server/store/datastore/ddl/postgres/files/022_add_task_columns.sql b/server/store/datastore/ddl/postgres/files/022_add_task_columns.sql deleted file mode 100644 index 555e1d882..000000000 --- a/server/store/datastore/ddl/postgres/files/022_add_task_columns.sql +++ /dev/null @@ -1,6 +0,0 @@ --- name: alter-table-add-task-dependencies -ALTER TABLE tasks ADD COLUMN task_dependencies BYTEA - --- name: alter-table-add-task-run-on - -ALTER TABLE tasks ADD COLUMN task_run_on BYTEA diff --git a/server/store/datastore/ddl/postgres/files/023_add_repo_fallback_column.sql b/server/store/datastore/ddl/postgres/files/023_add_repo_fallback_column.sql deleted file mode 100644 index 3e3384854..000000000 --- a/server/store/datastore/ddl/postgres/files/023_add_repo_fallback_column.sql +++ /dev/null @@ -1,5 +0,0 @@ --- name: alter-table-add-repo-fallback -ALTER TABLE repos ADD COLUMN repo_fallback BOOLEAN - --- name: update-table-set-repo-fallback -UPDATE repos SET repo_fallback='false' diff --git a/server/store/datastore/ddl/postgres/files/024_add_repo_fallback_column.sql b/server/store/datastore/ddl/postgres/files/024_add_repo_fallback_column.sql deleted file mode 100644 index 0a663b4e1..000000000 --- a/server/store/datastore/ddl/postgres/files/024_add_repo_fallback_column.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: update-table-set-repo-fallback-again -UPDATE repos SET repo_fallback='false' diff --git a/server/store/datastore/ddl/postgres/files/025_add_builds_changed_files_column.sql b/server/store/datastore/ddl/postgres/files/025_add_builds_changed_files_column.sql deleted file mode 100644 index 0406bb4e2..000000000 --- a/server/store/datastore/ddl/postgres/files/025_add_builds_changed_files_column.sql +++ /dev/null @@ -1,5 +0,0 @@ --- name: add-builds-changed_files-column -ALTER TABLE builds ADD COLUMN changed_files TEXT; - --- name: update-builds-set-changed_files -UPDATE builds SET changed_files='[]' \ No newline at end of file diff --git a/server/store/datastore/ddl/postgres/files/026_drop_repo_fallback_column.sql b/server/store/datastore/ddl/postgres/files/026_drop_repo_fallback_column.sql deleted file mode 100644 index 9cd766ffc..000000000 --- a/server/store/datastore/ddl/postgres/files/026_drop_repo_fallback_column.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: alter-table-drop-repo-fallback -ALTER TABLE repos DROP COLUMN repo_fallback diff --git a/server/store/datastore/ddl/postgres/files/027_drop_allow_push_tags_deployments_columns.sql b/server/store/datastore/ddl/postgres/files/027_drop_allow_push_tags_deployments_columns.sql deleted file mode 100644 index bae5a3b37..000000000 --- a/server/store/datastore/ddl/postgres/files/027_drop_allow_push_tags_deployments_columns.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: drop-allow-push-tags-deploys-columns -ALTER TABLE repos DROP COLUMN repo_allow_push, DROP COLUMN repo_allow_deploys, DROP COLUMN repo_allow_tags diff --git a/server/store/datastore/ddl/postgres/files/028_update_table_set_users_token_and_secret_length.sql b/server/store/datastore/ddl/postgres/files/028_update_table_set_users_token_and_secret_length.sql deleted file mode 100644 index 3bdec1580..000000000 --- a/server/store/datastore/ddl/postgres/files/028_update_table_set_users_token_and_secret_length.sql +++ /dev/null @@ -1,4 +0,0 @@ --- name: update-table-set-users-token-and-secret-length - -ALTER TABLE users ALTER COLUMN user_token TYPE varchar(1000); -ALTER TABLE users ALTER COLUMN user_secret TYPE varchar(1000); diff --git a/server/store/datastore/ddl/sqlite/ddl_gen.go b/server/store/datastore/ddl/sqlite/ddl_gen.go deleted file mode 100644 index fbf7e08cb..000000000 --- a/server/store/datastore/ddl/sqlite/ddl_gen.go +++ /dev/null @@ -1,884 +0,0 @@ -package sqlite - -import ( - "database/sql" -) - -var migrations = []struct { - name string - stmt string -}{ - { - name: "create-table-users", - stmt: createTableUsers, - }, - { - name: "create-table-repos", - stmt: createTableRepos, - }, - { - name: "create-table-builds", - stmt: createTableBuilds, - }, - { - name: "create-index-builds-repo", - stmt: createIndexBuildsRepo, - }, - { - name: "create-index-builds-author", - stmt: createIndexBuildsAuthor, - }, - { - name: "create-index-builds-status", - stmt: createIndexBuildsStatus, - }, - { - name: "create-table-procs", - stmt: createTableProcs, - }, - { - name: "create-index-procs-build", - stmt: createIndexProcsBuild, - }, - { - name: "create-table-logs", - stmt: createTableLogs, - }, - { - name: "create-table-files", - stmt: createTableFiles, - }, - { - name: "create-index-files-builds", - stmt: createIndexFilesBuilds, - }, - { - name: "create-index-files-procs", - stmt: createIndexFilesProcs, - }, - { - name: "create-table-secrets", - stmt: createTableSecrets, - }, - { - name: "create-index-secrets-repo", - stmt: createIndexSecretsRepo, - }, - { - name: "create-table-registry", - stmt: createTableRegistry, - }, - { - name: "create-index-registry-repo", - stmt: createIndexRegistryRepo, - }, - { - name: "create-table-config", - stmt: createTableConfig, - }, - { - name: "create-table-tasks", - stmt: createTableTasks, - }, - { - name: "create-table-agents", - stmt: createTableAgents, - }, - { - name: "create-table-senders", - stmt: createTableSenders, - }, - { - name: "create-index-sender-repos", - stmt: createIndexSenderRepos, - }, - { - name: "alter-table-add-repo-visibility", - stmt: alterTableAddRepoVisibility, - }, - { - name: "update-table-set-repo-visibility", - stmt: updateTableSetRepoVisibility, - }, - { - name: "alter-table-add-repo-seq", - stmt: alterTableAddRepoSeq, - }, - { - name: "update-table-set-repo-seq", - stmt: updateTableSetRepoSeq, - }, - { - name: "update-table-set-repo-seq-default", - stmt: updateTableSetRepoSeqDefault, - }, - { - name: "alter-table-add-repo-active", - stmt: alterTableAddRepoActive, - }, - { - name: "update-table-set-repo-active", - stmt: updateTableSetRepoActive, - }, - { - name: "alter-table-add-user-synced", - stmt: alterTableAddUserSynced, - }, - { - name: "update-table-set-user-synced", - stmt: updateTableSetUserSynced, - }, - { - name: "create-table-perms", - stmt: createTablePerms, - }, - { - name: "create-index-perms-repo", - stmt: createIndexPermsRepo, - }, - { - name: "create-index-perms-user", - stmt: createIndexPermsUser, - }, - { - name: "alter-table-add-file-pid", - stmt: alterTableAddFilePid, - }, - { - name: "alter-table-add-file-meta-passed", - stmt: alterTableAddFileMetaPassed, - }, - { - name: "alter-table-add-file-meta-failed", - stmt: alterTableAddFileMetaFailed, - }, - { - name: "alter-table-add-file-meta-skipped", - stmt: alterTableAddFileMetaSkipped, - }, - { - name: "alter-table-update-file-meta", - stmt: alterTableUpdateFileMeta, - }, - { - name: "create-table-build-config", - stmt: createTableBuildConfig, - }, - { - name: "alter-table-add-config-name", - stmt: alterTableAddConfigName, - }, - { - name: "update-table-set-config-name", - stmt: updateTableSetConfigName, - }, - { - name: "populate-build-config", - stmt: populateBuildConfig, - }, - { - name: "alter-table-add-task-dependencies", - stmt: alterTableAddTaskDependencies, - }, - { - name: "alter-table-add-task-run-on", - stmt: alterTableAddTaskRunOn, - }, - { - name: "alter-table-add-repo-fallback", - stmt: alterTableAddRepoFallback, - }, - { - name: "update-table-set-repo-fallback", - stmt: updateTableSetRepoFallback, - }, - { - name: "update-table-set-repo-fallback-again", - stmt: updateTableSetRepoFallbackAgain, - }, - { - name: "add-builds-changed_files-column", - stmt: addBuildsChangedfilesColumn, - }, - { - name: "update-builds-set-changed_files", - stmt: updateBuildsSetChangedfiles, - }, - { - name: "alter-table-drop-repo-fallback", - stmt: alterTableDropRepoFallback, - }, - { - name: "drop-allow-push-tags-deploys-columns", - stmt: dropAllowPushTagsDeploysColumns, - }, - { - name: "update-table-set-users-token-and-secret-length", - stmt: updateTableSetUsersTokenAndSecretLength, - }, -} - -// Migrate performs the database migration. If the migration fails -// and error is returned. -func Migrate(db *sql.DB) error { - if err := createTable(db); err != nil { - return err - } - completed, err := selectCompleted(db) - if err != nil && err != sql.ErrNoRows { - return err - } - for _, migration := range migrations { - if _, ok := completed[migration.name]; ok { - - continue - } - - if _, err := db.Exec(migration.stmt); err != nil { - return err - } - if err := insertMigration(db, migration.name); err != nil { - return err - } - - } - return nil -} - -func createTable(db *sql.DB) error { - _, err := db.Exec(migrationTableCreate) - return err -} - -func insertMigration(db *sql.DB, name string) error { - _, err := db.Exec(migrationInsert, name) - return err -} - -func selectCompleted(db *sql.DB) (map[string]struct{}, error) { - migrations := map[string]struct{}{} - rows, err := db.Query(migrationSelect) - if err != nil { - return nil, err - } - defer rows.Close() - for rows.Next() { - var name string - if err := rows.Scan(&name); err != nil { - return nil, err - } - migrations[name] = struct{}{} - } - return migrations, nil -} - -// -// migration table ddl and sql -// - -var migrationTableCreate = ` -CREATE TABLE IF NOT EXISTS migrations ( - name VARCHAR(255) -,UNIQUE(name) -) -` - -var migrationInsert = ` -INSERT INTO migrations (name) VALUES (?) -` - -var migrationSelect = ` -SELECT name FROM migrations -` - -// -// 001_create_table_users.sql -// - -var createTableUsers = ` -CREATE TABLE IF NOT EXISTS users ( - user_id INTEGER PRIMARY KEY AUTOINCREMENT -,user_login TEXT -,user_token TEXT -,user_secret TEXT -,user_expiry INTEGER -,user_email TEXT -,user_avatar TEXT -,user_active BOOLEAN -,user_admin BOOLEAN -,user_hash TEXT -,UNIQUE(user_login) -); -` - -// -// 002_create_table_repos.sql -// - -var createTableRepos = ` -CREATE TABLE IF NOT EXISTS repos ( - repo_id INTEGER PRIMARY KEY AUTOINCREMENT -,repo_user_id INTEGER -,repo_owner TEXT -,repo_name TEXT -,repo_full_name TEXT -,repo_avatar TEXT -,repo_link TEXT -,repo_clone TEXT -,repo_branch TEXT -,repo_timeout INTEGER -,repo_private BOOLEAN -,repo_trusted BOOLEAN -,repo_allow_pr BOOLEAN -,repo_allow_push BOOLEAN -,repo_allow_deploys BOOLEAN -,repo_allow_tags BOOLEAN -,repo_hash TEXT -,repo_scm TEXT -,repo_config_path TEXT -,repo_gated BOOLEAN -,UNIQUE(repo_full_name) -); -` - -// -// 003_create_table_builds.sql -// - -var createTableBuilds = ` -CREATE TABLE IF NOT EXISTS builds ( - build_id INTEGER PRIMARY KEY AUTOINCREMENT -,build_repo_id INTEGER -,build_number INTEGER -,build_event TEXT -,build_status TEXT -,build_enqueued INTEGER -,build_created INTEGER -,build_started INTEGER -,build_finished INTEGER -,build_commit TEXT -,build_branch TEXT -,build_ref TEXT -,build_refspec TEXT -,build_remote TEXT -,build_title TEXT -,build_message TEXT -,build_timestamp INTEGER -,build_author TEXT -,build_avatar TEXT -,build_email TEXT -,build_link TEXT -,build_deploy TEXT -,build_signed BOOLEAN -,build_verified BOOLEAN -,build_parent INTEGER -,build_error TEXT -,build_reviewer TEXT -,build_reviewed INTEGER -,build_sender TEXT -,build_config_id INTEGER -,UNIQUE(build_number, build_repo_id) -); -` - -var createIndexBuildsRepo = ` -CREATE INDEX IF NOT EXISTS ix_build_repo ON builds (build_repo_id); -` - -var createIndexBuildsAuthor = ` -CREATE INDEX IF NOT EXISTS ix_build_author ON builds (build_author); -` - -var createIndexBuildsStatus = ` -CREATE INDEX IF NOT EXISTS ix_build_status_running ON builds (build_status) -WHERE build_status IN ('pending', 'running'); -` - -// -// 004_create_table_procs.sql -// - -var createTableProcs = ` -CREATE TABLE IF NOT EXISTS procs ( - proc_id INTEGER PRIMARY KEY AUTOINCREMENT -,proc_build_id INTEGER -,proc_pid INTEGER -,proc_ppid INTEGER -,proc_pgid INTEGER -,proc_name TEXT -,proc_state TEXT -,proc_error TEXT -,proc_exit_code INTEGER -,proc_started INTEGER -,proc_stopped INTEGER -,proc_machine TEXT -,proc_platform TEXT -,proc_environ TEXT -,UNIQUE(proc_build_id, proc_pid) -); -` - -var createIndexProcsBuild = ` -CREATE INDEX IF NOT EXISTS proc_build_ix ON procs (proc_build_id); -` - -// -// 005_create_table_logs.sql -// - -var createTableLogs = ` -CREATE TABLE IF NOT EXISTS logs ( - log_id INTEGER PRIMARY KEY AUTOINCREMENT -,log_job_id INTEGER -,log_data BLOB -,UNIQUE(log_job_id) -); -` - -// -// 006_create_table_files.sql -// - -var createTableFiles = ` -CREATE TABLE IF NOT EXISTS files ( - file_id INTEGER PRIMARY KEY AUTOINCREMENT -,file_build_id INTEGER -,file_proc_id INTEGER -,file_name TEXT -,file_mime TEXT -,file_size INTEGER -,file_time INTEGER -,file_data BLOB -,UNIQUE(file_proc_id,file_name) -); -` - -var createIndexFilesBuilds = ` -CREATE INDEX IF NOT EXISTS file_build_ix ON files (file_build_id); -` - -var createIndexFilesProcs = ` -CREATE INDEX IF NOT EXISTS file_proc_ix ON files (file_proc_id); -` - -// -// 007_create_table_secets.sql -// - -var createTableSecrets = ` -CREATE TABLE IF NOT EXISTS secrets ( - secret_id INTEGER PRIMARY KEY AUTOINCREMENT -,secret_repo_id INTEGER -,secret_name TEXT -,secret_value TEXT -,secret_images TEXT -,secret_events TEXT -,secret_skip_verify BOOLEAN -,secret_conceal BOOLEAN -,UNIQUE(secret_name, secret_repo_id) -); -` - -var createIndexSecretsRepo = ` -CREATE INDEX IF NOT EXISTS ix_secrets_repo ON secrets (secret_repo_id); -` - -// -// 008_create_table_registry.sql -// - -var createTableRegistry = ` -CREATE TABLE IF NOT EXISTS registry ( - registry_id INTEGER PRIMARY KEY AUTOINCREMENT -,registry_repo_id INTEGER -,registry_addr TEXT -,registry_username TEXT -,registry_password TEXT -,registry_email TEXT -,registry_token TEXT - -,UNIQUE(registry_addr, registry_repo_id) -); -` - -var createIndexRegistryRepo = ` -CREATE INDEX IF NOT EXISTS ix_registry_repo ON registry (registry_repo_id); -` - -// -// 009_create_table_config.sql -// - -var createTableConfig = ` -CREATE TABLE IF NOT EXISTS config ( - config_id INTEGER PRIMARY KEY AUTOINCREMENT -,config_repo_id INTEGER -,config_hash TEXT -,config_data BLOB -,UNIQUE(config_hash, config_repo_id) -); -` - -// -// 010_create_table_tasks.sql -// - -var createTableTasks = ` -CREATE TABLE IF NOT EXISTS tasks ( - task_id TEXT PRIMARY KEY -,task_data BLOB -,task_labels BLOB -); -` - -// -// 011_create_table_agents.sql -// - -var createTableAgents = ` -CREATE TABLE IF NOT EXISTS agents ( - agent_id INTEGER PRIMARY KEY AUTOINCREMENT -,agent_addr TEXT -,agent_platform TEXT -,agent_capacity INTEGER -,agent_created INTEGER -,agent_updated INTEGER - -,UNIQUE(agent_addr) -); -` - -// -// 012_create_table_senders.sql -// - -var createTableSenders = ` -CREATE TABLE IF NOT EXISTS senders ( - sender_id INTEGER PRIMARY KEY AUTOINCREMENT -,sender_repo_id INTEGER -,sender_login TEXT -,sender_allow BOOLEAN -,sender_block BOOLEAN - -,UNIQUE(sender_repo_id,sender_login) -); -` - -var createIndexSenderRepos = ` -CREATE INDEX IF NOT EXISTS sender_repo_ix ON senders (sender_repo_id); -` - -// -// 013_add_column_repo_visibility.sql -// - -var alterTableAddRepoVisibility = ` -ALTER TABLE repos ADD COLUMN repo_visibility TEXT -` - -var updateTableSetRepoVisibility = ` -UPDATE repos -SET repo_visibility = CASE - WHEN repo_private = 0 THEN 'public' - ELSE 'private' - END -` - -// -// 014_add_column_repo_seq.sql -// - -var alterTableAddRepoSeq = ` -ALTER TABLE repos ADD COLUMN repo_counter INTEGER; -` - -var updateTableSetRepoSeq = ` -UPDATE repos SET repo_counter = ( - SELECT max(build_number) - FROM builds - WHERE builds.build_repo_id = repos.repo_id -) -` - -var updateTableSetRepoSeqDefault = ` -UPDATE repos SET repo_counter = 0 -WHERE repo_counter IS NULL -` - -// -// 015_add_column_repo_active.sql -// - -var alterTableAddRepoActive = ` -ALTER TABLE repos ADD COLUMN repo_active BOOLEAN -` - -var updateTableSetRepoActive = ` -UPDATE repos SET repo_active = 1 -` - -// -// 016_add_column_user_synced.sql -// - -var alterTableAddUserSynced = ` -ALTER TABLE users ADD COLUMN user_synced INTEGER; -` - -var updateTableSetUserSynced = ` -UPDATE users SET user_synced = 0 -` - -// -// 017_create_table_perms.sql -// - -var createTablePerms = ` -CREATE TABLE IF NOT EXISTS perms ( - perm_user_id INTEGER NOT NULL -,perm_repo_id INTEGER NOT NULL -,perm_pull BOOLEAN -,perm_push BOOLEAN -,perm_admin BOOLEAN -,perm_synced INTEGER -,UNIQUE(perm_user_id, perm_repo_id) -); -` - -var createIndexPermsRepo = ` -CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id); -` - -var createIndexPermsUser = ` -CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id); -` - -// -// 018_add_column_file_pid.sql -// - -var alterTableAddFilePid = ` -ALTER TABLE files ADD COLUMN file_pid INTEGER -` - -var alterTableAddFileMetaPassed = ` -ALTER TABLE files ADD COLUMN file_meta_passed INTEGER -` - -var alterTableAddFileMetaFailed = ` -ALTER TABLE files ADD COLUMN file_meta_failed INTEGER -` - -var alterTableAddFileMetaSkipped = ` -ALTER TABLE files ADD COLUMN file_meta_skipped INTEGER -` - -var alterTableUpdateFileMeta = ` -UPDATE files SET - file_meta_passed=0 -,file_meta_failed=0 -,file_meta_skipped=0 -` - -// -// 019_create_table_build_config.sql -// - -var createTableBuildConfig = ` -CREATE TABLE IF NOT EXISTS build_config ( - config_id INTEGER NOT NULL -,build_id INTEGER NOT NULL -,PRIMARY KEY (config_id, build_id) -,FOREIGN KEY (config_id) REFERENCES config (config_id) -,FOREIGN KEY (build_id) REFERENCES builds (build_id) -); -` - -// -// 020_add_column_config_name.sql -// - -var alterTableAddConfigName = ` -ALTER TABLE config ADD COLUMN config_name TEXT -` - -var updateTableSetConfigName = ` -UPDATE config SET config_name = "drone" -` - -// -// 021_populate_build_config.sql -// - -var populateBuildConfig = ` -INSERT INTO build_config (config_id, build_id) -SELECT build_config_id, build_id FROM builds -` - -// -// 022_add_task_columns.sql -// - -var alterTableAddTaskDependencies = ` -ALTER TABLE tasks ADD COLUMN task_dependencies BLOB -` - -var alterTableAddTaskRunOn = ` -ALTER TABLE tasks ADD COLUMN task_run_on BLOB -` - -// -// 023_add_repo_fallback_column.sql -// - -var alterTableAddRepoFallback = ` -ALTER TABLE repos ADD COLUMN repo_fallback BOOLEAN -` - -var updateTableSetRepoFallback = ` -UPDATE repos SET repo_fallback='false' -` - -// -// 024_add_repo_fallback_column.sql -// - -var updateTableSetRepoFallbackAgain = ` -UPDATE repos SET repo_fallback='false' -` - -// -// 025_add_builds_changed_files_column.sql -// - -var addBuildsChangedfilesColumn = ` -ALTER TABLE builds ADD COLUMN changed_files TEXT -` - -var updateBuildsSetChangedfiles = ` -UPDATE builds SET changed_files='[]' -` - -// -// 026_drop_repo_fallback_column.sql -// - -var alterTableDropRepoFallback = ` -BEGIN TRANSACTION; - -CREATE TABLE repos_new ( - repo_id INTEGER PRIMARY KEY AUTOINCREMENT, - repo_user_id INTEGER, - repo_owner TEXT, - repo_name TEXT, - repo_full_name TEXT, - repo_avatar TEXT, - repo_link TEXT, - repo_clone TEXT, - repo_branch TEXT, - repo_timeout INTEGER, - repo_private BOOLEAN, - repo_trusted BOOLEAN, - repo_active BOOLEAN, - repo_allow_pr BOOLEAN, - repo_allow_push BOOLEAN, - repo_allow_deploys BOOLEAN, - repo_allow_tags BOOLEAN, - repo_hash TEXT, - repo_scm TEXT, - repo_config_path TEXT, - repo_gated BOOLEAN, - repo_visibility TEXT, - repo_counter INTEGER, - UNIQUE(repo_full_name) -); - -INSERT INTO repos_new SELECT repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_allow_push -,repo_allow_deploys -,repo_allow_tags -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter FROM repos; -DROP TABLE repos; -ALTER TABLE repos_new RENAME TO repos; -COMMIT; -` - -// -// 027_drop_allow_push_tags_deployments_columns.sql -// - -var dropAllowPushTagsDeploysColumns = ` -BEGIN TRANSACTION; -CREATE TABLE repos_new ( - repo_id INTEGER PRIMARY KEY AUTOINCREMENT, - repo_user_id INTEGER, - repo_owner TEXT, - repo_name TEXT, - repo_full_name TEXT, - repo_avatar TEXT, - repo_link TEXT, - repo_clone TEXT, - repo_branch TEXT, - repo_timeout INTEGER, - repo_private BOOLEAN, - repo_trusted BOOLEAN, - repo_active BOOLEAN, - repo_allow_pr BOOLEAN, - repo_hash TEXT, - repo_scm TEXT, - repo_config_path TEXT, - repo_gated BOOLEAN, - repo_visibility TEXT, - repo_counter INTEGER, - UNIQUE(repo_full_name) -); -INSERT INTO repos_new SELECT repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter FROM repos; -DROP TABLE repos; -ALTER TABLE repos_new RENAME TO repos; -COMMIT; -` - -// -// 028_update_table_set_users_token_and_secret_length.sql -// - -var updateTableSetUsersTokenAndSecretLength = ` - -` diff --git a/server/store/datastore/ddl/sqlite/files/001_create_table_users.sql b/server/store/datastore/ddl/sqlite/files/001_create_table_users.sql deleted file mode 100644 index 7e0adffbc..000000000 --- a/server/store/datastore/ddl/sqlite/files/001_create_table_users.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: create-table-users - -CREATE TABLE IF NOT EXISTS users ( - user_id INTEGER PRIMARY KEY AUTOINCREMENT -,user_login TEXT -,user_token TEXT -,user_secret TEXT -,user_expiry INTEGER -,user_email TEXT -,user_avatar TEXT -,user_active BOOLEAN -,user_admin BOOLEAN -,user_hash TEXT -,UNIQUE(user_login) -); diff --git a/server/store/datastore/ddl/sqlite/files/002_create_table_repos.sql b/server/store/datastore/ddl/sqlite/files/002_create_table_repos.sql deleted file mode 100644 index d8f3683ec..000000000 --- a/server/store/datastore/ddl/sqlite/files/002_create_table_repos.sql +++ /dev/null @@ -1,25 +0,0 @@ --- name: create-table-repos - -CREATE TABLE IF NOT EXISTS repos ( - repo_id INTEGER PRIMARY KEY AUTOINCREMENT -,repo_user_id INTEGER -,repo_owner TEXT -,repo_name TEXT -,repo_full_name TEXT -,repo_avatar TEXT -,repo_link TEXT -,repo_clone TEXT -,repo_branch TEXT -,repo_timeout INTEGER -,repo_private BOOLEAN -,repo_trusted BOOLEAN -,repo_allow_pr BOOLEAN -,repo_allow_push BOOLEAN -,repo_allow_deploys BOOLEAN -,repo_allow_tags BOOLEAN -,repo_hash TEXT -,repo_scm TEXT -,repo_config_path TEXT -,repo_gated BOOLEAN -,UNIQUE(repo_full_name) -); diff --git a/server/store/datastore/ddl/sqlite/files/003_create_table_builds.sql b/server/store/datastore/ddl/sqlite/files/003_create_table_builds.sql deleted file mode 100644 index e68a7b5d6..000000000 --- a/server/store/datastore/ddl/sqlite/files/003_create_table_builds.sql +++ /dev/null @@ -1,48 +0,0 @@ --- name: create-table-builds - -CREATE TABLE IF NOT EXISTS builds ( - build_id INTEGER PRIMARY KEY AUTOINCREMENT -,build_repo_id INTEGER -,build_number INTEGER -,build_event TEXT -,build_status TEXT -,build_enqueued INTEGER -,build_created INTEGER -,build_started INTEGER -,build_finished INTEGER -,build_commit TEXT -,build_branch TEXT -,build_ref TEXT -,build_refspec TEXT -,build_remote TEXT -,build_title TEXT -,build_message TEXT -,build_timestamp INTEGER -,build_author TEXT -,build_avatar TEXT -,build_email TEXT -,build_link TEXT -,build_deploy TEXT -,build_signed BOOLEAN -,build_verified BOOLEAN -,build_parent INTEGER -,build_error TEXT -,build_reviewer TEXT -,build_reviewed INTEGER -,build_sender TEXT -,build_config_id INTEGER -,UNIQUE(build_number, build_repo_id) -); - --- name: create-index-builds-repo - -CREATE INDEX IF NOT EXISTS ix_build_repo ON builds (build_repo_id); - --- name: create-index-builds-author - -CREATE INDEX IF NOT EXISTS ix_build_author ON builds (build_author); - --- name: create-index-builds-status - -CREATE INDEX IF NOT EXISTS ix_build_status_running ON builds (build_status) -WHERE build_status IN ('pending', 'running'); diff --git a/server/store/datastore/ddl/sqlite/files/004_create_table_procs.sql b/server/store/datastore/ddl/sqlite/files/004_create_table_procs.sql deleted file mode 100644 index 08c7080c6..000000000 --- a/server/store/datastore/ddl/sqlite/files/004_create_table_procs.sql +++ /dev/null @@ -1,23 +0,0 @@ --- name: create-table-procs - -CREATE TABLE IF NOT EXISTS procs ( - proc_id INTEGER PRIMARY KEY AUTOINCREMENT -,proc_build_id INTEGER -,proc_pid INTEGER -,proc_ppid INTEGER -,proc_pgid INTEGER -,proc_name TEXT -,proc_state TEXT -,proc_error TEXT -,proc_exit_code INTEGER -,proc_started INTEGER -,proc_stopped INTEGER -,proc_machine TEXT -,proc_platform TEXT -,proc_environ TEXT -,UNIQUE(proc_build_id, proc_pid) -); - --- name: create-index-procs-build - -CREATE INDEX IF NOT EXISTS proc_build_ix ON procs (proc_build_id); diff --git a/server/store/datastore/ddl/sqlite/files/005_create_table_logs.sql b/server/store/datastore/ddl/sqlite/files/005_create_table_logs.sql deleted file mode 100644 index e6bf78c92..000000000 --- a/server/store/datastore/ddl/sqlite/files/005_create_table_logs.sql +++ /dev/null @@ -1,8 +0,0 @@ --- name: create-table-logs - -CREATE TABLE IF NOT EXISTS logs ( - log_id INTEGER PRIMARY KEY AUTOINCREMENT -,log_job_id INTEGER -,log_data BLOB -,UNIQUE(log_job_id) -); diff --git a/server/store/datastore/ddl/sqlite/files/006_create_table_files.sql b/server/store/datastore/ddl/sqlite/files/006_create_table_files.sql deleted file mode 100644 index fd08f035d..000000000 --- a/server/store/datastore/ddl/sqlite/files/006_create_table_files.sql +++ /dev/null @@ -1,21 +0,0 @@ --- name: create-table-files - -CREATE TABLE IF NOT EXISTS files ( - file_id INTEGER PRIMARY KEY AUTOINCREMENT -,file_build_id INTEGER -,file_proc_id INTEGER -,file_name TEXT -,file_mime TEXT -,file_size INTEGER -,file_time INTEGER -,file_data BLOB -,UNIQUE(file_proc_id,file_name) -); - --- name: create-index-files-builds - -CREATE INDEX IF NOT EXISTS file_build_ix ON files (file_build_id); - --- name: create-index-files-procs - -CREATE INDEX IF NOT EXISTS file_proc_ix ON files (file_proc_id); diff --git a/server/store/datastore/ddl/sqlite/files/007_create_table_secets.sql b/server/store/datastore/ddl/sqlite/files/007_create_table_secets.sql deleted file mode 100644 index 9305f16ad..000000000 --- a/server/store/datastore/ddl/sqlite/files/007_create_table_secets.sql +++ /dev/null @@ -1,17 +0,0 @@ --- name: create-table-secrets - -CREATE TABLE IF NOT EXISTS secrets ( - secret_id INTEGER PRIMARY KEY AUTOINCREMENT -,secret_repo_id INTEGER -,secret_name TEXT -,secret_value TEXT -,secret_images TEXT -,secret_events TEXT -,secret_skip_verify BOOLEAN -,secret_conceal BOOLEAN -,UNIQUE(secret_name, secret_repo_id) -); - --- name: create-index-secrets-repo - -CREATE INDEX IF NOT EXISTS ix_secrets_repo ON secrets (secret_repo_id); diff --git a/server/store/datastore/ddl/sqlite/files/008_create_table_registry.sql b/server/store/datastore/ddl/sqlite/files/008_create_table_registry.sql deleted file mode 100644 index 10bd39685..000000000 --- a/server/store/datastore/ddl/sqlite/files/008_create_table_registry.sql +++ /dev/null @@ -1,17 +0,0 @@ --- name: create-table-registry - -CREATE TABLE IF NOT EXISTS registry ( - registry_id INTEGER PRIMARY KEY AUTOINCREMENT -,registry_repo_id INTEGER -,registry_addr TEXT -,registry_username TEXT -,registry_password TEXT -,registry_email TEXT -,registry_token TEXT - -,UNIQUE(registry_addr, registry_repo_id) -); - --- name: create-index-registry-repo - -CREATE INDEX IF NOT EXISTS ix_registry_repo ON registry (registry_repo_id); diff --git a/server/store/datastore/ddl/sqlite/files/009_create_table_config.sql b/server/store/datastore/ddl/sqlite/files/009_create_table_config.sql deleted file mode 100644 index cf81a9889..000000000 --- a/server/store/datastore/ddl/sqlite/files/009_create_table_config.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: create-table-config - -CREATE TABLE IF NOT EXISTS config ( - config_id INTEGER PRIMARY KEY AUTOINCREMENT -,config_repo_id INTEGER -,config_hash TEXT -,config_data BLOB -,UNIQUE(config_hash, config_repo_id) -); diff --git a/server/store/datastore/ddl/sqlite/files/010_create_table_tasks.sql b/server/store/datastore/ddl/sqlite/files/010_create_table_tasks.sql deleted file mode 100644 index ddc9e7471..000000000 --- a/server/store/datastore/ddl/sqlite/files/010_create_table_tasks.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: create-table-tasks - -CREATE TABLE IF NOT EXISTS tasks ( - task_id TEXT PRIMARY KEY -,task_data BLOB -,task_labels BLOB -); diff --git a/server/store/datastore/ddl/sqlite/files/011_create_table_agents.sql b/server/store/datastore/ddl/sqlite/files/011_create_table_agents.sql deleted file mode 100644 index 273c42b79..000000000 --- a/server/store/datastore/ddl/sqlite/files/011_create_table_agents.sql +++ /dev/null @@ -1,12 +0,0 @@ --- name: create-table-agents - -CREATE TABLE IF NOT EXISTS agents ( - agent_id INTEGER PRIMARY KEY AUTOINCREMENT -,agent_addr TEXT -,agent_platform TEXT -,agent_capacity INTEGER -,agent_created INTEGER -,agent_updated INTEGER - -,UNIQUE(agent_addr) -); diff --git a/server/store/datastore/ddl/sqlite/files/012_create_table_senders.sql b/server/store/datastore/ddl/sqlite/files/012_create_table_senders.sql deleted file mode 100644 index e1b37772f..000000000 --- a/server/store/datastore/ddl/sqlite/files/012_create_table_senders.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: create-table-senders - -CREATE TABLE IF NOT EXISTS senders ( - sender_id INTEGER PRIMARY KEY AUTOINCREMENT -,sender_repo_id INTEGER -,sender_login TEXT -,sender_allow BOOLEAN -,sender_block BOOLEAN - -,UNIQUE(sender_repo_id,sender_login) -); - --- name: create-index-sender-repos - -CREATE INDEX IF NOT EXISTS sender_repo_ix ON senders (sender_repo_id); diff --git a/server/store/datastore/ddl/sqlite/files/013_add_column_repo_visibility.sql b/server/store/datastore/ddl/sqlite/files/013_add_column_repo_visibility.sql deleted file mode 100644 index f8dcef8f3..000000000 --- a/server/store/datastore/ddl/sqlite/files/013_add_column_repo_visibility.sql +++ /dev/null @@ -1,11 +0,0 @@ --- name: alter-table-add-repo-visibility - -ALTER TABLE repos ADD COLUMN repo_visibility TEXT - --- name: update-table-set-repo-visibility - -UPDATE repos -SET repo_visibility = CASE - WHEN repo_private = 0 THEN 'public' - ELSE 'private' - END diff --git a/server/store/datastore/ddl/sqlite/files/014_add_column_repo_seq.sql b/server/store/datastore/ddl/sqlite/files/014_add_column_repo_seq.sql deleted file mode 100644 index a0be87dda..000000000 --- a/server/store/datastore/ddl/sqlite/files/014_add_column_repo_seq.sql +++ /dev/null @@ -1,16 +0,0 @@ --- name: alter-table-add-repo-seq - -ALTER TABLE repos ADD COLUMN repo_counter INTEGER; - --- name: update-table-set-repo-seq - -UPDATE repos SET repo_counter = ( - SELECT max(build_number) - FROM builds - WHERE builds.build_repo_id = repos.repo_id -) - --- name: update-table-set-repo-seq-default - -UPDATE repos SET repo_counter = 0 -WHERE repo_counter IS NULL diff --git a/server/store/datastore/ddl/sqlite/files/015_add_column_repo_active.sql b/server/store/datastore/ddl/sqlite/files/015_add_column_repo_active.sql deleted file mode 100644 index 37e66754f..000000000 --- a/server/store/datastore/ddl/sqlite/files/015_add_column_repo_active.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-repo-active - -ALTER TABLE repos ADD COLUMN repo_active BOOLEAN - --- name: update-table-set-repo-active - -UPDATE repos SET repo_active = 1 diff --git a/server/store/datastore/ddl/sqlite/files/016_add_column_user_synced.sql b/server/store/datastore/ddl/sqlite/files/016_add_column_user_synced.sql deleted file mode 100644 index 43db914e7..000000000 --- a/server/store/datastore/ddl/sqlite/files/016_add_column_user_synced.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-user-synced - -ALTER TABLE users ADD COLUMN user_synced INTEGER; - --- name: update-table-set-user-synced - -UPDATE users SET user_synced = 0 diff --git a/server/store/datastore/ddl/sqlite/files/017_create_table_perms.sql b/server/store/datastore/ddl/sqlite/files/017_create_table_perms.sql deleted file mode 100644 index 23da6223a..000000000 --- a/server/store/datastore/ddl/sqlite/files/017_create_table_perms.sql +++ /dev/null @@ -1,19 +0,0 @@ --- name: create-table-perms - -CREATE TABLE IF NOT EXISTS perms ( - perm_user_id INTEGER NOT NULL -,perm_repo_id INTEGER NOT NULL -,perm_pull BOOLEAN -,perm_push BOOLEAN -,perm_admin BOOLEAN -,perm_synced INTEGER -,UNIQUE(perm_user_id, perm_repo_id) -); - --- name: create-index-perms-repo - -CREATE INDEX IF NOT EXISTS ix_perms_repo ON perms (perm_repo_id); - --- name: create-index-perms-user - -CREATE INDEX IF NOT EXISTS ix_perms_user ON perms (perm_user_id); diff --git a/server/store/datastore/ddl/sqlite/files/018_add_column_file_pid.sql b/server/store/datastore/ddl/sqlite/files/018_add_column_file_pid.sql deleted file mode 100644 index 0ad11ac78..000000000 --- a/server/store/datastore/ddl/sqlite/files/018_add_column_file_pid.sql +++ /dev/null @@ -1,22 +0,0 @@ --- name: alter-table-add-file-pid - -ALTER TABLE files ADD COLUMN file_pid INTEGER - --- name: alter-table-add-file-meta-passed - -ALTER TABLE files ADD COLUMN file_meta_passed INTEGER - --- name: alter-table-add-file-meta-failed - -ALTER TABLE files ADD COLUMN file_meta_failed INTEGER - --- name: alter-table-add-file-meta-skipped - -ALTER TABLE files ADD COLUMN file_meta_skipped INTEGER - --- name: alter-table-update-file-meta - -UPDATE files SET - file_meta_passed=0 -,file_meta_failed=0 -,file_meta_skipped=0 diff --git a/server/store/datastore/ddl/sqlite/files/019_create_table_build_config.sql b/server/store/datastore/ddl/sqlite/files/019_create_table_build_config.sql deleted file mode 100644 index be5d58718..000000000 --- a/server/store/datastore/ddl/sqlite/files/019_create_table_build_config.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: create-table-build-config - -CREATE TABLE IF NOT EXISTS build_config ( - config_id INTEGER NOT NULL -,build_id INTEGER NOT NULL -,PRIMARY KEY (config_id, build_id) -,FOREIGN KEY (config_id) REFERENCES config (config_id) -,FOREIGN KEY (build_id) REFERENCES builds (build_id) -); diff --git a/server/store/datastore/ddl/sqlite/files/020_add_column_config_name.sql b/server/store/datastore/ddl/sqlite/files/020_add_column_config_name.sql deleted file mode 100644 index 0140b4035..000000000 --- a/server/store/datastore/ddl/sqlite/files/020_add_column_config_name.sql +++ /dev/null @@ -1,7 +0,0 @@ --- name: alter-table-add-config-name - -ALTER TABLE config ADD COLUMN config_name TEXT - --- name: update-table-set-config-name - -UPDATE config SET config_name = "drone" \ No newline at end of file diff --git a/server/store/datastore/ddl/sqlite/files/021_populate_build_config.sql b/server/store/datastore/ddl/sqlite/files/021_populate_build_config.sql deleted file mode 100644 index e004b81c9..000000000 --- a/server/store/datastore/ddl/sqlite/files/021_populate_build_config.sql +++ /dev/null @@ -1,4 +0,0 @@ --- name: populate-build-config - -INSERT INTO build_config (config_id, build_id) -SELECT build_config_id, build_id FROM builds diff --git a/server/store/datastore/ddl/sqlite/files/022_add_task_columns.sql b/server/store/datastore/ddl/sqlite/files/022_add_task_columns.sql deleted file mode 100644 index 01b16d89a..000000000 --- a/server/store/datastore/ddl/sqlite/files/022_add_task_columns.sql +++ /dev/null @@ -1,6 +0,0 @@ --- name: alter-table-add-task-dependencies -ALTER TABLE tasks ADD COLUMN task_dependencies BLOB - --- name: alter-table-add-task-run-on - -ALTER TABLE tasks ADD COLUMN task_run_on BLOB diff --git a/server/store/datastore/ddl/sqlite/files/023_add_repo_fallback_column.sql b/server/store/datastore/ddl/sqlite/files/023_add_repo_fallback_column.sql deleted file mode 100644 index 3e3384854..000000000 --- a/server/store/datastore/ddl/sqlite/files/023_add_repo_fallback_column.sql +++ /dev/null @@ -1,5 +0,0 @@ --- name: alter-table-add-repo-fallback -ALTER TABLE repos ADD COLUMN repo_fallback BOOLEAN - --- name: update-table-set-repo-fallback -UPDATE repos SET repo_fallback='false' diff --git a/server/store/datastore/ddl/sqlite/files/024_add_repo_fallback_column.sql b/server/store/datastore/ddl/sqlite/files/024_add_repo_fallback_column.sql deleted file mode 100644 index 0a663b4e1..000000000 --- a/server/store/datastore/ddl/sqlite/files/024_add_repo_fallback_column.sql +++ /dev/null @@ -1,2 +0,0 @@ --- name: update-table-set-repo-fallback-again -UPDATE repos SET repo_fallback='false' diff --git a/server/store/datastore/ddl/sqlite/files/025_add_builds_changed_files_column.sql b/server/store/datastore/ddl/sqlite/files/025_add_builds_changed_files_column.sql deleted file mode 100644 index e834d7fbc..000000000 --- a/server/store/datastore/ddl/sqlite/files/025_add_builds_changed_files_column.sql +++ /dev/null @@ -1,5 +0,0 @@ --- name: add-builds-changed_files-column -ALTER TABLE builds ADD COLUMN changed_files TEXT - --- name: update-builds-set-changed_files -UPDATE builds SET changed_files='[]' diff --git a/server/store/datastore/ddl/sqlite/files/026_drop_repo_fallback_column.sql b/server/store/datastore/ddl/sqlite/files/026_drop_repo_fallback_column.sql deleted file mode 100644 index ce0a7f007..000000000 --- a/server/store/datastore/ddl/sqlite/files/026_drop_repo_fallback_column.sql +++ /dev/null @@ -1,56 +0,0 @@ --- name: alter-table-drop-repo-fallback -BEGIN TRANSACTION; - -CREATE TABLE repos_new ( - repo_id INTEGER PRIMARY KEY AUTOINCREMENT, - repo_user_id INTEGER, - repo_owner TEXT, - repo_name TEXT, - repo_full_name TEXT, - repo_avatar TEXT, - repo_link TEXT, - repo_clone TEXT, - repo_branch TEXT, - repo_timeout INTEGER, - repo_private BOOLEAN, - repo_trusted BOOLEAN, - repo_active BOOLEAN, - repo_allow_pr BOOLEAN, - repo_allow_push BOOLEAN, - repo_allow_deploys BOOLEAN, - repo_allow_tags BOOLEAN, - repo_hash TEXT, - repo_scm TEXT, - repo_config_path TEXT, - repo_gated BOOLEAN, - repo_visibility TEXT, - repo_counter INTEGER, - UNIQUE(repo_full_name) -); - -INSERT INTO repos_new SELECT repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_allow_push -,repo_allow_deploys -,repo_allow_tags -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter FROM repos; -DROP TABLE repos; -ALTER TABLE repos_new RENAME TO repos; -COMMIT; diff --git a/server/store/datastore/ddl/sqlite/files/027_drop_allow_push_tags_deployments_columns.sql b/server/store/datastore/ddl/sqlite/files/027_drop_allow_push_tags_deployments_columns.sql deleted file mode 100644 index 9ec03e71e..000000000 --- a/server/store/datastore/ddl/sqlite/files/027_drop_allow_push_tags_deployments_columns.sql +++ /dev/null @@ -1,48 +0,0 @@ --- name: drop-allow-push-tags-deploys-columns -BEGIN TRANSACTION; -CREATE TABLE repos_new ( - repo_id INTEGER PRIMARY KEY AUTOINCREMENT, - repo_user_id INTEGER, - repo_owner TEXT, - repo_name TEXT, - repo_full_name TEXT, - repo_avatar TEXT, - repo_link TEXT, - repo_clone TEXT, - repo_branch TEXT, - repo_timeout INTEGER, - repo_private BOOLEAN, - repo_trusted BOOLEAN, - repo_active BOOLEAN, - repo_allow_pr BOOLEAN, - repo_hash TEXT, - repo_scm TEXT, - repo_config_path TEXT, - repo_gated BOOLEAN, - repo_visibility TEXT, - repo_counter INTEGER, - UNIQUE(repo_full_name) -); -INSERT INTO repos_new SELECT repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter FROM repos; -DROP TABLE repos; -ALTER TABLE repos_new RENAME TO repos; -COMMIT; diff --git a/server/store/datastore/ddl/sqlite/files/028_update_table_set_users_token_and_secret_length.sql b/server/store/datastore/ddl/sqlite/files/028_update_table_set_users_token_and_secret_length.sql deleted file mode 100644 index a45fb212a..000000000 --- a/server/store/datastore/ddl/sqlite/files/028_update_table_set_users_token_and_secret_length.sql +++ /dev/null @@ -1,3 +0,0 @@ --- name: update-table-set-users-token-and-secret-length - --- noop since sqlite do use TEXT diff --git a/server/store/datastore/engine.go b/server/store/datastore/engine.go new file mode 100644 index 000000000..648147fb3 --- /dev/null +++ b/server/store/datastore/engine.go @@ -0,0 +1,56 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "github.com/woodpecker-ci/woodpecker/server/store" + "github.com/woodpecker-ci/woodpecker/server/store/datastore/migration" + + "xorm.io/xorm" +) + +type storage struct { + engine *xorm.Engine +} + +// make sure storage implement Store +var _ store.Store = &storage{} + +const perPage = 50 + +func NewEngine(opts *store.Opts) (store.Store, error) { + engine, err := xorm.NewEngine(opts.Driver, opts.Config) + if err != nil { + return nil, err + } + + // engine.SetLogger(X) // TODO: special config to enable xorm logging + return &storage{ + engine: engine, + }, nil +} + +func (s storage) Ping() error { + return s.engine.Ping() +} + +// Migrate old storage or init new one +func (s storage) Migrate() error { + return migration.Migrate(s.engine) +} + +func (s storage) Close() error { + return s.engine.Close() +} diff --git a/server/store/datastore/store_test.go b/server/store/datastore/engine_test.go similarity index 60% rename from server/store/datastore/store_test.go rename to server/store/datastore/engine_test.go index 0fee0057f..8de20e5a8 100644 --- a/server/store/datastore/store_test.go +++ b/server/store/datastore/engine_test.go @@ -15,8 +15,12 @@ package datastore import ( - "database/sql" "os" + "testing" + + "xorm.io/xorm" + + "github.com/stretchr/testify/assert" ) func testDriverConfig() (driver, config string) { @@ -27,26 +31,35 @@ func testDriverConfig() (driver, config string) { driver = os.Getenv("WOODPECKER_DATABASE_DRIVER") config = os.Getenv("WOODPECKER_DATABASE_CONFIG") } - return } -// openTest opens a new database connection for testing purposes. +// newTestStore creates a new database connection for testing purposes. // The database driver and connection string are provided by // environment variables, with fallback to in-memory sqlite. -func openTest() *sql.DB { - db, _ := open(testDriverConfig()) - return db -} - -// newTest creates a new database connection for testing purposes. -// The database driver and connection string are provided by -// environment variables, with fallback to in-memory sqlite. -func newTest() *datastore { - driver, config := testDriverConfig() - return &datastore{ - DB: openTest(), - driver: driver, - config: config, +func newTestStore(t *testing.T, tables ...interface{}) (*storage, func()) { + engine, err := xorm.NewEngine(testDriverConfig()) + if !assert.NoError(t, err) { + t.FailNow() } + + for _, table := range tables { + if err := engine.Sync2(table); err != nil { + t.Error(err) + t.FailNow() + } + } + + return &storage{ + engine: engine, + }, func() { + if err := engine.DropTables(tables...); err != nil { + t.Error(err) + t.FailNow() + } + if err := engine.Close(); err != nil { + t.Error(err) + t.FailNow() + } + } } diff --git a/server/store/datastore/feed.go b/server/store/datastore/feed.go new file mode 100644 index 000000000..ecc1990a2 --- /dev/null +++ b/server/store/datastore/feed.go @@ -0,0 +1,126 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "github.com/woodpecker-ci/woodpecker/server/model" +) + +// TODO: need tests before converting to builder statement +func (s storage) GetBuildQueue() ([]*model.Feed, error) { + feed := make([]*model.Feed, 0, perPage) + // TODO: use builder (do not behave same as pure sql, fix that) + err := s.engine.SQL(` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM + builds b +,repos r +WHERE b.build_repo_id = r.repo_id + AND b.build_status IN ('pending','running') +`).Find(&feed) + return feed, err +} + +func (s storage) UserFeed(user *model.User) ([]*model.Feed, error) { + feed := make([]*model.Feed, 0, perPage) + // TODO: use builder (do not behave same as pure sql, fix that) + return feed, s.engine.SQL(` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +INNER JOIN builds ON builds.build_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? + AND (perms.perm_push = ? OR perms.perm_admin = ?) +ORDER BY build_id DESC +LIMIT 50 +`, user.ID, true, true).Find(&feed) +} + +func (s storage) RepoListLatest(user *model.User) ([]*model.Feed, error) { + feed := make([]*model.Feed, 0, perPage) + // TODO: use builder (do not behave same as pure sql, fix that) + return feed, s.engine.SQL(` +SELECT + repo_owner +,repo_name +,repo_full_name +,build_number +,build_event +,build_status +,build_created +,build_started +,build_finished +,build_commit +,build_branch +,build_ref +,build_refspec +,build_remote +,build_title +,build_message +,build_author +,build_email +,build_avatar +FROM repos LEFT OUTER JOIN builds ON build_id = ( + SELECT build_id FROM builds + WHERE builds.build_repo_id = repos.repo_id + ORDER BY build_id DESC + LIMIT 1 +) +INNER JOIN perms ON perms.perm_repo_id = repos.repo_id +WHERE perms.perm_user_id = ? + AND (perms.perm_push = ? OR perms.perm_admin = ?) + AND repos.repo_active = ? +ORDER BY repo_full_name ASC; +`, user.ID, true, true, true). + Find(&feed) +} diff --git a/server/store/datastore/feed_test.go b/server/store/datastore/feed_test.go new file mode 100644 index 000000000..42eb592a5 --- /dev/null +++ b/server/store/datastore/feed_test.go @@ -0,0 +1,104 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func TestRepoListLatest(t *testing.T) { + store, closer := newTestStore(t, new(model.Repo), new(model.User), new(model.Perm), new(model.Build)) + defer closer() + + user := &model.User{ + Login: "joe", + Email: "foo@bar.com", + Token: "e42080dddf012c718e476da161d21ad5", + } + assert.NoError(t, store.CreateUser(user)) + + repo1 := &model.Repo{ + Owner: "bradrydzewski", + Name: "test", + FullName: "bradrydzewski/test", + IsActive: true, + } + repo2 := &model.Repo{ + Owner: "test", + Name: "test", + FullName: "test/test", + IsActive: true, + } + repo3 := &model.Repo{ + Owner: "octocat", + Name: "hello-world", + FullName: "octocat/hello-world", + IsActive: true, + } + assert.NoError(t, store.CreateRepo(repo1)) + assert.NoError(t, store.CreateRepo(repo2)) + assert.NoError(t, store.CreateRepo(repo3)) + + assert.NoError(t, store.PermBatch([]*model.Perm{ + {UserID: user.ID, Repo: repo1.FullName, Push: true, Admin: false}, + {UserID: user.ID, Repo: repo2.FullName, Push: true, Admin: true}, + })) + + build1 := &model.Build{ + RepoID: repo1.ID, + Status: model.StatusFailure, + } + build2 := &model.Build{ + RepoID: repo1.ID, + Status: model.StatusRunning, + } + build3 := &model.Build{ + RepoID: repo2.ID, + Status: model.StatusKilled, + } + build4 := &model.Build{ + RepoID: repo3.ID, + Status: model.StatusError, + } + assert.NoError(t, store.CreateBuild(build1)) + assert.NoError(t, store.CreateBuild(build2)) + assert.NoError(t, store.CreateBuild(build3)) + assert.NoError(t, store.CreateBuild(build4)) + + builds, err := store.RepoListLatest(user) + if err != nil { + t.Errorf("Unexpected error: repository list with latest build: %s", err) + return + } + if got, want := len(builds), 2; got != want { + t.Errorf("Want %d repositories, got %d", want, got) + } + if got, want := builds[0].Status, model.StatusRunning; want != got { + t.Errorf("Want repository status %s, got %s", want, got) + } + if got, want := builds[0].FullName, repo1.FullName; want != got { + t.Errorf("Want repository name %s, got %s", want, got) + } + if got, want := builds[1].Status, model.StatusKilled; want != got { + t.Errorf("Want repository status %s, got %s", want, got) + } + if got, want := builds[1].FullName, repo2.FullName; want != got { + t.Errorf("Want repository name %s, got %s", want, got) + } +} diff --git a/server/store/datastore/file.go b/server/store/datastore/file.go new file mode 100644 index 000000000..a0221b006 --- /dev/null +++ b/server/store/datastore/file.go @@ -0,0 +1,56 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "bytes" + "io" + "io/ioutil" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) FileList(build *model.Build) ([]*model.File, error) { + files := make([]*model.File, 0, perPage) + return files, s.engine.Where("file_build_id = ?", build.ID).Find(&files) +} + +func (s storage) FileFind(proc *model.Proc, name string) (*model.File, error) { + file := &model.File{ + ProcID: proc.ID, + Name: name, + } + return file, wrapGet(s.engine.Get(file)) +} + +func (s storage) FileRead(proc *model.Proc, name string) (io.ReadCloser, error) { + file, err := s.FileFind(proc, name) + if err != nil { + return nil, err + } + buf := bytes.NewBuffer(file.Data) + return ioutil.NopCloser(buf), err +} + +func (s storage) FileCreate(file *model.File, reader io.Reader) error { + data, err := ioutil.ReadAll(reader) + if err != nil { + return err + } + file.Data = data + // only Insert set auto created ID back to object + _, err = s.engine.Insert(file) + return err +} diff --git a/server/store/datastore/files_test.go b/server/store/datastore/file_test.go similarity index 62% rename from server/store/datastore/files_test.go rename to server/store/datastore/file_test.go index 3af8c41d1..cf5a1085c 100644 --- a/server/store/datastore/files_test.go +++ b/server/store/datastore/file_test.go @@ -19,17 +19,16 @@ import ( "io/ioutil" "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestFileFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from files") - s.Close() - }() + store, closer := newTestStore(t, new(model.File), new(model.Proc)) + defer closer() - if err := s.FileCreate( + if err := store.FileCreate( &model.File{ BuildID: 2, ProcID: 1, @@ -43,7 +42,7 @@ func TestFileFind(t *testing.T) { return } - file, err := s.FileFind(&model.Proc{ID: 1}, "hello.txt") + file, err := store.FileFind(&model.Proc{ID: 1}, "hello.txt") if err != nil { t.Error(err) return @@ -67,7 +66,7 @@ func TestFileFind(t *testing.T) { t.Errorf("Want file size %d, got %d", want, got) } - rc, err := s.FileRead(&model.Proc{ID: 1}, "hello.txt") + rc, err := store.FileRead(&model.Proc{ID: 1}, "hello.txt") if err != nil { t.Error(err) return @@ -79,13 +78,10 @@ func TestFileFind(t *testing.T) { } func TestFileList(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from files") - s.Close() - }() + store, closer := newTestStore(t, new(model.File), new(model.Build)) + defer closer() - s.FileCreate( + assert.NoError(t, store.FileCreate( &model.File{ BuildID: 1, ProcID: 1, @@ -94,8 +90,8 @@ func TestFileList(t *testing.T) { Size: 11, }, bytes.NewBufferString("hello world"), - ) - s.FileCreate( + )) + assert.NoError(t, store.FileCreate( &model.File{ BuildID: 1, ProcID: 1, @@ -104,9 +100,9 @@ func TestFileList(t *testing.T) { Size: 11, }, bytes.NewBufferString("hola mundo"), - ) + )) - files, err := s.FileList(&model.Build{ID: 1}) + files, err := store.FileList(&model.Build{ID: 1}) if err != nil { t.Errorf("Unexpected error: select files: %s", err) return @@ -118,13 +114,10 @@ func TestFileList(t *testing.T) { } func TestFileIndexes(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from files") - s.Close() - }() + store, closer := newTestStore(t, new(model.File), new(model.Build)) + defer closer() - if err := s.FileCreate( + if err := store.FileCreate( &model.File{ BuildID: 1, ProcID: 1, @@ -139,7 +132,7 @@ func TestFileIndexes(t *testing.T) { } // fail due to duplicate file name - if err := s.FileCreate( + if err := store.FileCreate( &model.File{ BuildID: 1, ProcID: 1, @@ -153,46 +146,47 @@ func TestFileIndexes(t *testing.T) { } } -// func TestFileCascade(t *testing.T) { -// s := newTest() -// defer s.Close() -// -// -// err1 := s.ProcCreate([]*model.Proc{ -// { -// BuildID: 1, -// PID: 1, -// PGID: 1, -// Name: "build", -// State: "success", -// }, -// }) -// err2 := s.FileCreate( -// &model.File{ -// BuildID: 1, -// ProcID: 1, -// Name: "hello.txt", -// Mime: "text/plain", -// Size: 11, -// }, -// bytes.NewBufferString("hello world"), -// ) -// -// if err1 != nil { -// t.Errorf("Unexpected error: cannot insert proc: %s", err1) -// } else if err2 != nil { -// t.Errorf("Unexpected error: cannot insert file: %s", err2) -// } -// -// if _, err3 := s.ProcFind(&model.Build{ID: 1}, 1); err3 != nil { -// t.Errorf("Unexpected error: cannot get inserted proc: %s", err3) -// } -// -// db.Exec("delete from procs where proc_id = 1") -// -// file, err4 := s.FileFind(&model.Proc{ID: 1}, "hello.txt") -// if err4 == nil { -// t.Errorf("Expected no rows in result set error") -// t.Log(file) -// } -// } +func TestFileCascade(t *testing.T) { + store, closer := newTestStore(t, new(model.File), new(model.Proc), new(model.Build)) + defer closer() + + procOne := &model.Proc{ + BuildID: 1, + PID: 1, + PGID: 1, + Name: "build", + State: "success", + } + err1 := store.ProcCreate([]*model.Proc{procOne}) + assert.EqualValues(t, int64(1), procOne.ID) + + err2 := store.FileCreate( + &model.File{ + BuildID: 1, + ProcID: 1, + Name: "hello.txt", + Mime: "text/plain", + Size: 11, + }, + bytes.NewBufferString("hello world"), + ) + + if err1 != nil { + t.Errorf("Unexpected error: cannot insert proc: %s", err1) + } else if err2 != nil { + t.Errorf("Unexpected error: cannot insert file: %s", err2) + } + + if _, err3 := store.ProcFind(&model.Build{ID: 1}, 1); err3 != nil { + t.Errorf("Unexpected error: cannot get inserted proc: %s", err3) + } + + err := store.ProcClear(&model.Build{ID: 1, Procs: []*model.Proc{procOne}}) + assert.NoError(t, err) + + file, err4 := store.FileFind(&model.Proc{ID: 1}, "hello.txt") + if err4 == nil { + t.Errorf("Expected no rows in result set error") + t.Log(file) + } +} diff --git a/server/store/datastore/files.go b/server/store/datastore/files.go deleted file mode 100644 index 9b29ab768..000000000 --- a/server/store/datastore/files.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "bytes" - "io" - "io/ioutil" - - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) FileList(build *model.Build) ([]*model.File, error) { - stmt := sql.Lookup(db.driver, "files-find-build") - list := []*model.File{} - err := meddler.QueryAll(db, &list, stmt, build.ID) - return list, err -} - -func (db *datastore) FileFind(proc *model.Proc, name string) (*model.File, error) { - stmt := sql.Lookup(db.driver, "files-find-proc-name") - file := new(model.File) - err := meddler.QueryRow(db, file, stmt, proc.ID, name) - return file, err -} - -func (db *datastore) FileRead(proc *model.Proc, name string) (io.ReadCloser, error) { - stmt := sql.Lookup(db.driver, "files-find-proc-name-data") - file := new(fileData) - err := meddler.QueryRow(db, file, stmt, proc.ID, name) - buf := bytes.NewBuffer(file.Data) - return ioutil.NopCloser(buf), err -} - -func (db *datastore) FileCreate(file *model.File, r io.Reader) error { - d, err := ioutil.ReadAll(r) - if err != nil { - return err - } - f := fileData{ - ID: file.ID, - BuildID: file.BuildID, - ProcID: file.ProcID, - PID: file.PID, - Name: file.Name, - Size: file.Size, - Mime: file.Mime, - Time: file.Time, - Passed: file.Passed, - Failed: file.Failed, - Skipped: file.Skipped, - Data: d, - } - return meddler.Insert(db, "files", &f) -} - -type fileData struct { - ID int64 `meddler:"file_id,pk"` - BuildID int64 `meddler:"file_build_id"` - ProcID int64 `meddler:"file_proc_id"` - PID int `meddler:"file_pid"` - Name string `meddler:"file_name"` - Size int `meddler:"file_size"` - Mime string `meddler:"file_mime"` - Time int64 `meddler:"file_time"` - Passed int `meddler:"file_meta_passed"` - Failed int `meddler:"file_meta_failed"` - Skipped int `meddler:"file_meta_skipped"` - Data []byte `meddler:"file_data"` -} diff --git a/server/store/datastore/ddl/sqlite/ddl.go b/server/store/datastore/helper.go similarity index 63% rename from server/store/datastore/ddl/sqlite/ddl.go rename to server/store/datastore/helper.go index 7cddb02eb..6fc7744f2 100644 --- a/server/store/datastore/ddl/sqlite/ddl.go +++ b/server/store/datastore/helper.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,6 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sqlite +package datastore -//go:generate togo ddl -package sqlite -dialect sqlite3 +import "database/sql" + +var RecordNotExist = sql.ErrNoRows + +// wrapGet return error if err not nil or if requested entry do not exist +func wrapGet(exist bool, err error) error { + if err != nil { + return err + } + if !exist { + return RecordNotExist + } + return nil +} diff --git a/server/store/datastore/init.go b/server/store/datastore/init.go index 3728245f0..8f8be7203 100644 --- a/server/store/datastore/init.go +++ b/server/store/datastore/init.go @@ -21,3 +21,18 @@ import ( _ "github.com/go-sql-driver/mysql" _ "github.com/lib/pq" ) + +// Supported database drivers +const ( + DriverMysql = "mysql" + DriverPostgres = "postgres" +) + +func SupportedDriver(driver string) bool { + switch driver { + case DriverMysql, DriverPostgres: + return true + default: + return false + } +} diff --git a/server/store/datastore/init_cgo.go b/server/store/datastore/init_cgo.go index 3d71d08a3..baeb48f29 100644 --- a/server/store/datastore/init_cgo.go +++ b/server/store/datastore/init_cgo.go @@ -22,3 +22,19 @@ import ( _ "github.com/lib/pq" _ "github.com/mattn/go-sqlite3" ) + +// Supported database drivers +const ( + DriverSqlite = "sqlite3" + DriverMysql = "mysql" + DriverPostgres = "postgres" +) + +func SupportedDriver(driver string) bool { + switch driver { + case DriverMysql, DriverPostgres, DriverSqlite: + return true + default: + return false + } +} diff --git a/server/store/datastore/log.go b/server/store/datastore/log.go new file mode 100644 index 000000000..9290c345e --- /dev/null +++ b/server/store/datastore/log.go @@ -0,0 +1,65 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "bytes" + "io" + "io/ioutil" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) LogFind(proc *model.Proc) (io.ReadCloser, error) { + logs := &model.Logs{ + ProcID: proc.ID, + } + if err := wrapGet(s.engine.Get(logs)); err != nil { + return nil, err + } + buf := bytes.NewBuffer(logs.Data) + return ioutil.NopCloser(buf), nil +} + +func (s storage) LogSave(proc *model.Proc, reader io.Reader) error { + data, _ := ioutil.ReadAll(reader) + + sess := s.engine.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + logs := new(model.Logs) + exist, err := sess.Where("log_job_id = ?", proc.ID).Get(logs) + if err != nil { + return err + } + + if exist { + if _, err := sess.ID(logs.ID).Cols("log_data").Update(&model.Logs{Data: data}); err != nil { + return err + } + } else { + if _, err := sess.Insert(&model.Logs{ + ProcID: proc.ID, + Data: data, + }); err != nil { + return err + } + } + + return sess.Commit() +} diff --git a/server/store/datastore/logs_test.go b/server/store/datastore/log_test.go similarity index 83% rename from server/store/datastore/logs_test.go rename to server/store/datastore/log_test.go index 611f5c4af..947e3def4 100644 --- a/server/store/datastore/logs_test.go +++ b/server/store/datastore/log_test.go @@ -23,22 +23,19 @@ import ( ) func TestLogCreateFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from logs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Logs)) + defer closer() proc := model.Proc{ ID: 1, } buf := bytes.NewBufferString("echo hi") - err := s.LogSave(&proc, buf) + err := store.LogSave(&proc, buf) if err != nil { t.Errorf("Unexpected error: log create: %s", err) } - rc, err := s.LogFind(&proc) + rc, err := store.LogFind(&proc) if err != nil { t.Errorf("Unexpected error: log create: %s", err) } @@ -51,19 +48,16 @@ func TestLogCreateFind(t *testing.T) { } func TestLogUpdate(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from logs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Logs)) + defer closer() proc := model.Proc{ ID: 1, } buf1 := bytes.NewBufferString("echo hi") buf2 := bytes.NewBufferString("echo allo?") - err1 := s.LogSave(&proc, buf1) - err2 := s.LogSave(&proc, buf2) + err1 := store.LogSave(&proc, buf1) + err2 := store.LogSave(&proc, buf2) if err1 != nil { t.Errorf("Unexpected error: log create: %s", err1) } @@ -71,7 +65,7 @@ func TestLogUpdate(t *testing.T) { t.Errorf("Unexpected error: log update: %s", err2) } - rc, err := s.LogFind(&proc) + rc, err := store.LogFind(&proc) if err != nil { t.Errorf("Unexpected error: log create: %s", err) } diff --git a/server/store/datastore/logs.go b/server/store/datastore/logs.go deleted file mode 100644 index 49777dc38..000000000 --- a/server/store/datastore/logs.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "bytes" - "io" - "io/ioutil" - - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) LogFind(proc *model.Proc) (io.ReadCloser, error) { - stmt := sql.Lookup(db.driver, "logs-find-proc") - data := new(logData) - err := meddler.QueryRow(db, data, stmt, proc.ID) - buf := bytes.NewBuffer(data.Data) - return ioutil.NopCloser(buf), err -} - -func (db *datastore) LogSave(proc *model.Proc, r io.Reader) error { - stmt := sql.Lookup(db.driver, "logs-find-proc") - data := new(logData) - err := meddler.QueryRow(db, data, stmt, proc.ID) - if err != nil { - data = &logData{ProcID: proc.ID} - } - data.Data, _ = ioutil.ReadAll(r) - return meddler.Save(db, "logs", data) -} - -type logData struct { - ID int64 `meddler:"log_id,pk"` - ProcID int64 `meddler:"log_job_id"` - Data []byte `meddler:"log_data"` -} diff --git a/server/store/datastore/migration/000_legacy_to_xorm.go b/server/store/datastore/migration/000_legacy_to_xorm.go new file mode 100644 index 000000000..db747f749 --- /dev/null +++ b/server/store/datastore/migration/000_legacy_to_xorm.go @@ -0,0 +1,149 @@ +// Copyright 2021 Woodpecker 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 migration + +import ( + "fmt" + + "github.com/rs/zerolog/log" + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +var legacy2Xorm = task{ + name: "xorm", + fn: func(sess *xorm.Session) error { + // make sure we have required migrations - else fail and point to last major version + for _, mig := range []string{ + // users + "create-table-users", + "update-table-set-users-token-and-secret-length", + // repos + "create-table-repos", + "alter-table-add-repo-visibility", + "update-table-set-repo-visibility", + "alter-table-add-repo-seq", + "update-table-set-repo-seq", + "update-table-set-repo-seq-default", + "alter-table-add-repo-active", + "update-table-set-repo-active", + "alter-table-add-repo-fallback", // needed to drop col + // builds + "create-table-builds", + "create-index-builds-repo", + "create-index-builds-author", + // procs + "create-table-procs", + "create-index-procs-build", + // files + "create-table-files", + "create-index-files-builds", + "create-index-files-procs", + "alter-table-add-file-pid", + "alter-table-add-file-meta-passed", + "alter-table-add-file-meta-failed", + "alter-table-add-file-meta-skipped", + "alter-table-update-file-meta", + // secrets + "create-table-secrets", + "create-index-secrets-repo", + // registry + "create-table-registry", + "create-index-registry-repo", + // senders + "create-table-senders", + "create-index-sender-repos", + // perms + "create-table-perms", + "create-index-perms-repo", + "create-index-perms-user", + // build_config + "create-table-build-config", + "populate-build-config", + } { + exist, err := sess.Exist(&migrations{mig}) + if err != nil { + return fmt.Errorf("test migration existence: %v", err) + } + if !exist { + log.Error().Msgf("migration step '%s' missing, please upgrade to last stable v0.14.x version first", mig) + return fmt.Errorf("legacy migration step missing") + } + } + + { // recreate build_config + type BuildConfig struct { + ConfigID int64 `xorm:"NOT NULL 'config_id'"` // xorm.Sync2() do not use index info of sess -> so it try to create it twice + BuildID int64 `xorm:"NOT NULL 'build_id'"` + } + if err := renameTable(sess, "build_config", "old_build_config"); err != nil { + return err + } + if err := sess.Sync2(new(BuildConfig)); err != nil { + return err + } + if _, err := sess.Exec("INSERT INTO build_config (config_id, build_id) SELECT config_id,build_id FROM old_build_config;"); err != nil { + return fmt.Errorf("unable to set copy data in to temp table %s. Error: %v", "old_build_config", err) + } + if err := sess.DropTable("old_build_config"); err != nil { + return fmt.Errorf("could not drop table '%s': %v", "old_build_config", err) + } + } + + dialect := sess.Engine().Dialect().URI().DBType + switch dialect { + case schemas.MYSQL: + for _, exec := range []string{ + "DROP INDEX IF EXISTS build_number ON builds;", + "DROP INDEX IF EXISTS ix_build_repo ON builds;", + "DROP INDEX IF EXISTS ix_build_author ON builds;", + "DROP INDEX IF EXISTS proc_build_ix ON procs;", + "DROP INDEX IF EXISTS file_build_ix ON files;", + "DROP INDEX IF EXISTS file_proc_ix ON files;", + "DROP INDEX IF EXISTS ix_secrets_repo ON secrets;", + "DROP INDEX IF EXISTS ix_registry_repo ON registry;", + "DROP INDEX IF EXISTS sender_repo_ix ON senders;", + "DROP INDEX IF EXISTS ix_perms_repo ON perms;", + "DROP INDEX IF EXISTS ix_perms_user ON perms;", + } { + if _, err := sess.Exec(exec); err != nil { + return fmt.Errorf("exec: '%s' failed: %v", exec, err) + } + } + case schemas.SQLITE, schemas.POSTGRES: + for _, exec := range []string{ + "DROP INDEX IF EXISTS ix_build_status_running;", + "DROP INDEX IF EXISTS ix_build_repo;", + "DROP INDEX IF EXISTS ix_build_author;", + "DROP INDEX IF EXISTS proc_build_ix;", + "DROP INDEX IF EXISTS file_build_ix;", + "DROP INDEX IF EXISTS file_proc_ix;", + "DROP INDEX IF EXISTS ix_secrets_repo;", + "DROP INDEX IF EXISTS ix_registry_repo;", + "DROP INDEX IF EXISTS sender_repo_ix;", + "DROP INDEX IF EXISTS ix_perms_repo;", + "DROP INDEX IF EXISTS ix_perms_user;", + } { + if _, err := sess.Exec(exec); err != nil { + return fmt.Errorf("exec: '%s' failed: %v", exec, err) + } + } + default: + return fmt.Errorf("dialect '%s' not supported", dialect) + } + + return nil + }, +} diff --git a/server/store/datastore/ddl/postgres/ddl.go b/server/store/datastore/migration/001_repos_drop_fallback.go similarity index 67% rename from server/store/datastore/ddl/postgres/ddl.go rename to server/store/datastore/migration/001_repos_drop_fallback.go index 6d50b2336..4ad5d56b6 100644 --- a/server/store/datastore/ddl/postgres/ddl.go +++ b/server/store/datastore/migration/001_repos_drop_fallback.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,6 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package postgres +package migration -//go:generate togo ddl -package postgres -dialect postgres +import ( + "xorm.io/xorm" +) + +var alterTableReposDropFallback = task{ + name: "alter-table-drop-repo-fallback", + fn: func(sess *xorm.Session) error { + return dropTableColumns(sess, "repos", "repo_fallback") + }, +} diff --git a/server/store/datastore/migration/002_repos_drop_allow_deploys_allow_tags.go b/server/store/datastore/migration/002_repos_drop_allow_deploys_allow_tags.go new file mode 100644 index 000000000..f13be0948 --- /dev/null +++ b/server/store/datastore/migration/002_repos_drop_allow_deploys_allow_tags.go @@ -0,0 +1,29 @@ +// Copyright 2021 Woodpecker 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 migration + +import ( + "xorm.io/xorm" +) + +var alterTableReposDropAllowDeploysAllowTags = task{ + name: "drop-allow-push-tags-deploys-columns", + fn: func(sess *xorm.Session) error { + return dropTableColumns(sess, "repos", + "repo_allow_deploys", + "repo_allow_tags", + ) + }, +} diff --git a/server/store/datastore/migration/common.go b/server/store/datastore/migration/common.go new file mode 100644 index 000000000..0c15e9d42 --- /dev/null +++ b/server/store/datastore/migration/common.go @@ -0,0 +1,206 @@ +// Copyright 2021 Woodpecker 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 migration + +import ( + "fmt" + "regexp" + "strings" + + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +func renameTable(sess *xorm.Session, old, new string) error { + dialect := sess.Engine().Dialect().URI().DBType + switch dialect { + case schemas.MYSQL: + _, err := sess.Exec(fmt.Sprintf("RENAME TABLE `%s` TO `%s`;", old, new)) + return err + case schemas.POSTGRES, schemas.SQLITE: + _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`;", old, new)) + return err + default: + return fmt.Errorf("dialect '%s' not supported", dialect) + } +} + +// WARNING: YOU MUST COMMIT THE SESSION AT THE END +func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...string) (err error) { + // Copyright 2017 The Gitea Authors. All rights reserved. + // Use of this source code is governed by a MIT-style + // license that can be found in the LICENSE file. + + if tableName == "" || len(columnNames) == 0 { + return nil + } + // TODO: This will not work if there are foreign keys + + dialect := sess.Engine().Dialect().URI().DBType + switch dialect { + case schemas.SQLITE: + // First drop the indexes on the columns + res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName)) + if errIndex != nil { + return errIndex + } + for _, row := range res { + indexName := row["name"] + indexRes, err := sess.Query(fmt.Sprintf("PRAGMA index_info(`%s`)", indexName)) + if err != nil { + return err + } + if len(indexRes) != 1 { + continue + } + indexColumn := string(indexRes[0]["name"]) + for _, name := range columnNames { + if name == indexColumn { + _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s`", indexName)) + if err != nil { + return err + } + } + } + } + + // Here we need to get the columns from the original table + sql := fmt.Sprintf("SELECT sql FROM sqlite_master WHERE tbl_name='%s' and type='table'", tableName) + res, err := sess.Query(sql) + if err != nil { + return err + } + tableSQL := string(res[0]["sql"]) + + // Separate out the column definitions + tableSQL = tableSQL[strings.Index(tableSQL, "("):] + + // Remove the required columnNames + for _, name := range columnNames { + tableSQL = regexp.MustCompile(regexp.QuoteMeta("`"+name+"`")+"[^`,)]*?[,)]").ReplaceAllString(tableSQL, "") + } + + // Ensure the query is ended properly + tableSQL = strings.TrimSpace(tableSQL) + if tableSQL[len(tableSQL)-1] != ')' { + if tableSQL[len(tableSQL)-1] == ',' { + tableSQL = tableSQL[:len(tableSQL)-1] + } + tableSQL += ")" + } + + // Find all the columns in the table + columns := regexp.MustCompile("`([^`]*)`").FindAllString(tableSQL, -1) + + tableSQL = fmt.Sprintf("CREATE TABLE `new_%s_new` ", tableName) + tableSQL + if _, err := sess.Exec(tableSQL); err != nil { + return err + } + + // Now restore the data + columnsSeparated := strings.Join(columns, ",") + insertSQL := fmt.Sprintf("INSERT INTO `new_%s_new` (%s) SELECT %s FROM %s", tableName, columnsSeparated, columnsSeparated, tableName) + if _, err := sess.Exec(insertSQL); err != nil { + return err + } + + // Now drop the old table + if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { + return err + } + + // Rename the table + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `new_%s_new` RENAME TO `%s`", tableName, tableName)); err != nil { + return err + } + case schemas.POSTGRES: + cols := "" + for _, col := range columnNames { + if cols != "" { + cols += ", " + } + cols += "DROP COLUMN `" + col + "` CASCADE" + } + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { + return fmt.Errorf("drop table `%s` columns %v: %v", tableName, columnNames, err) + } + case schemas.MYSQL: + // Drop indexes on columns first + sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','")) + res, err := sess.Query(sql) + if err != nil { + return err + } + for _, index := range res { + indexName := index["column_name"] + if len(indexName) > 0 { + _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s` ON `%s`", indexName, tableName)) + if err != nil { + return err + } + } + } + + // Now drop the columns + cols := "" + for _, col := range columnNames { + if cols != "" { + cols += ", " + } + cols += "DROP COLUMN `" + col + "`" + } + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { + return fmt.Errorf("drop table `%s` columns %v: %v", tableName, columnNames, err) + } + case schemas.MSSQL: + cols := "" + for _, col := range columnNames { + if cols != "" { + cols += ", " + } + cols += "`" + strings.ToLower(col) + "`" + } + sql := fmt.Sprintf("SELECT Name FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID('%[1]s') AND parent_column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", + tableName, strings.ReplaceAll(cols, "`", "'")) + constraints := make([]string, 0) + if err := sess.SQL(sql).Find(&constraints); err != nil { + return fmt.Errorf("find constraints: %v", err) + } + for _, constraint := range constraints { + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil { + return fmt.Errorf("drop table `%s` default constraint `%s`: %v", tableName, constraint, err) + } + } + sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", + tableName, strings.ReplaceAll(cols, "`", "'")) + constraints = make([]string, 0) + if err := sess.SQL(sql).Find(&constraints); err != nil { + return fmt.Errorf("find constraints: %v", err) + } + for _, constraint := range constraints { + if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil { + return fmt.Errorf("drop index `%[2]s` on `%[1]s`: %v", tableName, constraint, err) + } + } + + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil { + return fmt.Errorf("drop table `%s` columns %v: %v", tableName, columnNames, err) + } + default: + return fmt.Errorf("dialect '%s' not supported", dialect) + } + + return nil +} diff --git a/server/store/datastore/migration/migration.go b/server/store/datastore/migration/migration.go new file mode 100644 index 000000000..051e3404e --- /dev/null +++ b/server/store/datastore/migration/migration.go @@ -0,0 +1,144 @@ +// Copyright 2021 Woodpecker 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 migration + +import ( + "fmt" + "reflect" + + "github.com/rs/zerolog/log" + "xorm.io/xorm" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +// APPEND NEW MIGRATIONS +var migrationTasks = []task{ + legacy2Xorm, + alterTableReposDropFallback, + alterTableReposDropAllowDeploysAllowTags, +} + +type migrations struct { + Name string `xorm:"UNIQUE"` +} + +type task struct { + name string + fn func(sess *xorm.Session) error +} + +// initNew create tables for new instance +func initNew(sess *xorm.Session) error { + if err := syncAll(sess); err != nil { + return err + } + + // dummy run migrations + for _, task := range migrationTasks { + if _, err := sess.Insert(&migrations{task.name}); err != nil { + return err + } + } + + return nil +} + +func Migrate(e *xorm.Engine) error { + if err := e.Sync2(new(migrations)); err != nil { + return err + } + + sess := e.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + // check if we have a fresh installation or need to check for migrations + c, err := sess.Count(new(migrations)) + if err != nil { + return err + } + + if c == 0 { + if err := initNew(sess); err != nil { + return err + } + return sess.Commit() + } + + if err := runTasks(sess, migrationTasks); err != nil { + return err + } + + if err := syncAll(sess); err != nil { + return err + } + + return sess.Commit() +} + +func runTasks(sess *xorm.Session, tasks []task) error { + for _, task := range tasks { + log.Trace().Msgf("start migration task '%s'", task.name) + exist, err := sess.Exist(&migrations{task.name}) + if err != nil { + return err + } + if exist { + log.Trace().Msgf("migration task '%s' exist", task.name) + continue + } + + if task.fn != nil { + if err := task.fn(sess); err != nil { + return err + } + log.Info().Msgf("migration task '%s' done", task.name) + } else { + log.Trace().Msgf("skip migration task '%s'", task.name) + } + + if _, err := sess.Insert(&migrations{task.name}); err != nil { + return err + } + } + return nil +} + +func syncAll(sess *xorm.Session) error { + for _, bean := range []interface{}{ + new(model.Agent), + new(model.Build), + new(model.BuildConfig), + new(model.Config), + new(model.File), + new(model.Logs), + new(model.Perm), + new(model.Proc), + new(model.Registry), + new(model.Repo), + new(model.Secret), + new(model.Sender), + new(model.Task), + new(model.User), + } { + if err := sess.Sync2(bean); err != nil { + return fmt.Errorf("sync2 error '%s': %v", reflect.TypeOf(bean), err) + } + } + return nil +} diff --git a/server/store/datastore/permission.go b/server/store/datastore/permission.go new file mode 100644 index 000000000..9adfb6fb7 --- /dev/null +++ b/server/store/datastore/permission.go @@ -0,0 +1,93 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "fmt" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) PermFind(user *model.User, repo *model.Repo) (*model.Perm, error) { + perm := &model.Perm{ + UserID: user.ID, + RepoID: repo.ID, + } + return perm, wrapGet(s.engine.Get(perm)) +} + +func (s storage) PermUpsert(perm *model.Perm) error { + if len(perm.Repo) == 0 && perm.RepoID == 0 { + return fmt.Errorf("could not determine repo for permission: %v", perm) + } + + sess := s.engine.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + // lookup repo based on name if possible (preserve old behaviour) + // TODO: check if needed + if len(perm.Repo) != 0 { + if r, err := s.getRepoName(sess, perm.Repo); err != nil { + return err + } else { + perm.RepoID = r.ID + } + } + + exist, err := sess.Where("perm_user_id = ? AND perm_repo_id = ?", perm.UserID, perm.RepoID). + Exist(new(model.Perm)) + if err != nil { + return err + } + + if exist { + _, err = sess.Where("perm_user_id = ? AND perm_repo_id = ?", perm.UserID, perm.RepoID). + AllCols().Update(perm) + } else { + // only Insert set auto created ID back to object + _, err = sess.Insert(perm) + } + if err != nil { + return err + } + + return sess.Commit() +} + +func (s storage) PermBatch(perms []*model.Perm) error { + for i := range perms { + if err := s.PermUpsert(perms[i]); err != nil { + return err + } + } + return nil +} + +func (s storage) PermDelete(perm *model.Perm) error { + _, err := s.engine. + Where("perm_user_id = ? AND perm_repo_id = ?", perm.UserID, perm.RepoID). + Delete(new(model.Perm)) + return err +} + +func (s storage) PermFlush(user *model.User, before int64) error { + _, err := s.engine. + Where("perm_user_id = ? AND perm_synced < ?", user.ID, before). + Delete(new(model.Perm)) + return err +} diff --git a/server/store/datastore/perms_test.go b/server/store/datastore/permission_test.go similarity index 80% rename from server/store/datastore/perms_test.go rename to server/store/datastore/permission_test.go index cdf9f6b4f..92dda7708 100644 --- a/server/store/datastore/perms_test.go +++ b/server/store/datastore/permission_test.go @@ -17,16 +17,14 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestPermFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from perms") - s.Exec("delete from repos") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.Perm), new(model.User)) + defer closer() user := &model.User{ID: 1} repo := &model.Repo{ @@ -35,9 +33,9 @@ func TestPermFind(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - s.CreateRepo(repo) + assert.NoError(t, store.CreateRepo(repo)) - err := s.PermUpsert( + err := store.PermUpsert( &model.Perm{ UserID: user.ID, RepoID: repo.ID, @@ -52,7 +50,7 @@ func TestPermFind(t *testing.T) { return } - perm, err := s.PermFind(user, repo) + perm, err := store.PermFind(user, repo) if err != nil { t.Error(err) return @@ -69,12 +67,8 @@ func TestPermFind(t *testing.T) { } func TestPermUpsert(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from perms") - s.Exec("delete from repos") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.Perm), new(model.User)) + defer closer() user := &model.User{ID: 1} repo := &model.Repo{ @@ -83,9 +77,9 @@ func TestPermUpsert(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - s.CreateRepo(repo) + assert.NoError(t, store.CreateRepo(repo)) - err := s.PermUpsert( + err := store.PermUpsert( &model.Perm{ UserID: user.ID, RepoID: repo.ID, @@ -100,7 +94,7 @@ func TestPermUpsert(t *testing.T) { return } - perm, err := s.PermFind(user, repo) + perm, err := store.PermFind(user, repo) if err != nil { t.Error(err) return @@ -120,7 +114,7 @@ func TestPermUpsert(t *testing.T) { // using the insert or replace logic. // - err = s.PermUpsert( + err = store.PermUpsert( &model.Perm{ UserID: user.ID, RepoID: repo.ID, @@ -135,7 +129,7 @@ func TestPermUpsert(t *testing.T) { return } - perm, err = s.PermFind(user, repo) + perm, err = store.PermFind(user, repo) if err != nil { t.Error(err) return @@ -152,12 +146,8 @@ func TestPermUpsert(t *testing.T) { } func TestPermDelete(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from perms") - s.Exec("delete from repos") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.Perm), new(model.User)) + defer closer() user := &model.User{ID: 1} repo := &model.Repo{ @@ -166,9 +156,9 @@ func TestPermDelete(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - s.CreateRepo(repo) + assert.NoError(t, store.CreateRepo(repo)) - err := s.PermUpsert( + err := store.PermUpsert( &model.Perm{ UserID: user.ID, RepoID: repo.ID, @@ -183,17 +173,17 @@ func TestPermDelete(t *testing.T) { return } - perm, err := s.PermFind(user, repo) + perm, err := store.PermFind(user, repo) if err != nil { t.Errorf("Unexpected error: select perm: %s", err) return } - err = s.PermDelete(perm) + err = store.PermDelete(perm) if err != nil { t.Errorf("Unexpected error: delete perm: %s", err) return } - _, err = s.PermFind(user, repo) + _, err = store.PermFind(user, repo) if err == nil { t.Errorf("Expect error: sql.ErrNoRows") return diff --git a/server/store/datastore/perms.go b/server/store/datastore/perms.go deleted file mode 100644 index 2b83b6e3c..000000000 --- a/server/store/datastore/perms.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) PermFind(user *model.User, repo *model.Repo) (*model.Perm, error) { - stmt := sql.Lookup(db.driver, "perms-find-user-repo") - data := new(model.Perm) - err := meddler.QueryRow(db, data, stmt, user.ID, repo.ID) - return data, err -} - -func (db *datastore) PermUpsert(perm *model.Perm) error { - stmt := sql.Lookup(db.driver, "perms-insert-replace-lookup") - _, err := db.Exec(stmt, - perm.UserID, - perm.Repo, - perm.Pull, - perm.Push, - perm.Admin, - perm.Synced, - ) - return err -} - -func (db *datastore) PermBatch(perms []*model.Perm) (err error) { - for _, perm := range perms { - err = db.PermUpsert(perm) - if err != nil { - return err - } - } - return nil -} - -func (db *datastore) PermDelete(perm *model.Perm) error { - stmt := sql.Lookup(db.driver, "perms-delete-user-repo") - _, err := db.Exec(stmt, perm.UserID, perm.RepoID) - return err -} - -func (db *datastore) PermFlush(user *model.User, before int64) error { - stmt := sql.Lookup(db.driver, "perms-delete-user-date") - _, err := db.Exec(stmt, user.ID, before) - return err -} diff --git a/server/store/datastore/proc.go b/server/store/datastore/proc.go new file mode 100644 index 000000000..7924e62ec --- /dev/null +++ b/server/store/datastore/proc.go @@ -0,0 +1,86 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) ProcLoad(id int64) (*model.Proc, error) { + proc := new(model.Proc) + return proc, wrapGet(s.engine.ID(id).Get(proc)) +} + +func (s storage) ProcFind(build *model.Build, pid int) (*model.Proc, error) { + proc := &model.Proc{ + BuildID: build.ID, + PID: pid, + } + return proc, wrapGet(s.engine.Get(proc)) +} + +func (s storage) ProcChild(build *model.Build, ppid int, child string) (*model.Proc, error) { + proc := &model.Proc{ + BuildID: build.ID, + PPID: ppid, + Name: child, + } + return proc, wrapGet(s.engine.Get(proc)) +} + +func (s storage) ProcList(build *model.Build) ([]*model.Proc, error) { + procList := make([]*model.Proc, 0, perPage) + return procList, s.engine.Where("proc_build_id = ?", build.ID).Find(&procList) +} + +func (s storage) ProcCreate(procs []*model.Proc) error { + sess := s.engine.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + for i := range procs { + // only Insert on single object ref set auto created ID back to object + if _, err := sess.Insert(procs[i]); err != nil { + return err + } + } + + return sess.Commit() +} + +func (s storage) ProcUpdate(proc *model.Proc) error { + _, err := s.engine.ID(proc.ID).AllCols().Update(proc) + return err +} + +func (s storage) ProcClear(build *model.Build) error { + sess := s.engine.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + if _, err := sess.Where("file_build_id = ?", build.ID).Delete(new(model.File)); err != nil { + return err + } + + if _, err := sess.Where("proc_build_id = ?", build.ID).Delete(new(model.Proc)); err != nil { + return err + } + + return sess.Commit() +} diff --git a/server/store/datastore/procs_test.go b/server/store/datastore/proc_test.go similarity index 62% rename from server/store/datastore/procs_test.go rename to server/store/datastore/proc_test.go index 17147c4b7..dd66467a5 100644 --- a/server/store/datastore/procs_test.go +++ b/server/store/datastore/proc_test.go @@ -17,17 +17,16 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestProcFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from procs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Build)) + defer closer() - err := s.ProcCreate([]*model.Proc{ + procs := []*model.Proc{ { BuildID: 1000, PID: 1, @@ -41,45 +40,23 @@ func TestProcFind(t *testing.T) { Platform: "linux/amd64", Environ: map[string]string{"GOLANG": "tip"}, }, - }) - if err != nil { - t.Errorf("Unexpected error: insert procs: %s", err) - return } + assert.NoError(t, store.ProcCreate(procs)) + assert.EqualValues(t, 1, procs[0].ID) + assert.Error(t, store.ProcCreate(procs)) - proc, err := s.ProcFind(&model.Build{ID: 1000}, 1) - if err != nil { - t.Error(err) + proc, err := store.ProcFind(&model.Build{ID: 1000}, 1) + if !assert.NoError(t, err) { return } - if got, want := proc.BuildID, int64(1000); got != want { - t.Errorf("Want proc fk %d, got %d", want, got) - } - if got, want := proc.ID, int64(1); got != want { - t.Errorf("Want proc pk %d, got %d", want, got) - } - if got, want := proc.PID, 1; got != want { - t.Errorf("Want proc ppid %d, got %d", want, got) - } - if got, want := proc.PPID, 2; got != want { - t.Errorf("Want proc ppid %d, got %d", want, got) - } - if got, want := proc.PGID, 3; got != want { - t.Errorf("Want proc pgid %d, got %d", want, got) - } - if got, want := proc.Name, "build"; got != want { - t.Errorf("Want proc name %s, got %s", want, got) - } + assert.Equal(t, procs[0], proc) } func TestProcChild(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from procs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Build)) + defer closer() - err := s.ProcCreate([]*model.Proc{ + err := store.ProcCreate([]*model.Proc{ { BuildID: 1, PID: 1, @@ -100,7 +77,7 @@ func TestProcChild(t *testing.T) { t.Errorf("Unexpected error: insert procs: %s", err) return } - proc, err := s.ProcChild(&model.Build{ID: 1}, 1, "build") + proc, err := store.ProcChild(&model.Build{ID: 1}, 1, "build") if err != nil { t.Error(err) return @@ -115,13 +92,10 @@ func TestProcChild(t *testing.T) { } func TestProcList(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from procs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Build)) + defer closer() - err := s.ProcCreate([]*model.Proc{ + err := store.ProcCreate([]*model.Proc{ { BuildID: 2, PID: 1, @@ -149,7 +123,7 @@ func TestProcList(t *testing.T) { t.Errorf("Unexpected error: insert procs: %s", err) return } - procs, err := s.ProcList(&model.Build{ID: 1}) + procs, err := store.ProcList(&model.Build{ID: 1}) if err != nil { t.Error(err) return @@ -160,11 +134,8 @@ func TestProcList(t *testing.T) { } func TestProcUpdate(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from procs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Build)) + defer closer() proc := &model.Proc{ BuildID: 1, @@ -179,16 +150,16 @@ func TestProcUpdate(t *testing.T) { Platform: "linux/amd64", Environ: map[string]string{"GOLANG": "tip"}, } - if err := s.ProcCreate([]*model.Proc{proc}); err != nil { + if err := store.ProcCreate([]*model.Proc{proc}); err != nil { t.Errorf("Unexpected error: insert proc: %s", err) return } proc.State = "running" - if err := s.ProcUpdate(proc); err != nil { + if err := store.ProcUpdate(proc); err != nil { t.Errorf("Unexpected error: update proc: %s", err) return } - updated, err := s.ProcFind(&model.Build{ID: 1}, 1) + updated, err := store.ProcFind(&model.Build{ID: 1}, 1) if err != nil { t.Error(err) return @@ -199,13 +170,10 @@ func TestProcUpdate(t *testing.T) { } func TestProcIndexes(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from procs") - s.Close() - }() + store, closer := newTestStore(t, new(model.Proc), new(model.Build)) + defer closer() - if err := s.ProcCreate([]*model.Proc{ + if err := store.ProcCreate([]*model.Proc{ { BuildID: 1, PID: 1, @@ -220,7 +188,7 @@ func TestProcIndexes(t *testing.T) { } // fail due to duplicate pid - if err := s.ProcCreate([]*model.Proc{ + if err := store.ProcCreate([]*model.Proc{ { BuildID: 1, PID: 1, @@ -232,22 +200,6 @@ func TestProcIndexes(t *testing.T) { }); err == nil { t.Errorf("Unexpected error: duplicate pid") } - - // // fail due to duplicate process name - // if err := s.ProcCreate([]*model.Proc{ - // { - // BuildID: 1, - // PID: 2, - // PPID: 1, - // PGID: 1, - // State: "success", - // Name: "build", - // }, - // }); err == nil { - // t.Errorf("Unexpected error: duplicate name") - // } } -// func TestProcCascade(t *testing.T) { -// -// } +// TODO: func TestProcCascade(t *testing.T) {} diff --git a/server/store/datastore/procs.go b/server/store/datastore/procs.go deleted file mode 100644 index 172f31556..000000000 --- a/server/store/datastore/procs.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) ProcLoad(id int64) (*model.Proc, error) { - stmt := sql.Lookup(db.driver, "procs-find-id") - proc := new(model.Proc) - err := meddler.QueryRow(db, proc, stmt, id) - return proc, err -} - -func (db *datastore) ProcFind(build *model.Build, pid int) (*model.Proc, error) { - stmt := sql.Lookup(db.driver, "procs-find-build-pid") - proc := new(model.Proc) - err := meddler.QueryRow(db, proc, stmt, build.ID, pid) - return proc, err -} - -func (db *datastore) ProcChild(build *model.Build, pid int, child string) (*model.Proc, error) { - stmt := sql.Lookup(db.driver, "procs-find-build-ppid") - proc := new(model.Proc) - err := meddler.QueryRow(db, proc, stmt, build.ID, pid, child) - return proc, err -} - -func (db *datastore) ProcList(build *model.Build) ([]*model.Proc, error) { - stmt := sql.Lookup(db.driver, "procs-find-build") - list := []*model.Proc{} - err := meddler.QueryAll(db, &list, stmt, build.ID) - return list, err -} - -func (db *datastore) ProcCreate(procs []*model.Proc) error { - for _, proc := range procs { - if err := meddler.Insert(db, "procs", proc); err != nil { - return err - } - } - return nil -} - -func (db *datastore) ProcUpdate(proc *model.Proc) error { - return meddler.Update(db, "procs", proc) -} - -func (db *datastore) ProcClear(build *model.Build) (err error) { - stmt1 := sql.Lookup(db.driver, "files-delete-build") - stmt2 := sql.Lookup(db.driver, "procs-delete-build") - _, err = db.Exec(stmt1, build.ID) - if err != nil { - return - } - _, err = db.Exec(stmt2, build.ID) - return -} diff --git a/server/store/datastore/registry.go b/server/store/datastore/registry.go index 06cadbd00..39c5cce31 100644 --- a/server/store/datastore/registry.go +++ b/server/store/datastore/registry.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,36 +15,34 @@ package datastore import ( - "github.com/russross/meddler" - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" ) -func (db *datastore) RegistryFind(repo *model.Repo, addr string) (*model.Registry, error) { - stmt := sql.Lookup(db.driver, "registry-find-repo-addr") - data := new(model.Registry) - err := meddler.QueryRow(db, data, stmt, repo.ID, addr) - return data, err +func (s storage) RegistryFind(repo *model.Repo, addr string) (*model.Registry, error) { + reg := &model.Registry{ + RepoID: repo.ID, + Address: addr, + } + return reg, wrapGet(s.engine.Get(reg)) } -func (db *datastore) RegistryList(repo *model.Repo) ([]*model.Registry, error) { - stmt := sql.Lookup(db.driver, "registry-find-repo") - data := []*model.Registry{} - err := meddler.QueryAll(db, &data, stmt, repo.ID) - return data, err +func (s storage) RegistryList(repo *model.Repo) ([]*model.Registry, error) { + regs := make([]*model.Registry, 0, perPage) + return regs, s.engine.Where("registry_repo_id = ?", repo.ID).Find(®s) } -func (db *datastore) RegistryCreate(registry *model.Registry) error { - return meddler.Insert(db, "registry", registry) -} - -func (db *datastore) RegistryUpdate(registry *model.Registry) error { - return meddler.Update(db, "registry", registry) -} - -func (db *datastore) RegistryDelete(registry *model.Registry) error { - stmt := sql.Lookup(db.driver, "registry-delete") - _, err := db.Exec(stmt, registry.ID) +func (s storage) RegistryCreate(registry *model.Registry) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(registry) + return err +} + +func (s storage) RegistryUpdate(registry *model.Registry) error { + _, err := s.engine.ID(registry.ID).AllCols().Update(registry) + return err +} + +func (s storage) RegistryDelete(registry *model.Registry) error { + _, err := s.engine.ID(registry.ID).Delete(new(model.Registry)) return err } diff --git a/server/store/datastore/registry_test.go b/server/store/datastore/registry_test.go index 220bab820..967d273e3 100644 --- a/server/store/datastore/registry_test.go +++ b/server/store/datastore/registry_test.go @@ -17,17 +17,16 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestRegistryFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from registry") - s.Close() - }() + store, closer := newTestStore(t, new(model.Registry)) + defer closer() - err := s.RegistryCreate(&model.Registry{ + err := store.RegistryCreate(&model.Registry{ RepoID: 1, Address: "index.docker.io", Username: "foo", @@ -40,7 +39,7 @@ func TestRegistryFind(t *testing.T) { return } - registry, err := s.RegistryFind(&model.Repo{ID: 1}, "index.docker.io") + registry, err := store.RegistryFind(&model.Repo{ID: 1}, "index.docker.io") if err != nil { t.Error(err) return @@ -66,26 +65,23 @@ func TestRegistryFind(t *testing.T) { } func TestRegistryList(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from registry") - s.Close() - }() + store, closer := newTestStore(t, new(model.Registry)) + defer closer() - s.RegistryCreate(&model.Registry{ + assert.NoError(t, store.RegistryCreate(&model.Registry{ RepoID: 1, Address: "index.docker.io", Username: "foo", Password: "bar", - }) - s.RegistryCreate(&model.Registry{ + })) + assert.NoError(t, store.RegistryCreate(&model.Registry{ RepoID: 1, Address: "foo.docker.io", Username: "foo", Password: "bar", - }) + })) - list, err := s.RegistryList(&model.Repo{ID: 1}) + list, err := store.RegistryList(&model.Repo{ID: 1}) if err != nil { t.Error(err) return @@ -96,11 +92,8 @@ func TestRegistryList(t *testing.T) { } func TestRegistryUpdate(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from registry") - s.Close() - }() + store, closer := newTestStore(t, new(model.Registry)) + defer closer() registry := &model.Registry{ RepoID: 1, @@ -108,16 +101,16 @@ func TestRegistryUpdate(t *testing.T) { Username: "foo", Password: "bar", } - if err := s.RegistryCreate(registry); err != nil { + if err := store.RegistryCreate(registry); err != nil { t.Errorf("Unexpected error: insert registry: %s", err) return } registry.Password = "qux" - if err := s.RegistryUpdate(registry); err != nil { + if err := store.RegistryUpdate(registry); err != nil { t.Errorf("Unexpected error: update registry: %s", err) return } - updated, err := s.RegistryFind(&model.Repo{ID: 1}, "index.docker.io") + updated, err := store.RegistryFind(&model.Repo{ID: 1}, "index.docker.io") if err != nil { t.Error(err) return @@ -128,13 +121,10 @@ func TestRegistryUpdate(t *testing.T) { } func TestRegistryIndexes(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from registry") - s.Close() - }() + store, closer := newTestStore(t, new(model.Registry)) + defer closer() - if err := s.RegistryCreate(&model.Registry{ + if err := store.RegistryCreate(&model.Registry{ RepoID: 1, Address: "index.docker.io", Username: "foo", @@ -145,7 +135,7 @@ func TestRegistryIndexes(t *testing.T) { } // fail due to duplicate addr - if err := s.RegistryCreate(&model.Registry{ + if err := store.RegistryCreate(&model.Registry{ RepoID: 1, Address: "index.docker.io", Username: "baz", diff --git a/server/store/datastore/repo.go b/server/store/datastore/repo.go new file mode 100644 index 000000000..a8e719d08 --- /dev/null +++ b/server/store/datastore/repo.go @@ -0,0 +1,111 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "github.com/rs/zerolog/log" + "xorm.io/builder" + "xorm.io/xorm" + + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) GetRepo(id int64) (*model.Repo, error) { + repo := new(model.Repo) + return repo, wrapGet(s.engine.ID(id).Get(repo)) +} + +func (s storage) GetRepoName(fullName string) (*model.Repo, error) { + sess := s.engine.NewSession() + defer sess.Close() + return s.getRepoName(sess, fullName) +} + +func (s storage) getRepoName(e *xorm.Session, fullName string) (*model.Repo, error) { + repo := new(model.Repo) + return repo, wrapGet(e.Where("repo_full_name = ?", fullName).Get(repo)) +} + +func (s storage) GetRepoCount() (int64, error) { + return s.engine.Where(builder.Eq{"repo_active": true}).Count(new(model.Repo)) +} + +func (s storage) CreateRepo(repo *model.Repo) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(repo) + return err +} + +func (s storage) UpdateRepo(repo *model.Repo) error { + _, err := s.engine.ID(repo.ID).AllCols().Update(repo) + return err +} + +func (s storage) DeleteRepo(repo *model.Repo) error { + _, err := s.engine.ID(repo.ID).Delete(new(model.Repo)) + // TODO: delete related within a session + return err +} + +// RepoList list all repos where permissions fo specific user are stored +// TODO: paginate +func (s storage) RepoList(user *model.User, owned bool) ([]*model.Repo, error) { + repos := make([]*model.Repo, 0, perPage) + sess := s.engine.Table("repos"). + Join("INNER", "perms", "perms.perm_repo_id = repos.repo_id"). + Where("perms.perm_user_id = ?", user.ID) + if owned { + sess = sess.And(builder.Eq{"perms.perm_push": true}.Or(builder.Eq{"perms.perm_admin": true})) + } + return repos, sess. + Asc("repo_full_name"). + Find(&repos) +} + +func (s storage) RepoBatch(repos []*model.Repo) error { + sess := s.engine.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + + for i := range repos { + if repos[i].UserID == 0 || len(repos[i].Owner) == 0 || len(repos[i].Name) == 0 || len(repos[i].FullName) == 0 { + log.Debug().Msgf("skip insert/update repo: %v", repos[i]) + continue + } + exist, err := sess. + Where("repo_owner = ? AND repo_name = ?", repos[i].Owner, repos[i].Name). + Exist(new(model.Repo)) + if err != nil { + return err + } + if exist { + if _, err := sess. + Where("repo_owner = ? AND repo_name = ?", repos[i].Owner, repos[i].Name). + AllCols(). + Update(repos[i]); err != nil { + return err + } + } else { + // only Insert on single object ref set auto created ID back to object + if _, err := sess.Insert(repos[i]); err != nil { + return err + } + } + } + + return sess.Commit() +} diff --git a/server/store/datastore/repos_test.go b/server/store/datastore/repo_test.go similarity index 57% rename from server/store/datastore/repos_test.go rename to server/store/datastore/repo_test.go index 695d30a71..b94462713 100644 --- a/server/store/datastore/repos_test.go +++ b/server/store/datastore/repo_test.go @@ -18,24 +18,27 @@ import ( "testing" "github.com/franela/goblin" + "github.com/stretchr/testify/assert" "github.com/woodpecker-ci/woodpecker/server/model" ) func TestRepos(t *testing.T) { - db := openTest() - defer db.Close() + store, closer := newTestStore(t, new(model.Repo), new(model.User), new(model.Build)) + defer closer() - s := From(db) g := goblin.Goblin(t) g.Describe("Repo", func() { // before each test be sure to purge the package // table data from the database. g.BeforeEach(func() { - db.Exec("DELETE FROM builds") - db.Exec("DELETE FROM repos") - db.Exec("DELETE FROM users") + _, err := store.engine.Exec("DELETE FROM builds") + g.Assert(err).IsNil() + _, err = store.engine.Exec("DELETE FROM repos") + g.Assert(err).IsNil() + _, err = store.engine.Exec("DELETE FROM users") + g.Assert(err).IsNil() }) g.It("Should Set a Repo", func() { @@ -45,14 +48,14 @@ func TestRepos(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - err1 := s.CreateRepo(&repo) - err2 := s.UpdateRepo(&repo) - getrepo, err3 := s.GetRepo(repo.ID) + err1 := store.CreateRepo(&repo) + err2 := store.UpdateRepo(&repo) + getRepo, err3 := store.GetRepo(repo.ID) g.Assert(err1).IsNil() g.Assert(err2).IsNil() g.Assert(err3).IsNil() - g.Assert(repo.ID).Equal(getrepo.ID) + g.Assert(repo.ID).Equal(getRepo.ID) }) g.It("Should Add a Repo", func() { @@ -62,7 +65,7 @@ func TestRepos(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - err := s.CreateRepo(&repo) + err := store.CreateRepo(&repo) g.Assert(err).IsNil() g.Assert(repo.ID != 0).IsTrue() }) @@ -74,8 +77,8 @@ func TestRepos(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - s.CreateRepo(&repo) - getrepo, err := s.GetRepo(repo.ID) + g.Assert(store.CreateRepo(&repo)).IsNil() + getrepo, err := store.GetRepo(repo.ID) g.Assert(err).IsNil() g.Assert(repo.ID).Equal(getrepo.ID) g.Assert(repo.UserID).Equal(getrepo.UserID) @@ -90,8 +93,8 @@ func TestRepos(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - s.CreateRepo(&repo) - getrepo, err := s.GetRepoName(repo.FullName) + g.Assert(store.CreateRepo(&repo)).IsNil() + getrepo, err := store.GetRepoName(repo.FullName) g.Assert(err).IsNil() g.Assert(repo.ID).Equal(getrepo.ID) g.Assert(repo.UserID).Equal(getrepo.UserID) @@ -112,33 +115,24 @@ func TestRepos(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - err1 := s.CreateRepo(&repo1) - err2 := s.CreateRepo(&repo2) + err1 := store.CreateRepo(&repo1) + err2 := store.CreateRepo(&repo2) g.Assert(err1).IsNil() - g.Assert(err2).IsNotNil() + g.Assert(err2 == nil).IsFalse() }) }) } func TestRepoList(t *testing.T) { - s := newTest() - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - - defer func() { - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.User), new(model.Perm)) + defer closer() user := &model.User{ Login: "joe", Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - s.CreateUser(user) + assert.NoError(t, store.CreateUser(user)) repo1 := &model.Repo{ Owner: "bradrydzewski", @@ -155,16 +149,16 @@ func TestRepoList(t *testing.T) { Name: "hello-world", FullName: "octocat/hello-world", } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - s.CreateRepo(repo3) + assert.NoError(t, store.CreateRepo(repo1)) + assert.NoError(t, store.CreateRepo(repo2)) + assert.NoError(t, store.CreateRepo(repo3)) - s.PermBatch([]*model.Perm{ + assert.NoError(t, store.PermBatch([]*model.Perm{ {UserID: user.ID, Repo: repo1.FullName}, {UserID: user.ID, Repo: repo2.FullName}, - }) + })) - repos, err := s.RepoList(user, false) + repos, err := store.RepoList(user, false) if err != nil { t.Error(err) return @@ -181,24 +175,15 @@ func TestRepoList(t *testing.T) { } func TestOwnedRepoList(t *testing.T) { - s := newTest() - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - - defer func() { - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.User), new(model.Perm)) + defer closer() user := &model.User{ Login: "joe", Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - s.CreateUser(user) + assert.NoError(t, store.CreateUser(user)) repo1 := &model.Repo{ Owner: "bradrydzewski", @@ -220,19 +205,19 @@ func TestOwnedRepoList(t *testing.T) { Name: "demo", FullName: "demo/demo", } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - s.CreateRepo(repo3) - s.CreateRepo(repo4) + assert.NoError(t, store.CreateRepo(repo1)) + assert.NoError(t, store.CreateRepo(repo2)) + assert.NoError(t, store.CreateRepo(repo3)) + assert.NoError(t, store.CreateRepo(repo4)) - s.PermBatch([]*model.Perm{ + assert.NoError(t, store.PermBatch([]*model.Perm{ {UserID: user.ID, Repo: repo1.FullName, Push: true, Admin: false}, {UserID: user.ID, Repo: repo2.FullName, Push: false, Admin: true}, {UserID: user.ID, Repo: repo3.FullName}, {UserID: user.ID, Repo: repo4.FullName}, - }) + })) - repos, err := s.RepoList(user, true) + repos, err := store.RepoList(user, true) if err != nil { t.Error(err) return @@ -248,100 +233,9 @@ func TestOwnedRepoList(t *testing.T) { } } -func TestRepoListLatest(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - s.Close() - }() - - user := &model.User{ - Login: "joe", - Email: "foo@bar.com", - Token: "e42080dddf012c718e476da161d21ad5", - } - s.CreateUser(user) - - repo1 := &model.Repo{ - Owner: "bradrydzewski", - Name: "test", - FullName: "bradrydzewski/test", - IsActive: true, - } - repo2 := &model.Repo{ - Owner: "test", - Name: "test", - FullName: "test/test", - IsActive: true, - } - repo3 := &model.Repo{ - Owner: "octocat", - Name: "hello-world", - FullName: "octocat/hello-world", - IsActive: true, - } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - s.CreateRepo(repo3) - - s.PermBatch([]*model.Perm{ - {UserID: user.ID, Repo: repo1.FullName, Push: true, Admin: false}, - {UserID: user.ID, Repo: repo2.FullName, Push: true, Admin: true}, - }) - - build1 := &model.Build{ - RepoID: repo1.ID, - Status: model.StatusFailure, - } - build2 := &model.Build{ - RepoID: repo1.ID, - Status: model.StatusRunning, - } - build3 := &model.Build{ - RepoID: repo2.ID, - Status: model.StatusKilled, - } - build4 := &model.Build{ - RepoID: repo3.ID, - Status: model.StatusError, - } - s.CreateBuild(build1) - s.CreateBuild(build2) - s.CreateBuild(build3) - s.CreateBuild(build4) - - builds, err := s.RepoListLatest(user) - if err != nil { - t.Errorf("Unexpected error: repository list with latest build: %s", err) - return - } - if got, want := len(builds), 2; got != want { - t.Errorf("Want %d repositories, got %d", want, got) - } - if got, want := builds[0].Status, model.StatusRunning; want != got { - t.Errorf("Want repository status %s, got %s", want, got) - } - if got, want := builds[0].FullName, repo1.FullName; want != got { - t.Errorf("Want repository name %s, got %s", want, got) - } - if got, want := builds[1].Status, model.StatusKilled; want != got { - t.Errorf("Want repository status %s, got %s", want, got) - } - if got, want := builds[1].FullName, repo2.FullName; want != got { - t.Errorf("Want repository name %s, got %s", want, got) - } -} - func TestRepoCount(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo)) + defer closer() repo1 := &model.Repo{ Owner: "bradrydzewski", @@ -361,40 +255,31 @@ func TestRepoCount(t *testing.T) { FullName: "test/test-ui", IsActive: false, } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - s.CreateRepo(repo3) + assert.NoError(t, store.CreateRepo(repo1)) + assert.NoError(t, store.CreateRepo(repo2)) + assert.NoError(t, store.CreateRepo(repo3)) - s.Exec("ANALYZE") - count, _ := s.GetRepoCount() - if got, want := count, 2; got != want { + count, _ := store.GetRepoCount() + if got, want := count, int64(2); got != want { t.Errorf("Want %d repositories, got %d", want, got) } } func TestRepoBatch(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.User), new(model.Perm)) + defer closer() - repo := &model.Repo{ + if !assert.NoError(t, store.CreateRepo(&model.Repo{ UserID: 1, FullName: "foo/bar", Owner: "foo", Name: "bar", IsActive: true, - } - err := s.CreateRepo(repo) - if err != nil { - t.Error(err) + })) { return } - err = s.RepoBatch( + if !assert.NoError(t, store.RepoBatch( []*model.Repo{ { UserID: 1, @@ -418,27 +303,18 @@ func TestRepoBatch(t *testing.T) { IsActive: true, }, }, - ) - if err != nil { - t.Error(err) + )) { return } - s.Exec("ANALYZE") - count, _ := s.GetRepoCount() - if got, want := count, 3; got != want { - t.Errorf("Want %d repositories, got %d", want, got) - } + count, err := store.GetRepoCount() + assert.NoError(t, err) + assert.EqualValues(t, 3, count) } func TestRepoCrud(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from repos") - s.Exec("delete from users") - s.Exec("delete from perms") - s.Close() - }() + store, closer := newTestStore(t, new(model.Repo), new(model.User), new(model.Perm)) + defer closer() repo := model.Repo{ UserID: 1, @@ -446,10 +322,10 @@ func TestRepoCrud(t *testing.T) { Owner: "bradrydzewski", Name: "test", } - s.CreateRepo(&repo) - _, err1 := s.GetRepo(repo.ID) - err2 := s.DeleteRepo(&repo) - _, err3 := s.GetRepo(repo.ID) + assert.NoError(t, store.CreateRepo(&repo)) + _, err1 := store.GetRepo(repo.ID) + err2 := store.DeleteRepo(&repo) + _, err3 := store.GetRepo(repo.ID) if err1 != nil { t.Errorf("Unexpected error: select repository: %s", err1) } diff --git a/server/store/datastore/repos.go b/server/store/datastore/repos.go deleted file mode 100644 index 94cb23089..000000000 --- a/server/store/datastore/repos.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) GetRepo(id int64) (*model.Repo, error) { - var repo = new(model.Repo) - var err = meddler.Load(db, repoTable, repo, id) - return repo, err -} - -func (db *datastore) GetRepoName(name string) (*model.Repo, error) { - var repo = new(model.Repo) - var err = meddler.QueryRow(db, repo, rebind(repoNameQuery), name) - return repo, err -} - -func (db *datastore) GetRepoCount() (count int, err error) { - err = db.QueryRow( - sql.Lookup(db.driver, "count-repos"), - ).Scan(&count) - return -} - -func (db *datastore) CreateRepo(repo *model.Repo) error { - return meddler.Insert(db, repoTable, repo) -} - -func (db *datastore) UpdateRepo(repo *model.Repo) error { - return meddler.Update(db, repoTable, repo) -} - -func (db *datastore) DeleteRepo(repo *model.Repo) error { - stmt := sql.Lookup(db.driver, "repo-delete") - _, err := db.Exec(stmt, repo.ID) - return err -} - -func (db *datastore) RepoList(user *model.User, owned bool) ([]*model.Repo, error) { - stmt := sql.Lookup(db.driver, "repo-find-user") - if owned { - stmt = sql.Lookup(db.driver, "repo-find-user-owned") - } - data := []*model.Repo{} - err := meddler.QueryAll(db, &data, stmt, user.ID) - return data, err -} - -func (db *datastore) RepoListLatest(user *model.User) ([]*model.Feed, error) { - stmt := sql.Lookup(db.driver, "feed-latest-build") - data := []*model.Feed{} - err := meddler.QueryAll(db, &data, stmt, user.ID) - return data, err -} - -func (db *datastore) RepoBatch(repos []*model.Repo) error { - stmt := sql.Lookup(db.driver, "repo-insert-ignore") - for _, repo := range repos { - _, err := db.Exec(stmt, - repo.UserID, - repo.Owner, - repo.Name, - repo.FullName, - repo.Avatar, - repo.Link, - repo.Clone, - repo.Branch, - repo.Timeout, - repo.IsPrivate, - repo.IsTrusted, - repo.IsActive, - repo.AllowPull, - repo.Hash, - repo.Kind, - repo.Config, - repo.IsGated, - repo.Visibility, - repo.Counter, - ) - if err != nil { - return err - } - } - return nil -} - -const repoTable = "repos" - -const repoNameQuery = ` -SELECT * -FROM repos -WHERE repo_full_name = ? -LIMIT 1; -` - -const repoDeleteStmt = ` -DELETE FROM repos -WHERE repo_id = ? -` diff --git a/server/store/datastore/secret.go b/server/store/datastore/secret.go index 3d2bfe5fa..d64ad0e27 100644 --- a/server/store/datastore/secret.go +++ b/server/store/datastore/secret.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,36 +15,34 @@ package datastore import ( - "github.com/russross/meddler" - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" ) -func (db *datastore) SecretFind(repo *model.Repo, name string) (*model.Secret, error) { - stmt := sql.Lookup(db.driver, "secret-find-repo-name") - data := new(model.Secret) - err := meddler.QueryRow(db, data, stmt, repo.ID, name) - return data, err +func (s storage) SecretFind(repo *model.Repo, name string) (*model.Secret, error) { + secret := &model.Secret{ + RepoID: repo.ID, + Name: name, + } + return secret, wrapGet(s.engine.Get(secret)) } -func (db *datastore) SecretList(repo *model.Repo) ([]*model.Secret, error) { - stmt := sql.Lookup(db.driver, "secret-find-repo") - data := []*model.Secret{} - err := meddler.QueryAll(db, &data, stmt, repo.ID) - return data, err +func (s storage) SecretList(repo *model.Repo) ([]*model.Secret, error) { + secrets := make([]*model.Secret, 0, perPage) + return secrets, s.engine.Where("secret_repo_id = ?", repo.ID).Find(&secrets) } -func (db *datastore) SecretCreate(secret *model.Secret) error { - return meddler.Insert(db, "secrets", secret) -} - -func (db *datastore) SecretUpdate(secret *model.Secret) error { - return meddler.Update(db, "secrets", secret) -} - -func (db *datastore) SecretDelete(secret *model.Secret) error { - stmt := sql.Lookup(db.driver, "secret-delete") - _, err := db.Exec(stmt, secret.ID) +func (s storage) SecretCreate(secret *model.Secret) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(secret) + return err +} + +func (s storage) SecretUpdate(secret *model.Secret) error { + _, err := s.engine.ID(secret.ID).AllCols().Update(secret) + return err +} + +func (s storage) SecretDelete(secret *model.Secret) error { + _, err := s.engine.ID(secret.ID).Delete(new(model.Secret)) return err } diff --git a/server/store/datastore/secret_test.go b/server/store/datastore/secret_test.go index 86cad79d6..4b0887888 100644 --- a/server/store/datastore/secret_test.go +++ b/server/store/datastore/secret_test.go @@ -17,17 +17,16 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestSecretFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from secrets") - s.Close() - }() + store, closer := newTestStore(t, new(model.Secret)) + defer closer() - err := s.SecretCreate(&model.Secret{ + err := store.SecretCreate(&model.Secret{ RepoID: 1, Name: "password", Value: "correct-horse-battery-staple", @@ -39,7 +38,7 @@ func TestSecretFind(t *testing.T) { return } - secret, err := s.SecretFind(&model.Repo{ID: 1}, "password") + secret, err := store.SecretFind(&model.Repo{ID: 1}, "password") if err != nil { t.Error(err) return @@ -68,55 +67,45 @@ func TestSecretFind(t *testing.T) { } func TestSecretList(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from secrets") - s.Close() - }() + store, closer := newTestStore(t, new(model.Secret)) + defer closer() - s.SecretCreate(&model.Secret{ + assert.NoError(t, store.SecretCreate(&model.Secret{ RepoID: 1, Name: "foo", Value: "bar", - }) - s.SecretCreate(&model.Secret{ + })) + assert.NoError(t, store.SecretCreate(&model.Secret{ RepoID: 1, Name: "baz", Value: "qux", - }) + })) - list, err := s.SecretList(&model.Repo{ID: 1}) - if err != nil { - t.Error(err) - return - } - if got, want := len(list), 2; got != want { - t.Errorf("Want %d secrets, got %d", want, got) - } + list, err := store.SecretList(&model.Repo{ID: 1}) + assert.NoError(t, err) + assert.Len(t, list, 2) } func TestSecretUpdate(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from secrets") - s.Close() - }() + store, closer := newTestStore(t, new(model.Secret)) + defer closer() secret := &model.Secret{ RepoID: 1, Name: "foo", Value: "baz", } - if err := s.SecretCreate(secret); err != nil { + if err := store.SecretCreate(secret); err != nil { t.Errorf("Unexpected error: insert secret: %s", err) return } secret.Value = "qux" - if err := s.SecretUpdate(secret); err != nil { + assert.EqualValues(t, 1, secret.ID) + if err := store.SecretUpdate(secret); err != nil { t.Errorf("Unexpected error: update secret: %s", err) return } - updated, err := s.SecretFind(&model.Repo{ID: 1}, "foo") + updated, err := store.SecretFind(&model.Repo{ID: 1}, "foo") if err != nil { t.Error(err) return @@ -127,27 +116,24 @@ func TestSecretUpdate(t *testing.T) { } func TestSecretDelete(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from secrets") - s.Close() - }() + store, closer := newTestStore(t, new(model.Secret)) + defer closer() secret := &model.Secret{ RepoID: 1, Name: "foo", Value: "baz", } - if err := s.SecretCreate(secret); err != nil { + if err := store.SecretCreate(secret); err != nil { t.Errorf("Unexpected error: insert secret: %s", err) return } - if err := s.SecretDelete(secret); err != nil { + if err := store.SecretDelete(secret); err != nil { t.Errorf("Unexpected error: delete secret: %s", err) return } - _, err := s.SecretFind(&model.Repo{ID: 1}, "foo") + _, err := store.SecretFind(&model.Repo{ID: 1}, "foo") if err == nil { t.Errorf("Expect error: sql.ErrNoRows") return @@ -155,13 +141,10 @@ func TestSecretDelete(t *testing.T) { } func TestSecretIndexes(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from secrets") - s.Close() - }() + store, closer := newTestStore(t, new(model.Secret)) + defer closer() - if err := s.SecretCreate(&model.Secret{ + if err := store.SecretCreate(&model.Secret{ RepoID: 1, Name: "foo", Value: "bar", @@ -171,7 +154,7 @@ func TestSecretIndexes(t *testing.T) { } // fail due to duplicate name - if err := s.SecretCreate(&model.Secret{ + if err := store.SecretCreate(&model.Secret{ RepoID: 1, Name: "foo", Value: "baz", diff --git a/server/store/datastore/sender.go b/server/store/datastore/sender.go index 983c90d35..c63d2409e 100644 --- a/server/store/datastore/sender.go +++ b/server/store/datastore/sender.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,36 +15,34 @@ package datastore import ( - "github.com/russross/meddler" - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" ) -func (db *datastore) SenderFind(repo *model.Repo, login string) (*model.Sender, error) { - stmt := sql.Lookup(db.driver, "sender-find-repo-login") - data := new(model.Sender) - err := meddler.QueryRow(db, data, stmt, repo.ID, login) - return data, err +func (s storage) SenderFind(repo *model.Repo, login string) (*model.Sender, error) { + sender := &model.Sender{ + RepoID: repo.ID, + Login: login, + } + return sender, wrapGet(s.engine.Get(sender)) } -func (db *datastore) SenderList(repo *model.Repo) ([]*model.Sender, error) { - stmt := sql.Lookup(db.driver, "sender-find-repo") - data := []*model.Sender{} - err := meddler.QueryAll(db, &data, stmt, repo.ID) - return data, err +func (s storage) SenderList(repo *model.Repo) ([]*model.Sender, error) { + senders := make([]*model.Sender, 0, perPage) + return senders, s.engine.Where("sender_repo_id = ?", repo.ID).Find(&senders) } -func (db *datastore) SenderCreate(sender *model.Sender) error { - return meddler.Insert(db, "senders", sender) -} - -func (db *datastore) SenderUpdate(sender *model.Sender) error { - return meddler.Update(db, "senders", sender) -} - -func (db *datastore) SenderDelete(sender *model.Sender) error { - stmt := sql.Lookup(db.driver, "sender-delete") - _, err := db.Exec(stmt, sender.ID) +func (s storage) SenderCreate(sender *model.Sender) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(sender) + return err +} + +func (s storage) SenderUpdate(sender *model.Sender) error { + _, err := s.engine.ID(sender.ID).AllCols().Update(sender) + return err +} + +func (s storage) SenderDelete(sender *model.Sender) error { + _, err := s.engine.ID(sender.ID).Delete(new(model.Sender)) return err } diff --git a/server/store/datastore/sender_test.go b/server/store/datastore/sender_test.go index b5b4519d5..cf9cb2824 100644 --- a/server/store/datastore/sender_test.go +++ b/server/store/datastore/sender_test.go @@ -17,17 +17,16 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestSenderFind(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from senders") - s.Close() - }() + store, closer := newTestStore(t, new(model.Sender)) + defer closer() - err := s.SenderCreate(&model.Sender{ + err := store.SenderCreate(&model.Sender{ RepoID: 1, Login: "octocat", Allow: true, @@ -38,7 +37,7 @@ func TestSenderFind(t *testing.T) { return } - sender, err := s.SenderFind(&model.Repo{ID: 1}, "octocat") + sender, err := store.SenderFind(&model.Repo{ID: 1}, "octocat") if err != nil { t.Error(err) return @@ -55,26 +54,23 @@ func TestSenderFind(t *testing.T) { } func TestSenderList(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from senders") - s.Close() - }() + store, closer := newTestStore(t, new(model.Sender)) + defer closer() - s.SenderCreate(&model.Sender{ + assert.NoError(t, store.SenderCreate(&model.Sender{ RepoID: 1, Login: "octocat", Allow: true, Block: false, - }) - s.SenderCreate(&model.Sender{ + })) + assert.NoError(t, store.SenderCreate(&model.Sender{ RepoID: 1, Login: "defunkt", Allow: true, Block: false, - }) + })) - list, err := s.SenderList(&model.Repo{ID: 1}) + list, err := store.SenderList(&model.Repo{ID: 1}) if err != nil { t.Error(err) return @@ -85,11 +81,8 @@ func TestSenderList(t *testing.T) { } func TestSenderUpdate(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from senders") - s.Close() - }() + store, closer := newTestStore(t, new(model.Sender)) + defer closer() sender := &model.Sender{ RepoID: 1, @@ -97,33 +90,26 @@ func TestSenderUpdate(t *testing.T) { Allow: true, Block: false, } - if err := s.SenderCreate(sender); err != nil { + if err := store.SenderCreate(sender); err != nil { t.Errorf("Unexpected error: insert sender: %s", err) return } + assert.EqualValues(t, 1, sender.ID) sender.Allow = false - if err := s.SenderUpdate(sender); err != nil { + if err := store.SenderUpdate(sender); err != nil { t.Errorf("Unexpected error: update sender: %s", err) return } - updated, err := s.SenderFind(&model.Repo{ID: 1}, "octocat") - if err != nil { - t.Error(err) - return - } - if got, want := updated.Allow, false; got != want { - t.Errorf("Want allow value %v, got %v", want, got) - } + updated, err := store.SenderFind(&model.Repo{ID: 1}, "octocat") + assert.NoError(t, err) + assert.False(t, updated.Allow) } func TestSenderIndexes(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from senders") - s.Close() - }() + store, closer := newTestStore(t, new(model.Sender)) + defer closer() - if err := s.SenderCreate(&model.Sender{ + if err := store.SenderCreate(&model.Sender{ RepoID: 1, Login: "octocat", Allow: true, @@ -134,7 +120,7 @@ func TestSenderIndexes(t *testing.T) { } // fail due to duplicate name - if err := s.SenderCreate(&model.Sender{ + if err := store.SenderCreate(&model.Sender{ RepoID: 1, Login: "octocat", Allow: true, diff --git a/server/store/datastore/sql/lookup.go b/server/store/datastore/sql/lookup.go deleted file mode 100644 index 5c306db90..000000000 --- a/server/store/datastore/sql/lookup.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 sql - -import ( - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql/mysql" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql/postgres" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql/sqlite" -) - -// Supported database drivers -const ( - DriverSqlite = "sqlite3" - DriverMysql = "mysql" - DriverPostgres = "postgres" -) - -// Lookup returns the named sql statement compatible with -// the specified database driver. -func Lookup(driver string, name string) string { - switch driver { - case DriverPostgres: - return postgres.Lookup(name) - case DriverMysql: - return mysql.Lookup(name) - default: - return sqlite.Lookup(name) - } -} diff --git a/server/store/datastore/sql/mysql/files/config.sql b/server/store/datastore/sql/mysql/files/config.sql deleted file mode 100644 index 64f63e7a0..000000000 --- a/server/store/datastore/sql/mysql/files/config.sql +++ /dev/null @@ -1,35 +0,0 @@ --- name: config-find-id - -SELECT - config.config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -LEFT JOIN build_config ON config.config_id = build_config.config_id -WHERE build_config.build_id = ? - --- name: config-find-repo-hash - -SELECT - config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -WHERE config_repo_id = ? - AND config_hash = ? - --- name: config-find-approved - -SELECT build_id FROM builds -WHERE build_repo_id = ? -AND build_id in ( - SELECT build_id - FROM build_config - WHERE build_config.config_id = ? - ) -AND build_status NOT IN ('blocked', 'pending') -LIMIT 1 diff --git a/server/store/datastore/sql/mysql/files/counts.sql b/server/store/datastore/sql/mysql/files/counts.sql deleted file mode 100644 index f6efb43f7..000000000 --- a/server/store/datastore/sql/mysql/files/counts.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: count-users - -SELECT count(1) -FROM users - --- name: count-repos - -SELECT count(1) -FROM repos -WHERE repo_active = true - --- name: count-builds - -SELECT count(1) -FROM builds diff --git a/server/store/datastore/sql/mysql/files/feed.sql b/server/store/datastore/sql/mysql/files/feed.sql deleted file mode 100644 index d0f003eab..000000000 --- a/server/store/datastore/sql/mysql/files/feed.sql +++ /dev/null @@ -1,63 +0,0 @@ --- name: feed-latest-build - -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN builds ON build_id = ( - SELECT build_id FROM builds - WHERE builds.build_repo_id = repos.repo_id - ORDER BY build_id DESC - LIMIT 1 -) -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) - AND repos.repo_active = true -ORDER BY repo_full_name ASC; - --- name: feed - -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -INNER JOIN builds ON builds.build_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY build_id DESC -LIMIT 50 diff --git a/server/store/datastore/sql/mysql/files/files.sql b/server/store/datastore/sql/mysql/files/files.sql deleted file mode 100644 index b3364f29f..000000000 --- a/server/store/datastore/sql/mysql/files/files.sql +++ /dev/null @@ -1,57 +0,0 @@ --- name: files-find-build - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_build_id = ? - --- name: files-find-proc-name - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_proc_id = ? - AND file_name = ? - --- name: files-find-proc-name-data - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -,file_data -FROM files -WHERE file_proc_id = ? - AND file_name = ? - --- name: files-delete-build - -DELETE FROM files WHERE file_build_id = ? diff --git a/server/store/datastore/sql/mysql/files/logs.sql b/server/store/datastore/sql/mysql/files/logs.sql deleted file mode 100644 index 7473d7dcc..000000000 --- a/server/store/datastore/sql/mysql/files/logs.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: logs-find-proc - -SELECT - log_id -,log_job_id -,log_data -FROM logs -WHERE log_job_id = ? -LIMIT 1 diff --git a/server/store/datastore/sql/mysql/files/perms.sql b/server/store/datastore/sql/mysql/files/perms.sql deleted file mode 100644 index 15c80f969..000000000 --- a/server/store/datastore/sql/mysql/files/perms.sql +++ /dev/null @@ -1,58 +0,0 @@ --- name: perms-find-user - -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_date -FROM perms -WHERE perm_user_id = ? - --- name: perms-find-user-repo - -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? - --- name: perms-insert-replace - -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,?,?,?,?,?) - --- name: perms-insert-replace-lookup - -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?) - --- name: perms-delete-user-repo - -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? - --- name: perms-delete-user-date - -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_synced < ? diff --git a/server/store/datastore/sql/mysql/files/procs.sql b/server/store/datastore/sql/mysql/files/procs.sql deleted file mode 100644 index 43ea11627..000000000 --- a/server/store/datastore/sql/mysql/files/procs.sql +++ /dev/null @@ -1,87 +0,0 @@ --- name: procs-find-id - -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_id = ? - --- name: procs-find-build - -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? -ORDER BY proc_id ASC - --- name: procs-find-build-pid - -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_pid = ? - --- name: procs-find-build-ppid - -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_ppid = ? - AND proc_name = ? - --- name: procs-delete-build - -DELETE FROM procs WHERE proc_build_id = ? diff --git a/server/store/datastore/sql/mysql/files/registry.sql b/server/store/datastore/sql/mysql/files/registry.sql deleted file mode 100644 index c28ae0f35..000000000 --- a/server/store/datastore/sql/mysql/files/registry.sql +++ /dev/null @@ -1,34 +0,0 @@ --- name: registry-find-repo - -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? - --- name: registry-find-repo-addr - -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? - AND registry_addr = ? - --- name: registry-delete-repo - -DELETE FROM registry WHERE registry_repo_id = ? - --- name: registry-delete - -DELETE FROM registry WHERE registry_id = ? diff --git a/server/store/datastore/sql/mysql/files/repos.sql b/server/store/datastore/sql/mysql/files/repos.sql deleted file mode 100644 index 9c141643b..000000000 --- a/server/store/datastore/sql/mysql/files/repos.sql +++ /dev/null @@ -1,90 +0,0 @@ --- name: repo-update-counter - -UPDATE repos SET repo_counter = ? -WHERE repo_counter = ? - AND repo_id = ? - --- name: repo-find-user - -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? -ORDER BY repo_full_name ASC - --- name: repo-find-user-owned - -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY repo_full_name ASC - --- name: repo-insert-ignore - -INSERT IGNORE INTO repos ( - repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) - --- name: repo-delete - -DELETE FROM repos WHERE repo_id = ? diff --git a/server/store/datastore/sql/mysql/files/secret.sql b/server/store/datastore/sql/mysql/files/secret.sql deleted file mode 100644 index 1eea03fa6..000000000 --- a/server/store/datastore/sql/mysql/files/secret.sql +++ /dev/null @@ -1,32 +0,0 @@ --- name: secret-find-repo - -SELECT - secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? - --- name: secret-find-repo-name - -SELECT -secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? - AND secret_name = ? - --- name: secret-delete - -DELETE FROM secrets WHERE secret_id = ? diff --git a/server/store/datastore/sql/mysql/files/sender.sql b/server/store/datastore/sql/mysql/files/sender.sql deleted file mode 100644 index 7e87a6541..000000000 --- a/server/store/datastore/sql/mysql/files/sender.sql +++ /dev/null @@ -1,30 +0,0 @@ --- name: sender-find-repo - -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? - --- name: sender-find-repo-login - -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? - AND sender_login = ? - --- name: sender-delete-repo - -DELETE FROM senders WHERE sender_repo_id = ? - --- name: sender-delete - -DELETE FROM senders WHERE sender_id = ? diff --git a/server/store/datastore/sql/mysql/files/task.sql b/server/store/datastore/sql/mysql/files/task.sql deleted file mode 100644 index 61890f721..000000000 --- a/server/store/datastore/sql/mysql/files/task.sql +++ /dev/null @@ -1,13 +0,0 @@ --- name: task-list - -SELECT - task_id -,task_data -,task_labels -,task_dependencies -,task_run_on -FROM tasks - --- name: task-delete - -DELETE FROM tasks WHERE task_id = ? diff --git a/server/store/datastore/sql/mysql/files/users.sql b/server/store/datastore/sql/mysql/files/users.sql deleted file mode 100644 index 62c98eb99..000000000 --- a/server/store/datastore/sql/mysql/files/users.sql +++ /dev/null @@ -1,53 +0,0 @@ --- name: user-find - -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -ORDER BY user_login ASC - --- name: user-find-login - -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -WHERE user_login = ? -LIMIT 1 - --- name: user-update - -UPDATE users -SET -,user_token = ? -,user_secret = ? -,user_expiry = ? -,user_email = ? -,user_avatar = ? -,user_active = ? -,user_synced = ? -,user_admin = ? -,user_hash = ? -WHERE user_id = ? - --- name: user-delete - -DELETE FROM users WHERE user_id = ? diff --git a/server/store/datastore/sql/mysql/sql_gen.go b/server/store/datastore/sql/mysql/sql_gen.go deleted file mode 100644 index 4227ee29d..000000000 --- a/server/store/datastore/sql/mysql/sql_gen.go +++ /dev/null @@ -1,644 +0,0 @@ -package mysql - -// Lookup returns the named statement. -func Lookup(name string) string { - return index[name] -} - -var index = map[string]string{ - "config-find-id": configFindId, - "config-find-repo-hash": configFindRepoHash, - "config-find-approved": configFindApproved, - "count-users": countUsers, - "count-repos": countRepos, - "count-builds": countBuilds, - "feed-latest-build": feedLatestBuild, - "feed": feed, - "files-find-build": filesFindBuild, - "files-find-proc-name": filesFindProcName, - "files-find-proc-name-data": filesFindProcNameData, - "files-delete-build": filesDeleteBuild, - "logs-find-proc": logsFindProc, - "perms-find-user": permsFindUser, - "perms-find-user-repo": permsFindUserRepo, - "perms-insert-replace": permsInsertReplace, - "perms-insert-replace-lookup": permsInsertReplaceLookup, - "perms-delete-user-repo": permsDeleteUserRepo, - "perms-delete-user-date": permsDeleteUserDate, - "procs-find-id": procsFindId, - "procs-find-build": procsFindBuild, - "procs-find-build-pid": procsFindBuildPid, - "procs-find-build-ppid": procsFindBuildPpid, - "procs-delete-build": procsDeleteBuild, - "registry-find-repo": registryFindRepo, - "registry-find-repo-addr": registryFindRepoAddr, - "registry-delete-repo": registryDeleteRepo, - "registry-delete": registryDelete, - "repo-update-counter": repoUpdateCounter, - "repo-find-user": repoFindUser, - "repo-find-user-owned": repoFindUserOwned, - "repo-insert-ignore": repoInsertIgnore, - "repo-delete": repoDelete, - "secret-find-repo": secretFindRepo, - "secret-find-repo-name": secretFindRepoName, - "secret-delete": secretDelete, - "sender-find-repo": senderFindRepo, - "sender-find-repo-login": senderFindRepoLogin, - "sender-delete-repo": senderDeleteRepo, - "sender-delete": senderDelete, - "task-list": taskList, - "task-delete": taskDelete, - "user-find": userFind, - "user-find-login": userFindLogin, - "user-update": userUpdate, - "user-delete": userDelete, -} - -var configFindId = ` -SELECT - config.config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -LEFT JOIN build_config ON config.config_id = build_config.config_id -WHERE build_config.build_id = ? -` - -var configFindRepoHash = ` -SELECT - config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -WHERE config_repo_id = ? - AND config_hash = ? -` - -var configFindApproved = ` -SELECT build_id FROM builds -WHERE build_repo_id = ? -AND build_id in ( - SELECT build_id - FROM build_config - WHERE build_config.config_id = ? - ) -AND build_status NOT IN ('blocked', 'pending') -LIMIT 1 -` - -var countUsers = ` -SELECT count(1) -FROM users -` - -var countRepos = ` -SELECT count(1) -FROM repos -WHERE repo_active = true -` - -var countBuilds = ` -SELECT count(1) -FROM builds -` - -var feedLatestBuild = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN builds ON build_id = ( - SELECT build_id FROM builds - WHERE builds.build_repo_id = repos.repo_id - ORDER BY build_id DESC - LIMIT 1 -) -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) - AND repos.repo_active = true -ORDER BY repo_full_name ASC; -` - -var feed = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -INNER JOIN builds ON builds.build_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY build_id DESC -LIMIT 50 -` - -var filesFindBuild = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_build_id = ? -` - -var filesFindProcName = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_proc_id = ? - AND file_name = ? -` - -var filesFindProcNameData = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -,file_data -FROM files -WHERE file_proc_id = ? - AND file_name = ? -` - -var filesDeleteBuild = ` -DELETE FROM files WHERE file_build_id = ? -` - -var logsFindProc = ` -SELECT - log_id -,log_job_id -,log_data -FROM logs -WHERE log_job_id = ? -LIMIT 1 -` - -var permsFindUser = ` -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_date -FROM perms -WHERE perm_user_id = ? -` - -var permsFindUserRepo = ` -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? -` - -var permsInsertReplace = ` -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,?,?,?,?,?) -` - -var permsInsertReplaceLookup = ` -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?) -` - -var permsDeleteUserRepo = ` -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? -` - -var permsDeleteUserDate = ` -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_synced < ? -` - -var procsFindId = ` -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_id = ? -` - -var procsFindBuild = ` -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? -ORDER BY proc_id ASC -` - -var procsFindBuildPid = ` -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_pid = ? -` - -var procsFindBuildPpid = ` -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_ppid = ? - AND proc_name = ? -` - -var procsDeleteBuild = ` -DELETE FROM procs WHERE proc_build_id = ? -` - -var registryFindRepo = ` -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? -` - -var registryFindRepoAddr = ` -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? - AND registry_addr = ? -` - -var registryDeleteRepo = ` -DELETE FROM registry WHERE registry_repo_id = ? -` - -var registryDelete = ` -DELETE FROM registry WHERE registry_id = ? -` - -var repoUpdateCounter = ` -UPDATE repos SET repo_counter = ? -WHERE repo_counter = ? - AND repo_id = ? -` - -var repoFindUser = ` -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? -ORDER BY repo_full_name ASC -` - -var repoFindUserOwned = ` -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY repo_full_name ASC -` - -var repoInsertIgnore = ` -INSERT IGNORE INTO repos ( - repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) -` - -var repoDelete = ` -DELETE FROM repos WHERE repo_id = ? -` - -var secretFindRepo = ` -SELECT - secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? -` - -var secretFindRepoName = ` -SELECT -secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? - AND secret_name = ? -` - -var secretDelete = ` -DELETE FROM secrets WHERE secret_id = ? -` - -var senderFindRepo = ` -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? -` - -var senderFindRepoLogin = ` -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? - AND sender_login = ? -` - -var senderDeleteRepo = ` -DELETE FROM senders WHERE sender_repo_id = ? -` - -var senderDelete = ` -DELETE FROM senders WHERE sender_id = ? -` - -var taskList = ` -SELECT - task_id -,task_data -,task_labels -,task_dependencies -,task_run_on -FROM tasks -` - -var taskDelete = ` -DELETE FROM tasks WHERE task_id = ? -` - -var userFind = ` -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -ORDER BY user_login ASC -` - -var userFindLogin = ` -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -WHERE user_login = ? -LIMIT 1 -` - -var userUpdate = ` -UPDATE users -SET -,user_token = ? -,user_secret = ? -,user_expiry = ? -,user_email = ? -,user_avatar = ? -,user_active = ? -,user_synced = ? -,user_admin = ? -,user_hash = ? -WHERE user_id = ? -` - -var userDelete = ` -DELETE FROM users WHERE user_id = ? -` diff --git a/server/store/datastore/sql/postgres/files/config.sql b/server/store/datastore/sql/postgres/files/config.sql deleted file mode 100644 index 17076138b..000000000 --- a/server/store/datastore/sql/postgres/files/config.sql +++ /dev/null @@ -1,35 +0,0 @@ --- name: config-find-id - -SELECT - config.config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -LEFT JOIN build_config ON config.config_id = build_config.config_id -WHERE build_config.build_id = $1 - --- name: config-find-repo-hash - -SELECT - config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -WHERE config_repo_id = $1 - AND config_hash = $2 - --- name: config-find-approved - -SELECT build_id FROM builds -WHERE build_repo_id = $1 -AND build_id in ( - SELECT build_id - FROM build_config - WHERE build_config.config_id = $2 - ) -AND build_status NOT IN ('blocked', 'pending') -LIMIT 1 diff --git a/server/store/datastore/sql/postgres/files/counts.sql b/server/store/datastore/sql/postgres/files/counts.sql deleted file mode 100644 index 38bb531ab..000000000 --- a/server/store/datastore/sql/postgres/files/counts.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: count-users - -SELECT reltuples -FROM pg_class WHERE relname = 'users' - --- name: count-repos - -SELECT count(1) -FROM repos -WHERE repo_active = true - --- name: count-builds - -SELECT count(1) -FROM builds diff --git a/server/store/datastore/sql/postgres/files/feed.sql b/server/store/datastore/sql/postgres/files/feed.sql deleted file mode 100644 index 941678144..000000000 --- a/server/store/datastore/sql/postgres/files/feed.sql +++ /dev/null @@ -1,61 +0,0 @@ --- name: feed-latest-build - -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN ( - SELECT DISTINCT ON (build_repo_id) * FROM builds - ORDER BY build_repo_id, build_id DESC -) b ON b.build_repo_id = repos.repo_id -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 - AND (perms.perm_push = true OR perms.perm_admin = true) - AND repos.repo_active = TRUE -ORDER BY repo_full_name ASC; - --- name: feed - -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -INNER JOIN builds ON builds.build_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 - AND (perms.perm_push = true OR perms.perm_admin = true) -ORDER BY build_id DESC -LIMIT 50 diff --git a/server/store/datastore/sql/postgres/files/files.sql b/server/store/datastore/sql/postgres/files/files.sql deleted file mode 100644 index f6854fa52..000000000 --- a/server/store/datastore/sql/postgres/files/files.sql +++ /dev/null @@ -1,57 +0,0 @@ --- name: files-find-build - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_build_id = $1 - --- name: files-find-proc-name - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_proc_id = $1 - AND file_name = $2 - --- name: files-find-proc-name-data - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -,file_data -FROM files -WHERE file_proc_id = $1 - AND file_name = $2 - --- name: files-delete-build - -DELETE FROM files WHERE file_build_id = $1 diff --git a/server/store/datastore/sql/postgres/files/logs.sql b/server/store/datastore/sql/postgres/files/logs.sql deleted file mode 100644 index fe209c672..000000000 --- a/server/store/datastore/sql/postgres/files/logs.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: logs-find-proc - -SELECT - log_id -,log_job_id -,log_data -FROM logs -WHERE log_job_id = $1 -LIMIT 1 diff --git a/server/store/datastore/sql/postgres/files/perms.sql b/server/store/datastore/sql/postgres/files/perms.sql deleted file mode 100644 index ea56e6417..000000000 --- a/server/store/datastore/sql/postgres/files/perms.sql +++ /dev/null @@ -1,63 +0,0 @@ --- name: perms-find-user - -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_date -FROM perms -WHERE perm_user_id = $1 - --- name: perms-find-user-repo - -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -FROM perms -WHERE perm_user_id = $1 - AND perm_repo_id = $2 - --- name: perms-insert-replace - -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES ($1,$2,$3,$4,$5,$6) - --- name: perms-insert-replace-lookup - -INSERT INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES ($1,(SELECT repo_id FROM repos WHERE repo_full_name = $2),$3,$4,$5,$6) -ON CONFLICT (perm_user_id, perm_repo_id) DO UPDATE SET - perm_pull = EXCLUDED.perm_pull -,perm_push = EXCLUDED.perm_push -,perm_admin = EXCLUDED.perm_admin -,perm_synced = EXCLUDED.perm_synced - --- name: perms-delete-user-repo - -DELETE FROM perms -WHERE perm_user_id = $1 - AND perm_repo_id = $2 - --- name: perms-delete-user-date - -DELETE FROM perms -WHERE perm_user_id = $1 - AND perm_synced < $2 diff --git a/server/store/datastore/sql/postgres/files/procs.sql b/server/store/datastore/sql/postgres/files/procs.sql deleted file mode 100644 index 7f7c240fb..000000000 --- a/server/store/datastore/sql/postgres/files/procs.sql +++ /dev/null @@ -1,87 +0,0 @@ --- name: procs-find-id - -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_id = $1 - --- name: procs-find-build - -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = $1 -ORDER BY proc_id ASC - --- name: procs-find-build-pid - -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = $1 - AND proc_pid = $2 - --- name: procs-find-build-ppid - -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = $1 - AND proc_ppid = $2 - AND proc_name = $3 - --- name: procs-delete-build - -DELETE FROM procs WHERE proc_build_id = $1 diff --git a/server/store/datastore/sql/postgres/files/registry.sql b/server/store/datastore/sql/postgres/files/registry.sql deleted file mode 100644 index 4cc5d4b23..000000000 --- a/server/store/datastore/sql/postgres/files/registry.sql +++ /dev/null @@ -1,34 +0,0 @@ --- name: registry-find-repo - -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = $1 - --- name: registry-find-repo-addr - -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = $1 - AND registry_addr = $2 - --- name: registry-delete-repo - -DELETE FROM registry WHERE registry_repo_id = $1 - --- name: registry-delete - -DELETE FROM registry WHERE registry_id = $1 diff --git a/server/store/datastore/sql/postgres/files/repos.sql b/server/store/datastore/sql/postgres/files/repos.sql deleted file mode 100644 index 6e8c6aedf..000000000 --- a/server/store/datastore/sql/postgres/files/repos.sql +++ /dev/null @@ -1,92 +0,0 @@ --- name: repo-update-counter - -UPDATE repos SET repo_counter = $1 -WHERE repo_counter = $2 - AND repo_id = $3 - --- name: repo-find-user - -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 -ORDER BY repo_full_name ASC - --- name: repo-find-user-owned - -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 - AND (perms.perm_push = true OR perms.perm_admin = true) -ORDER BY repo_full_name ASC - --- name: repo-insert-ignore - -INSERT INTO repos ( - repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19) -ON CONFLICT (repo_full_name) DO NOTHING - --- name: repo-delete - -DELETE FROM repos -WHERE repo_id = $1 diff --git a/server/store/datastore/sql/postgres/files/secret.sql b/server/store/datastore/sql/postgres/files/secret.sql deleted file mode 100644 index 4b7f024f3..000000000 --- a/server/store/datastore/sql/postgres/files/secret.sql +++ /dev/null @@ -1,32 +0,0 @@ --- name: secret-find-repo - -SELECT - secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = $1 - --- name: secret-find-repo-name - -SELECT -secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = $1 - AND secret_name = $2 - --- name: secret-delete - -DELETE FROM secrets WHERE secret_id = $1 diff --git a/server/store/datastore/sql/postgres/files/sender.sql b/server/store/datastore/sql/postgres/files/sender.sql deleted file mode 100644 index 666eb4a9a..000000000 --- a/server/store/datastore/sql/postgres/files/sender.sql +++ /dev/null @@ -1,30 +0,0 @@ --- name: sender-find-repo - -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = $1 - --- name: sender-find-repo-login - -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = $1 - AND sender_login = $2 - --- name: sender-delete-repo - -DELETE FROM senders WHERE sender_repo_id = $1 - --- name: sender-delete - -DELETE FROM senders WHERE sender_id = $1 diff --git a/server/store/datastore/sql/postgres/files/tasks.sql b/server/store/datastore/sql/postgres/files/tasks.sql deleted file mode 100644 index 515ec5e83..000000000 --- a/server/store/datastore/sql/postgres/files/tasks.sql +++ /dev/null @@ -1,13 +0,0 @@ --- name: task-list - -SELECT - task_id -,task_data -,task_labels -,task_dependencies -,task_run_on -FROM tasks - --- name: task-delete - -DELETE FROM tasks WHERE task_id = $1 diff --git a/server/store/datastore/sql/postgres/files/users.sql b/server/store/datastore/sql/postgres/files/users.sql deleted file mode 100644 index 4255c53da..000000000 --- a/server/store/datastore/sql/postgres/files/users.sql +++ /dev/null @@ -1,53 +0,0 @@ --- name: user-find - -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -ORDER BY user_login ASC - --- name: user-find-login - -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -WHERE user_login = $1 -LIMIT 1 - --- name: user-update - -UPDATE users -SET -,user_token = $1 -,user_secret = $2 -,user_expiry = $3 -,user_email = $4 -,user_avatar = $5 -,user_active = $6 -,user_synced = $7 -,user_admin = $8 -,user_hash = $9 -WHERE user_id = $10 - --- name: user-delete - -DELETE FROM users WHERE user_id = $1 diff --git a/server/store/datastore/sql/postgres/sql.go b/server/store/datastore/sql/postgres/sql.go deleted file mode 100644 index dafdfc040..000000000 --- a/server/store/datastore/sql/postgres/sql.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 postgres - -//go:generate togo sql --package=postgres diff --git a/server/store/datastore/sql/postgres/sql_gen.go b/server/store/datastore/sql/postgres/sql_gen.go deleted file mode 100644 index 3803b818e..000000000 --- a/server/store/datastore/sql/postgres/sql_gen.go +++ /dev/null @@ -1,649 +0,0 @@ -package postgres - -// Lookup returns the named statement. -func Lookup(name string) string { - return index[name] -} - -var index = map[string]string{ - "config-find-id": configFindId, - "config-find-repo-hash": configFindRepoHash, - "config-find-approved": configFindApproved, - "count-users": countUsers, - "count-repos": countRepos, - "count-builds": countBuilds, - "feed-latest-build": feedLatestBuild, - "feed": feed, - "files-find-build": filesFindBuild, - "files-find-proc-name": filesFindProcName, - "files-find-proc-name-data": filesFindProcNameData, - "files-delete-build": filesDeleteBuild, - "logs-find-proc": logsFindProc, - "perms-find-user": permsFindUser, - "perms-find-user-repo": permsFindUserRepo, - "perms-insert-replace": permsInsertReplace, - "perms-insert-replace-lookup": permsInsertReplaceLookup, - "perms-delete-user-repo": permsDeleteUserRepo, - "perms-delete-user-date": permsDeleteUserDate, - "procs-find-id": procsFindId, - "procs-find-build": procsFindBuild, - "procs-find-build-pid": procsFindBuildPid, - "procs-find-build-ppid": procsFindBuildPpid, - "procs-delete-build": procsDeleteBuild, - "registry-find-repo": registryFindRepo, - "registry-find-repo-addr": registryFindRepoAddr, - "registry-delete-repo": registryDeleteRepo, - "registry-delete": registryDelete, - "repo-update-counter": repoUpdateCounter, - "repo-find-user": repoFindUser, - "repo-find-user-owned": repoFindUserOwned, - "repo-insert-ignore": repoInsertIgnore, - "repo-delete": repoDelete, - "secret-find-repo": secretFindRepo, - "secret-find-repo-name": secretFindRepoName, - "secret-delete": secretDelete, - "sender-find-repo": senderFindRepo, - "sender-find-repo-login": senderFindRepoLogin, - "sender-delete-repo": senderDeleteRepo, - "sender-delete": senderDelete, - "task-list": taskList, - "task-delete": taskDelete, - "user-find": userFind, - "user-find-login": userFindLogin, - "user-update": userUpdate, - "user-delete": userDelete, -} - -var configFindId = ` -SELECT - config.config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -LEFT JOIN build_config ON config.config_id = build_config.config_id -WHERE build_config.build_id = $1 -` - -var configFindRepoHash = ` -SELECT - config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -WHERE config_repo_id = $1 - AND config_hash = $2 -` - -var configFindApproved = ` -SELECT build_id FROM builds -WHERE build_repo_id = $1 -AND build_id in ( - SELECT build_id - FROM build_config - WHERE build_config.config_id = $2 - ) -AND build_status NOT IN ('blocked', 'pending') -LIMIT 1 -` - -var countUsers = ` -SELECT reltuples -FROM pg_class WHERE relname = 'users' -` - -var countRepos = ` -SELECT count(1) -FROM repos -WHERE repo_active = true -` - -var countBuilds = ` -SELECT count(1) -FROM builds -` - -var feedLatestBuild = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN ( - SELECT DISTINCT ON (build_repo_id) * FROM builds - ORDER BY build_repo_id, build_id DESC -) b ON b.build_repo_id = repos.repo_id -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 - AND (perms.perm_push = true OR perms.perm_admin = true) - AND repos.repo_active = TRUE -ORDER BY repo_full_name ASC; -` - -var feed = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -INNER JOIN builds ON builds.build_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 - AND (perms.perm_push = true OR perms.perm_admin = true) -ORDER BY build_id DESC -LIMIT 50 -` - -var filesFindBuild = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_build_id = $1 -` - -var filesFindProcName = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_proc_id = $1 - AND file_name = $2 -` - -var filesFindProcNameData = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -,file_data -FROM files -WHERE file_proc_id = $1 - AND file_name = $2 -` - -var filesDeleteBuild = ` -DELETE FROM files WHERE file_build_id = $1 -` - -var logsFindProc = ` -SELECT - log_id -,log_job_id -,log_data -FROM logs -WHERE log_job_id = $1 -LIMIT 1 -` - -var permsFindUser = ` -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_date -FROM perms -WHERE perm_user_id = $1 -` - -var permsFindUserRepo = ` -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -FROM perms -WHERE perm_user_id = $1 - AND perm_repo_id = $2 -` - -var permsInsertReplace = ` -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES ($1,$2,$3,$4,$5,$6) -` - -var permsInsertReplaceLookup = ` -INSERT INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES ($1,(SELECT repo_id FROM repos WHERE repo_full_name = $2),$3,$4,$5,$6) -ON CONFLICT (perm_user_id, perm_repo_id) DO UPDATE SET - perm_pull = EXCLUDED.perm_pull -,perm_push = EXCLUDED.perm_push -,perm_admin = EXCLUDED.perm_admin -,perm_synced = EXCLUDED.perm_synced -` - -var permsDeleteUserRepo = ` -DELETE FROM perms -WHERE perm_user_id = $1 - AND perm_repo_id = $2 -` - -var permsDeleteUserDate = ` -DELETE FROM perms -WHERE perm_user_id = $1 - AND perm_synced < $2 -` - -var procsFindId = ` -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_id = $1 -` - -var procsFindBuild = ` -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = $1 -ORDER BY proc_id ASC -` - -var procsFindBuildPid = ` -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = $1 - AND proc_pid = $2 -` - -var procsFindBuildPpid = ` -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = $1 - AND proc_ppid = $2 - AND proc_name = $3 -` - -var procsDeleteBuild = ` -DELETE FROM procs WHERE proc_build_id = $1 -` - -var registryFindRepo = ` -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = $1 -` - -var registryFindRepoAddr = ` -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = $1 - AND registry_addr = $2 -` - -var registryDeleteRepo = ` -DELETE FROM registry WHERE registry_repo_id = $1 -` - -var registryDelete = ` -DELETE FROM registry WHERE registry_id = $1 -` - -var repoUpdateCounter = ` -UPDATE repos SET repo_counter = $1 -WHERE repo_counter = $2 - AND repo_id = $3 -` - -var repoFindUser = ` -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 -ORDER BY repo_full_name ASC -` - -var repoFindUserOwned = ` -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = $1 - AND (perms.perm_push = true OR perms.perm_admin = true) -ORDER BY repo_full_name ASC -` - -var repoInsertIgnore = ` -INSERT INTO repos ( - repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19) -ON CONFLICT (repo_full_name) DO NOTHING -` - -var repoDelete = ` -DELETE FROM repos -WHERE repo_id = $1 -` - -var secretFindRepo = ` -SELECT - secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = $1 -` - -var secretFindRepoName = ` -SELECT -secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = $1 - AND secret_name = $2 -` - -var secretDelete = ` -DELETE FROM secrets WHERE secret_id = $1 -` - -var senderFindRepo = ` -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = $1 -` - -var senderFindRepoLogin = ` -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = $1 - AND sender_login = $2 -` - -var senderDeleteRepo = ` -DELETE FROM senders WHERE sender_repo_id = $1 -` - -var senderDelete = ` -DELETE FROM senders WHERE sender_id = $1 -` - -var taskList = ` -SELECT - task_id -,task_data -,task_labels -,task_dependencies -,task_run_on -FROM tasks -` - -var taskDelete = ` -DELETE FROM tasks WHERE task_id = $1 -` - -var userFind = ` -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -ORDER BY user_login ASC -` - -var userFindLogin = ` -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -WHERE user_login = $1 -LIMIT 1 -` - -var userUpdate = ` -UPDATE users -SET -,user_token = $1 -,user_secret = $2 -,user_expiry = $3 -,user_email = $4 -,user_avatar = $5 -,user_active = $6 -,user_synced = $7 -,user_admin = $8 -,user_hash = $9 -WHERE user_id = $10 -` - -var userDelete = ` -DELETE FROM users WHERE user_id = $1 -` diff --git a/server/store/datastore/sql/sqlite/files/config.sql b/server/store/datastore/sql/sqlite/files/config.sql deleted file mode 100644 index 64f63e7a0..000000000 --- a/server/store/datastore/sql/sqlite/files/config.sql +++ /dev/null @@ -1,35 +0,0 @@ --- name: config-find-id - -SELECT - config.config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -LEFT JOIN build_config ON config.config_id = build_config.config_id -WHERE build_config.build_id = ? - --- name: config-find-repo-hash - -SELECT - config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -WHERE config_repo_id = ? - AND config_hash = ? - --- name: config-find-approved - -SELECT build_id FROM builds -WHERE build_repo_id = ? -AND build_id in ( - SELECT build_id - FROM build_config - WHERE build_config.config_id = ? - ) -AND build_status NOT IN ('blocked', 'pending') -LIMIT 1 diff --git a/server/store/datastore/sql/sqlite/files/counts.sql b/server/store/datastore/sql/sqlite/files/counts.sql deleted file mode 100644 index 11c9138fb..000000000 --- a/server/store/datastore/sql/sqlite/files/counts.sql +++ /dev/null @@ -1,15 +0,0 @@ --- name: count-users - -SELECT count(1) -FROM users - --- name: count-repos - -SELECT count(1) -FROM repos -WHERE repo_active = 1 - --- name: count-builds - -SELECT count(1) -FROM builds diff --git a/server/store/datastore/sql/sqlite/files/feed.sql b/server/store/datastore/sql/sqlite/files/feed.sql deleted file mode 100644 index 1e967f3e0..000000000 --- a/server/store/datastore/sql/sqlite/files/feed.sql +++ /dev/null @@ -1,63 +0,0 @@ --- name: feed-latest-build - -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN builds ON build_id = ( - SELECT build_id FROM builds - WHERE builds.build_repo_id = repos.repo_id - ORDER BY build_id DESC - LIMIT 1 -) -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) - AND repos.repo_active = 1 -ORDER BY repo_full_name ASC; - --- name: feed - -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -INNER JOIN builds ON builds.build_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY build_id DESC -LIMIT 50 diff --git a/server/store/datastore/sql/sqlite/files/files.sql b/server/store/datastore/sql/sqlite/files/files.sql deleted file mode 100644 index b3364f29f..000000000 --- a/server/store/datastore/sql/sqlite/files/files.sql +++ /dev/null @@ -1,57 +0,0 @@ --- name: files-find-build - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_build_id = ? - --- name: files-find-proc-name - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_proc_id = ? - AND file_name = ? - --- name: files-find-proc-name-data - -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -,file_data -FROM files -WHERE file_proc_id = ? - AND file_name = ? - --- name: files-delete-build - -DELETE FROM files WHERE file_build_id = ? diff --git a/server/store/datastore/sql/sqlite/files/logs.sql b/server/store/datastore/sql/sqlite/files/logs.sql deleted file mode 100644 index 7473d7dcc..000000000 --- a/server/store/datastore/sql/sqlite/files/logs.sql +++ /dev/null @@ -1,9 +0,0 @@ --- name: logs-find-proc - -SELECT - log_id -,log_job_id -,log_data -FROM logs -WHERE log_job_id = ? -LIMIT 1 diff --git a/server/store/datastore/sql/sqlite/files/perms.sql b/server/store/datastore/sql/sqlite/files/perms.sql deleted file mode 100644 index 15c80f969..000000000 --- a/server/store/datastore/sql/sqlite/files/perms.sql +++ /dev/null @@ -1,58 +0,0 @@ --- name: perms-find-user - -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_date -FROM perms -WHERE perm_user_id = ? - --- name: perms-find-user-repo - -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? - --- name: perms-insert-replace - -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,?,?,?,?,?) - --- name: perms-insert-replace-lookup - -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?) - --- name: perms-delete-user-repo - -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? - --- name: perms-delete-user-date - -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_synced < ? diff --git a/server/store/datastore/sql/sqlite/files/procs.sql b/server/store/datastore/sql/sqlite/files/procs.sql deleted file mode 100644 index 43ea11627..000000000 --- a/server/store/datastore/sql/sqlite/files/procs.sql +++ /dev/null @@ -1,87 +0,0 @@ --- name: procs-find-id - -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_id = ? - --- name: procs-find-build - -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? -ORDER BY proc_id ASC - --- name: procs-find-build-pid - -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_pid = ? - --- name: procs-find-build-ppid - -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_ppid = ? - AND proc_name = ? - --- name: procs-delete-build - -DELETE FROM procs WHERE proc_build_id = ? diff --git a/server/store/datastore/sql/sqlite/files/registry.sql b/server/store/datastore/sql/sqlite/files/registry.sql deleted file mode 100644 index c28ae0f35..000000000 --- a/server/store/datastore/sql/sqlite/files/registry.sql +++ /dev/null @@ -1,34 +0,0 @@ --- name: registry-find-repo - -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? - --- name: registry-find-repo-addr - -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? - AND registry_addr = ? - --- name: registry-delete-repo - -DELETE FROM registry WHERE registry_repo_id = ? - --- name: registry-delete - -DELETE FROM registry WHERE registry_id = ? diff --git a/server/store/datastore/sql/sqlite/files/repos.sql b/server/store/datastore/sql/sqlite/files/repos.sql deleted file mode 100644 index 8c3cb86c0..000000000 --- a/server/store/datastore/sql/sqlite/files/repos.sql +++ /dev/null @@ -1,90 +0,0 @@ --- name: repo-update-counter - -UPDATE repos SET repo_counter = ? -WHERE repo_counter = ? - AND repo_id = ? - --- name: repo-find-user - -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? -ORDER BY repo_full_name ASC - --- name: repo-find-user-owned - -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY repo_full_name ASC - --- name: repo-insert-ignore - -INSERT OR IGNORE INTO repos ( - repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) - --- name: repo-delete - -DELETE FROM repos WHERE repo_id = ? diff --git a/server/store/datastore/sql/sqlite/files/secret.sql b/server/store/datastore/sql/sqlite/files/secret.sql deleted file mode 100644 index 1eea03fa6..000000000 --- a/server/store/datastore/sql/sqlite/files/secret.sql +++ /dev/null @@ -1,32 +0,0 @@ --- name: secret-find-repo - -SELECT - secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? - --- name: secret-find-repo-name - -SELECT -secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? - AND secret_name = ? - --- name: secret-delete - -DELETE FROM secrets WHERE secret_id = ? diff --git a/server/store/datastore/sql/sqlite/files/sender.sql b/server/store/datastore/sql/sqlite/files/sender.sql deleted file mode 100644 index 7e87a6541..000000000 --- a/server/store/datastore/sql/sqlite/files/sender.sql +++ /dev/null @@ -1,30 +0,0 @@ --- name: sender-find-repo - -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? - --- name: sender-find-repo-login - -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? - AND sender_login = ? - --- name: sender-delete-repo - -DELETE FROM senders WHERE sender_repo_id = ? - --- name: sender-delete - -DELETE FROM senders WHERE sender_id = ? diff --git a/server/store/datastore/sql/sqlite/files/task.sql b/server/store/datastore/sql/sqlite/files/task.sql deleted file mode 100644 index 61890f721..000000000 --- a/server/store/datastore/sql/sqlite/files/task.sql +++ /dev/null @@ -1,13 +0,0 @@ --- name: task-list - -SELECT - task_id -,task_data -,task_labels -,task_dependencies -,task_run_on -FROM tasks - --- name: task-delete - -DELETE FROM tasks WHERE task_id = ? diff --git a/server/store/datastore/sql/sqlite/files/user.sql b/server/store/datastore/sql/sqlite/files/user.sql deleted file mode 100644 index 62c98eb99..000000000 --- a/server/store/datastore/sql/sqlite/files/user.sql +++ /dev/null @@ -1,53 +0,0 @@ --- name: user-find - -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -ORDER BY user_login ASC - --- name: user-find-login - -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -WHERE user_login = ? -LIMIT 1 - --- name: user-update - -UPDATE users -SET -,user_token = ? -,user_secret = ? -,user_expiry = ? -,user_email = ? -,user_avatar = ? -,user_active = ? -,user_synced = ? -,user_admin = ? -,user_hash = ? -WHERE user_id = ? - --- name: user-delete - -DELETE FROM users WHERE user_id = ? diff --git a/server/store/datastore/sql/sqlite/sql.go b/server/store/datastore/sql/sqlite/sql.go deleted file mode 100644 index d1481e699..000000000 --- a/server/store/datastore/sql/sqlite/sql.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 sqlite - -//go:generate togo sql --package=sqlite diff --git a/server/store/datastore/sql/sqlite/sql_gen.go b/server/store/datastore/sql/sqlite/sql_gen.go deleted file mode 100644 index 3372cee80..000000000 --- a/server/store/datastore/sql/sqlite/sql_gen.go +++ /dev/null @@ -1,644 +0,0 @@ -package sqlite - -// Lookup returns the named statement. -func Lookup(name string) string { - return index[name] -} - -var index = map[string]string{ - "config-find-id": configFindId, - "config-find-repo-hash": configFindRepoHash, - "config-find-approved": configFindApproved, - "count-users": countUsers, - "count-repos": countRepos, - "count-builds": countBuilds, - "feed-latest-build": feedLatestBuild, - "feed": feed, - "files-find-build": filesFindBuild, - "files-find-proc-name": filesFindProcName, - "files-find-proc-name-data": filesFindProcNameData, - "files-delete-build": filesDeleteBuild, - "logs-find-proc": logsFindProc, - "perms-find-user": permsFindUser, - "perms-find-user-repo": permsFindUserRepo, - "perms-insert-replace": permsInsertReplace, - "perms-insert-replace-lookup": permsInsertReplaceLookup, - "perms-delete-user-repo": permsDeleteUserRepo, - "perms-delete-user-date": permsDeleteUserDate, - "procs-find-id": procsFindId, - "procs-find-build": procsFindBuild, - "procs-find-build-pid": procsFindBuildPid, - "procs-find-build-ppid": procsFindBuildPpid, - "procs-delete-build": procsDeleteBuild, - "registry-find-repo": registryFindRepo, - "registry-find-repo-addr": registryFindRepoAddr, - "registry-delete-repo": registryDeleteRepo, - "registry-delete": registryDelete, - "repo-update-counter": repoUpdateCounter, - "repo-find-user": repoFindUser, - "repo-find-user-owned": repoFindUserOwned, - "repo-insert-ignore": repoInsertIgnore, - "repo-delete": repoDelete, - "secret-find-repo": secretFindRepo, - "secret-find-repo-name": secretFindRepoName, - "secret-delete": secretDelete, - "sender-find-repo": senderFindRepo, - "sender-find-repo-login": senderFindRepoLogin, - "sender-delete-repo": senderDeleteRepo, - "sender-delete": senderDelete, - "task-list": taskList, - "task-delete": taskDelete, - "user-find": userFind, - "user-find-login": userFindLogin, - "user-update": userUpdate, - "user-delete": userDelete, -} - -var configFindId = ` -SELECT - config.config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -LEFT JOIN build_config ON config.config_id = build_config.config_id -WHERE build_config.build_id = ? -` - -var configFindRepoHash = ` -SELECT - config_id -,config_repo_id -,config_hash -,config_data -,config_name -FROM config -WHERE config_repo_id = ? - AND config_hash = ? -` - -var configFindApproved = ` -SELECT build_id FROM builds -WHERE build_repo_id = ? -AND build_id in ( - SELECT build_id - FROM build_config - WHERE build_config.config_id = ? - ) -AND build_status NOT IN ('blocked', 'pending') -LIMIT 1 -` - -var countUsers = ` -SELECT count(1) -FROM users -` - -var countRepos = ` -SELECT count(1) -FROM repos -WHERE repo_active = 1 -` - -var countBuilds = ` -SELECT count(1) -FROM builds -` - -var feedLatestBuild = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos LEFT OUTER JOIN builds ON build_id = ( - SELECT build_id FROM builds - WHERE builds.build_repo_id = repos.repo_id - ORDER BY build_id DESC - LIMIT 1 -) -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) - AND repos.repo_active = 1 -ORDER BY repo_full_name ASC; -` - -var feed = ` -SELECT - repo_owner -,repo_name -,repo_full_name -,build_number -,build_event -,build_status -,build_created -,build_started -,build_finished -,build_commit -,build_branch -,build_ref -,build_refspec -,build_remote -,build_title -,build_message -,build_author -,build_email -,build_avatar -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -INNER JOIN builds ON builds.build_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY build_id DESC -LIMIT 50 -` - -var filesFindBuild = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_build_id = ? -` - -var filesFindProcName = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -FROM files -WHERE file_proc_id = ? - AND file_name = ? -` - -var filesFindProcNameData = ` -SELECT - file_id -,file_build_id -,file_proc_id -,file_pid -,file_name -,file_mime -,file_size -,file_time -,file_meta_passed -,file_meta_failed -,file_meta_skipped -,file_data -FROM files -WHERE file_proc_id = ? - AND file_name = ? -` - -var filesDeleteBuild = ` -DELETE FROM files WHERE file_build_id = ? -` - -var logsFindProc = ` -SELECT - log_id -,log_job_id -,log_data -FROM logs -WHERE log_job_id = ? -LIMIT 1 -` - -var permsFindUser = ` -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_date -FROM perms -WHERE perm_user_id = ? -` - -var permsFindUserRepo = ` -SELECT - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? -` - -var permsInsertReplace = ` -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,?,?,?,?,?) -` - -var permsInsertReplaceLookup = ` -REPLACE INTO perms ( - perm_user_id -,perm_repo_id -,perm_pull -,perm_push -,perm_admin -,perm_synced -) VALUES (?,(SELECT repo_id FROM repos WHERE repo_full_name = ?),?,?,?,?) -` - -var permsDeleteUserRepo = ` -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_repo_id = ? -` - -var permsDeleteUserDate = ` -DELETE FROM perms -WHERE perm_user_id = ? - AND perm_synced < ? -` - -var procsFindId = ` -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_id = ? -` - -var procsFindBuild = ` -SELECT - proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? -ORDER BY proc_id ASC -` - -var procsFindBuildPid = ` -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_pid = ? -` - -var procsFindBuildPpid = ` -SELECT -proc_id -,proc_build_id -,proc_pid -,proc_ppid -,proc_pgid -,proc_name -,proc_state -,proc_error -,proc_exit_code -,proc_started -,proc_stopped -,proc_machine -,proc_platform -,proc_environ -FROM procs -WHERE proc_build_id = ? - AND proc_ppid = ? - AND proc_name = ? -` - -var procsDeleteBuild = ` -DELETE FROM procs WHERE proc_build_id = ? -` - -var registryFindRepo = ` -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? -` - -var registryFindRepoAddr = ` -SELECT - registry_id -,registry_repo_id -,registry_addr -,registry_username -,registry_password -,registry_email -,registry_token -FROM registry -WHERE registry_repo_id = ? - AND registry_addr = ? -` - -var registryDeleteRepo = ` -DELETE FROM registry WHERE registry_repo_id = ? -` - -var registryDelete = ` -DELETE FROM registry WHERE registry_id = ? -` - -var repoUpdateCounter = ` -UPDATE repos SET repo_counter = ? -WHERE repo_counter = ? - AND repo_id = ? -` - -var repoFindUser = ` -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? -ORDER BY repo_full_name ASC -` - -var repoFindUserOwned = ` -SELECT - repo_id -,repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -FROM repos -INNER JOIN perms ON perms.perm_repo_id = repos.repo_id -WHERE perms.perm_user_id = ? - AND (perms.perm_push = 1 OR perms.perm_admin = 1) -ORDER BY repo_full_name ASC -` - -var repoInsertIgnore = ` -INSERT OR IGNORE INTO repos ( - repo_user_id -,repo_owner -,repo_name -,repo_full_name -,repo_avatar -,repo_link -,repo_clone -,repo_branch -,repo_timeout -,repo_private -,repo_trusted -,repo_active -,repo_allow_pr -,repo_hash -,repo_scm -,repo_config_path -,repo_gated -,repo_visibility -,repo_counter -) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) -` - -var repoDelete = ` -DELETE FROM repos WHERE repo_id = ? -` - -var secretFindRepo = ` -SELECT - secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? -` - -var secretFindRepoName = ` -SELECT -secret_id -,secret_repo_id -,secret_name -,secret_value -,secret_images -,secret_events -,secret_conceal -,secret_skip_verify -FROM secrets -WHERE secret_repo_id = ? - AND secret_name = ? -` - -var secretDelete = ` -DELETE FROM secrets WHERE secret_id = ? -` - -var senderFindRepo = ` -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? -` - -var senderFindRepoLogin = ` -SELECT - sender_id -,sender_repo_id -,sender_login -,sender_allow -,sender_block -FROM senders -WHERE sender_repo_id = ? - AND sender_login = ? -` - -var senderDeleteRepo = ` -DELETE FROM senders WHERE sender_repo_id = ? -` - -var senderDelete = ` -DELETE FROM senders WHERE sender_id = ? -` - -var taskList = ` -SELECT - task_id -,task_data -,task_labels -,task_dependencies -,task_run_on -FROM tasks -` - -var taskDelete = ` -DELETE FROM tasks WHERE task_id = ? -` - -var userFind = ` -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -ORDER BY user_login ASC -` - -var userFindLogin = ` -SELECT - user_id -,user_login -,user_token -,user_secret -,user_expiry -,user_email -,user_avatar -,user_active -,user_synced -,user_admin -,user_hash -FROM users -WHERE user_login = ? -LIMIT 1 -` - -var userUpdate = ` -UPDATE users -SET -,user_token = ? -,user_secret = ? -,user_expiry = ? -,user_email = ? -,user_avatar = ? -,user_active = ? -,user_synced = ? -,user_admin = ? -,user_hash = ? -WHERE user_id = ? -` - -var userDelete = ` -DELETE FROM users WHERE user_id = ? -` diff --git a/server/store/datastore/store.go b/server/store/datastore/store.go deleted file mode 100644 index 7f27f35d1..000000000 --- a/server/store/datastore/store.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "database/sql" - "fmt" - "time" - - "github.com/rs/zerolog/log" - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/store" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/ddl" -) - -// datastore is an implementation of a model.Store built on top -// of the sql/database driver with a relational database backend. -type datastore struct { - *sql.DB - - driver string - config string -} - -// Opts are options for a new database connection -type Opts struct { - Driver string - Config string -} - -// New creates a database connection for the given driver and datasource -// and returns a new Store. -func New(opts *Opts) (store.Store, error) { - db, err := open(opts.Driver, opts.Config) - return &datastore{ - DB: db, - driver: opts.Driver, - config: opts.Config, - }, err -} - -// From returns a Store using an existing database connection. -func From(db *sql.DB) store.Store { - return &datastore{DB: db} -} - -// open opens a new database connection with the specified -// driver and connection string and returns a store. -func open(driver, config string) (*sql.DB, error) { - db, err := sql.Open(driver, config) - if err != nil { - return nil, fmt.Errorf("database connection failed: %v", err) - } - if driver == "mysql" { - // per issue https://github.com/go-sql-driver/mysql/issues/257 - db.SetMaxIdleConns(0) - } - - setupMeddler(driver) - - if err := pingDatabase(db); err != nil { - return nil, fmt.Errorf("database ping attempts failed: %v", err) - } - - if err := setupDatabase(driver, db); err != nil { - return nil, fmt.Errorf("database migration failed: %v", err) - } - return db, nil -} - -// helper function to ping the database with backoff to ensure -// a connection can be established before we proceed with the -// database setup and migration. -func pingDatabase(db *sql.DB) (err error) { - for i := 0; i < 30; i++ { - err = db.Ping() - if err == nil { - return - } - log.Info().Msgf("database ping failed. retry in 1s") - time.Sleep(time.Second) - } - return -} - -// helper function to setup the database by performing -// automated database migration steps. -func setupDatabase(driver string, db *sql.DB) error { - return ddl.Migrate(driver, db) -} - -// helper function to setup the meddler default driver -// based on the selected driver name. -func setupMeddler(driver string) { - switch driver { - case "sqlite3": - meddler.Default = meddler.SQLite - case "mysql": - meddler.Default = meddler.MySQL - case "postgres": - meddler.Default = meddler.PostgreSQL - } -} diff --git a/server/store/datastore/task.go b/server/store/datastore/task.go index 276115450..1897e47ba 100644 --- a/server/store/datastore/task.go +++ b/server/store/datastore/task.go @@ -1,4 +1,4 @@ -// Copyright 2018 Drone.IO Inc. +// Copyright 2021 Woodpecker Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,25 +15,21 @@ package datastore import ( - "github.com/russross/meddler" - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" ) -func (db *datastore) TaskList() ([]*model.Task, error) { - stmt := sql.Lookup(db.driver, "task-list") - data := []*model.Task{} - err := meddler.QueryAll(db, &data, stmt) - return data, err +func (s storage) TaskList() ([]*model.Task, error) { + tasks := make([]*model.Task, 0, perPage) + return tasks, s.engine.Find(&tasks) } -func (db *datastore) TaskInsert(task *model.Task) error { - return meddler.Insert(db, "tasks", task) -} - -func (db *datastore) TaskDelete(id string) error { - stmt := sql.Lookup(db.driver, "task-delete") - _, err := db.Exec(stmt, id) +func (s storage) TaskInsert(task *model.Task) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(task) + return err +} + +func (s storage) TaskDelete(id string) error { + _, err := s.engine.Where("task_id = ?", id).Delete(new(model.Task)) return err } diff --git a/server/store/datastore/task_test.go b/server/store/datastore/task_test.go index 35f7f736c..54ed7d4fd 100644 --- a/server/store/datastore/task_test.go +++ b/server/store/datastore/task_test.go @@ -17,23 +17,22 @@ package datastore import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/woodpecker-ci/woodpecker/server/model" ) func TestTaskList(t *testing.T) { - s := newTest() - defer func() { - s.Exec("delete from tasks") - s.Close() - }() + store, closer := newTestStore(t, new(model.Task)) + defer closer() - s.TaskInsert(&model.Task{ + assert.NoError(t, store.TaskInsert(&model.Task{ ID: "some_random_id", Data: []byte("foo"), Labels: map[string]string{"foo": "bar"}, - }) + })) - list, err := s.TaskList() + list, err := store.TaskList() if err != nil { t.Error(err) return @@ -49,13 +48,13 @@ func TestTaskList(t *testing.T) { t.Errorf("Want task data %s, got %s", want, string(got)) } - err = s.TaskDelete("some_random_id") + err = store.TaskDelete("some_random_id") if err != nil { t.Error(err) return } - list, err = s.TaskList() + list, err = store.TaskList() if err != nil { t.Error(err) return diff --git a/server/store/datastore/user.go b/server/store/datastore/user.go new file mode 100644 index 000000000..bfa57eb14 --- /dev/null +++ b/server/store/datastore/user.go @@ -0,0 +1,55 @@ +// Copyright 2021 Woodpecker 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 datastore + +import ( + "github.com/woodpecker-ci/woodpecker/server/model" +) + +func (s storage) GetUser(id int64) (*model.User, error) { + user := new(model.User) + return user, wrapGet(s.engine.ID(id).Get(user)) +} + +func (s storage) GetUserLogin(login string) (*model.User, error) { + user := new(model.User) + return user, wrapGet(s.engine.Where("user_login=?", login).Get(user)) +} + +func (s storage) GetUserList() ([]*model.User, error) { + users := make([]*model.User, 0, 10) + return users, s.engine.Find(&users) +} + +func (s storage) GetUserCount() (int64, error) { + return s.engine.Count(new(model.User)) +} + +func (s storage) CreateUser(user *model.User) error { + // only Insert set auto created ID back to object + _, err := s.engine.Insert(user) + return err +} + +func (s storage) UpdateUser(user *model.User) error { + _, err := s.engine.ID(user.ID).AllCols().Update(user) + return err +} + +func (s storage) DeleteUser(user *model.User) error { + _, err := s.engine.ID(user.ID).Delete(new(model.User)) + // TODO: delete related content that need this user to work + return err +} diff --git a/server/store/datastore/users.go b/server/store/datastore/users.go deleted file mode 100644 index 5cf04844b..000000000 --- a/server/store/datastore/users.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "github.com/russross/meddler" - - "github.com/woodpecker-ci/woodpecker/server/model" - "github.com/woodpecker-ci/woodpecker/server/store/datastore/sql" -) - -func (db *datastore) GetUser(id int64) (*model.User, error) { - var usr = new(model.User) - var err = meddler.Load(db, "users", usr, id) - return usr, err -} - -func (db *datastore) GetUserLogin(login string) (*model.User, error) { - stmt := sql.Lookup(db.driver, "user-find-login") - data := new(model.User) - err := meddler.QueryRow(db, data, stmt, login) - return data, err -} - -func (db *datastore) GetUserList() ([]*model.User, error) { - stmt := sql.Lookup(db.driver, "user-find") - data := []*model.User{} - err := meddler.QueryAll(db, &data, stmt) - return data, err -} - -func (db *datastore) GetUserCount() (count int, err error) { - err = db.QueryRow( - sql.Lookup(db.driver, "count-users"), - ).Scan(&count) - return -} - -func (db *datastore) CreateUser(user *model.User) error { - return meddler.Insert(db, "users", user) -} - -func (db *datastore) UpdateUser(user *model.User) error { - return meddler.Update(db, "users", user) -} - -func (db *datastore) DeleteUser(user *model.User) error { - stmt := sql.Lookup(db.driver, "user-delete") - _, err := db.Exec(stmt, user.ID) - return err -} - -func (db *datastore) UserFeed(user *model.User) ([]*model.Feed, error) { - stmt := sql.Lookup(db.driver, "feed") - data := []*model.Feed{} - err := meddler.QueryAll(db, &data, stmt, user.ID) - return data, err -} diff --git a/server/store/datastore/users_test.go b/server/store/datastore/users_test.go index b1648b17a..694ebf2c2 100644 --- a/server/store/datastore/users_test.go +++ b/server/store/datastore/users_test.go @@ -23,8 +23,8 @@ import ( ) func TestUsers(t *testing.T) { - s := newTest() - defer s.Close() + store, closer := newTestStore(t, new(model.User), new(model.Repo), new(model.Build), new(model.Proc), new(model.Perm)) + defer closer() g := goblin.Goblin(t) g.Describe("User", func() { @@ -32,10 +32,14 @@ func TestUsers(t *testing.T) { // before each test be sure to purge the package // table data from the database. g.BeforeEach(func() { - s.Exec("DELETE FROM users") - s.Exec("DELETE FROM repos") - s.Exec("DELETE FROM builds") - s.Exec("DELETE FROM procs") + _, err := store.engine.Exec("DELETE FROM users") + g.Assert(err).IsNil() + _, err = store.engine.Exec("DELETE FROM repos") + g.Assert(err).IsNil() + _, err = store.engine.Exec("DELETE FROM builds") + g.Assert(err).IsNil() + _, err = store.engine.Exec("DELETE FROM procs") + g.Assert(err).IsNil() }) g.It("Should Update a User", func() { @@ -44,9 +48,9 @@ func TestUsers(t *testing.T) { Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - err1 := s.CreateUser(&user) - err2 := s.UpdateUser(&user) - getuser, err3 := s.GetUser(user.ID) + err1 := store.CreateUser(&user) + err2 := store.UpdateUser(&user) + getuser, err3 := store.GetUser(user.ID) g.Assert(err1).IsNil() g.Assert(err2).IsNil() g.Assert(err3).IsNil() @@ -59,13 +63,13 @@ func TestUsers(t *testing.T) { Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - err := s.CreateUser(&user) + err := store.CreateUser(&user) g.Assert(err).IsNil() g.Assert(user.ID != 0).IsTrue() }) g.It("Should Get a User", func() { - user := model.User{ + user := &model.User{ Login: "joe", Token: "f0b461ca586c27872b43a0685cbc2847", Secret: "976f22a5eef7caacb7e678d6c52f49b1", @@ -74,8 +78,8 @@ func TestUsers(t *testing.T) { Active: true, } - s.CreateUser(&user) - getuser, err := s.GetUser(user.ID) + g.Assert(store.CreateUser(user)).IsNil() + getuser, err := store.GetUser(user.ID) g.Assert(err).IsNil() g.Assert(user.ID).Equal(getuser.ID) g.Assert(user.Login).Equal(getuser.Login) @@ -87,13 +91,13 @@ func TestUsers(t *testing.T) { }) g.It("Should Get a User By Login", func() { - user := model.User{ + user := &model.User{ Login: "joe", Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - s.CreateUser(&user) - getuser, err := s.GetUserLogin(user.Login) + g.Assert(store.CreateUser(user)) + getuser, err := store.GetUserLogin(user.Login) g.Assert(err).IsNil() g.Assert(user.ID).Equal(getuser.ID) g.Assert(user.Login).Equal(getuser.Login) @@ -110,10 +114,10 @@ func TestUsers(t *testing.T) { Email: "foo@bar.com", Token: "ab20g0ddaf012c744e136da16aa21ad9", } - err1 := s.CreateUser(&user1) - err2 := s.CreateUser(&user2) + err1 := store.CreateUser(&user1) + err2 := store.CreateUser(&user2) g.Assert(err1).IsNil() - g.Assert(err2).IsNotNil() + g.Assert(err2 == nil).IsFalse() }) g.It("Should Get a User List", func() { @@ -121,15 +125,16 @@ func TestUsers(t *testing.T) { Login: "jane", Email: "foo@bar.com", Token: "ab20g0ddaf012c744e136da16aa21ad9", + Hash: "A", } user2 := model.User{ Login: "joe", Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - s.CreateUser(&user1) - s.CreateUser(&user2) - users, err := s.GetUserList() + g.Assert(store.CreateUser(&user1)).IsNil() + g.Assert(store.CreateUser(&user2)).IsNil() + users, err := store.GetUserList() g.Assert(err).IsNil() g.Assert(len(users)).Equal(2) g.Assert(users[0].Login).Equal(user1.Login) @@ -142,41 +147,39 @@ func TestUsers(t *testing.T) { Login: "jane", Email: "foo@bar.com", Token: "ab20g0ddaf012c744e136da16aa21ad9", + Hash: "A", } user2 := model.User{ Login: "joe", Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", + Hash: "B", } - s.CreateUser(&user1) - s.CreateUser(&user2) - count, err := s.GetUserCount() + g.Assert(store.CreateUser(&user1)).IsNil() + g.Assert(store.CreateUser(&user2)).IsNil() + count, err := store.GetUserCount() g.Assert(err).IsNil() - if s.driver != "postgres" { - // we have to skip this check for postgres because it uses - // an estimate which may not be updated. - g.Assert(count).Equal(2) - } + g.Assert(count).Equal(int64(2)) }) g.It("Should Get a User Count Zero", func() { - count, err := s.GetUserCount() + count, err := store.GetUserCount() g.Assert(err).IsNil() - g.Assert(count).Equal(0) + g.Assert(count).Equal(int64(0)) }) g.It("Should Del a User", func() { - user := model.User{ + user := &model.User{ Login: "joe", Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - s.CreateUser(&user) - _, err1 := s.GetUser(user.ID) - err2 := s.DeleteUser(&user) - _, err3 := s.GetUser(user.ID) + g.Assert(store.CreateUser(user)).IsNil() + user, err1 := store.GetUser(user.ID) g.Assert(err1).IsNil() + err2 := store.DeleteUser(user) g.Assert(err2).IsNil() + _, err3 := store.GetUser(user.ID) g.Assert(err3).IsNotNil() }) @@ -186,7 +189,7 @@ func TestUsers(t *testing.T) { Email: "foo@bar.com", Token: "e42080dddf012c718e476da161d21ad5", } - s.CreateUser(user) + g.Assert(store.CreateUser(user)).IsNil() repo1 := &model.Repo{ Owner: "bradrydzewski", @@ -206,14 +209,14 @@ func TestUsers(t *testing.T) { FullName: "octocat/hello-world", IsActive: true, } - s.CreateRepo(repo1) - s.CreateRepo(repo2) - s.CreateRepo(repo3) + g.Assert(store.CreateRepo(repo1)).IsNil() + g.Assert(store.CreateRepo(repo2)).IsNil() + g.Assert(store.CreateRepo(repo3)).IsNil() - s.PermBatch([]*model.Perm{ + g.Assert(store.PermBatch([]*model.Perm{ {UserID: user.ID, Repo: repo1.FullName, Push: true, Admin: false}, {UserID: user.ID, Repo: repo2.FullName, Push: false, Admin: true}, - }) + })).IsNil() build1 := &model.Build{ RepoID: repo1.ID, @@ -231,12 +234,12 @@ func TestUsers(t *testing.T) { RepoID: repo3.ID, Status: model.StatusSuccess, } - s.CreateBuild(build1) - s.CreateBuild(build2) - s.CreateBuild(build3) - s.CreateBuild(build4) + g.Assert(store.CreateBuild(build1)).IsNil() + g.Assert(store.CreateBuild(build2)).IsNil() + g.Assert(store.CreateBuild(build3)).IsNil() + g.Assert(store.CreateBuild(build4)).IsNil() - builds, err := s.UserFeed(user) + builds, err := store.UserFeed(user) g.Assert(err).IsNil() g.Assert(len(builds)).Equal(3) g.Assert(builds[0].FullName).Equal(repo2.FullName) diff --git a/server/store/datastore/utils.go b/server/store/datastore/utils.go deleted file mode 100644 index 979501cef..000000000 --- a/server/store/datastore/utils.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 Drone.IO Inc. -// -// 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 datastore - -import ( - "strconv" - - "github.com/russross/meddler" -) - -// rebind is a helper function that changes the sql -// bind type from ? to $ for postgres queries. -func rebind(query string) string { - if meddler.Default != meddler.PostgreSQL { - return query - } - - qb := []byte(query) - // Add space enough for 5 params before we have to allocate - rqb := make([]byte, 0, len(qb)+5) - j := 1 - for _, b := range qb { - switch b { - case '?': - rqb = append(rqb, '$') - for _, b := range strconv.Itoa(j) { - rqb = append(rqb, byte(b)) - } - j++ - case '`': - rqb = append(rqb, ' ') - default: - rqb = append(rqb, b) - } - } - return string(rqb) -} diff --git a/server/store/store.go b/server/store/store.go index d7991fc1b..d4241ccae 100644 --- a/server/store/store.go +++ b/server/store/store.go @@ -20,6 +20,8 @@ import ( "github.com/woodpecker-ci/woodpecker/server/model" ) +// TODO: CreateX func should return new object to not indirect let storage change an existing object (alter ID etc...) + type Store interface { // GetUser gets a user by unique ID. GetUser(int64) (*model.User, error) @@ -28,10 +30,11 @@ type Store interface { GetUserLogin(string) (*model.User, error) // GetUserList gets a list of all users in the system. + // TODO: paginate GetUserList() ([]*model.User, error) // GetUserCount gets a count of all users in the system. - GetUserCount() (int, error) + GetUserCount() (int64, error) // CreateUser creates a new user account. CreateUser(*model.User) error @@ -49,7 +52,7 @@ type Store interface { GetRepoName(string) (*model.Repo, error) // GetRepoCount gets a count of all repositories in the system. - GetRepoCount() (int, error) + GetRepoCount() (int64, error) // CreateRepo creates a new repository. CreateRepo(*model.Repo) error @@ -64,7 +67,7 @@ type Store interface { GetBuild(int64) (*model.Build, error) // GetBuildNumber gets a build by number. - GetBuildNumber(*model.Repo, int) (*model.Build, error) + GetBuildNumber(*model.Repo, int64) (*model.Build, error) // GetBuildRef gets a build by its ref. GetBuildRef(*model.Repo, string) (*model.Build, error) @@ -79,13 +82,14 @@ type Store interface { GetBuildLastBefore(*model.Repo, string, int64) (*model.Build, error) // GetBuildList gets a list of builds for the repository + // TODO: paginate GetBuildList(*model.Repo, int) ([]*model.Build, error) // GetBuildQueue gets a list of build in queue. GetBuildQueue() ([]*model.Feed, error) // GetBuildCount gets a count of all builds in the system. - GetBuildCount() (int, error) + GetBuildCount() (int64, error) // CreateBuild creates a new build and jobs. CreateBuild(*model.Build, ...*model.Proc) error @@ -99,8 +103,10 @@ type Store interface { UserFeed(*model.User) ([]*model.Feed, error) + // RepoList TODO: paginate RepoList(user *model.User, owned bool) ([]*model.Repo, error) - RepoListLatest(user *model.User) ([]*model.Feed, error) + RepoListLatest(*model.User) ([]*model.Feed, error) + // RepoBatch TODO: only store activated repos ... RepoBatch([]*model.Repo) error PermFind(user *model.User, repo *model.Repo) (*model.Perm, error) @@ -110,12 +116,13 @@ type Store interface { PermFlush(user *model.User, before int64) error ConfigsForBuild(buildID int64) ([]*model.Config, error) - ConfigFindIdentical(repoID int64, sha string) (*model.Config, error) + ConfigFindIdentical(repoID int64, hash string) (*model.Config, error) ConfigFindApproved(*model.Config) (bool, error) ConfigCreate(*model.Config) error BuildConfigCreate(*model.BuildConfig) error SenderFind(*model.Repo, string) (*model.Sender, error) + // SenderList TODO: paginate SenderList(*model.Repo) ([]*model.Sender, error) SenderCreate(*model.Sender) error SenderUpdate(*model.Sender) error @@ -142,6 +149,8 @@ type Store interface { ProcClear(*model.Build) error LogFind(*model.Proc) (io.ReadCloser, error) + // TODO: since we do ReadAll in any case a ioReader is not the best idear + // so either find a way to write log in chunks by xorm ... LogSave(*model.Proc, io.Reader) error FileList(*model.Build) ([]*model.File, error) @@ -149,9 +158,12 @@ type Store interface { FileRead(*model.Proc, string) (io.ReadCloser, error) FileCreate(*model.File, io.Reader) error + // TaskList TODO: paginate & opt filter TaskList() ([]*model.Task, error) TaskInsert(*model.Task) error TaskDelete(string) error Ping() error + Close() error + Migrate() error } diff --git a/tools.go b/tools.go index f4def3b3e..c5603957b 100644 --- a/tools.go +++ b/tools.go @@ -6,5 +6,4 @@ package tools import ( _ "github.com/rs/zerolog/cmd/lint" - _ "github.com/woodpecker-ci/togo" ) diff --git a/vendor/github.com/goccy/go-json/.codecov.yml b/vendor/github.com/goccy/go-json/.codecov.yml new file mode 100644 index 000000000..e98134570 --- /dev/null +++ b/vendor/github.com/goccy/go-json/.codecov.yml @@ -0,0 +1,32 @@ +codecov: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "70...100" + + status: + project: + default: + target: 70% + threshold: 2% + patch: off + changes: no + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "header,diff" + behavior: default + require_changes: no + +ignore: + - internal/encoder/vm_color + - internal/encoder/vm_color_indent diff --git a/vendor/github.com/goccy/go-json/.gitignore b/vendor/github.com/goccy/go-json/.gitignore new file mode 100644 index 000000000..378283829 --- /dev/null +++ b/vendor/github.com/goccy/go-json/.gitignore @@ -0,0 +1,2 @@ +cover.html +cover.out diff --git a/vendor/github.com/goccy/go-json/.golangci.yml b/vendor/github.com/goccy/go-json/.golangci.yml new file mode 100644 index 000000000..44ae40f69 --- /dev/null +++ b/vendor/github.com/goccy/go-json/.golangci.yml @@ -0,0 +1,75 @@ +run: + skip-files: + - encode_optype.go + - ".*_test\\.go$" + +linters-settings: + govet: + enable-all: true + disable: + - shadow + +linters: + enable-all: true + disable: + - dogsled + - dupl + - exhaustive + - exhaustivestruct + - errorlint + - forbidigo + - funlen + - gci + - gochecknoglobals + - gochecknoinits + - gocognit + - gocritic + - gocyclo + - godot + - godox + - goerr113 + - gofumpt + - gomnd + - gosec + - ifshort + - lll + - makezero + - nakedret + - nestif + - nlreturn + - paralleltest + - testpackage + - thelper + - wrapcheck + - interfacer + - lll + - nakedret + - nestif + - nlreturn + - testpackage + - wsl + +issues: + exclude-rules: + # not needed + - path: /*.go + text: "ST1003: should not use underscores in package names" + linters: + - stylecheck + - path: /*.go + text: "don't use an underscore in package name" + linters: + - golint + - path: rtype.go + linters: + - golint + - stylecheck + - path: error.go + linters: + - staticcheck + + # Maximum issues count per one linter. Set to 0 to disable. Default is 50. + max-issues-per-linter: 0 + + # Maximum count of issues with the same text. Set to 0 to disable. Default is 3. + max-same-issues: 0 diff --git a/vendor/github.com/goccy/go-json/CHANGELOG.md b/vendor/github.com/goccy/go-json/CHANGELOG.md new file mode 100644 index 000000000..fd6aa9d6c --- /dev/null +++ b/vendor/github.com/goccy/go-json/CHANGELOG.md @@ -0,0 +1,236 @@ +# v0.7.4 - 2021/07/06 + +* Fix encoding of indirect layout structure ( #264 ) + +# v0.7.3 - 2021/06/29 + +* Fix encoding of pointer type in empty interface ( #262 ) + +# v0.7.2 - 2021/06/26 + +### Fix decoder + +* Add decoder for func type to fix decoding of nil function value ( #257 ) +* Fix stream decoding of []byte type ( #258 ) + +### Performance + +* Improve decoding performance of map[string]interface{} type ( use `mapassign_faststr` ) ( #256 ) +* Improve encoding performance of empty interface type ( remove recursive calling of `vm.Run` ) ( #259 ) + +### Benchmark + +* Add bytedance/sonic as benchmark target ( #254 ) + +# v0.7.1 - 2021/06/18 + +### Fix decoder + +* Fix error when unmarshal empty array ( #253 ) + +# v0.7.0 - 2021/06/12 + +### Support context for MarshalJSON and UnmarshalJSON ( #248 ) + +* json.MarshalContext(context.Context, interface{}, ...json.EncodeOption) ([]byte, error) +* json.NewEncoder(io.Writer).EncodeContext(context.Context, interface{}, ...json.EncodeOption) error +* json.UnmarshalContext(context.Context, []byte, interface{}, ...json.DecodeOption) error +* json.NewDecoder(io.Reader).DecodeContext(context.Context, interface{}) error + +```go +type MarshalerContext interface { + MarshalJSON(context.Context) ([]byte, error) +} + +type UnmarshalerContext interface { + UnmarshalJSON(context.Context, []byte) error +} +``` + +### Add DecodeFieldPriorityFirstWin option ( #242 ) + +In the default behavior, go-json, like encoding/json, will reflect the result of the last evaluation when a field with the same name exists. I've added new options to allow you to change this behavior. `json.DecodeFieldPriorityFirstWin` option reflects the result of the first evaluation if a field with the same name exists. This behavior has a performance advantage as it allows the subsequent strings to be skipped if all fields have been evaluated. + +### Fix encoder + +* Fix indent number contains recursive type ( #249 ) +* Fix encoding of using empty interface as map key ( #244 ) + +### Fix decoder + +* Fix decoding fields containing escaped characters ( #237 ) + +### Refactor + +* Move some tests to subdirectory ( #243 ) +* Refactor package layout for decoder ( #238 ) + +# v0.6.1 - 2021/06/02 + +### Fix encoder + +* Fix value of totalLength for encoding ( #236 ) + +# v0.6.0 - 2021/06/01 + +### Support Colorize option for encoding (#233) + +```go +b, err := json.MarshalWithOption(v, json.Colorize(json.DefaultColorScheme)) +if err != nil { + ... +} +fmt.Println(string(b)) // print colored json +``` + +### Refactor + +* Fix opcode layout - Adjust memory layout of the opcode to 128 bytes in a 64-bit environment ( #230 ) +* Refactor encode option ( #231 ) +* Refactor escape string ( #232 ) + +# v0.5.1 - 2021/5/20 + +### Optimization + +* Add type addrShift to enable bigger encoder/decoder cache ( #213 ) + +### Fix decoder + +* Keep original reference of slice element ( #229 ) + +### Refactor + +* Refactor Debug mode for encoding ( #226 ) +* Generate VM sources for encoding ( #227 ) +* Refactor validator for null/true/false for decoding ( #221 ) + +# v0.5.0 - 2021/5/9 + +### Supports using omitempty and string tags at the same time ( #216 ) + +### Fix decoder + +* Fix stream decoder for unicode char ( #215 ) +* Fix decoding of slice element ( #219 ) +* Fix calculating of buffer length for stream decoder ( #220 ) + +### Refactor + +* replace skipWhiteSpace goto by loop ( #212 ) + +# v0.4.14 - 2021/5/4 + +### Benchmark + +* Add valyala/fastjson to benchmark ( #193 ) +* Add benchmark task for CI ( #211 ) + +### Fix decoder + +* Fix decoding of slice with unmarshal json type ( #198 ) +* Fix decoding of null value for interface type that does not implement Unmarshaler ( #205 ) +* Fix decoding of null value to []byte by json.Unmarshal ( #206 ) +* Fix decoding of backslash char at the end of string ( #207 ) +* Fix stream decoder for null/true/false value ( #208 ) +* Fix stream decoder for slow reader ( #211 ) + +### Performance + +* If cap of slice is enough, reuse slice data for compatibility with encoding/json ( #200 ) + +# v0.4.13 - 2021/4/20 + +### Fix json.Compact and json.Indent + +* Support validation the input buffer for json.Compact and json.Indent ( #189 ) +* Optimize json.Compact and json.Indent ( improve memory footprint ) ( #190 ) + +# v0.4.12 - 2021/4/15 + +### Fix encoder + +* Fix unnecessary indent for empty slice type ( #181 ) +* Fix encoding of omitempty feature for the slice or interface type ( #183 ) +* Fix encoding custom types zero values with omitempty when marshaller exists ( #187 ) + +### Fix decoder + +* Fix decoder for invalid top level value ( #184 ) +* Fix decoder for invalid number value ( #185 ) + +# v0.4.11 - 2021/4/3 + +* Improve decoder performance for interface type + +# v0.4.10 - 2021/4/2 + +### Fix encoder + +* Fixed a bug when encoding slice and map containing recursive structures +* Fixed a logic to determine if indirect reference + +# v0.4.9 - 2021/3/29 + +### Add debug mode + +If you use `json.MarshalWithOption(v, json.Debug())` and `panic` occurred in `go-json`, produces debug information to console. + +### Support a new feature to compatible with encoding/json + +- invalid UTF-8 is coerced to valid UTF-8 ( without performance down ) + +### Fix encoder + +- Fixed handling of MarshalJSON of function type + +### Fix decoding of slice of pointer type + +If there is a pointer value, go-json will use it. (This behavior is necessary to achieve the ability to prioritize pre-filled values). However, since slices are reused internally, there was a bug that referred to the previous pointer value. Therefore, it is not necessary to refer to the pointer value in advance for the slice element, so we explicitly initialize slice element by `nil`. + +# v0.4.8 - 2021/3/21 + +### Reduce memory usage at compile time + +* go-json have used about 2GB of memory at compile time, but now it can compile with about less than 550MB. + +### Fix any encoder's bug + +* Add many test cases for encoder +* Fix composite type ( slice/array/map ) +* Fix pointer types +* Fix encoding of MarshalJSON or MarshalText or json.Number type + +### Refactor encoder + +* Change package layout for reducing memory usage at compile +* Remove anonymous and only operation +* Remove root property from encodeCompileContext and opcode + +### Fix CI + +* Add Go 1.16 +* Remove Go 1.13 +* Fix `make cover` task + +### Number/Delim/Token/RawMessage use the types defined in encoding/json by type alias + +# v0.4.7 - 2021/02/22 + +### Fix decoder + +* Fix decoding of deep recursive structure +* Fix decoding of embedded unexported pointer field +* Fix invalid test case +* Fix decoding of invalid value +* Fix decoding of prefilled value +* Fix not being able to return UnmarshalTypeError when it should be returned +* Fix decoding of null value +* Fix decoding of type of null string +* Use pre allocated pointer if exists it at decoding + +### Reduce memory usage at compile + +* Integrate int/int8/int16/int32/int64 and uint/uint8/uint16/uint32/uint64 operation to reduce memory usage at compile + +### Remove unnecessary optype diff --git a/vendor/github.com/urfave/cli/LICENSE b/vendor/github.com/goccy/go-json/LICENSE similarity index 95% rename from vendor/github.com/urfave/cli/LICENSE rename to vendor/github.com/goccy/go-json/LICENSE index 42a597e29..6449c8bff 100644 --- a/vendor/github.com/urfave/cli/LICENSE +++ b/vendor/github.com/goccy/go-json/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2016 Jeremy Saenz & Contributors +Copyright (c) 2020 Masaaki Goshima Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/github.com/goccy/go-json/Makefile b/vendor/github.com/goccy/go-json/Makefile new file mode 100644 index 000000000..363563ab9 --- /dev/null +++ b/vendor/github.com/goccy/go-json/Makefile @@ -0,0 +1,39 @@ +PKG := github.com/goccy/go-json + +BIN_DIR := $(CURDIR)/bin +PKGS := $(shell go list ./... | grep -v internal/cmd|grep -v test) +COVER_PKGS := $(foreach pkg,$(PKGS),$(subst $(PKG),.,$(pkg))) + +COMMA := , +EMPTY := +SPACE := $(EMPTY) $(EMPTY) +COVERPKG_OPT := $(subst $(SPACE),$(COMMA),$(COVER_PKGS)) + +$(BIN_DIR): + @mkdir -p $(BIN_DIR) + +.PHONY: cover +cover: + go test -coverpkg=$(COVERPKG_OPT) -coverprofile=cover.out ./... + +.PHONY: cover-html +cover-html: cover + go tool cover -html=cover.out + +.PHONY: lint +lint: golangci-lint + golangci-lint run + +golangci-lint: | $(BIN_DIR) + @{ \ + set -e; \ + GOLANGCI_LINT_TMP_DIR=$$(mktemp -d); \ + cd $$GOLANGCI_LINT_TMP_DIR; \ + go mod init tmp; \ + GOBIN=$(BIN_DIR) go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.36.0; \ + rm -rf $$GOLANGCI_LINT_TMP_DIR; \ + } + +.PHONY: generate +generate: + go generate ./internal/... diff --git a/vendor/github.com/goccy/go-json/README.md b/vendor/github.com/goccy/go-json/README.md new file mode 100644 index 000000000..418854e52 --- /dev/null +++ b/vendor/github.com/goccy/go-json/README.md @@ -0,0 +1,529 @@ +# go-json + +![Go](https://github.com/goccy/go-json/workflows/Go/badge.svg) +[![GoDoc](https://godoc.org/github.com/goccy/go-json?status.svg)](https://pkg.go.dev/github.com/goccy/go-json?tab=doc) +[![codecov](https://codecov.io/gh/goccy/go-json/branch/master/graph/badge.svg)](https://codecov.io/gh/goccy/go-json) + +Fast JSON encoder/decoder compatible with encoding/json for Go + + + +# Roadmap + +``` +* version ( expected release date ) + +* v0.7.0 + | + | while maintaining compatibility with encoding/json, we will add convenient APIs + | + v +* v1.0.0 +``` + +We are accepting requests for features that will be implemented between v0.7.0 and v.1.0.0. +If you have the API you need, please submit your issue [here](https://github.com/goccy/go-json/issues). +For example, I'm thinking of supporting `context.Context` of `json.Marshaler` and decoding using JSON Path. + +# Features + +- Drop-in replacement of `encoding/json` +- Fast ( See [Benchmark section](https://github.com/goccy/go-json#benchmarks) ) +- Flexible customization with options +- Coloring the encoded string +- Can propagate context.Context to `MarshalJSON` or `UnmarshalJSON` + +# Installation + +``` +go get github.com/goccy/go-json +``` + +# How to use + +Replace import statement from `encoding/json` to `github.com/goccy/go-json` + +``` +-import "encoding/json" ++import "github.com/goccy/go-json" +``` + +# JSON library comparison + +| name | encoder | decoder | compatible with `encoding/json` | +| :----: | :------: | :-----: | :-----------------------------: | +| encoding/json | yes | yes | N/A | +| [json-iterator/go](https://github.com/json-iterator/go) | yes | yes | partial | +| [easyjson](https://github.com/mailru/easyjson) | yes | yes | no | +| [gojay](https://github.com/francoispqt/gojay) | yes | yes | no | +| [segmentio/encoding/json](https://github.com/segmentio/encoding/tree/master/json) | yes | yes | partial | +| [jettison](https://github.com/wI2L/jettison) | yes | no | no | +| [simdjson-go](https://github.com/minio/simdjson-go) | no | yes | no | +| goccy/go-json | yes | yes | yes | + +- `json-iterator/go` isn't compatible with `encoding/json` in many ways (e.g. https://github.com/json-iterator/go/issues/229 ), but it hasn't been supported for a long time. +- `segmentio/encoding/json` is well supported for encoders, but some are not supported for decoder APIs such as `Token` ( streaming decode ) + +## Other libraries + +- [jingo](https://github.com/bet365/jingo) + +I tried the benchmark but it didn't work. +Also, it seems to panic when it receives an unexpected value because there is no error handling... + +- [ffjson](https://github.com/pquerna/ffjson) + +Benchmarking gave very slow results. +It seems that it is assumed that the user will use the buffer pool properly. +Also, development seems to have already stopped + +# Benchmarks + +``` +$ cd benchmarks +$ go test -bench . +``` + +## Encode + + + + +## Decode + + + + + + +# Fuzzing + +[go-json-fuzz](https://github.com/goccy/go-json-fuzz) is the repository for fuzzing tests. +If you run the test in this repository and find a bug, please commit to corpus to go-json-fuzz and report the issue to [go-json](https://github.com/goccy/go-json/issues). + +# How it works + +`go-json` is very fast in both encoding and decoding compared to other libraries. +It's easier to implement by using automatic code generation for performance or by using a dedicated interface, but `go-json` dares to stick to compatibility with `encoding/json` and is the simple interface. Despite this, we are developing with the aim of being the fastest library. + +Here, we explain the various speed-up techniques implemented by `go-json`. + +## Basic technique + +The techniques listed here are the ones used by most of the libraries listed above. + +### Buffer reuse + +Since the only value required for the result of `json.Marshal(interface{}) ([]byte, error)` is `[]byte`, the only value that must be allocated during encoding is the return value `[]byte` . + +Also, as the number of allocations increases, the performance will be affected, so the number of allocations should be kept as low as possible when creating `[]byte`. + +Therefore, there is a technique to reduce the number of times a new buffer must be allocated by reusing the buffer used for the previous encoding by using `sync.Pool`. + +Finally, you allocate a buffer that is as long as the resulting buffer and copy the contents into it, you only need to allocate the buffer once in theory. + +```go +type buffer struct { + data []byte +} + +var bufPool = sync.Pool{ + New: func() interface{} { + return &buffer{data: make([]byte, 0, 1024)} + }, +} + +buf := bufPool.Get().(*buffer) +data := encode(buf.data) // reuse buf.data + +newBuf := make([]byte, len(data)) +copy(newBuf, buf) + +buf.data = data +bufPool.Put(buf) +``` + +### Elimination of reflection + +As you know, the reflection operation is very slow. + +Therefore, using the fact that the address position where the type information is stored is fixed for each binary ( we call this `typeptr` ), +we can use the address in the type information to call a pre-built optimized process. + +For example, you can get the address to the type information from `interface{}` as follows and you can use that information to call a process that does not have reflection. + +To process without reflection, pass a pointer (`unsafe.Pointer`) to the value is stored. + +```go + +type emptyInterface struct { + typ unsafe.Pointer + ptr unsafe.Pointer +} + +var typeToEncoder = map[uintptr]func(unsafe.Pointer)([]byte, error){} + +func Marshal(v interface{}) ([]byte, error) { + iface := (*emptyInterface)(unsafe.Pointer(&v) + typeptr := uintptr(iface.typ) + if enc, exists := typeToEncoder[typeptr]; exists { + return enc(iface.ptr) + } + ... +} +``` + +※ In reality, `typeToEncoder` can be referenced by multiple goroutines, so exclusive control is required. + +## Unique speed-up technique + +## Encoder + +### Do not escape arguments of `Marshal` + +`json.Marshal` and `json.Unmarshal` receive `interface{}` value and they perform type determination dynamically to process. +In normal case, you need to use the `reflect` library to determine the type dynamically, but since `reflect.Type` is defined as `interface`, when you call the method of `reflect.Type`, The reflect's argument is escaped. + +Therefore, the arguments for `Marshal` and `Unmarshal` are always escape to the heap. +However, `go-json` can use the feature of `reflect.Type` while avoiding escaping. + +`reflect.Type` is defined as `interface`, but in reality `reflect.Type` is implemented only by the structure `rtype` defined in the `reflect` package. +For this reason, to date `reflect.Type` is the same as `*reflect.rtype`. + +Therefore, by directly handling `*reflect.rtype`, which is an implementation of `reflect.Type`, it is possible to avoid escaping because it changes from `interface` to using `struct`. + +The technique for working with `*reflect.rtype` directly from `go-json` is implemented at [rtype.go](https://github.com/goccy/go-json/blob/master/internal/runtime/rtype.go) + +Also, the same technique is cut out as a library ( https://github.com/goccy/go-reflect ) + +Initially this feature was the default behavior of `go-json`. +But after careful testing, I found that I passed a large value to `json.Marshal()` and if the argument could not be assigned to the stack, it could not be properly escaped to the heap (a bug in the Go compiler). + +Therefore, this feature will be provided as an **optional** until this issue is resolved. + +To use it, add `NoEscape` like `MarshalNoEscape()` + +### Encoding using opcode sequence + +I explained that you can use `typeptr` to call a pre-built process from type information. + +In other libraries, this dedicated process is processed by making it an function calling like anonymous function, but function calls are inherently slow processes and should be avoided as much as possible. + +Therefore, `go-json` adopted the Instruction-based execution processing system, which is also used to implement virtual machines for programming language. + +If it is the first type to encode, create the opcode ( instruction ) sequence required for encoding. +From the second time onward, use `typeptr` to get the cached pre-built opcode sequence and encode it based on it. An example of the opcode sequence is shown below. + +```go +json.Marshal(struct{ + X int `json:"x"` + Y string `json:"y"` +}{X: 1, Y: "hello"}) +``` + +When encoding a structure like the one above, create a sequence of opcodes like this: + +``` +- opStructFieldHead ( `{` ) +- opStructFieldInt ( `"x": 1,` ) +- opStructFieldString ( `"y": "hello"` ) +- opStructEnd ( `}` ) +- opEnd +``` + +※ When processing each operation, write the letters on the right. + +In addition, each opcode is managed by the following structure ( +Pseudo code ). + +```go +type opType int +const ( + opStructFieldHead opType = iota + opStructFieldInt + opStructFieldStirng + opStructEnd + opEnd +) +type opcode struct { + op opType + key []byte + next *opcode +} +``` + +The process of encoding using the opcode sequence is roughly implemented as follows. + +```go +func encode(code *opcode, b []byte, p unsafe.Pointer) ([]byte, error) { + for { + switch code.op { + case opStructFieldHead: + b = append(b, '{') + code = code.next + case opStructFieldInt: + b = append(b, code.key...) + b = appendInt((*int)(unsafe.Pointer(uintptr(p)+code.offset))) + code = code.next + case opStructFieldString: + b = append(b, code.key...) + b = appendString((*string)(unsafe.Pointer(uintptr(p)+code.offset))) + code = code.next + case opStructEnd: + b = append(b, '}') + code = code.next + case opEnd: + goto END + } + } +END: + return b, nil +} +``` + +In this way, the huge `switch-case` is used to encode by manipulating the linked list opcodes to avoid unnecessary function calls. + +### Opcode sequence optimization + +One of the advantages of encoding using the opcode sequence is the ease of optimization. +The opcode sequence mentioned above is actually converted into the following optimized operations and used. + +``` +- opStructFieldHeadInt ( `{"x": 1,` ) +- opStructEndString ( `"y": "hello"}` ) +- opEnd +``` + +It has been reduced from 5 opcodes to 3 opcodes ! +Reducing the number of opcodees means reducing the number of branches with `switch-case`. +In other words, the closer the number of operations is to 1, the faster the processing can be performed. + +In `go-json`, optimization to reduce the number of opcodes itself like the above and it speeds up by preparing opcodes with optimized paths. + +### Change recursive call from CALL to JMP + +Recursive processing is required during encoding if the type is defined recursively as follows: + +```go +type T struct { + X int + U *U +} + +type U struct { + T *T +} + +b, err := json.Marshal(&T{ + X: 1, + U: &U{ + T: &T{ + X: 2, + }, + }, +}) +fmt.Println(string(b)) // {"X":1,"U":{"T":{"X":2,"U":null}}} +``` + +In `go-json`, recursive processing is processed by the operation type of ` opStructFieldRecursive`. + +In this operation, after acquiring the opcode sequence used for recursive processing, the function is **not** called recursively as it is, but the necessary values ​​are saved by itself and implemented by moving to the next operation. + +The technique of implementing recursive processing with the `JMP` operation while avoiding the `CALL` operation is a famous technique for implementing a high-speed virtual machine. + +For more details, please refer to [the article](https://engineering.mercari.com/blog/entry/1599563768-081104c850) ( but Japanese only ). + +### Dispatch by typeptr from map to slice + +When retrieving the data cached from the type information by `typeptr`, we usually use map. +Map requires exclusive control, so use `sync.Map` for a naive implementation. + +However, this is slow, so it's a good idea to use the `atomic` package for exclusive control as implemented by `segmentio/encoding/json` ( https://github.com/segmentio/encoding/blob/master/json/codec.go#L41-L55 ). + +This implementation slows down the set instead of speeding up the get, but it works well because of the nature of the library, it encodes much more for the same type. + +However, as a result of profiling, I noticed that `runtime.mapaccess2` accounts for a significant percentage of the execution time. So I thought if I could change the lookup from map to slice. + +There is an API named `typelinks` defined in the `runtime` package that the `reflect` package uses internally. +This allows you to get all the type information defined in the binary at runtime. + +The fact that all type information can be acquired means that by constructing slices in advance with the acquired total number of type information, it is possible to look up with the value of `typeptr` without worrying about out-of-range access. + +However, if there is too much type information, it will use a lot of memory, so by default we will only use this optimization if the slice size fits within **2Mib** . + +If this approach is not available, it will fall back to the `atomic` based process described above. + +If you want to know more, please refer to the implementation [here](https://github.com/goccy/go-json/blob/master/internal/runtime/type.go#L36-L100) + +## Decoder + +### Dispatch by typeptr from map to slice + +Like the encoder, the decoder also uses typeptr to call the dedicated process. + +### Faster termination character inspection using NUL character + +In order to decode, you have to traverse the input buffer character by position. +At that time, if you check whether the buffer has reached the end, it will be very slow. + +`buf` : `[]byte` type variable. holds the string passed to the decoder +`cursor` : `int64` type variable. holds the current read position + +```go +buflen := len(buf) +for ; cursor < buflen; cursor++ { // compare cursor and buflen at all times, it is so slow. + switch buf[cursor] { + case ' ', '\n', '\r', '\t': + } +} +``` + +Therefore, by adding the `NUL` (`\000`) character to the end of the read buffer as shown below, it is possible to check the termination character at the same time as other characters. + +```go +for { + switch buf[cursor] { + case ' ', '\n', '\r', '\t': + case '\000': + return nil + } + cursor++ +} +``` + +### Use Boundary Check Elimination + +Due to the `NUL` character optimization, the Go compiler does a boundary check every time, even though `buf[cursor]` does not cause out-of-range access. + +Therefore, `go-json` eliminates boundary check by fetching characters for hotspot by pointer operation. For example, the following code. + +```go +func char(ptr unsafe.Pointer, offset int64) byte { + return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset))) +} + +p := (*sliceHeader)(&unsafe.Pointer(buf)).data +for { + switch char(p, cursor) { + case ' ', '\n', '\r', '\t': + case '\000': + return nil + } + cursor++ +} +``` + +### Checking the existence of fields of struct using Bitmaps + +I found by the profiling result, in the struct decode, lookup process for field was taking a long time. + +For example, consider decoding a string like `{"a":1,"b":2,"c":3}` into the following structure: + +```go +type T struct { + A int `json:"a"` + B int `json:"b"` + C int `json:"c"` +} +``` + +At this time, it was found that it takes a lot of time to acquire the decoding process corresponding to the field from the field name as shown below during the decoding process. + +```go +fieldName := decodeKey(buf, cursor) // "a" or "b" or "c" +decoder, exists := fieldToDecoderMap[fieldName] // so slow +if exists { + decoder(buf, cursor) +} else { + skipValue(buf, cursor) +} +``` + +To improve this process, `json-iterator/go` is optimized so that it can be branched by switch-case when the number of fields in the structure is 10 or less (switch-case is faster than map). However, there is a risk of hash collision because the value hashed by the FNV algorithm is used for conditional branching. Also, `gojay` processes this part at high speed by letting the library user yourself write `switch-case`. + + +`go-json` considers and implements a new approach that is different from these. I call this **bitmap field optimization**. + +The range of values ​​per character can be represented by `[256]byte`. Also, if the number of fields in the structure is 8 or less, `int8` type can represent the state of each field. +In other words, it has the following structure. + +- Base ( 8bit ): `00000000` +- Key "a": `00000001` ( assign key "a" to the first bit ) +- Key "b": `00000010` ( assign key "b" to the second bit ) +- Key "c": `00000100` ( assign key "c" to the third bit ) + +Bitmap structure is the following + +``` + | key index(0) | +------------------------ + 0 | 00000000 | + 1 | 00000000 | +~~ | | +97 (a) | 00000001 | +98 (b) | 00000010 | +99 (c) | 00000100 | +~~ | | +255 | 00000000 | +``` + +You can think of this as a Bitmap with a height of `256` and a width of the maximum string length in the field name. +In other words, it can be represented by the following type . + +```go +[maxFieldKeyLength][256]int8 +``` + +When decoding a field character, check whether the corresponding character exists by referring to the pre-built bitmap like the following. + +```go +var curBit int8 = math.MaxInt8 // 11111111 + +c := char(buf, cursor) +bit := bitmap[keyIdx][c] +curBit &= bit +if curBit == 0 { + // not found field +} +``` + +If `curBit` is not `0` until the end of the field string, then the string is +You may have hit one of the fields. +But the possibility is that if the decoded string is shorter than the field string, you will get a false hit. + +- input: `{"a":1}` +```go +type T struct { + X int `json:"abc"` +} +``` +※ Since `a` is shorter than `abc`, it can decode to the end of the field character without `curBit` being 0. + +Rest assured. In this case, it doesn't matter because you can tell if you hit by comparing the string length of `a` with the string length of `abc`. + +Finally, calculate the position of the bit where `1` is set and get the corresponding value, and you're done. + +Using this technique, field lookups are possible with only bitwise operations and access to slices. + +`go-json` uses a similar technique for fields with 9 or more and 16 or less fields. At this time, Bitmap is constructed as `[maxKeyLen][256]int16` type. + +Currently, this optimization is not performed when the maximum length of the field name is long (specifically, 64 bytes or more) in addition to the limitation of the number of fields from the viewpoint of saving memory usage. + +### Others + +I have done a lot of other optimizations. I will find time to write about them. If you have any questions about what's written here or other optimizations, please visit the `#go-json` channel on `gophers.slack.com` . + +## Reference + +Regarding the story of go-json, there are the following articles in Japanese only. + +- https://speakerdeck.com/goccy/zui-su-falsejsonraiburariwoqiu-mete +- https://engineering.mercari.com/blog/entry/1599563768-081104c850/ + +# Looking for Sponsors + +I'm looking for sponsors this library. This library is being developed as a personal project in my spare time. If you want a quick response or problem resolution when using this library in your project, please register as a [sponsor](https://github.com/sponsors/goccy). I will cooperate as much as possible. Of course, this library is developed as an MIT license, so you can use it freely for free. + +# License + +MIT diff --git a/vendor/github.com/goccy/go-json/color.go b/vendor/github.com/goccy/go-json/color.go new file mode 100644 index 000000000..e80b22b48 --- /dev/null +++ b/vendor/github.com/goccy/go-json/color.go @@ -0,0 +1,68 @@ +package json + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +type ( + ColorFormat = encoder.ColorFormat + ColorScheme = encoder.ColorScheme +) + +const escape = "\x1b" + +type colorAttr int + +//nolint:deadcode,varcheck +const ( + fgBlackColor colorAttr = iota + 30 + fgRedColor + fgGreenColor + fgYellowColor + fgBlueColor + fgMagentaColor + fgCyanColor + fgWhiteColor +) + +//nolint:deadcode,varcheck +const ( + fgHiBlackColor colorAttr = iota + 90 + fgHiRedColor + fgHiGreenColor + fgHiYellowColor + fgHiBlueColor + fgHiMagentaColor + fgHiCyanColor + fgHiWhiteColor +) + +func createColorFormat(attr colorAttr) ColorFormat { + return ColorFormat{ + Header: wrapColor(attr), + Footer: resetColor(), + } +} + +func wrapColor(attr colorAttr) string { + return fmt.Sprintf("%s[%dm", escape, attr) +} + +func resetColor() string { + return wrapColor(colorAttr(0)) +} + +var ( + DefaultColorScheme = &ColorScheme{ + Int: createColorFormat(fgHiMagentaColor), + Uint: createColorFormat(fgHiMagentaColor), + Float: createColorFormat(fgHiMagentaColor), + Bool: createColorFormat(fgHiYellowColor), + String: createColorFormat(fgHiGreenColor), + Binary: createColorFormat(fgHiRedColor), + ObjectKey: createColorFormat(fgHiCyanColor), + Null: createColorFormat(fgBlueColor), + } +) diff --git a/vendor/github.com/goccy/go-json/decode.go b/vendor/github.com/goccy/go-json/decode.go new file mode 100644 index 000000000..d99749d05 --- /dev/null +++ b/vendor/github.com/goccy/go-json/decode.go @@ -0,0 +1,232 @@ +package json + +import ( + "context" + "fmt" + "io" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/decoder" + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type Decoder struct { + s *decoder.Stream +} + +const ( + nul = '\000' +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func unmarshal(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + header := (*emptyInterface)(unsafe.Pointer(&v)) + + if err := validateType(header.typ, uintptr(header.ptr)); err != nil { + return err + } + dec, err := decoder.CompileToGetDecoder(header.typ) + if err != nil { + return err + } + ctx := decoder.TakeRuntimeContext() + ctx.Buf = src + ctx.Option.Flags = 0 + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + cursor, err := dec.Decode(ctx, 0, 0, header.ptr) + if err != nil { + decoder.ReleaseRuntimeContext(ctx) + return err + } + decoder.ReleaseRuntimeContext(ctx) + return validateEndBuf(src, cursor) +} + +func unmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + header := (*emptyInterface)(unsafe.Pointer(&v)) + + if err := validateType(header.typ, uintptr(header.ptr)); err != nil { + return err + } + dec, err := decoder.CompileToGetDecoder(header.typ) + if err != nil { + return err + } + rctx := decoder.TakeRuntimeContext() + rctx.Buf = src + rctx.Option.Flags = 0 + rctx.Option.Flags |= decoder.ContextOption + rctx.Option.Context = ctx + for _, optFunc := range optFuncs { + optFunc(rctx.Option) + } + cursor, err := dec.Decode(rctx, 0, 0, header.ptr) + if err != nil { + decoder.ReleaseRuntimeContext(rctx) + return err + } + decoder.ReleaseRuntimeContext(rctx) + return validateEndBuf(src, cursor) +} + +func unmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + src := make([]byte, len(data)+1) // append nul byte to the end + copy(src, data) + + header := (*emptyInterface)(unsafe.Pointer(&v)) + + if err := validateType(header.typ, uintptr(header.ptr)); err != nil { + return err + } + dec, err := decoder.CompileToGetDecoder(header.typ) + if err != nil { + return err + } + + ctx := decoder.TakeRuntimeContext() + ctx.Buf = src + ctx.Option.Flags = 0 + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + cursor, err := dec.Decode(ctx, 0, 0, noescape(header.ptr)) + if err != nil { + decoder.ReleaseRuntimeContext(ctx) + return err + } + decoder.ReleaseRuntimeContext(ctx) + return validateEndBuf(src, cursor) +} + +func validateEndBuf(src []byte, cursor int64) error { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case nul: + return nil + } + return errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]), + cursor+1, + ) + } +} + +//nolint:staticcheck +//go:nosplit +func noescape(p unsafe.Pointer) unsafe.Pointer { + x := uintptr(p) + return unsafe.Pointer(x ^ 0) +} + +func validateType(typ *runtime.Type, p uintptr) error { + if typ == nil || typ.Kind() != reflect.Ptr || p == 0 { + return &InvalidUnmarshalError{Type: runtime.RType2Type(typ)} + } + return nil +} + +// NewDecoder returns a new decoder that reads from r. +// +// The decoder introduces its own buffering and may +// read data from r beyond the JSON values requested. +func NewDecoder(r io.Reader) *Decoder { + s := decoder.NewStream(r) + return &Decoder{ + s: s, + } +} + +// Buffered returns a reader of the data remaining in the Decoder's +// buffer. The reader is valid until the next call to Decode. +func (d *Decoder) Buffered() io.Reader { + return d.s.Buffered() +} + +// Decode reads the next JSON-encoded value from its +// input and stores it in the value pointed to by v. +// +// See the documentation for Unmarshal for details about +// the conversion of JSON into a Go value. +func (d *Decoder) Decode(v interface{}) error { + return d.DecodeWithOption(v) +} + +// DecodeContext reads the next JSON-encoded value from its +// input and stores it in the value pointed to by v with context.Context. +func (d *Decoder) DecodeContext(ctx context.Context, v interface{}) error { + d.s.Option.Flags |= decoder.ContextOption + d.s.Option.Context = ctx + return d.DecodeWithOption(v) +} + +func (d *Decoder) DecodeWithOption(v interface{}, optFuncs ...DecodeOptionFunc) error { + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + ptr := uintptr(header.ptr) + typeptr := uintptr(unsafe.Pointer(typ)) + // noescape trick for header.typ ( reflect.*rtype ) + copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr)) + + if err := validateType(copiedType, ptr); err != nil { + return err + } + + dec, err := decoder.CompileToGetDecoder(typ) + if err != nil { + return err + } + if err := d.s.PrepareForDecode(); err != nil { + return err + } + s := d.s + for _, optFunc := range optFuncs { + optFunc(s.Option) + } + if err := dec.DecodeStream(s, 0, header.ptr); err != nil { + return err + } + s.Reset() + return nil +} + +func (d *Decoder) More() bool { + return d.s.More() +} + +func (d *Decoder) Token() (Token, error) { + return d.s.Token() +} + +// DisallowUnknownFields causes the Decoder to return an error when the destination +// is a struct and the input contains object keys which do not match any +// non-ignored, exported fields in the destination. +func (d *Decoder) DisallowUnknownFields() { + d.s.DisallowUnknownFields = true +} + +func (d *Decoder) InputOffset() int64 { + return d.s.TotalOffset() +} + +// UseNumber causes the Decoder to unmarshal a number into an interface{} as a +// Number instead of as a float64. +func (d *Decoder) UseNumber() { + d.s.UseNumber = true +} diff --git a/vendor/github.com/goccy/go-json/encode.go b/vendor/github.com/goccy/go-json/encode.go new file mode 100644 index 000000000..7f198bdca --- /dev/null +++ b/vendor/github.com/goccy/go-json/encode.go @@ -0,0 +1,323 @@ +package json + +import ( + "context" + "io" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/encoder/vm" + "github.com/goccy/go-json/internal/encoder/vm_color" + "github.com/goccy/go-json/internal/encoder/vm_color_indent" + "github.com/goccy/go-json/internal/encoder/vm_indent" +) + +// An Encoder writes JSON values to an output stream. +type Encoder struct { + w io.Writer + enabledIndent bool + enabledHTMLEscape bool + prefix string + indentStr string +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + return &Encoder{w: w, enabledHTMLEscape: true} +} + +// Encode writes the JSON encoding of v to the stream, followed by a newline character. +// +// See the documentation for Marshal for details about the conversion of Go values to JSON. +func (e *Encoder) Encode(v interface{}) error { + return e.EncodeWithOption(v) +} + +// EncodeWithOption call Encode with EncodeOption. +func (e *Encoder) EncodeWithOption(v interface{}, optFuncs ...EncodeOptionFunc) error { + ctx := encoder.TakeRuntimeContext() + ctx.Option.Flag = 0 + + err := e.encodeWithOption(ctx, v, optFuncs...) + + encoder.ReleaseRuntimeContext(ctx) + return err +} + +// EncodeContext call Encode with context.Context and EncodeOption. +func (e *Encoder) EncodeContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) error { + rctx := encoder.TakeRuntimeContext() + rctx.Option.Flag = 0 + rctx.Option.Flag |= encoder.ContextOption + rctx.Option.Context = ctx + + err := e.encodeWithOption(rctx, v, optFuncs...) + + encoder.ReleaseRuntimeContext(rctx) + return err +} + +func (e *Encoder) encodeWithOption(ctx *encoder.RuntimeContext, v interface{}, optFuncs ...EncodeOptionFunc) error { + if e.enabledHTMLEscape { + ctx.Option.Flag |= encoder.HTMLEscapeOption + } + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + var ( + buf []byte + err error + ) + if e.enabledIndent { + buf, err = encodeIndent(ctx, v, e.prefix, e.indentStr) + } else { + buf, err = encode(ctx, v) + } + if err != nil { + return err + } + if e.enabledIndent { + buf = buf[:len(buf)-2] + } else { + buf = buf[:len(buf)-1] + } + buf = append(buf, '\n') + if _, err := e.w.Write(buf); err != nil { + return err + } + return nil +} + +// SetEscapeHTML specifies whether problematic HTML characters should be escaped inside JSON quoted strings. +// The default behavior is to escape &, <, and > to \u0026, \u003c, and \u003e to avoid certain safety problems that can arise when embedding JSON in HTML. +// +// In non-HTML settings where the escaping interferes with the readability of the output, SetEscapeHTML(false) disables this behavior. +func (e *Encoder) SetEscapeHTML(on bool) { + e.enabledHTMLEscape = on +} + +// SetIndent instructs the encoder to format each subsequent encoded value as if indented by the package-level function Indent(dst, src, prefix, indent). +// Calling SetIndent("", "") disables indentation. +func (e *Encoder) SetIndent(prefix, indent string) { + if prefix == "" && indent == "" { + e.enabledIndent = false + return + } + e.prefix = prefix + e.indentStr = indent + e.enabledIndent = true +} + +func marshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + rctx := encoder.TakeRuntimeContext() + rctx.Option.Flag = 0 + rctx.Option.Flag = encoder.HTMLEscapeOption | encoder.ContextOption + rctx.Option.Context = ctx + for _, optFunc := range optFuncs { + optFunc(rctx.Option) + } + + buf, err := encode(rctx, v) + if err != nil { + encoder.ReleaseRuntimeContext(rctx) + return nil, err + } + + // this line exists to escape call of `runtime.makeslicecopy` . + // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`, + // dst buffer size and src buffer size are differrent. + // in this case, compiler uses `runtime.makeslicecopy`, but it is slow. + buf = buf[:len(buf)-1] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(rctx) + return copied, nil +} + +func marshal(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + ctx := encoder.TakeRuntimeContext() + + ctx.Option.Flag = 0 + ctx.Option.Flag |= encoder.HTMLEscapeOption + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + + buf, err := encode(ctx, v) + if err != nil { + encoder.ReleaseRuntimeContext(ctx) + return nil, err + } + + // this line exists to escape call of `runtime.makeslicecopy` . + // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`, + // dst buffer size and src buffer size are differrent. + // in this case, compiler uses `runtime.makeslicecopy`, but it is slow. + buf = buf[:len(buf)-1] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(ctx) + return copied, nil +} + +func marshalNoEscape(v interface{}) ([]byte, error) { + ctx := encoder.TakeRuntimeContext() + + ctx.Option.Flag = 0 + ctx.Option.Flag |= encoder.HTMLEscapeOption + + buf, err := encodeNoEscape(ctx, v) + if err != nil { + encoder.ReleaseRuntimeContext(ctx) + return nil, err + } + + // this line exists to escape call of `runtime.makeslicecopy` . + // if use `make([]byte, len(buf)-1)` and `copy(copied, buf)`, + // dst buffer size and src buffer size are differrent. + // in this case, compiler uses `runtime.makeslicecopy`, but it is slow. + buf = buf[:len(buf)-1] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(ctx) + return copied, nil +} + +func marshalIndent(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) { + ctx := encoder.TakeRuntimeContext() + + ctx.Option.Flag = 0 + ctx.Option.Flag |= (encoder.HTMLEscapeOption | encoder.IndentOption) + for _, optFunc := range optFuncs { + optFunc(ctx.Option) + } + + buf, err := encodeIndent(ctx, v, prefix, indent) + if err != nil { + encoder.ReleaseRuntimeContext(ctx) + return nil, err + } + + buf = buf[:len(buf)-2] + copied := make([]byte, len(buf)) + copy(copied, buf) + + encoder.ReleaseRuntimeContext(ctx) + return copied, nil +} + +func encode(ctx *encoder.RuntimeContext, v interface{}) ([]byte, error) { + b := ctx.Buf[:0] + if v == nil { + b = encoder.AppendNull(ctx, b) + b = encoder.AppendComma(ctx, b) + return b, nil + } + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + + typeptr := uintptr(unsafe.Pointer(typ)) + codeSet, err := encoder.CompileToGetCodeSet(typeptr) + if err != nil { + return nil, err + } + + p := uintptr(header.ptr) + ctx.Init(p, codeSet.CodeLength) + ctx.KeepRefs = append(ctx.KeepRefs, header.ptr) + + buf, err := encodeRunCode(ctx, b, codeSet) + if err != nil { + return nil, err + } + ctx.Buf = buf + return buf, nil +} + +func encodeNoEscape(ctx *encoder.RuntimeContext, v interface{}) ([]byte, error) { + b := ctx.Buf[:0] + if v == nil { + b = encoder.AppendNull(ctx, b) + b = encoder.AppendComma(ctx, b) + return b, nil + } + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + + typeptr := uintptr(unsafe.Pointer(typ)) + codeSet, err := encoder.CompileToGetCodeSet(typeptr) + if err != nil { + return nil, err + } + + p := uintptr(header.ptr) + ctx.Init(p, codeSet.CodeLength) + buf, err := encodeRunCode(ctx, b, codeSet) + if err != nil { + return nil, err + } + + ctx.Buf = buf + return buf, nil +} + +func encodeIndent(ctx *encoder.RuntimeContext, v interface{}, prefix, indent string) ([]byte, error) { + b := ctx.Buf[:0] + if v == nil { + b = encoder.AppendNull(ctx, b) + b = encoder.AppendCommaIndent(ctx, b) + return b, nil + } + header := (*emptyInterface)(unsafe.Pointer(&v)) + typ := header.typ + + typeptr := uintptr(unsafe.Pointer(typ)) + codeSet, err := encoder.CompileToGetCodeSet(typeptr) + if err != nil { + return nil, err + } + + p := uintptr(header.ptr) + ctx.Init(p, codeSet.CodeLength) + buf, err := encodeRunIndentCode(ctx, b, codeSet, prefix, indent) + + ctx.KeepRefs = append(ctx.KeepRefs, header.ptr) + + if err != nil { + return nil, err + } + + ctx.Buf = buf + return buf, nil +} + +func encodeRunCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + if (ctx.Option.Flag & encoder.DebugOption) != 0 { + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color.DebugRun(ctx, b, codeSet) + } + return vm.DebugRun(ctx, b, codeSet) + } + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color.Run(ctx, b, codeSet) + } + return vm.Run(ctx, b, codeSet) +} + +func encodeRunIndentCode(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet, prefix, indent string) ([]byte, error) { + ctx.Prefix = []byte(prefix) + ctx.IndentStr = []byte(indent) + if (ctx.Option.Flag & encoder.DebugOption) != 0 { + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color_indent.DebugRun(ctx, b, codeSet) + } + return vm_indent.DebugRun(ctx, b, codeSet) + } + if (ctx.Option.Flag & encoder.ColorizeOption) != 0 { + return vm_color_indent.Run(ctx, b, codeSet) + } + return vm_indent.Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/error.go b/vendor/github.com/goccy/go-json/error.go new file mode 100644 index 000000000..94c1339a0 --- /dev/null +++ b/vendor/github.com/goccy/go-json/error.go @@ -0,0 +1,39 @@ +package json + +import ( + "github.com/goccy/go-json/internal/errors" +) + +// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when +// attempting to encode a string value with invalid UTF-8 sequences. +// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by +// replacing invalid bytes with the Unicode replacement rune U+FFFD. +// +// Deprecated: No longer used; kept for compatibility. +type InvalidUTF8Error = errors.InvalidUTF8Error + +// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. +// (The argument to Unmarshal must be a non-nil pointer.) +type InvalidUnmarshalError = errors.InvalidUnmarshalError + +// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. +type MarshalerError = errors.MarshalerError + +// A SyntaxError is a description of a JSON syntax error. +type SyntaxError = errors.SyntaxError + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// +// Deprecated: No longer used; kept for compatibility. +type UnmarshalFieldError = errors.UnmarshalFieldError + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError = errors.UnmarshalTypeError + +// An UnsupportedTypeError is returned by Marshal when attempting +// to encode an unsupported value type. +type UnsupportedTypeError = errors.UnsupportedTypeError + +type UnsupportedValueError = errors.UnsupportedValueError diff --git a/vendor/github.com/goccy/go-json/go.mod b/vendor/github.com/goccy/go-json/go.mod new file mode 100644 index 000000000..58a14881f --- /dev/null +++ b/vendor/github.com/goccy/go-json/go.mod @@ -0,0 +1,3 @@ +module github.com/goccy/go-json + +go 1.12 diff --git a/vendor/github.com/goccy/go-json/go.sum b/vendor/github.com/goccy/go-json/go.sum new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go new file mode 100644 index 000000000..030cb7a97 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/anonymous_field.go @@ -0,0 +1,37 @@ +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type anonymousFieldDecoder struct { + structType *runtime.Type + offset uintptr + dec Decoder +} + +func newAnonymousFieldDecoder(structType *runtime.Type, offset uintptr, dec Decoder) *anonymousFieldDecoder { + return &anonymousFieldDecoder{ + structType: structType, + offset: offset, + dec: dec, + } +} + +func (d *anonymousFieldDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + if *(*unsafe.Pointer)(p) == nil { + *(*unsafe.Pointer)(p) = unsafe_New(d.structType) + } + p = *(*unsafe.Pointer)(p) + return d.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+d.offset)) +} + +func (d *anonymousFieldDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + if *(*unsafe.Pointer)(p) == nil { + *(*unsafe.Pointer)(p) = unsafe_New(d.structType) + } + p = *(*unsafe.Pointer)(p) + return d.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+d.offset)) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/array.go b/vendor/github.com/goccy/go-json/internal/decoder/array.go new file mode 100644 index 000000000..21f1fd585 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/array.go @@ -0,0 +1,169 @@ +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type arrayDecoder struct { + elemType *runtime.Type + size uintptr + valueDecoder Decoder + alen int + structName string + fieldName string + zeroValue unsafe.Pointer +} + +func newArrayDecoder(dec Decoder, elemType *runtime.Type, alen int, structName, fieldName string) *arrayDecoder { + zeroValue := *(*unsafe.Pointer)(unsafe_New(elemType)) + return &arrayDecoder{ + valueDecoder: dec, + elemType: elemType, + size: elemType.Size(), + alen: alen, + structName: structName, + fieldName: fieldName, + zeroValue: zeroValue, + } +} + +func (d *arrayDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + case 'n': + if err := nullBytes(s); err != nil { + return err + } + return nil + case '[': + idx := 0 + s.cursor++ + if s.skipWhiteSpace() == ']' { + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + s.cursor++ + return nil + } + for { + if idx < d.alen { + if err := d.valueDecoder.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)); err != nil { + return err + } + } else { + if err := s.skipValue(depth); err != nil { + return err + } + } + idx++ + switch s.skipWhiteSpace() { + case ']': + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + s.cursor++ + return nil + case ',': + s.cursor++ + continue + case nul: + if s.read() { + s.cursor++ + continue + } + goto ERROR + default: + goto ERROR + } + } + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + s.cursor++ + } +ERROR: + return errors.ErrUnexpectedEndOfJSON("array", s.totalOffset()) +} + +func (d *arrayDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + case '[': + idx := 0 + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == ']' { + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + cursor++ + return cursor, nil + } + for { + if idx < d.alen { + c, err := d.valueDecoder.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+uintptr(idx)*d.size)) + if err != nil { + return 0, err + } + cursor = c + } else { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + cursor = c + } + idx++ + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case ']': + for idx < d.alen { + *(*unsafe.Pointer)(unsafe.Pointer(uintptr(p) + uintptr(idx)*d.size)) = d.zeroValue + idx++ + } + cursor++ + return cursor, nil + case ',': + cursor++ + continue + default: + return 0, errors.ErrInvalidCharacter(buf[cursor], "array", cursor) + } + } + default: + return 0, errors.ErrUnexpectedEndOfJSON("array", cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bool.go b/vendor/github.com/goccy/go-json/internal/decoder/bool.go new file mode 100644 index 000000000..455042a53 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/bool.go @@ -0,0 +1,78 @@ +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type boolDecoder struct { + structName string + fieldName string +} + +func newBoolDecoder(structName, fieldName string) *boolDecoder { + return &boolDecoder{structName: structName, fieldName: fieldName} +} + +func (d *boolDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + c := s.skipWhiteSpace() + for { + switch c { + case 't': + if err := trueBytes(s); err != nil { + return err + } + **(**bool)(unsafe.Pointer(&p)) = true + return nil + case 'f': + if err := falseBytes(s); err != nil { + return err + } + **(**bool)(unsafe.Pointer(&p)) = false + return nil + case 'n': + if err := nullBytes(s); err != nil { + return err + } + return nil + case nul: + if s.read() { + c = s.char() + continue + } + goto ERROR + } + break + } +ERROR: + return errors.ErrUnexpectedEndOfJSON("bool", s.totalOffset()) +} + +func (d *boolDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case 't': + if err := validateTrue(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**bool)(unsafe.Pointer(&p)) = true + return cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return 0, err + } + cursor += 5 + **(**bool)(unsafe.Pointer(&p)) = false + return cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + } + return 0, errors.ErrUnexpectedEndOfJSON("bool", cursor) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/bytes.go b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go new file mode 100644 index 000000000..0c4681a11 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/bytes.go @@ -0,0 +1,177 @@ +package decoder + +import ( + "encoding/base64" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type bytesDecoder struct { + typ *runtime.Type + sliceDecoder Decoder + structName string + fieldName string +} + +func byteUnmarshalerSliceDecoder(typ *runtime.Type, structName string, fieldName string) Decoder { + var unmarshalDecoder Decoder + switch { + case runtime.PtrTo(typ).Implements(unmarshalJSONType): + unmarshalDecoder = newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName) + case runtime.PtrTo(typ).Implements(unmarshalTextType): + unmarshalDecoder = newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName) + } + if unmarshalDecoder == nil { + return nil + } + return newSliceDecoder(unmarshalDecoder, typ, 1, structName, fieldName) +} + +func newBytesDecoder(typ *runtime.Type, structName string, fieldName string) *bytesDecoder { + return &bytesDecoder{ + typ: typ, + sliceDecoder: byteUnmarshalerSliceDecoder(typ, structName, fieldName), + structName: structName, + fieldName: fieldName, + } +} + +func (d *bytesDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamBinary(s, depth, p) + if err != nil { + return err + } + if bytes == nil { + s.reset() + return nil + } + decodedLen := base64.StdEncoding.DecodedLen(len(bytes)) + buf := make([]byte, decodedLen) + n, err := base64.StdEncoding.Decode(buf, bytes) + if err != nil { + return err + } + *(*[]byte)(p) = buf[:n] + s.reset() + return nil +} + +func (d *bytesDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeBinary(ctx, cursor, depth, p) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + decodedLen := base64.StdEncoding.DecodedLen(len(bytes)) + b := make([]byte, decodedLen) + n, err := base64.StdEncoding.Decode(b, bytes) + if err != nil { + return 0, err + } + *(*[]byte)(p) = b[:n] + return cursor, nil +} + +func binaryBytes(s *Stream) ([]byte, error) { + s.cursor++ + start := s.cursor + for { + switch s.char() { + case '"': + literal := s.buf[start:s.cursor] + s.cursor++ + return literal, nil + case nul: + if s.read() { + continue + } + goto ERROR + } + s.cursor++ + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("[]byte", s.totalOffset()) +} + +func (d *bytesDecoder) decodeStreamBinary(s *Stream, depth int64, p unsafe.Pointer) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '"': + return binaryBytes(s) + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case '[': + if d.sliceDecoder == nil { + return nil, &errors.UnmarshalTypeError{ + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + } + if err := d.sliceDecoder.DecodeStream(s, depth, p); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + } + break + } + return nil, errors.ErrNotAtBeginningOfValue(s.totalOffset()) +} + +func (d *bytesDecoder) decodeBinary(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) ([]byte, int64, error) { + buf := ctx.Buf + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + case '"': + cursor++ + start := cursor + for { + switch buf[cursor] { + case '"': + literal := buf[start:cursor] + cursor++ + return literal, cursor, nil + case nul: + return nil, 0, errors.ErrUnexpectedEndOfJSON("[]byte", cursor) + } + cursor++ + } + case '[': + if d.sliceDecoder == nil { + return nil, 0, &errors.UnmarshalTypeError{ + Type: runtime.RType2Type(d.typ), + Offset: cursor, + } + } + c, err := d.sliceDecoder.Decode(ctx, cursor, depth, p) + if err != nil { + return nil, 0, err + } + return nil, c, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, errors.ErrNotAtBeginningOfValue(cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile.go b/vendor/github.com/goccy/go-json/internal/decoder/compile.go new file mode 100644 index 000000000..08dd044e6 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/compile.go @@ -0,0 +1,510 @@ +package decoder + +import ( + "encoding/json" + "fmt" + "reflect" + "strings" + "sync/atomic" + "unicode" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +var ( + jsonNumberType = reflect.TypeOf(json.Number("")) + typeAddr *runtime.TypeAddr + cachedDecoderMap unsafe.Pointer // map[uintptr]decoder + cachedDecoder []Decoder +) + +func init() { + typeAddr = runtime.AnalyzeTypeAddr() + if typeAddr == nil { + typeAddr = &runtime.TypeAddr{} + } + cachedDecoder = make([]Decoder, typeAddr.AddrRange>>typeAddr.AddrShift) +} + +func loadDecoderMap() map[uintptr]Decoder { + p := atomic.LoadPointer(&cachedDecoderMap) + return *(*map[uintptr]Decoder)(unsafe.Pointer(&p)) +} + +func storeDecoder(typ uintptr, dec Decoder, m map[uintptr]Decoder) { + newDecoderMap := make(map[uintptr]Decoder, len(m)+1) + newDecoderMap[typ] = dec + + for k, v := range m { + newDecoderMap[k] = v + } + + atomic.StorePointer(&cachedDecoderMap, *(*unsafe.Pointer)(unsafe.Pointer(&newDecoderMap))) +} + +func compileToGetDecoderSlowPath(typeptr uintptr, typ *runtime.Type) (Decoder, error) { + decoderMap := loadDecoderMap() + if dec, exists := decoderMap[typeptr]; exists { + return dec, nil + } + + dec, err := compileHead(typ, map[uintptr]Decoder{}) + if err != nil { + return nil, err + } + storeDecoder(typeptr, dec, decoderMap) + return dec, nil +} + +func compileHead(typ *runtime.Type, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + switch { + case implementsUnmarshalJSONType(runtime.PtrTo(typ)): + return newUnmarshalJSONDecoder(runtime.PtrTo(typ), "", ""), nil + case runtime.PtrTo(typ).Implements(unmarshalTextType): + return newUnmarshalTextDecoder(runtime.PtrTo(typ), "", ""), nil + } + return compile(typ.Elem(), "", "", structTypeToDecoder) +} + +func compile(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + switch { + case implementsUnmarshalJSONType(runtime.PtrTo(typ)): + return newUnmarshalJSONDecoder(runtime.PtrTo(typ), structName, fieldName), nil + case runtime.PtrTo(typ).Implements(unmarshalTextType): + return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil + } + + switch typ.Kind() { + case reflect.Ptr: + return compilePtr(typ, structName, fieldName, structTypeToDecoder) + case reflect.Struct: + return compileStruct(typ, structName, fieldName, structTypeToDecoder) + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + return compileBytes(elem, structName, fieldName) + } + return compileSlice(typ, structName, fieldName, structTypeToDecoder) + case reflect.Array: + return compileArray(typ, structName, fieldName, structTypeToDecoder) + case reflect.Map: + return compileMap(typ, structName, fieldName, structTypeToDecoder) + case reflect.Interface: + return compileInterface(typ, structName, fieldName) + case reflect.Uintptr: + return compileUint(typ, structName, fieldName) + case reflect.Int: + return compileInt(typ, structName, fieldName) + case reflect.Int8: + return compileInt8(typ, structName, fieldName) + case reflect.Int16: + return compileInt16(typ, structName, fieldName) + case reflect.Int32: + return compileInt32(typ, structName, fieldName) + case reflect.Int64: + return compileInt64(typ, structName, fieldName) + case reflect.Uint: + return compileUint(typ, structName, fieldName) + case reflect.Uint8: + return compileUint8(typ, structName, fieldName) + case reflect.Uint16: + return compileUint16(typ, structName, fieldName) + case reflect.Uint32: + return compileUint32(typ, structName, fieldName) + case reflect.Uint64: + return compileUint64(typ, structName, fieldName) + case reflect.String: + return compileString(typ, structName, fieldName) + case reflect.Bool: + return compileBool(structName, fieldName) + case reflect.Float32: + return compileFloat32(structName, fieldName) + case reflect.Float64: + return compileFloat64(structName, fieldName) + case reflect.Func: + return compileFunc(typ, structName, fieldName) + } + return nil, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(typ), + Offset: 0, + Struct: structName, + Field: fieldName, + } +} + +func isStringTagSupportedType(typ *runtime.Type) bool { + switch { + case implementsUnmarshalJSONType(runtime.PtrTo(typ)): + return false + case runtime.PtrTo(typ).Implements(unmarshalTextType): + return false + } + switch typ.Kind() { + case reflect.Map: + return false + case reflect.Slice: + return false + case reflect.Array: + return false + case reflect.Struct: + return false + case reflect.Interface: + return false + } + return true +} + +func compileMapKey(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + if runtime.PtrTo(typ).Implements(unmarshalTextType) { + return newUnmarshalTextDecoder(runtime.PtrTo(typ), structName, fieldName), nil + } + dec, err := compile(typ, structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + for { + switch t := dec.(type) { + case *stringDecoder, *interfaceDecoder: + return dec, nil + case *boolDecoder, *intDecoder, *uintDecoder, *numberDecoder: + return newWrappedStringDecoder(typ, dec, structName, fieldName), nil + case *ptrDecoder: + dec = t.dec + default: + goto ERROR + } + } +ERROR: + return nil, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(typ), + Offset: 0, + Struct: structName, + Field: fieldName, + } +} + +func compilePtr(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + dec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newPtrDecoder(dec, typ.Elem(), structName, fieldName), nil +} + +func compileInt(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int)(p) = int(v) + }), nil +} + +func compileInt8(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int8)(p) = int8(v) + }), nil +} + +func compileInt16(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int16)(p) = int16(v) + }), nil +} + +func compileInt32(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int32)(p) = int32(v) + }), nil +} + +func compileInt64(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newIntDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v int64) { + *(*int64)(p) = v + }), nil +} + +func compileUint(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint)(p) = uint(v) + }), nil +} + +func compileUint8(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint8)(p) = uint8(v) + }), nil +} + +func compileUint16(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint16)(p) = uint16(v) + }), nil +} + +func compileUint32(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint32)(p) = uint32(v) + }), nil +} + +func compileUint64(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newUintDecoder(typ, structName, fieldName, func(p unsafe.Pointer, v uint64) { + *(*uint64)(p) = v + }), nil +} + +func compileFloat32(structName, fieldName string) (Decoder, error) { + return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*float32)(p) = float32(v) + }), nil +} + +func compileFloat64(structName, fieldName string) (Decoder, error) { + return newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*float64)(p) = v + }), nil +} + +func compileString(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + if typ == runtime.Type2RType(jsonNumberType) { + return newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { + *(*json.Number)(p) = v + }), nil + } + return newStringDecoder(structName, fieldName), nil +} + +func compileBool(structName, fieldName string) (Decoder, error) { + return newBoolDecoder(structName, fieldName), nil +} + +func compileBytes(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newBytesDecoder(typ, structName, fieldName), nil +} + +func compileSlice(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + elem := typ.Elem() + decoder, err := compile(elem, structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newSliceDecoder(decoder, elem, elem.Size(), structName, fieldName), nil +} + +func compileArray(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + elem := typ.Elem() + decoder, err := compile(elem, structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newArrayDecoder(decoder, elem, typ.Len(), structName, fieldName), nil +} + +func compileMap(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + keyDec, err := compileMapKey(typ.Key(), structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + valueDec, err := compile(typ.Elem(), structName, fieldName, structTypeToDecoder) + if err != nil { + return nil, err + } + return newMapDecoder(typ, typ.Key(), keyDec, typ.Elem(), valueDec, structName, fieldName), nil +} + +func compileInterface(typ *runtime.Type, structName, fieldName string) (Decoder, error) { + return newInterfaceDecoder(typ, structName, fieldName), nil +} + +func compileFunc(typ *runtime.Type, strutName, fieldName string) (Decoder, error) { + return newFuncDecoder(typ, strutName, fieldName), nil +} + +func removeConflictFields(fieldMap map[string]*structFieldSet, conflictedMap map[string]struct{}, dec *structDecoder, field reflect.StructField) { + for k, v := range dec.fieldMap { + if _, exists := conflictedMap[k]; exists { + // already conflicted key + continue + } + set, exists := fieldMap[k] + if !exists { + fieldSet := &structFieldSet{ + dec: v.dec, + offset: field.Offset + v.offset, + isTaggedKey: v.isTaggedKey, + key: k, + keyLen: int64(len(k)), + } + fieldMap[k] = fieldSet + lower := strings.ToLower(k) + if _, exists := fieldMap[lower]; !exists { + fieldMap[lower] = fieldSet + } + continue + } + if set.isTaggedKey { + if v.isTaggedKey { + // conflict tag key + delete(fieldMap, k) + delete(fieldMap, strings.ToLower(k)) + conflictedMap[k] = struct{}{} + conflictedMap[strings.ToLower(k)] = struct{}{} + } + } else { + if v.isTaggedKey { + fieldSet := &structFieldSet{ + dec: v.dec, + offset: field.Offset + v.offset, + isTaggedKey: v.isTaggedKey, + key: k, + keyLen: int64(len(k)), + } + fieldMap[k] = fieldSet + lower := strings.ToLower(k) + if _, exists := fieldMap[lower]; !exists { + fieldMap[lower] = fieldSet + } + } else { + // conflict tag key + delete(fieldMap, k) + delete(fieldMap, strings.ToLower(k)) + conflictedMap[k] = struct{}{} + conflictedMap[strings.ToLower(k)] = struct{}{} + } + } + } +} + +func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeToDecoder map[uintptr]Decoder) (Decoder, error) { + fieldNum := typ.NumField() + conflictedMap := map[string]struct{}{} + fieldMap := map[string]*structFieldSet{} + typeptr := uintptr(unsafe.Pointer(typ)) + if dec, exists := structTypeToDecoder[typeptr]; exists { + return dec, nil + } + structDec := newStructDecoder(structName, fieldName, fieldMap) + structTypeToDecoder[typeptr] = structDec + structName = typ.Name() + for i := 0; i < fieldNum; i++ { + field := typ.Field(i) + if runtime.IsIgnoredStructField(field) { + continue + } + isUnexportedField := unicode.IsLower([]rune(field.Name)[0]) + tag := runtime.StructTagFromField(field) + dec, err := compile(runtime.Type2RType(field.Type), structName, field.Name, structTypeToDecoder) + if err != nil { + return nil, err + } + if field.Anonymous && !tag.IsTaggedKey { + if stDec, ok := dec.(*structDecoder); ok { + if runtime.Type2RType(field.Type) == typ { + // recursive definition + continue + } + removeConflictFields(fieldMap, conflictedMap, stDec, field) + } else if pdec, ok := dec.(*ptrDecoder); ok { + contentDec := pdec.contentDecoder() + if pdec.typ == typ { + // recursive definition + continue + } + var fieldSetErr error + if isUnexportedField { + fieldSetErr = fmt.Errorf( + "json: cannot set embedded pointer to unexported struct: %v", + field.Type.Elem(), + ) + } + if dec, ok := contentDec.(*structDecoder); ok { + for k, v := range dec.fieldMap { + if _, exists := conflictedMap[k]; exists { + // already conflicted key + continue + } + set, exists := fieldMap[k] + if !exists { + fieldSet := &structFieldSet{ + dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec), + offset: field.Offset, + isTaggedKey: v.isTaggedKey, + key: k, + keyLen: int64(len(k)), + err: fieldSetErr, + } + fieldMap[k] = fieldSet + lower := strings.ToLower(k) + if _, exists := fieldMap[lower]; !exists { + fieldMap[lower] = fieldSet + } + continue + } + if set.isTaggedKey { + if v.isTaggedKey { + // conflict tag key + delete(fieldMap, k) + delete(fieldMap, strings.ToLower(k)) + conflictedMap[k] = struct{}{} + conflictedMap[strings.ToLower(k)] = struct{}{} + } + } else { + if v.isTaggedKey { + fieldSet := &structFieldSet{ + dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec), + offset: field.Offset, + isTaggedKey: v.isTaggedKey, + key: k, + keyLen: int64(len(k)), + err: fieldSetErr, + } + fieldMap[k] = fieldSet + lower := strings.ToLower(k) + if _, exists := fieldMap[lower]; !exists { + fieldMap[lower] = fieldSet + } + } else { + // conflict tag key + delete(fieldMap, k) + delete(fieldMap, strings.ToLower(k)) + conflictedMap[k] = struct{}{} + conflictedMap[strings.ToLower(k)] = struct{}{} + } + } + } + } + } + } else { + if tag.IsString && isStringTagSupportedType(runtime.Type2RType(field.Type)) { + dec = newWrappedStringDecoder(runtime.Type2RType(field.Type), dec, structName, field.Name) + } + var key string + if tag.Key != "" { + key = tag.Key + } else { + key = field.Name + } + fieldSet := &structFieldSet{ + dec: dec, + offset: field.Offset, + isTaggedKey: tag.IsTaggedKey, + key: key, + keyLen: int64(len(key)), + } + fieldMap[key] = fieldSet + lower := strings.ToLower(key) + if _, exists := fieldMap[lower]; !exists { + fieldMap[lower] = fieldSet + } + } + } + delete(structTypeToDecoder, typeptr) + structDec.tryOptimize() + return structDec, nil +} + +func implementsUnmarshalJSONType(typ *runtime.Type) bool { + return typ.Implements(unmarshalJSONType) || typ.Implements(unmarshalJSONContextType) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go b/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go new file mode 100644 index 000000000..592f63737 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/compile_norace.go @@ -0,0 +1,28 @@ +// +build !race + +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) { + typeptr := uintptr(unsafe.Pointer(typ)) + if typeptr > typeAddr.MaxTypeAddr { + return compileToGetDecoderSlowPath(typeptr, typ) + } + + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + if dec := cachedDecoder[index]; dec != nil { + return dec, nil + } + + dec, err := compileHead(typ, map[uintptr]Decoder{}) + if err != nil { + return nil, err + } + cachedDecoder[index] = dec + return dec, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go b/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go new file mode 100644 index 000000000..b691bc947 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/compile_race.go @@ -0,0 +1,36 @@ +// +build race + +package decoder + +import ( + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +var decMu sync.RWMutex + +func CompileToGetDecoder(typ *runtime.Type) (Decoder, error) { + typeptr := uintptr(unsafe.Pointer(typ)) + if typeptr > typeAddr.MaxTypeAddr { + return compileToGetDecoderSlowPath(typeptr, typ) + } + + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + decMu.RLock() + if dec := cachedDecoder[index]; dec != nil { + decMu.RUnlock() + return dec, nil + } + decMu.RUnlock() + + dec, err := compileHead(typ, map[uintptr]Decoder{}) + if err != nil { + return nil, err + } + decMu.Lock() + cachedDecoder[index] = dec + decMu.Unlock() + return dec, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/context.go b/vendor/github.com/goccy/go-json/internal/decoder/context.go new file mode 100644 index 000000000..cb2ffdafd --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/context.go @@ -0,0 +1,254 @@ +package decoder + +import ( + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type RuntimeContext struct { + Buf []byte + Option *Option +} + +var ( + runtimeContextPool = sync.Pool{ + New: func() interface{} { + return &RuntimeContext{ + Option: &Option{}, + } + }, + } +) + +func TakeRuntimeContext() *RuntimeContext { + return runtimeContextPool.Get().(*RuntimeContext) +} + +func ReleaseRuntimeContext(ctx *RuntimeContext) { + runtimeContextPool.Put(ctx) +} + +var ( + isWhiteSpace = [256]bool{} +) + +func init() { + isWhiteSpace[' '] = true + isWhiteSpace['\n'] = true + isWhiteSpace['\t'] = true + isWhiteSpace['\r'] = true +} + +func char(ptr unsafe.Pointer, offset int64) byte { + return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset))) +} + +func skipWhiteSpace(buf []byte, cursor int64) int64 { + for isWhiteSpace[buf[cursor]] { + cursor++ + } + return cursor +} + +func skipObject(buf []byte, cursor, depth int64) (int64, error) { + braceCount := 1 + for { + switch buf[cursor] { + case '{': + braceCount++ + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case '}': + depth-- + braceCount-- + if braceCount == 0 { + return cursor + 1, nil + } + case '[': + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case ']': + depth-- + case '"': + for { + cursor++ + switch buf[cursor] { + case '\\': + cursor++ + if buf[cursor] == nul { + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("object of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func skipArray(buf []byte, cursor, depth int64) (int64, error) { + bracketCount := 1 + for { + switch buf[cursor] { + case '[': + bracketCount++ + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case ']': + bracketCount-- + depth-- + if bracketCount == 0 { + return cursor + 1, nil + } + case '{': + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + case '}': + depth-- + case '"': + for { + cursor++ + switch buf[cursor] { + case '\\': + cursor++ + if buf[cursor] == nul { + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("array of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func skipValue(buf []byte, cursor, depth int64) (int64, error) { + for { + switch buf[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case '{': + return skipObject(buf, cursor+1, depth+1) + case '[': + return skipArray(buf, cursor+1, depth+1) + case '"': + for { + cursor++ + switch buf[cursor] { + case '\\': + cursor++ + if buf[cursor] == nul { + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + return cursor + 1, nil + case nul: + return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + for { + cursor++ + if floatTable[buf[cursor]] { + continue + } + break + } + return cursor, nil + case 't': + if err := validateTrue(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return 0, err + } + cursor += 5 + return cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + default: + return cursor, errors.ErrUnexpectedEndOfJSON("null", cursor) + } + } +} + +func validateTrue(buf []byte, cursor int64) error { + if cursor+3 >= int64(len(buf)) { + return errors.ErrUnexpectedEndOfJSON("true", cursor) + } + if buf[cursor+1] != 'r' { + return errors.ErrInvalidCharacter(buf[cursor+1], "true", cursor) + } + if buf[cursor+2] != 'u' { + return errors.ErrInvalidCharacter(buf[cursor+2], "true", cursor) + } + if buf[cursor+3] != 'e' { + return errors.ErrInvalidCharacter(buf[cursor+3], "true", cursor) + } + return nil +} + +func validateFalse(buf []byte, cursor int64) error { + if cursor+4 >= int64(len(buf)) { + return errors.ErrUnexpectedEndOfJSON("false", cursor) + } + if buf[cursor+1] != 'a' { + return errors.ErrInvalidCharacter(buf[cursor+1], "false", cursor) + } + if buf[cursor+2] != 'l' { + return errors.ErrInvalidCharacter(buf[cursor+2], "false", cursor) + } + if buf[cursor+3] != 's' { + return errors.ErrInvalidCharacter(buf[cursor+3], "false", cursor) + } + if buf[cursor+4] != 'e' { + return errors.ErrInvalidCharacter(buf[cursor+4], "false", cursor) + } + return nil +} + +func validateNull(buf []byte, cursor int64) error { + if cursor+3 >= int64(len(buf)) { + return errors.ErrUnexpectedEndOfJSON("null", cursor) + } + if buf[cursor+1] != 'u' { + return errors.ErrInvalidCharacter(buf[cursor+1], "null", cursor) + } + if buf[cursor+2] != 'l' { + return errors.ErrInvalidCharacter(buf[cursor+2], "null", cursor) + } + if buf[cursor+3] != 'l' { + return errors.ErrInvalidCharacter(buf[cursor+3], "null", cursor) + } + return nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/float.go b/vendor/github.com/goccy/go-json/internal/decoder/float.go new file mode 100644 index 000000000..dfb7168da --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/float.go @@ -0,0 +1,158 @@ +package decoder + +import ( + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type floatDecoder struct { + op func(unsafe.Pointer, float64) + structName string + fieldName string +} + +func newFloatDecoder(structName, fieldName string, op func(unsafe.Pointer, float64)) *floatDecoder { + return &floatDecoder{op: op, structName: structName, fieldName: fieldName} +} + +var ( + floatTable = [256]bool{ + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + '.': true, + 'e': true, + 'E': true, + '+': true, + '-': true, + } + + validEndNumberChar = [256]bool{ + nul: true, + ' ': true, + '\t': true, + '\r': true, + '\n': true, + ',': true, + ':': true, + '}': true, + ']': true, + } +) + +func floatBytes(s *Stream) []byte { + start := s.cursor + for { + s.cursor++ + if floatTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + return s.buf[start:s.cursor] +} + +func (d *floatDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return floatBytes(s), nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("float", s.totalOffset()) +} + +func (d *floatDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for floatTable[buf[cursor]] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("float", cursor) + } + } +} + +func (d *floatDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + str := *(*string)(unsafe.Pointer(&bytes)) + f64, err := strconv.ParseFloat(str, 64) + if err != nil { + return errors.ErrSyntax(err.Error(), s.totalOffset()) + } + d.op(p, f64) + return nil +} + +func (d *floatDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + bytes, c, err := d.decodeByte(buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + if !validEndNumberChar[buf[cursor]] { + return 0, errors.ErrUnexpectedEndOfJSON("float", cursor) + } + s := *(*string)(unsafe.Pointer(&bytes)) + f64, err := strconv.ParseFloat(s, 64) + if err != nil { + return 0, errors.ErrSyntax(err.Error(), cursor) + } + d.op(p, f64) + return cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/func.go b/vendor/github.com/goccy/go-json/internal/decoder/func.go new file mode 100644 index 000000000..75afe75cd --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/func.go @@ -0,0 +1,141 @@ +package decoder + +import ( + "bytes" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type funcDecoder struct { + typ *runtime.Type + structName string + fieldName string +} + +func newFuncDecoder(typ *runtime.Type, structName, fieldName string) *funcDecoder { + fnDecoder := &funcDecoder{typ, structName, fieldName} + return fnDecoder +} + +func (d *funcDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + s.skipWhiteSpace() + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + if len(src) > 0 { + switch src[0] { + case '"': + return &errors.UnmarshalTypeError{ + Value: "string", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '[': + return &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '{': + return &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case 'n': + if err := nullBytes(s); err != nil { + return err + } + *(*unsafe.Pointer)(p) = nil + return nil + case 't': + if err := trueBytes(s); err == nil { + return &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + } + case 'f': + if err := falseBytes(s); err == nil { + return &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + } + } + } + return errors.ErrNotAtBeginningOfValue(start) +} + +func (d *funcDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + if len(src) > 0 { + switch src[0] { + case '"': + return 0, &errors.UnmarshalTypeError{ + Value: "string", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '[': + return 0, &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '{': + return 0, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return 0, &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case 'n': + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return end, nil + } + case 't': + if err := validateTrue(buf, start); err == nil { + return 0, &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + } + case 'f': + if err := validateFalse(buf, start); err == nil { + return 0, &errors.UnmarshalTypeError{ + Value: "boolean", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + } + } + } + return 0, errors.ErrNotAtBeginningOfValue(start) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/int.go b/vendor/github.com/goccy/go-json/internal/decoder/int.go new file mode 100644 index 000000000..7edfb0411 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/int.go @@ -0,0 +1,242 @@ +package decoder + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type intDecoder struct { + typ *runtime.Type + kind reflect.Kind + op func(unsafe.Pointer, int64) + structName string + fieldName string +} + +func newIntDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, int64)) *intDecoder { + return &intDecoder{ + typ: typ, + kind: typ.Kind(), + op: op, + structName: structName, + fieldName: fieldName, + } +} + +func (d *intDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: fmt.Sprintf("number %s", string(buf)), + Type: runtime.RType2Type(d.typ), + Struct: d.structName, + Field: d.fieldName, + Offset: offset, + } +} + +var ( + pow10i64 = [...]int64{ + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, + } + pow10i64Len = len(pow10i64) +) + +func (d *intDecoder) parseInt(b []byte) (int64, error) { + isNegative := false + if b[0] == '-' { + b = b[1:] + isNegative = true + } + maxDigit := len(b) + if maxDigit > pow10i64Len { + return 0, fmt.Errorf("invalid length of number") + } + sum := int64(0) + for i := 0; i < maxDigit; i++ { + c := int64(b[i]) - 48 + digitValue := pow10i64[maxDigit-i-1] + sum += c * digitValue + } + if isNegative { + return -1 * sum, nil + } + return sum, nil +} + +var ( + numTable = [256]bool{ + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + } +) + +var ( + numZeroBuf = []byte{'0'} +) + +func (d *intDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '-': + start := s.cursor + for { + s.cursor++ + if numTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + num := s.buf[start:s.cursor] + if len(num) < 2 { + goto ERROR + } + return num, nil + case '0': + s.cursor++ + return numZeroBuf, nil + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := s.cursor + for { + s.cursor++ + if numTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + num := s.buf[start:s.cursor] + return num, nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + goto ERROR + default: + return nil, d.typeError([]byte{s.char()}, s.totalOffset()) + } + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("number(integer)", s.totalOffset()) +} + +func (d *intDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '0': + cursor++ + return numZeroBuf, cursor, nil + case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for numTable[char(b, cursor)] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, d.typeError([]byte{char(b, cursor)}, cursor) + } + } +} + +func (d *intDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + i64, err := d.parseInt(bytes) + if err != nil { + return d.typeError(bytes, s.totalOffset()) + } + switch d.kind { + case reflect.Int8: + if i64 <= -1*(1<<7) || (1<<7) <= i64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Int16: + if i64 <= -1*(1<<15) || (1<<15) <= i64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Int32: + if i64 <= -1*(1<<31) || (1<<31) <= i64 { + return d.typeError(bytes, s.totalOffset()) + } + } + d.op(p, i64) + s.reset() + return nil +} + +func (d *intDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + + i64, err := d.parseInt(bytes) + if err != nil { + return 0, d.typeError(bytes, cursor) + } + switch d.kind { + case reflect.Int8: + if i64 <= -1*(1<<7) || (1<<7) <= i64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Int16: + if i64 <= -1*(1<<15) || (1<<15) <= i64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Int32: + if i64 <= -1*(1<<31) || (1<<31) <= i64 { + return 0, d.typeError(bytes, cursor) + } + } + d.op(p, i64) + return cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/interface.go b/vendor/github.com/goccy/go-json/internal/decoder/interface.go new file mode 100644 index 000000000..ea1b4aa57 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/interface.go @@ -0,0 +1,458 @@ +package decoder + +import ( + "bytes" + "encoding" + "encoding/json" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type interfaceDecoder struct { + typ *runtime.Type + structName string + fieldName string + sliceDecoder *sliceDecoder + mapDecoder *mapDecoder + floatDecoder *floatDecoder + numberDecoder *numberDecoder + stringDecoder *stringDecoder +} + +func newEmptyInterfaceDecoder(structName, fieldName string) *interfaceDecoder { + ifaceDecoder := &interfaceDecoder{ + typ: emptyInterfaceType, + structName: structName, + fieldName: fieldName, + floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*interface{})(p) = v + }), + numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { + *(*interface{})(p) = v + }), + stringDecoder: newStringDecoder(structName, fieldName), + } + ifaceDecoder.sliceDecoder = newSliceDecoder( + ifaceDecoder, + emptyInterfaceType, + emptyInterfaceType.Size(), + structName, fieldName, + ) + ifaceDecoder.mapDecoder = newMapDecoder( + interfaceMapType, + stringType, + ifaceDecoder.stringDecoder, + interfaceMapType.Elem(), + ifaceDecoder, + structName, + fieldName, + ) + return ifaceDecoder +} + +func newInterfaceDecoder(typ *runtime.Type, structName, fieldName string) *interfaceDecoder { + emptyIfaceDecoder := newEmptyInterfaceDecoder(structName, fieldName) + stringDecoder := newStringDecoder(structName, fieldName) + return &interfaceDecoder{ + typ: typ, + structName: structName, + fieldName: fieldName, + sliceDecoder: newSliceDecoder( + emptyIfaceDecoder, + emptyInterfaceType, + emptyInterfaceType.Size(), + structName, fieldName, + ), + mapDecoder: newMapDecoder( + interfaceMapType, + stringType, + stringDecoder, + interfaceMapType.Elem(), + emptyIfaceDecoder, + structName, + fieldName, + ), + floatDecoder: newFloatDecoder(structName, fieldName, func(p unsafe.Pointer, v float64) { + *(*interface{})(p) = v + }), + numberDecoder: newNumberDecoder(structName, fieldName, func(p unsafe.Pointer, v json.Number) { + *(*interface{})(p) = v + }), + stringDecoder: stringDecoder, + } +} + +func (d *interfaceDecoder) numDecoder(s *Stream) Decoder { + if s.UseNumber { + return d.numberDecoder + } + return d.floatDecoder +} + +var ( + emptyInterfaceType = runtime.Type2RType(reflect.TypeOf((*interface{})(nil)).Elem()) + interfaceMapType = runtime.Type2RType( + reflect.TypeOf((*map[string]interface{})(nil)).Elem(), + ) + stringType = runtime.Type2RType( + reflect.TypeOf(""), + ) +) + +func decodeStreamUnmarshaler(s *Stream, depth int64, unmarshaler json.Unmarshaler) error { + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(dst); err != nil { + return err + } + return nil +} + +func decodeStreamUnmarshalerContext(s *Stream, depth int64, unmarshaler unmarshalerContext) error { + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(s.Option.Context, dst); err != nil { + return err + } + return nil +} + +func decodeUnmarshaler(buf []byte, cursor, depth int64, unmarshaler json.Unmarshaler) (int64, error) { + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(dst); err != nil { + return 0, err + } + return end, nil +} + +func decodeUnmarshalerContext(ctx *RuntimeContext, buf []byte, cursor, depth int64, unmarshaler unmarshalerContext) (int64, error) { + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalJSON(ctx.Option.Context, dst); err != nil { + return 0, err + } + return end, nil +} + +func decodeStreamTextUnmarshaler(s *Stream, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) error { + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return nil + } + + dst := make([]byte, len(src)) + copy(dst, src) + + if err := unmarshaler.UnmarshalText(dst); err != nil { + return err + } + return nil +} + +func decodeTextUnmarshaler(buf []byte, cursor, depth int64, unmarshaler encoding.TextUnmarshaler, p unsafe.Pointer) (int64, error) { + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return end, nil + } + if s, ok := unquoteBytes(src); ok { + src = s + } + if err := unmarshaler.UnmarshalText(src); err != nil { + return 0, err + } + return end, nil +} + +func (d *interfaceDecoder) decodeStreamEmptyInterface(s *Stream, depth int64, p unsafe.Pointer) error { + c := s.skipWhiteSpace() + for { + switch c { + case '{': + var v map[string]interface{} + ptr := unsafe.Pointer(&v) + if err := d.mapDecoder.DecodeStream(s, depth, ptr); err != nil { + return err + } + *(*interface{})(p) = v + return nil + case '[': + var v []interface{} + ptr := unsafe.Pointer(&v) + if err := d.sliceDecoder.DecodeStream(s, depth, ptr); err != nil { + return err + } + *(*interface{})(p) = v + return nil + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.numDecoder(s).DecodeStream(s, depth, p) + case '"': + s.cursor++ + start := s.cursor + for { + switch s.char() { + case '\\': + if _, err := decodeEscapeString(s, nil); err != nil { + return err + } + case '"': + literal := s.buf[start:s.cursor] + s.cursor++ + *(*interface{})(p) = string(literal) + return nil + case nul: + if s.read() { + continue + } + return errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + s.cursor++ + } + case 't': + if err := trueBytes(s); err != nil { + return err + } + **(**interface{})(unsafe.Pointer(&p)) = true + return nil + case 'f': + if err := falseBytes(s); err != nil { + return err + } + **(**interface{})(unsafe.Pointer(&p)) = false + return nil + case 'n': + if err := nullBytes(s); err != nil { + return err + } + *(*interface{})(p) = nil + return nil + case nul: + if s.read() { + c = s.char() + continue + } + } + break + } + return errors.ErrNotAtBeginningOfValue(s.totalOffset()) +} + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func (d *interfaceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + rv := reflect.ValueOf(runtimeInterfaceValue) + if rv.NumMethod() > 0 && rv.CanInterface() { + if u, ok := rv.Interface().(unmarshalerContext); ok { + return decodeStreamUnmarshalerContext(s, depth, u) + } + if u, ok := rv.Interface().(json.Unmarshaler); ok { + return decodeStreamUnmarshaler(s, depth, u) + } + if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { + return decodeStreamTextUnmarshaler(s, depth, u, p) + } + if s.skipWhiteSpace() == 'n' { + if err := nullBytes(s); err != nil { + return err + } + *(*interface{})(p) = nil + return nil + } + return d.errUnmarshalType(rv.Type(), s.totalOffset()) + } + iface := rv.Interface() + ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) + typ := ifaceHeader.typ + if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { + // concrete type is empty interface + return d.decodeStreamEmptyInterface(s, depth, p) + } + if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { + return d.decodeStreamEmptyInterface(s, depth, p) + } + if s.skipWhiteSpace() == 'n' { + if err := nullBytes(s); err != nil { + return err + } + *(*interface{})(p) = nil + return nil + } + decoder, err := CompileToGetDecoder(typ) + if err != nil { + return err + } + return decoder.DecodeStream(s, depth, ifaceHeader.ptr) +} + +func (d *interfaceDecoder) errUnmarshalType(typ reflect.Type, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: typ.String(), + Type: typ, + Offset: offset, + Struct: d.structName, + Field: d.fieldName, + } +} + +func (d *interfaceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + runtimeInterfaceValue := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + rv := reflect.ValueOf(runtimeInterfaceValue) + if rv.NumMethod() > 0 && rv.CanInterface() { + if u, ok := rv.Interface().(unmarshalerContext); ok { + return decodeUnmarshalerContext(ctx, buf, cursor, depth, u) + } + if u, ok := rv.Interface().(json.Unmarshaler); ok { + return decodeUnmarshaler(buf, cursor, depth, u) + } + if u, ok := rv.Interface().(encoding.TextUnmarshaler); ok { + return decodeTextUnmarshaler(buf, cursor, depth, u, p) + } + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == 'n' { + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = nil + return cursor, nil + } + return 0, d.errUnmarshalType(rv.Type(), cursor) + } + + iface := rv.Interface() + ifaceHeader := (*emptyInterface)(unsafe.Pointer(&iface)) + typ := ifaceHeader.typ + if ifaceHeader.ptr == nil || d.typ == typ || typ == nil { + // concrete type is empty interface + return d.decodeEmptyInterface(ctx, cursor, depth, p) + } + if typ.Kind() == reflect.Ptr && typ.Elem() == d.typ || typ.Kind() != reflect.Ptr { + return d.decodeEmptyInterface(ctx, cursor, depth, p) + } + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == 'n' { + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = nil + return cursor, nil + } + decoder, err := CompileToGetDecoder(typ) + if err != nil { + return 0, err + } + return decoder.Decode(ctx, cursor, depth, ifaceHeader.ptr) +} + +func (d *interfaceDecoder) decodeEmptyInterface(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case '{': + var v map[string]interface{} + ptr := unsafe.Pointer(&v) + cursor, err := d.mapDecoder.Decode(ctx, cursor, depth, ptr) + if err != nil { + return 0, err + } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil + case '[': + var v []interface{} + ptr := unsafe.Pointer(&v) + cursor, err := d.sliceDecoder.Decode(ctx, cursor, depth, ptr) + if err != nil { + return 0, err + } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.floatDecoder.Decode(ctx, cursor, depth, p) + case '"': + var v string + ptr := unsafe.Pointer(&v) + cursor, err := d.stringDecoder.Decode(ctx, cursor, depth, ptr) + if err != nil { + return 0, err + } + **(**interface{})(unsafe.Pointer(&p)) = v + return cursor, nil + case 't': + if err := validateTrue(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = true + return cursor, nil + case 'f': + if err := validateFalse(buf, cursor); err != nil { + return 0, err + } + cursor += 5 + **(**interface{})(unsafe.Pointer(&p)) = false + return cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**interface{})(unsafe.Pointer(&p)) = nil + return cursor, nil + } + return cursor, errors.ErrNotAtBeginningOfValue(cursor) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/map.go b/vendor/github.com/goccy/go-json/internal/decoder/map.go new file mode 100644 index 000000000..dd480e168 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/map.go @@ -0,0 +1,173 @@ +package decoder + +import ( + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type mapDecoder struct { + mapType *runtime.Type + keyType *runtime.Type + valueType *runtime.Type + stringKeyType bool + keyDecoder Decoder + valueDecoder Decoder + structName string + fieldName string +} + +func newMapDecoder(mapType *runtime.Type, keyType *runtime.Type, keyDec Decoder, valueType *runtime.Type, valueDec Decoder, structName, fieldName string) *mapDecoder { + return &mapDecoder{ + mapType: mapType, + keyDecoder: keyDec, + keyType: keyType, + stringKeyType: keyType.Kind() == reflect.String, + valueType: valueType, + valueDecoder: valueDec, + structName: structName, + fieldName: fieldName, + } +} + +//go:linkname makemap reflect.makemap +func makemap(*runtime.Type, int) unsafe.Pointer + +//nolint:golint +//go:linkname mapassign_faststr runtime.mapassign_faststr +//go:noescape +func mapassign_faststr(t *runtime.Type, m unsafe.Pointer, s string) unsafe.Pointer + +//go:linkname mapassign reflect.mapassign +//go:noescape +func mapassign(t *runtime.Type, m unsafe.Pointer, k, v unsafe.Pointer) + +func (d *mapDecoder) mapassign(t *runtime.Type, m, k, v unsafe.Pointer) { + if d.stringKeyType { + mapV := mapassign_faststr(d.mapType, m, *(*string)(k)) + typedmemmove(d.valueType, mapV, v) + } else { + mapassign(t, m, k, v) + } +} + +func (d *mapDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + switch s.skipWhiteSpace() { + case 'n': + if err := nullBytes(s); err != nil { + return err + } + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil + return nil + case '{': + default: + return errors.ErrExpected("{ character for map value", s.totalOffset()) + } + mapValue := *(*unsafe.Pointer)(p) + if mapValue == nil { + mapValue = makemap(d.mapType, 0) + } + if s.buf[s.cursor+1] == '}' { + *(*unsafe.Pointer)(p) = mapValue + s.cursor += 2 + return nil + } + for { + s.cursor++ + k := unsafe_New(d.keyType) + if err := d.keyDecoder.DecodeStream(s, depth, k); err != nil { + return err + } + s.skipWhiteSpace() + if !s.equalChar(':') { + return errors.ErrExpected("colon after object key", s.totalOffset()) + } + s.cursor++ + v := unsafe_New(d.valueType) + if err := d.valueDecoder.DecodeStream(s, depth, v); err != nil { + return err + } + d.mapassign(d.mapType, mapValue, k, v) + s.skipWhiteSpace() + if s.equalChar('}') { + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue + s.cursor++ + return nil + } + if !s.equalChar(',') { + return errors.ErrExpected("comma after object value", s.totalOffset()) + } + } +} + +func (d *mapDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + cursor = skipWhiteSpace(buf, cursor) + buflen := int64(len(buf)) + if buflen < 2 { + return 0, errors.ErrExpected("{} for map", cursor) + } + switch buf[cursor] { + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = nil + return cursor, nil + case '{': + default: + return 0, errors.ErrExpected("{ character for map value", cursor) + } + cursor++ + cursor = skipWhiteSpace(buf, cursor) + mapValue := *(*unsafe.Pointer)(p) + if mapValue == nil { + mapValue = makemap(d.mapType, 0) + } + if buf[cursor] == '}' { + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue + cursor++ + return cursor, nil + } + for { + k := unsafe_New(d.keyType) + keyCursor, err := d.keyDecoder.Decode(ctx, cursor, depth, k) + if err != nil { + return 0, err + } + cursor = skipWhiteSpace(buf, keyCursor) + if buf[cursor] != ':' { + return 0, errors.ErrExpected("colon after object key", cursor) + } + cursor++ + v := unsafe_New(d.valueType) + valueCursor, err := d.valueDecoder.Decode(ctx, cursor, depth, v) + if err != nil { + return 0, err + } + d.mapassign(d.mapType, mapValue, k, v) + cursor = skipWhiteSpace(buf, valueCursor) + if buf[cursor] == '}' { + **(**unsafe.Pointer)(unsafe.Pointer(&p)) = mapValue + cursor++ + return cursor, nil + } + if buf[cursor] != ',' { + return 0, errors.ErrExpected("comma after object value", cursor) + } + cursor++ + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/number.go b/vendor/github.com/goccy/go-json/internal/decoder/number.go new file mode 100644 index 000000000..c50d62b99 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/number.go @@ -0,0 +1,108 @@ +package decoder + +import ( + "encoding/json" + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type numberDecoder struct { + stringDecoder *stringDecoder + op func(unsafe.Pointer, json.Number) + structName string + fieldName string +} + +func newNumberDecoder(structName, fieldName string, op func(unsafe.Pointer, json.Number)) *numberDecoder { + return &numberDecoder{ + stringDecoder: newStringDecoder(structName, fieldName), + op: op, + structName: structName, + fieldName: fieldName, + } +} + +func (d *numberDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil { + return errors.ErrSyntax(err.Error(), s.totalOffset()) + } + d.op(p, json.Number(string(bytes))) + s.reset() + return nil +} + +func (d *numberDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&bytes)), 64); err != nil { + return 0, errors.ErrSyntax(err.Error(), c) + } + cursor = c + s := *(*string)(unsafe.Pointer(&bytes)) + d.op(p, json.Number(s)) + return cursor, nil +} + +func (d *numberDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return floatBytes(s), nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case '"': + return d.stringDecoder.decodeStreamByte(s) + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("json.Number", s.totalOffset()) +} + +func (d *numberDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for floatTable[buf[cursor]] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + case '"': + return d.stringDecoder.decodeByte(buf, cursor) + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("json.Number", cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/option.go b/vendor/github.com/goccy/go-json/internal/decoder/option.go new file mode 100644 index 000000000..e41f876b0 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/option.go @@ -0,0 +1,15 @@ +package decoder + +import "context" + +type OptionFlags uint8 + +const ( + FirstWinOption OptionFlags = 1 << iota + ContextOption +) + +type Option struct { + Flags OptionFlags + Context context.Context +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/ptr.go b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go new file mode 100644 index 000000000..2c83b9c44 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/ptr.go @@ -0,0 +1,87 @@ +package decoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type ptrDecoder struct { + dec Decoder + typ *runtime.Type + structName string + fieldName string +} + +func newPtrDecoder(dec Decoder, typ *runtime.Type, structName, fieldName string) *ptrDecoder { + return &ptrDecoder{ + dec: dec, + typ: typ, + structName: structName, + fieldName: fieldName, + } +} + +func (d *ptrDecoder) contentDecoder() Decoder { + dec, ok := d.dec.(*ptrDecoder) + if !ok { + return d.dec + } + return dec.contentDecoder() +} + +//nolint:golint +//go:linkname unsafe_New reflect.unsafe_New +func unsafe_New(*runtime.Type) unsafe.Pointer + +func (d *ptrDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + if s.skipWhiteSpace() == nul { + s.read() + } + if s.char() == 'n' { + if err := nullBytes(s); err != nil { + return err + } + *(*unsafe.Pointer)(p) = nil + return nil + } + var newptr unsafe.Pointer + if *(*unsafe.Pointer)(p) == nil { + newptr = unsafe_New(d.typ) + *(*unsafe.Pointer)(p) = newptr + } else { + newptr = *(*unsafe.Pointer)(p) + } + if err := d.dec.DecodeStream(s, depth, newptr); err != nil { + return err + } + return nil +} + +func (d *ptrDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == 'n' { + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + if p != nil { + *(*unsafe.Pointer)(p) = nil + } + cursor += 4 + return cursor, nil + } + var newptr unsafe.Pointer + if *(*unsafe.Pointer)(p) == nil { + newptr = unsafe_New(d.typ) + *(*unsafe.Pointer)(p) = newptr + } else { + newptr = *(*unsafe.Pointer)(p) + } + c, err := d.dec.Decode(ctx, cursor, depth, newptr) + if err != nil { + return 0, err + } + cursor = c + return cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/slice.go b/vendor/github.com/goccy/go-json/internal/decoder/slice.go new file mode 100644 index 000000000..853a555ec --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/slice.go @@ -0,0 +1,294 @@ +package decoder + +import ( + "reflect" + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type sliceDecoder struct { + elemType *runtime.Type + isElemPointerType bool + valueDecoder Decoder + size uintptr + arrayPool sync.Pool + structName string + fieldName string +} + +// If use reflect.SliceHeader, data type is uintptr. +// In this case, Go compiler cannot trace reference created by newArray(). +// So, define using unsafe.Pointer as data type +type sliceHeader struct { + data unsafe.Pointer + len int + cap int +} + +const ( + defaultSliceCapacity = 2 +) + +func newSliceDecoder(dec Decoder, elemType *runtime.Type, size uintptr, structName, fieldName string) *sliceDecoder { + return &sliceDecoder{ + valueDecoder: dec, + elemType: elemType, + isElemPointerType: elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map, + size: size, + arrayPool: sync.Pool{ + New: func() interface{} { + return &sliceHeader{ + data: newArray(elemType, defaultSliceCapacity), + len: 0, + cap: defaultSliceCapacity, + } + }, + }, + structName: structName, + fieldName: fieldName, + } +} + +func (d *sliceDecoder) newSlice(src *sliceHeader) *sliceHeader { + slice := d.arrayPool.Get().(*sliceHeader) + if src.len > 0 { + // copy original elem + if slice.cap < src.cap { + data := newArray(d.elemType, src.cap) + slice = &sliceHeader{data: data, len: src.len, cap: src.cap} + } else { + slice.len = src.len + } + copySlice(d.elemType, *slice, *src) + } else { + slice.len = 0 + } + return slice +} + +func (d *sliceDecoder) releaseSlice(p *sliceHeader) { + d.arrayPool.Put(p) +} + +//go:linkname copySlice reflect.typedslicecopy +func copySlice(elemType *runtime.Type, dst, src sliceHeader) int + +//go:linkname newArray reflect.unsafe_NewArray +func newArray(*runtime.Type, int) unsafe.Pointer + +//go:linkname typedmemmove reflect.typedmemmove +func typedmemmove(t *runtime.Type, dst, src unsafe.Pointer) + +func (d *sliceDecoder) errNumber(offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: "number", + Type: reflect.SliceOf(runtime.RType2Type(d.elemType)), + Struct: d.structName, + Field: d.fieldName, + Offset: offset, + } +} + +func (d *sliceDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case 'n': + if err := nullBytes(s); err != nil { + return err + } + *(*unsafe.Pointer)(p) = nil + return nil + case '[': + s.cursor++ + if s.skipWhiteSpace() == ']' { + dst := (*sliceHeader)(p) + if dst.data == nil { + dst.data = newArray(d.elemType, 0) + } else { + dst.len = 0 + } + s.cursor++ + return nil + } + idx := 0 + slice := d.newSlice((*sliceHeader)(p)) + srcLen := slice.len + capacity := slice.cap + data := slice.data + for { + if capacity <= idx { + src := sliceHeader{data: data, len: idx, cap: capacity} + capacity *= 2 + data = newArray(d.elemType, capacity) + dst := sliceHeader{data: data, len: idx, cap: capacity} + copySlice(d.elemType, dst, src) + } + ep := unsafe.Pointer(uintptr(data) + uintptr(idx)*d.size) + + // if srcLen is greater than idx, keep the original reference + if srcLen <= idx { + if d.isElemPointerType { + **(**unsafe.Pointer)(unsafe.Pointer(&ep)) = nil // initialize elem pointer + } else { + // assign new element to the slice + typedmemmove(d.elemType, ep, unsafe_New(d.elemType)) + } + } + + if err := d.valueDecoder.DecodeStream(s, depth, ep); err != nil { + return err + } + s.skipWhiteSpace() + RETRY: + switch s.char() { + case ']': + slice.cap = capacity + slice.len = idx + 1 + slice.data = data + dst := (*sliceHeader)(p) + dst.len = idx + 1 + if dst.len > dst.cap { + dst.data = newArray(d.elemType, dst.len) + dst.cap = dst.len + } + copySlice(d.elemType, *dst, *slice) + d.releaseSlice(slice) + s.cursor++ + return nil + case ',': + idx++ + case nul: + if s.read() { + goto RETRY + } + slice.cap = capacity + slice.data = data + d.releaseSlice(slice) + goto ERROR + default: + slice.cap = capacity + slice.data = data + d.releaseSlice(slice) + goto ERROR + } + s.cursor++ + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return d.errNumber(s.totalOffset()) + case nul: + if s.read() { + continue + } + goto ERROR + default: + goto ERROR + } + } +ERROR: + return errors.ErrUnexpectedEndOfJSON("slice", s.totalOffset()) +} + +func (d *sliceDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + *(*unsafe.Pointer)(p) = nil + return cursor, nil + case '[': + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == ']' { + dst := (*sliceHeader)(p) + if dst.data == nil { + dst.data = newArray(d.elemType, 0) + } else { + dst.len = 0 + } + cursor++ + return cursor, nil + } + idx := 0 + slice := d.newSlice((*sliceHeader)(p)) + srcLen := slice.len + capacity := slice.cap + data := slice.data + for { + if capacity <= idx { + src := sliceHeader{data: data, len: idx, cap: capacity} + capacity *= 2 + data = newArray(d.elemType, capacity) + dst := sliceHeader{data: data, len: idx, cap: capacity} + copySlice(d.elemType, dst, src) + } + ep := unsafe.Pointer(uintptr(data) + uintptr(idx)*d.size) + // if srcLen is greater than idx, keep the original reference + if srcLen <= idx { + if d.isElemPointerType { + **(**unsafe.Pointer)(unsafe.Pointer(&ep)) = nil // initialize elem pointer + } else { + // assign new element to the slice + typedmemmove(d.elemType, ep, unsafe_New(d.elemType)) + } + } + c, err := d.valueDecoder.Decode(ctx, cursor, depth, ep) + if err != nil { + return 0, err + } + cursor = c + cursor = skipWhiteSpace(buf, cursor) + switch buf[cursor] { + case ']': + slice.cap = capacity + slice.len = idx + 1 + slice.data = data + dst := (*sliceHeader)(p) + dst.len = idx + 1 + if dst.len > dst.cap { + dst.data = newArray(d.elemType, dst.len) + dst.cap = dst.len + } + copySlice(d.elemType, *dst, *slice) + d.releaseSlice(slice) + cursor++ + return cursor, nil + case ',': + idx++ + default: + slice.cap = capacity + slice.data = data + d.releaseSlice(slice) + return 0, errors.ErrInvalidCharacter(buf[cursor], "slice", cursor) + } + cursor++ + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return 0, d.errNumber(cursor) + default: + return 0, errors.ErrUnexpectedEndOfJSON("slice", cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/stream.go b/vendor/github.com/goccy/go-json/internal/decoder/stream.go new file mode 100644 index 000000000..c27468348 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/stream.go @@ -0,0 +1,554 @@ +package decoder + +import ( + "bytes" + "encoding/json" + "io" + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +const ( + initBufSize = 512 +) + +type Stream struct { + buf []byte + bufSize int64 + length int64 + r io.Reader + offset int64 + cursor int64 + filledBuffer bool + allRead bool + UseNumber bool + DisallowUnknownFields bool + Option *Option +} + +func NewStream(r io.Reader) *Stream { + return &Stream{ + r: r, + bufSize: initBufSize, + buf: make([]byte, initBufSize), + Option: &Option{}, + } +} + +func (s *Stream) TotalOffset() int64 { + return s.totalOffset() +} + +func (s *Stream) Buffered() io.Reader { + buflen := int64(len(s.buf)) + for i := s.cursor; i < buflen; i++ { + if s.buf[i] == nul { + return bytes.NewReader(s.buf[s.cursor:i]) + } + } + return bytes.NewReader(s.buf[s.cursor:]) +} + +func (s *Stream) PrepareForDecode() error { + for { + switch s.char() { + case ' ', '\t', '\r', '\n': + s.cursor++ + continue + case ',', ':': + s.cursor++ + return nil + case nul: + if s.read() { + continue + } + return io.EOF + } + break + } + return nil +} + +func (s *Stream) totalOffset() int64 { + return s.offset + s.cursor +} + +func (s *Stream) char() byte { + return s.buf[s.cursor] +} + +func (s *Stream) equalChar(c byte) bool { + cur := s.buf[s.cursor] + if cur == nul { + s.read() + cur = s.buf[s.cursor] + } + return cur == c +} + +func (s *Stream) stat() ([]byte, int64, unsafe.Pointer) { + return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data +} + +func (s *Stream) bufptr() unsafe.Pointer { + return (*sliceHeader)(unsafe.Pointer(&s.buf)).data +} + +func (s *Stream) statForRetry() ([]byte, int64, unsafe.Pointer) { + s.cursor-- // for retry ( because caller progress cursor position in each loop ) + return s.buf, s.cursor, (*sliceHeader)(unsafe.Pointer(&s.buf)).data +} + +func (s *Stream) Reset() { + s.reset() + s.bufSize = initBufSize +} + +func (s *Stream) More() bool { + for { + switch s.char() { + case ' ', '\n', '\r', '\t': + s.cursor++ + continue + case '}', ']': + return false + case nul: + if s.read() { + continue + } + return false + } + break + } + return true +} + +func (s *Stream) Token() (interface{}, error) { + for { + c := s.char() + switch c { + case ' ', '\n', '\r', '\t': + s.cursor++ + case '{', '[', ']', '}': + s.cursor++ + return json.Delim(c), nil + case ',', ':': + s.cursor++ + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + bytes := floatBytes(s) + s := *(*string)(unsafe.Pointer(&bytes)) + f64, err := strconv.ParseFloat(s, 64) + if err != nil { + return nil, err + } + return f64, nil + case '"': + bytes, err := stringBytes(s) + if err != nil { + return nil, err + } + return string(bytes), nil + case 't': + if err := trueBytes(s); err != nil { + return nil, err + } + return true, nil + case 'f': + if err := falseBytes(s); err != nil { + return nil, err + } + return false, nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + goto END + default: + return nil, errors.ErrInvalidCharacter(s.char(), "token", s.totalOffset()) + } + } +END: + return nil, io.EOF +} + +func (s *Stream) reset() { + s.offset += s.cursor + s.buf = s.buf[s.cursor:] + s.length -= s.cursor + s.cursor = 0 +} + +func (s *Stream) readBuf() []byte { + if s.filledBuffer { + s.bufSize *= 2 + remainBuf := s.buf + s.buf = make([]byte, s.bufSize) + copy(s.buf, remainBuf) + } + remainLen := s.length - s.cursor + remainNotNulCharNum := int64(0) + for i := int64(0); i < remainLen; i++ { + if s.buf[s.cursor+i] == nul { + break + } + remainNotNulCharNum++ + } + s.length = s.cursor + remainNotNulCharNum + return s.buf[s.cursor+remainNotNulCharNum:] +} + +func (s *Stream) read() bool { + if s.allRead { + return false + } + buf := s.readBuf() + last := len(buf) - 1 + buf[last] = nul + n, err := s.r.Read(buf[:last]) + s.length += int64(n) + if n == last { + s.filledBuffer = true + } else { + s.filledBuffer = false + } + if err == io.EOF { + s.allRead = true + } else if err != nil { + return false + } + return true +} + +func (s *Stream) skipWhiteSpace() byte { + p := s.bufptr() +LOOP: + c := char(p, s.cursor) + switch c { + case ' ', '\n', '\t', '\r': + s.cursor++ + goto LOOP + case nul: + if s.read() { + p = s.bufptr() + goto LOOP + } + } + return c +} + +func (s *Stream) skipObject(depth int64) error { + braceCount := 1 + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case '{': + braceCount++ + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case '}': + braceCount-- + depth-- + if braceCount == 0 { + s.cursor = cursor + 1 + return nil + } + case '[': + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case ']': + depth-- + case '"': + for { + cursor++ + switch char(p, cursor) { + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("object of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func (s *Stream) skipArray(depth int64) error { + bracketCount := 1 + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case '[': + bracketCount++ + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case ']': + bracketCount-- + depth-- + if bracketCount == 0 { + s.cursor = cursor + 1 + return nil + } + case '{': + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + case '}': + depth-- + case '"': + for { + cursor++ + switch char(p, cursor) { + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + case '"': + goto SWITCH_OUT + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("string of object", cursor) + } + } + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("array of object", cursor) + } + SWITCH_OUT: + cursor++ + } +} + +func (s *Stream) skipValue(depth int64) error { + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return errors.ErrUnexpectedEndOfJSON("value of object", s.totalOffset()) + case '{': + s.cursor = cursor + 1 + return s.skipObject(depth + 1) + case '[': + s.cursor = cursor + 1 + return s.skipArray(depth + 1) + case '"': + for { + cursor++ + switch char(p, cursor) { + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset()) + } + case '"': + s.cursor = cursor + 1 + return nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.statForRetry() + continue + } + return errors.ErrUnexpectedEndOfJSON("value of string", s.totalOffset()) + } + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + for { + cursor++ + c := char(p, cursor) + if floatTable[c] { + continue + } else if c == nul { + if s.read() { + s.cursor-- // for retry current character + _, cursor, p = s.stat() + continue + } + } + s.cursor = cursor + return nil + } + case 't': + s.cursor = cursor + if err := trueBytes(s); err != nil { + return err + } + return nil + case 'f': + s.cursor = cursor + if err := falseBytes(s); err != nil { + return err + } + return nil + case 'n': + s.cursor = cursor + if err := nullBytes(s); err != nil { + return err + } + return nil + } + cursor++ + } +} + +func nullBytes(s *Stream) error { + // current cursor's character is 'n' + s.cursor++ + if s.char() != 'u' { + if err := retryReadNull(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'l' { + if err := retryReadNull(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'l' { + if err := retryReadNull(s); err != nil { + return err + } + } + s.cursor++ + return nil +} + +func retryReadNull(s *Stream) error { + if s.char() == nul && s.read() { + return nil + } + return errors.ErrInvalidCharacter(s.char(), "null", s.totalOffset()) +} + +func trueBytes(s *Stream) error { + // current cursor's character is 't' + s.cursor++ + if s.char() != 'r' { + if err := retryReadTrue(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'u' { + if err := retryReadTrue(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'e' { + if err := retryReadTrue(s); err != nil { + return err + } + } + s.cursor++ + return nil +} + +func retryReadTrue(s *Stream) error { + if s.char() == nul && s.read() { + return nil + } + return errors.ErrInvalidCharacter(s.char(), "bool(true)", s.totalOffset()) +} + +func falseBytes(s *Stream) error { + // current cursor's character is 'f' + s.cursor++ + if s.char() != 'a' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'l' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 's' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + if s.char() != 'e' { + if err := retryReadFalse(s); err != nil { + return err + } + } + s.cursor++ + return nil +} + +func retryReadFalse(s *Stream) error { + if s.char() == nul && s.read() { + return nil + } + return errors.ErrInvalidCharacter(s.char(), "bool(false)", s.totalOffset()) +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/string.go b/vendor/github.com/goccy/go-json/internal/decoder/string.go new file mode 100644 index 000000000..1e1ce157d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/string.go @@ -0,0 +1,361 @@ +package decoder + +import ( + "reflect" + "unicode" + "unicode/utf16" + "unicode/utf8" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type stringDecoder struct { + structName string + fieldName string +} + +func newStringDecoder(structName, fieldName string) *stringDecoder { + return &stringDecoder{ + structName: structName, + fieldName: fieldName, + } +} + +func (d *stringDecoder) errUnmarshalType(typeName string, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: typeName, + Type: reflect.TypeOf(""), + Offset: offset, + Struct: d.structName, + Field: d.fieldName, + } +} + +func (d *stringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes)) + s.reset() + return nil +} + +func (d *stringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes)) + return cursor, nil +} + +var ( + hexToInt = [256]int{ + '0': 0, + '1': 1, + '2': 2, + '3': 3, + '4': 4, + '5': 5, + '6': 6, + '7': 7, + '8': 8, + '9': 9, + 'A': 10, + 'B': 11, + 'C': 12, + 'D': 13, + 'E': 14, + 'F': 15, + 'a': 10, + 'b': 11, + 'c': 12, + 'd': 13, + 'e': 14, + 'f': 15, + } +) + +func unicodeToRune(code []byte) rune { + var r rune + for i := 0; i < len(code); i++ { + r = r*16 + rune(hexToInt[code[i]]) + } + return r +} + +func decodeUnicodeRune(s *Stream, p unsafe.Pointer) (rune, int64, unsafe.Pointer, error) { + const defaultOffset = 5 + const surrogateOffset = 11 + + if s.cursor+defaultOffset >= s.length { + if !s.read() { + return rune(0), 0, nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset()) + } + p = s.bufptr() + } + + r := unicodeToRune(s.buf[s.cursor+1 : s.cursor+defaultOffset]) + if utf16.IsSurrogate(r) { + if s.cursor+surrogateOffset >= s.length { + s.read() + p = s.bufptr() + } + if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor+defaultOffset] != '\\' || s.buf[s.cursor+defaultOffset+1] != 'u' { + return unicode.ReplacementChar, defaultOffset, p, nil + } + r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset]) + if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar { + return r, surrogateOffset, p, nil + } + } + return r, defaultOffset, p, nil +} + +func decodeUnicode(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) { + const backSlashAndULen = 2 // length of \u + + r, offset, pp, err := decodeUnicodeRune(s, p) + if err != nil { + return nil, err + } + unicode := []byte(string(r)) + unicodeLen := int64(len(unicode)) + s.buf = append(append(s.buf[:s.cursor-1], unicode...), s.buf[s.cursor+offset:]...) + unicodeOrgLen := offset - 1 + s.length = s.length - (backSlashAndULen + (unicodeOrgLen - unicodeLen)) + s.cursor = s.cursor - backSlashAndULen + unicodeLen + return pp, nil +} + +func decodeEscapeString(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) { + s.cursor++ +RETRY: + switch s.buf[s.cursor] { + case '"': + s.buf[s.cursor] = '"' + case '\\': + s.buf[s.cursor] = '\\' + case '/': + s.buf[s.cursor] = '/' + case 'b': + s.buf[s.cursor] = '\b' + case 'f': + s.buf[s.cursor] = '\f' + case 'n': + s.buf[s.cursor] = '\n' + case 'r': + s.buf[s.cursor] = '\r' + case 't': + s.buf[s.cursor] = '\t' + case 'u': + return decodeUnicode(s, p) + case nul: + if !s.read() { + return nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset()) + } + goto RETRY + default: + return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + s.buf = append(s.buf[:s.cursor-1], s.buf[s.cursor:]...) + s.length-- + s.cursor-- + return p, nil +} + +var ( + runeErrBytes = []byte(string(utf8.RuneError)) + runeErrBytesLen = int64(len(runeErrBytes)) +) + +func stringBytes(s *Stream) ([]byte, error) { + _, cursor, p := s.stat() + cursor++ // skip double quote char + start := cursor + for { + switch char(p, cursor) { + case '\\': + s.cursor = cursor + pp, err := decodeEscapeString(s, p) + if err != nil { + return nil, err + } + p = pp + cursor = s.cursor + case '"': + literal := s.buf[start:cursor] + cursor++ + s.cursor = cursor + return literal, nil + case + // 0x00 is nul, 0x5c is '\\', 0x22 is '"' . + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0x00-0x0F + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 0x10-0x1F + 0x20, 0x21 /*0x22,*/, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x20-0x2F + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x30-0x3F + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x40-0x4F + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B /*0x5C,*/, 0x5D, 0x5E, 0x5F, // 0x50-0x5F + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x60-0x6F + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F: // 0x70-0x7F + // character is ASCII. skip to next char + case + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // 0x80-0x8F + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, // 0x90-0x9F + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, // 0xA0-0xAF + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, // 0xB0-0xBF + 0xC0, 0xC1, // 0xC0-0xC1 + 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF: // 0xF5-0xFE + // character is invalid + s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...) + _, _, p = s.stat() + cursor += runeErrBytesLen + s.length += runeErrBytesLen + continue + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + goto ERROR + case 0xEF: + // RuneError is {0xEF, 0xBF, 0xBD} + if s.buf[cursor+1] == 0xBF && s.buf[cursor+2] == 0xBD { + // found RuneError: skip + cursor += 2 + break + } + fallthrough + default: + // multi bytes character + r, _ := utf8.DecodeRune(s.buf[cursor:]) + b := []byte(string(r)) + if r == utf8.RuneError { + s.buf = append(append(append([]byte{}, s.buf[:cursor]...), b...), s.buf[cursor+1:]...) + _, _, p = s.stat() + } + cursor += int64(len(b)) + s.length += int64(len(b)) + continue + } + cursor++ + } +ERROR: + return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) +} + +func (d *stringDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '[': + return nil, d.errUnmarshalType("array", s.totalOffset()) + case '{': + return nil, d.errUnmarshalType("object", s.totalOffset()) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return nil, d.errUnmarshalType("number", s.totalOffset()) + case '"': + return stringBytes(s) + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + } + break + } + return nil, errors.ErrNotAtBeginningOfValue(s.totalOffset()) +} + +func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + case '[': + return nil, 0, d.errUnmarshalType("array", cursor) + case '{': + return nil, 0, d.errUnmarshalType("object", cursor) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return nil, 0, d.errUnmarshalType("number", cursor) + case '"': + cursor++ + start := cursor + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case '\\': + cursor++ + switch char(b, cursor) { + case '"': + buf[cursor] = '"' + buf = append(buf[:cursor-1], buf[cursor:]...) + case '\\': + buf[cursor] = '\\' + buf = append(buf[:cursor-1], buf[cursor:]...) + case '/': + buf[cursor] = '/' + buf = append(buf[:cursor-1], buf[cursor:]...) + case 'b': + buf[cursor] = '\b' + buf = append(buf[:cursor-1], buf[cursor:]...) + case 'f': + buf[cursor] = '\f' + buf = append(buf[:cursor-1], buf[cursor:]...) + case 'n': + buf[cursor] = '\n' + buf = append(buf[:cursor-1], buf[cursor:]...) + case 'r': + buf[cursor] = '\r' + buf = append(buf[:cursor-1], buf[cursor:]...) + case 't': + buf[cursor] = '\t' + buf = append(buf[:cursor-1], buf[cursor:]...) + case 'u': + buflen := int64(len(buf)) + if cursor+5 >= buflen { + return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor) + } + code := unicodeToRune(buf[cursor+1 : cursor+5]) + unicode := []byte(string(code)) + buf = append(append(buf[:cursor-1], unicode...), buf[cursor+5:]...) + default: + return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor) + } + continue + case '"': + literal := buf[start:cursor] + cursor++ + return literal, cursor, nil + case nul: + return nil, 0, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + cursor++ + } + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, errors.ErrNotAtBeginningOfValue(cursor) + } + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/struct.go b/vendor/github.com/goccy/go-json/internal/decoder/struct.go new file mode 100644 index 000000000..d467b0d25 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/struct.go @@ -0,0 +1,819 @@ +package decoder + +import ( + "fmt" + "math" + "math/bits" + "sort" + "strings" + "unicode" + "unicode/utf16" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +type structFieldSet struct { + dec Decoder + offset uintptr + isTaggedKey bool + fieldIdx int + key string + keyLen int64 + err error +} + +type structDecoder struct { + fieldMap map[string]*structFieldSet + fieldUniqueNameNum int + stringDecoder *stringDecoder + structName string + fieldName string + isTriedOptimize bool + keyBitmapUint8 [][256]uint8 + keyBitmapUint16 [][256]uint16 + sortedFieldSets []*structFieldSet + keyDecoder func(*structDecoder, []byte, int64) (int64, *structFieldSet, error) + keyStreamDecoder func(*structDecoder, *Stream) (*structFieldSet, string, error) +} + +var ( + largeToSmallTable [256]byte +) + +func init() { + for i := 0; i < 256; i++ { + c := i + if 'A' <= c && c <= 'Z' { + c += 'a' - 'A' + } + largeToSmallTable[i] = byte(c) + } +} + +func newStructDecoder(structName, fieldName string, fieldMap map[string]*structFieldSet) *structDecoder { + return &structDecoder{ + fieldMap: fieldMap, + stringDecoder: newStringDecoder(structName, fieldName), + structName: structName, + fieldName: fieldName, + keyDecoder: decodeKey, + keyStreamDecoder: decodeKeyStream, + } +} + +const ( + allowOptimizeMaxKeyLen = 64 + allowOptimizeMaxFieldLen = 16 +) + +func (d *structDecoder) tryOptimize() { + fieldUniqueNameMap := map[string]int{} + fieldIdx := -1 + for k, v := range d.fieldMap { + lower := strings.ToLower(k) + idx, exists := fieldUniqueNameMap[lower] + if exists { + v.fieldIdx = idx + } else { + fieldIdx++ + v.fieldIdx = fieldIdx + } + fieldUniqueNameMap[lower] = fieldIdx + } + d.fieldUniqueNameNum = len(fieldUniqueNameMap) + + if d.isTriedOptimize { + return + } + fieldMap := map[string]*structFieldSet{} + conflicted := map[string]struct{}{} + for k, v := range d.fieldMap { + key := strings.ToLower(k) + if key != k { + // already exists same key (e.g. Hello and HELLO has same lower case key + if _, exists := conflicted[key]; exists { + d.isTriedOptimize = true + return + } + conflicted[key] = struct{}{} + } + if field, exists := fieldMap[key]; exists { + if field != v { + d.isTriedOptimize = true + return + } + } + fieldMap[key] = v + } + + if len(fieldMap) > allowOptimizeMaxFieldLen { + d.isTriedOptimize = true + return + } + + var maxKeyLen int + sortedKeys := []string{} + for key := range fieldMap { + keyLen := len(key) + if keyLen > allowOptimizeMaxKeyLen { + d.isTriedOptimize = true + return + } + if maxKeyLen < keyLen { + maxKeyLen = keyLen + } + sortedKeys = append(sortedKeys, key) + } + sort.Strings(sortedKeys) + + // By allocating one extra capacity than `maxKeyLen`, + // it is possible to avoid the process of comparing the index of the key with the length of the bitmap each time. + bitmapLen := maxKeyLen + 1 + if len(sortedKeys) <= 8 { + keyBitmap := make([][256]uint8, bitmapLen) + for i, key := range sortedKeys { + for j := 0; j < len(key); j++ { + c := key[j] + keyBitmap[j][c] |= (1 << uint(i)) + } + d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key]) + } + d.keyBitmapUint8 = keyBitmap + d.keyDecoder = decodeKeyByBitmapUint8 + d.keyStreamDecoder = decodeKeyByBitmapUint8Stream + } else { + keyBitmap := make([][256]uint16, bitmapLen) + for i, key := range sortedKeys { + for j := 0; j < len(key); j++ { + c := key[j] + keyBitmap[j][c] |= (1 << uint(i)) + } + d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key]) + } + d.keyBitmapUint16 = keyBitmap + d.keyDecoder = decodeKeyByBitmapUint16 + d.keyStreamDecoder = decodeKeyByBitmapUint16Stream + } +} + +// decode from '\uXXXX' +func decodeKeyCharByUnicodeRune(buf []byte, cursor int64) ([]byte, int64) { + const defaultOffset = 4 + const surrogateOffset = 6 + + r := unicodeToRune(buf[cursor : cursor+defaultOffset]) + if utf16.IsSurrogate(r) { + cursor += defaultOffset + if cursor+surrogateOffset >= int64(len(buf)) || buf[cursor] != '\\' || buf[cursor+1] != 'u' { + return []byte(string(unicode.ReplacementChar)), cursor + defaultOffset - 1 + } + cursor += 2 + r2 := unicodeToRune(buf[cursor : cursor+defaultOffset]) + if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar { + return []byte(string(r)), cursor + defaultOffset - 1 + } + } + return []byte(string(r)), cursor + defaultOffset - 1 +} + +func decodeKeyCharByEscapedChar(buf []byte, cursor int64) ([]byte, int64) { + c := buf[cursor] + cursor++ + switch c { + case '"': + return []byte{'"'}, cursor + case '\\': + return []byte{'\\'}, cursor + case '/': + return []byte{'/'}, cursor + case 'b': + return []byte{'\b'}, cursor + case 'f': + return []byte{'\f'}, cursor + case 'n': + return []byte{'\n'}, cursor + case 'r': + return []byte{'\r'}, cursor + case 't': + return []byte{'\t'}, cursor + case 'u': + return decodeKeyCharByUnicodeRune(buf, cursor) + } + return nil, cursor +} + +func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) { + var ( + curBit uint8 = math.MaxUint8 + ) + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case '"': + cursor++ + c := char(b, cursor) + switch c { + case '"': + cursor++ + return cursor, nil, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + keyIdx := 0 + bitmap := d.keyBitmapUint8 + start := cursor + for { + c := char(b, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros8(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + if keyLen < field.keyLen { + // early match + return cursor, nil, nil + } + return cursor, field, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + case '\\': + cursor++ + chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor) + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor = nextCursor + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor++ + } + default: + return cursor, nil, errors.ErrNotAtBeginningOfValue(cursor) + } + } +} + +func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) { + var ( + curBit uint16 = math.MaxUint16 + ) + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + for { + switch char(b, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case '"': + cursor++ + c := char(b, cursor) + switch c { + case '"': + cursor++ + return cursor, nil, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + keyIdx := 0 + bitmap := d.keyBitmapUint16 + start := cursor + for { + c := char(b, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros16(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + if keyLen < field.keyLen { + // early match + return cursor, nil, nil + } + return cursor, field, nil + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + case '\\': + cursor++ + chars, nextCursor := decodeKeyCharByEscapedChar(buf, cursor) + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor = nextCursor + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + return decodeKeyNotFound(b, cursor) + } + keyIdx++ + } + cursor++ + } + default: + return cursor, nil, errors.ErrNotAtBeginningOfValue(cursor) + } + } +} + +func decodeKeyNotFound(b unsafe.Pointer, cursor int64) (int64, *structFieldSet, error) { + for { + cursor++ + switch char(b, cursor) { + case '"': + cursor++ + return cursor, nil, nil + case '\\': + cursor++ + if char(b, cursor) == nul { + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + case nul: + return 0, nil, errors.ErrUnexpectedEndOfJSON("string", cursor) + } + } +} + +func decodeKey(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) { + key, c, err := d.stringDecoder.decodeByte(buf, cursor) + if err != nil { + return 0, nil, err + } + cursor = c + k := *(*string)(unsafe.Pointer(&key)) + field, exists := d.fieldMap[k] + if !exists { + return cursor, nil, nil + } + return cursor, field, nil +} + +func decodeKeyByBitmapUint8Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) { + var ( + curBit uint8 = math.MaxUint8 + ) + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrNotAtBeginningOfValue(s.totalOffset()) + case '"': + cursor++ + FIRST_CHAR: + start := cursor + switch char(p, cursor) { + case '"': + cursor++ + s.cursor = cursor + return nil, "", nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + goto FIRST_CHAR + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + keyIdx := 0 + bitmap := d.keyBitmapUint8 + for { + c := char(p, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros8(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + s.cursor = cursor + if keyLen < field.keyLen { + // early match + return nil, field.key, nil + } + return field, field.key, nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + case '\\': + s.cursor = cursor + 1 // skip '\' char + chars, err := decodeKeyCharByEscapeCharStream(s) + if err != nil { + return nil, "", err + } + cursor = s.cursor + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + cursor++ + } + default: + return nil, "", errors.ErrNotAtBeginningOfValue(s.totalOffset()) + } + } +} + +func decodeKeyByBitmapUint16Stream(d *structDecoder, s *Stream) (*structFieldSet, string, error) { + var ( + curBit uint16 = math.MaxUint16 + ) + _, cursor, p := s.stat() + for { + switch char(p, cursor) { + case ' ', '\n', '\t', '\r': + cursor++ + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrNotAtBeginningOfValue(s.totalOffset()) + case '"': + cursor++ + FIRST_CHAR: + start := cursor + switch char(p, cursor) { + case '"': + cursor++ + s.cursor = cursor + return nil, "", nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + goto FIRST_CHAR + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + keyIdx := 0 + bitmap := d.keyBitmapUint16 + for { + c := char(p, cursor) + switch c { + case '"': + fieldSetIndex := bits.TrailingZeros16(curBit) + field := d.sortedFieldSets[fieldSetIndex] + keyLen := cursor - start + cursor++ + s.cursor = cursor + if keyLen < field.keyLen { + // early match + return nil, field.key, nil + } + return field, field.key, nil + case nul: + s.cursor = cursor + if s.read() { + _, cursor, p = s.stat() + continue + } + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + case '\\': + s.cursor = cursor + 1 // skip '\' char + chars, err := decodeKeyCharByEscapeCharStream(s) + if err != nil { + return nil, "", err + } + cursor = s.cursor + for _, c := range chars { + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + default: + curBit &= bitmap[keyIdx][largeToSmallTable[c]] + if curBit == 0 { + s.cursor = cursor + return decodeKeyNotFoundStream(s, start) + } + keyIdx++ + } + cursor++ + } + default: + return nil, "", errors.ErrNotAtBeginningOfValue(s.totalOffset()) + } + } +} + +// decode from '\uXXXX' +func decodeKeyCharByUnicodeRuneStream(s *Stream) ([]byte, error) { + const defaultOffset = 4 + const surrogateOffset = 6 + + if s.cursor+defaultOffset >= s.length { + if !s.read() { + return nil, errors.ErrInvalidCharacter(s.char(), "escaped unicode char", s.totalOffset()) + } + } + + r := unicodeToRune(s.buf[s.cursor : s.cursor+defaultOffset]) + if utf16.IsSurrogate(r) { + s.cursor += defaultOffset + if s.cursor+surrogateOffset >= s.length { + s.read() + } + if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor] != '\\' || s.buf[s.cursor+1] != 'u' { + s.cursor += defaultOffset - 1 + return []byte(string(unicode.ReplacementChar)), nil + } + r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset]) + if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar { + s.cursor += defaultOffset - 1 + return []byte(string(r)), nil + } + } + s.cursor += defaultOffset - 1 + return []byte(string(r)), nil +} + +func decodeKeyCharByEscapeCharStream(s *Stream) ([]byte, error) { + c := s.buf[s.cursor] + s.cursor++ +RETRY: + switch c { + case '"': + return []byte{'"'}, nil + case '\\': + return []byte{'\\'}, nil + case '/': + return []byte{'/'}, nil + case 'b': + return []byte{'\b'}, nil + case 'f': + return []byte{'\f'}, nil + case 'n': + return []byte{'\n'}, nil + case 'r': + return []byte{'\r'}, nil + case 't': + return []byte{'\t'}, nil + case 'u': + return decodeKeyCharByUnicodeRuneStream(s) + case nul: + if !s.read() { + return nil, errors.ErrInvalidCharacter(s.char(), "escaped char", s.totalOffset()) + } + goto RETRY + default: + return nil, errors.ErrUnexpectedEndOfJSON("struct field", s.totalOffset()) + } +} + +func decodeKeyNotFoundStream(s *Stream, start int64) (*structFieldSet, string, error) { + buf, cursor, p := s.stat() + for { + cursor++ + switch char(p, cursor) { + case '"': + b := buf[start:cursor] + key := *(*string)(unsafe.Pointer(&b)) + cursor++ + s.cursor = cursor + return nil, key, nil + case '\\': + cursor++ + if char(p, cursor) == nul { + s.cursor = cursor + if !s.read() { + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + buf, cursor, p = s.statForRetry() + } + case nul: + s.cursor = cursor + if !s.read() { + return nil, "", errors.ErrUnexpectedEndOfJSON("string", s.totalOffset()) + } + buf, cursor, p = s.statForRetry() + } + } +} + +func decodeKeyStream(d *structDecoder, s *Stream) (*structFieldSet, string, error) { + key, err := d.stringDecoder.decodeStreamByte(s) + if err != nil { + return nil, "", err + } + k := *(*string)(unsafe.Pointer(&key)) + return d.fieldMap[k], k, nil +} + +func (d *structDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + depth++ + if depth > maxDecodeNestingDepth { + return errors.ErrExceededMaxDepth(s.char(), s.cursor) + } + + c := s.skipWhiteSpace() + switch c { + case 'n': + if err := nullBytes(s); err != nil { + return err + } + return nil + default: + if s.char() != '{' { + return errors.ErrNotAtBeginningOfValue(s.totalOffset()) + } + } + s.cursor++ + if s.skipWhiteSpace() == '}' { + s.cursor++ + return nil + } + var ( + seenFields map[int]struct{} + seenFieldNum int + ) + firstWin := (s.Option.Flags & FirstWinOption) != 0 + if firstWin { + seenFields = make(map[int]struct{}, d.fieldUniqueNameNum) + } + for { + s.reset() + field, key, err := d.keyStreamDecoder(d, s) + if err != nil { + return err + } + if s.skipWhiteSpace() != ':' { + return errors.ErrExpected("colon after object key", s.totalOffset()) + } + s.cursor++ + if field != nil { + if field.err != nil { + return field.err + } + if firstWin { + if _, exists := seenFields[field.fieldIdx]; exists { + if err := s.skipValue(depth); err != nil { + return err + } + } else { + if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil { + return err + } + seenFieldNum++ + if d.fieldUniqueNameNum <= seenFieldNum { + return s.skipObject(depth) + } + seenFields[field.fieldIdx] = struct{}{} + } + } else { + if err := field.dec.DecodeStream(s, depth, unsafe.Pointer(uintptr(p)+field.offset)); err != nil { + return err + } + } + } else if s.DisallowUnknownFields { + return fmt.Errorf("json: unknown field %q", key) + } else { + if err := s.skipValue(depth); err != nil { + return err + } + } + c := s.skipWhiteSpace() + if c == '}' { + s.cursor++ + return nil + } + if c != ',' { + return errors.ErrExpected("comma after object element", s.totalOffset()) + } + s.cursor++ + } +} + +func (d *structDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + depth++ + if depth > maxDecodeNestingDepth { + return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor) + } + buflen := int64(len(buf)) + cursor = skipWhiteSpace(buf, cursor) + b := (*sliceHeader)(unsafe.Pointer(&buf)).data + switch char(b, cursor) { + case 'n': + if err := validateNull(buf, cursor); err != nil { + return 0, err + } + cursor += 4 + return cursor, nil + case '{': + default: + return 0, errors.ErrNotAtBeginningOfValue(cursor) + } + cursor++ + cursor = skipWhiteSpace(buf, cursor) + if buf[cursor] == '}' { + cursor++ + return cursor, nil + } + var ( + seenFields map[int]struct{} + seenFieldNum int + ) + firstWin := (ctx.Option.Flags & FirstWinOption) != 0 + if firstWin { + seenFields = make(map[int]struct{}, d.fieldUniqueNameNum) + } + for { + c, field, err := d.keyDecoder(d, buf, cursor) + if err != nil { + return 0, err + } + cursor = skipWhiteSpace(buf, c) + if char(b, cursor) != ':' { + return 0, errors.ErrExpected("colon after object key", cursor) + } + cursor++ + if cursor >= buflen { + return 0, errors.ErrExpected("object value after colon", cursor) + } + if field != nil { + if field.err != nil { + return 0, field.err + } + if firstWin { + if _, exists := seenFields[field.fieldIdx]; exists { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + cursor = c + } else { + c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset)) + if err != nil { + return 0, err + } + cursor = c + seenFieldNum++ + if d.fieldUniqueNameNum <= seenFieldNum { + return skipObject(buf, cursor, depth) + } + seenFields[field.fieldIdx] = struct{}{} + } + } else { + c, err := field.dec.Decode(ctx, cursor, depth, unsafe.Pointer(uintptr(p)+field.offset)) + if err != nil { + return 0, err + } + cursor = c + } + } else { + c, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + cursor = c + } + cursor = skipWhiteSpace(buf, cursor) + if char(b, cursor) == '}' { + cursor++ + return cursor, nil + } + if char(b, cursor) != ',' { + return 0, errors.ErrExpected("comma after object element", cursor) + } + cursor++ + } +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/type.go b/vendor/github.com/goccy/go-json/internal/decoder/type.go new file mode 100644 index 000000000..70e9907c8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/type.go @@ -0,0 +1,29 @@ +package decoder + +import ( + "context" + "encoding" + "encoding/json" + "reflect" + "unsafe" +) + +type Decoder interface { + Decode(*RuntimeContext, int64, int64, unsafe.Pointer) (int64, error) + DecodeStream(*Stream, int64, unsafe.Pointer) error +} + +const ( + nul = '\000' + maxDecodeNestingDepth = 10000 +) + +type unmarshalerContext interface { + UnmarshalJSON(context.Context, []byte) error +} + +var ( + unmarshalJSONType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem() + unmarshalJSONContextType = reflect.TypeOf((*unmarshalerContext)(nil)).Elem() + unmarshalTextType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) diff --git a/vendor/github.com/goccy/go-json/internal/decoder/uint.go b/vendor/github.com/goccy/go-json/internal/decoder/uint.go new file mode 100644 index 000000000..a62c51492 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/uint.go @@ -0,0 +1,190 @@ +package decoder + +import ( + "fmt" + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type uintDecoder struct { + typ *runtime.Type + kind reflect.Kind + op func(unsafe.Pointer, uint64) + structName string + fieldName string +} + +func newUintDecoder(typ *runtime.Type, structName, fieldName string, op func(unsafe.Pointer, uint64)) *uintDecoder { + return &uintDecoder{ + typ: typ, + kind: typ.Kind(), + op: op, + structName: structName, + fieldName: fieldName, + } +} + +func (d *uintDecoder) typeError(buf []byte, offset int64) *errors.UnmarshalTypeError { + return &errors.UnmarshalTypeError{ + Value: fmt.Sprintf("number %s", string(buf)), + Type: runtime.RType2Type(d.typ), + Offset: offset, + } +} + +var ( + pow10u64 = [...]uint64{ + 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + } + pow10u64Len = len(pow10u64) +) + +func (d *uintDecoder) parseUint(b []byte) (uint64, error) { + maxDigit := len(b) + if maxDigit > pow10u64Len { + return 0, fmt.Errorf("invalid length of number") + } + sum := uint64(0) + for i := 0; i < maxDigit; i++ { + c := uint64(b[i]) - 48 + digitValue := pow10u64[maxDigit-i-1] + sum += c * digitValue + } + return sum, nil +} + +func (d *uintDecoder) decodeStreamByte(s *Stream) ([]byte, error) { + for { + switch s.char() { + case ' ', '\n', '\t', '\r': + s.cursor++ + continue + case '0': + s.cursor++ + return numZeroBuf, nil + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := s.cursor + for { + s.cursor++ + if numTable[s.char()] { + continue + } else if s.char() == nul { + if s.read() { + s.cursor-- // for retry current character + continue + } + } + break + } + num := s.buf[start:s.cursor] + return num, nil + case 'n': + if err := nullBytes(s); err != nil { + return nil, err + } + return nil, nil + case nul: + if s.read() { + continue + } + default: + return nil, d.typeError([]byte{s.char()}, s.totalOffset()) + } + break + } + return nil, errors.ErrUnexpectedEndOfJSON("number(unsigned integer)", s.totalOffset()) +} + +func (d *uintDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) { + for { + switch buf[cursor] { + case ' ', '\n', '\t', '\r': + cursor++ + continue + case '0': + cursor++ + return numZeroBuf, cursor, nil + case '1', '2', '3', '4', '5', '6', '7', '8', '9': + start := cursor + cursor++ + for numTable[buf[cursor]] { + cursor++ + } + num := buf[start:cursor] + return num, cursor, nil + case 'n': + if err := validateNull(buf, cursor); err != nil { + return nil, 0, err + } + cursor += 4 + return nil, cursor, nil + default: + return nil, 0, d.typeError([]byte{buf[cursor]}, cursor) + } + } +} + +func (d *uintDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + return nil + } + u64, err := d.parseUint(bytes) + if err != nil { + return d.typeError(bytes, s.totalOffset()) + } + switch d.kind { + case reflect.Uint8: + if (1 << 8) <= u64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Uint16: + if (1 << 16) <= u64 { + return d.typeError(bytes, s.totalOffset()) + } + case reflect.Uint32: + if (1 << 32) <= u64 { + return d.typeError(bytes, s.totalOffset()) + } + } + d.op(p, u64) + return nil +} + +func (d *uintDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + return c, nil + } + cursor = c + u64, err := d.parseUint(bytes) + if err != nil { + return 0, d.typeError(bytes, cursor) + } + switch d.kind { + case reflect.Uint8: + if (1 << 8) <= u64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Uint16: + if (1 << 16) <= u64 { + return 0, d.typeError(bytes, cursor) + } + case reflect.Uint32: + if (1 << 32) <= u64 { + return 0, d.typeError(bytes, cursor) + } + } + d.op(p, u64) + return cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go new file mode 100644 index 000000000..d90f39cc5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_json.go @@ -0,0 +1,91 @@ +package decoder + +import ( + "encoding/json" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type unmarshalJSONDecoder struct { + typ *runtime.Type + structName string + fieldName string +} + +func newUnmarshalJSONDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalJSONDecoder { + return &unmarshalJSONDecoder{ + typ: typ, + structName: structName, + fieldName: fieldName, + } +} + +func (d *unmarshalJSONDecoder) annotateError(cursor int64, err error) { + switch e := err.(type) { + case *errors.UnmarshalTypeError: + e.Struct = d.structName + e.Field = d.fieldName + case *errors.SyntaxError: + e.Offset = cursor + } +} + +func (d *unmarshalJSONDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + s.skipWhiteSpace() + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + dst := make([]byte, len(src)) + copy(dst, src) + + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + if (s.Option.Flags & ContextOption) != 0 { + if err := v.(unmarshalerContext).UnmarshalJSON(s.Option.Context, dst); err != nil { + d.annotateError(s.cursor, err) + return err + } + } else { + if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil { + d.annotateError(s.cursor, err) + return err + } + } + return nil +} + +func (d *unmarshalJSONDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + dst := make([]byte, len(src)) + copy(dst, src) + + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + if (ctx.Option.Flags & ContextOption) != 0 { + if err := v.(unmarshalerContext).UnmarshalJSON(ctx.Option.Context, dst); err != nil { + d.annotateError(cursor, err) + return 0, err + } + } else { + if err := v.(json.Unmarshaler).UnmarshalJSON(dst); err != nil { + d.annotateError(cursor, err) + return 0, err + } + } + return end, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go new file mode 100644 index 000000000..1ef287782 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/unmarshal_text.go @@ -0,0 +1,280 @@ +package decoder + +import ( + "bytes" + "encoding" + "unicode" + "unicode/utf16" + "unicode/utf8" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type unmarshalTextDecoder struct { + typ *runtime.Type + structName string + fieldName string +} + +func newUnmarshalTextDecoder(typ *runtime.Type, structName, fieldName string) *unmarshalTextDecoder { + return &unmarshalTextDecoder{ + typ: typ, + structName: structName, + fieldName: fieldName, + } +} + +func (d *unmarshalTextDecoder) annotateError(cursor int64, err error) { + switch e := err.(type) { + case *errors.UnmarshalTypeError: + e.Struct = d.structName + e.Field = d.fieldName + case *errors.SyntaxError: + e.Offset = cursor + } +} + +var ( + nullbytes = []byte(`null`) +) + +func (d *unmarshalTextDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + s.skipWhiteSpace() + start := s.cursor + if err := s.skipValue(depth); err != nil { + return err + } + src := s.buf[start:s.cursor] + if len(src) > 0 { + switch src[0] { + case '[': + return &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '{': + return &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: s.totalOffset(), + } + case 'n': + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return nil + } + } + } + dst := make([]byte, len(src)) + copy(dst, src) + + if b, ok := unquoteBytes(dst); ok { + dst = b + } + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: p, + })) + if err := v.(encoding.TextUnmarshaler).UnmarshalText(dst); err != nil { + d.annotateError(s.cursor, err) + return err + } + return nil +} + +func (d *unmarshalTextDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + buf := ctx.Buf + cursor = skipWhiteSpace(buf, cursor) + start := cursor + end, err := skipValue(buf, cursor, depth) + if err != nil { + return 0, err + } + src := buf[start:end] + if len(src) > 0 { + switch src[0] { + case '[': + return 0, &errors.UnmarshalTypeError{ + Value: "array", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '{': + return 0, &errors.UnmarshalTypeError{ + Value: "object", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return 0, &errors.UnmarshalTypeError{ + Value: "number", + Type: runtime.RType2Type(d.typ), + Offset: start, + } + case 'n': + if bytes.Equal(src, nullbytes) { + *(*unsafe.Pointer)(p) = nil + return end, nil + } + } + } + + if s, ok := unquoteBytes(src); ok { + src = s + } + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: d.typ, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) + if err := v.(encoding.TextUnmarshaler).UnmarshalText(src); err != nil { + d.annotateError(cursor, err) + return 0, err + } + return end, nil +} + +func unquoteBytes(s []byte) (t []byte, ok bool) { + length := len(s) + if length < 2 || s[0] != '"' || s[length-1] != '"' { + return + } + s = s[1 : length-1] + length -= 2 + + // Check for unusual characters. If there are none, + // then no unquoting is needed, so return a slice of the + // original bytes. + r := 0 + for r < length { + c := s[r] + if c == '\\' || c == '"' || c < ' ' { + break + } + if c < utf8.RuneSelf { + r++ + continue + } + rr, size := utf8.DecodeRune(s[r:]) + if rr == utf8.RuneError && size == 1 { + break + } + r += size + } + if r == length { + return s, true + } + + b := make([]byte, length+2*utf8.UTFMax) + w := copy(b, s[0:r]) + for r < length { + // Out of room? Can only happen if s is full of + // malformed UTF-8 and we're replacing each + // byte with RuneError. + if w >= len(b)-2*utf8.UTFMax { + nb := make([]byte, (len(b)+utf8.UTFMax)*2) + copy(nb, b[0:w]) + b = nb + } + switch c := s[r]; { + case c == '\\': + r++ + if r >= length { + return + } + switch s[r] { + default: + return + case '"', '\\', '/', '\'': + b[w] = s[r] + r++ + w++ + case 'b': + b[w] = '\b' + r++ + w++ + case 'f': + b[w] = '\f' + r++ + w++ + case 'n': + b[w] = '\n' + r++ + w++ + case 'r': + b[w] = '\r' + r++ + w++ + case 't': + b[w] = '\t' + r++ + w++ + case 'u': + r-- + rr := getu4(s[r:]) + if rr < 0 { + return + } + r += 6 + if utf16.IsSurrogate(rr) { + rr1 := getu4(s[r:]) + if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar { + // A valid pair; consume. + r += 6 + w += utf8.EncodeRune(b[w:], dec) + break + } + // Invalid surrogate; fall back to replacement rune. + rr = unicode.ReplacementChar + } + w += utf8.EncodeRune(b[w:], rr) + } + + // Quote, control characters are invalid. + case c == '"', c < ' ': + return + + // ASCII + case c < utf8.RuneSelf: + b[w] = c + r++ + w++ + + // Coerce to well-formed UTF-8. + default: + rr, size := utf8.DecodeRune(s[r:]) + r += size + w += utf8.EncodeRune(b[w:], rr) + } + } + return b[0:w], true +} + +func getu4(s []byte) rune { + if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { + return -1 + } + var r rune + for _, c := range s[2:6] { + switch { + case '0' <= c && c <= '9': + c = c - '0' + case 'a' <= c && c <= 'f': + c = c - 'a' + 10 + case 'A' <= c && c <= 'F': + c = c - 'A' + 10 + default: + return -1 + } + r = r*16 + rune(c) + } + return r +} diff --git a/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go new file mode 100644 index 000000000..66227ae02 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/decoder/wrapped_string.go @@ -0,0 +1,68 @@ +package decoder + +import ( + "reflect" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type wrappedStringDecoder struct { + typ *runtime.Type + dec Decoder + stringDecoder *stringDecoder + structName string + fieldName string + isPtrType bool +} + +func newWrappedStringDecoder(typ *runtime.Type, dec Decoder, structName, fieldName string) *wrappedStringDecoder { + return &wrappedStringDecoder{ + typ: typ, + dec: dec, + stringDecoder: newStringDecoder(structName, fieldName), + structName: structName, + fieldName: fieldName, + isPtrType: typ.Kind() == reflect.Ptr, + } +} + +func (d *wrappedStringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error { + bytes, err := d.stringDecoder.decodeStreamByte(s) + if err != nil { + return err + } + if bytes == nil { + if d.isPtrType { + *(*unsafe.Pointer)(p) = nil + } + return nil + } + b := make([]byte, len(bytes)+1) + copy(b, bytes) + if _, err := d.dec.Decode(&RuntimeContext{Buf: b}, 0, depth, p); err != nil { + return err + } + return nil +} + +func (d *wrappedStringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) { + bytes, c, err := d.stringDecoder.decodeByte(ctx.Buf, cursor) + if err != nil { + return 0, err + } + if bytes == nil { + if d.isPtrType { + *(*unsafe.Pointer)(p) = nil + } + return c, nil + } + bytes = append(bytes, nul) + oldBuf := ctx.Buf + ctx.Buf = bytes + if _, err := d.dec.Decode(ctx, 0, depth, p); err != nil { + return 0, err + } + ctx.Buf = oldBuf + return c, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compact.go b/vendor/github.com/goccy/go-json/internal/encoder/compact.go new file mode 100644 index 000000000..0eb9545d8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compact.go @@ -0,0 +1,286 @@ +package encoder + +import ( + "bytes" + "fmt" + "strconv" + "unsafe" + + "github.com/goccy/go-json/internal/errors" +) + +var ( + isWhiteSpace = [256]bool{ + ' ': true, + '\n': true, + '\t': true, + '\r': true, + } + isHTMLEscapeChar = [256]bool{ + '<': true, + '>': true, + '&': true, + } + nul = byte('\000') +) + +func Compact(buf *bytes.Buffer, src []byte, escape bool) error { + if len(src) == 0 { + return errors.ErrUnexpectedEndOfJSON("", 0) + } + buf.Grow(len(src)) + dst := buf.Bytes() + + ctx := TakeRuntimeContext() + ctxBuf := ctx.Buf[:0] + ctxBuf = append(append(ctxBuf, src...), nul) + ctx.Buf = ctxBuf + + if err := compactAndWrite(buf, dst, ctxBuf, escape); err != nil { + ReleaseRuntimeContext(ctx) + return err + } + ReleaseRuntimeContext(ctx) + return nil +} + +func compactAndWrite(buf *bytes.Buffer, dst []byte, src []byte, escape bool) error { + dst, err := compact(dst, src, escape) + if err != nil { + return err + } + if _, err := buf.Write(dst); err != nil { + return err + } + return nil +} + +func compact(dst, src []byte, escape bool) ([]byte, error) { + buf, cursor, err := compactValue(dst, src, 0, escape) + if err != nil { + return nil, err + } + if err := validateEndBuf(src, cursor); err != nil { + return nil, err + } + return buf, nil +} + +func validateEndBuf(src []byte, cursor int64) error { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case nul: + return nil + } + return errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after top-level value", src[cursor]), + cursor+1, + ) + } +} + +func skipWhiteSpace(buf []byte, cursor int64) int64 { +LOOP: + if isWhiteSpace[buf[cursor]] { + cursor++ + goto LOOP + } + return cursor +} + +func compactValue(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case '{': + return compactObject(dst, src, cursor, escape) + case '}': + return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor) + case '[': + return compactArray(dst, src, cursor, escape) + case ']': + return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor) + case '"': + return compactString(dst, src, cursor, escape) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return compactNumber(dst, src, cursor) + case 't': + return compactTrue(dst, src, cursor) + case 'f': + return compactFalse(dst, src, cursor) + case 'n': + return compactNull(dst, src, cursor) + default: + return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor) + } + } +} + +func compactObject(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + if src[cursor] == '{' { + dst = append(dst, '{') + } else { + return nil, 0, errors.ErrExpected("expected { character for object value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == '}' { + dst = append(dst, '}') + return dst, cursor + 1, nil + } + var err error + for { + cursor = skipWhiteSpace(src, cursor) + dst, cursor, err = compactString(dst, src, cursor, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + if src[cursor] != ':' { + return nil, 0, errors.ErrExpected("colon after object key", cursor) + } + dst = append(dst, ':') + dst, cursor, err = compactValue(dst, src, cursor+1, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case '}': + dst = append(dst, '}') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrExpected("comma after object value", cursor) + } + cursor++ + } +} + +func compactArray(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + if src[cursor] == '[' { + dst = append(dst, '[') + } else { + return nil, 0, errors.ErrExpected("expected [ character for array value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == ']' { + dst = append(dst, ']') + return dst, cursor + 1, nil + } + var err error + for { + dst, cursor, err = compactValue(dst, src, cursor, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case ']': + dst = append(dst, ']') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrExpected("comma after array value", cursor) + } + cursor++ + } +} + +func compactString(dst, src []byte, cursor int64, escape bool) ([]byte, int64, error) { + if src[cursor] != '"' { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "string", cursor) + } + start := cursor + for { + cursor++ + c := src[cursor] + if escape { + if isHTMLEscapeChar[c] { + dst = append(dst, src[start:cursor]...) + dst = append(dst, `\u00`...) + dst = append(dst, hex[c>>4], hex[c&0xF]) + start = cursor + 1 + } else if c == 0xE2 && cursor+2 < int64(len(src)) && src[cursor+1] == 0x80 && src[cursor+2]&^1 == 0xA8 { + dst = append(dst, src[start:cursor]...) + dst = append(dst, `\u202`...) + dst = append(dst, hex[src[cursor+2]&0xF]) + cursor += 2 + start = cursor + 3 + } + } + switch c { + case '\\': + cursor++ + if src[cursor] == nul { + return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src))) + } + case '"': + cursor++ + return append(dst, src[start:cursor]...), cursor, nil + case nul: + return nil, 0, errors.ErrUnexpectedEndOfJSON("string", int64(len(src))) + } + } +} + +func compactNumber(dst, src []byte, cursor int64) ([]byte, int64, error) { + start := cursor + for { + cursor++ + if floatTable[src[cursor]] { + continue + } + break + } + num := src[start:cursor] + if _, err := strconv.ParseFloat(*(*string)(unsafe.Pointer(&num)), 64); err != nil { + return nil, 0, err + } + dst = append(dst, num...) + return dst, cursor, nil +} + +func compactTrue(dst, src []byte, cursor int64) ([]byte, int64, error) { + if cursor+3 >= int64(len(src)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("true", cursor) + } + if !bytes.Equal(src[cursor:cursor+4], []byte(`true`)) { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "true", cursor) + } + dst = append(dst, "true"...) + cursor += 4 + return dst, cursor, nil +} + +func compactFalse(dst, src []byte, cursor int64) ([]byte, int64, error) { + if cursor+4 >= int64(len(src)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("false", cursor) + } + if !bytes.Equal(src[cursor:cursor+5], []byte(`false`)) { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "false", cursor) + } + dst = append(dst, "false"...) + cursor += 5 + return dst, cursor, nil +} + +func compactNull(dst, src []byte, cursor int64) ([]byte, int64, error) { + if cursor+3 >= int64(len(src)) { + return nil, 0, errors.ErrUnexpectedEndOfJSON("null", cursor) + } + if !bytes.Equal(src[cursor:cursor+4], []byte(`null`)) { + return nil, 0, errors.ErrInvalidCharacter(src[cursor], "null", cursor) + } + dst = append(dst, "null"...) + cursor += 4 + return dst, cursor, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go new file mode 100644 index 000000000..01a5d4b28 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler.go @@ -0,0 +1,1569 @@ +package encoder + +import ( + "context" + "encoding" + "encoding/json" + "fmt" + "reflect" + "strings" + "sync/atomic" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +type marshalerContext interface { + MarshalJSON(context.Context) ([]byte, error) +} + +var ( + marshalJSONType = reflect.TypeOf((*json.Marshaler)(nil)).Elem() + marshalJSONContextType = reflect.TypeOf((*marshalerContext)(nil)).Elem() + marshalTextType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + jsonNumberType = reflect.TypeOf(json.Number("")) + cachedOpcodeSets []*OpcodeSet + cachedOpcodeMap unsafe.Pointer // map[uintptr]*OpcodeSet + typeAddr *runtime.TypeAddr +) + +func init() { + typeAddr = runtime.AnalyzeTypeAddr() + if typeAddr == nil { + typeAddr = &runtime.TypeAddr{} + } + cachedOpcodeSets = make([]*OpcodeSet, typeAddr.AddrRange>>typeAddr.AddrShift) +} + +func loadOpcodeMap() map[uintptr]*OpcodeSet { + p := atomic.LoadPointer(&cachedOpcodeMap) + return *(*map[uintptr]*OpcodeSet)(unsafe.Pointer(&p)) +} + +func storeOpcodeSet(typ uintptr, set *OpcodeSet, m map[uintptr]*OpcodeSet) { + newOpcodeMap := make(map[uintptr]*OpcodeSet, len(m)+1) + newOpcodeMap[typ] = set + + for k, v := range m { + newOpcodeMap[k] = v + } + + atomic.StorePointer(&cachedOpcodeMap, *(*unsafe.Pointer)(unsafe.Pointer(&newOpcodeMap))) +} + +func compileToGetCodeSetSlowPath(typeptr uintptr) (*OpcodeSet, error) { + opcodeMap := loadOpcodeMap() + if codeSet, exists := opcodeMap[typeptr]; exists { + return codeSet, nil + } + + // noescape trick for header.typ ( reflect.*rtype ) + copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr)) + + noescapeKeyCode, err := compileHead(&compileContext{ + typ: copiedType, + structTypeToCompiledCode: map[uintptr]*CompiledCode{}, + }) + if err != nil { + return nil, err + } + escapeKeyCode, err := compileHead(&compileContext{ + typ: copiedType, + structTypeToCompiledCode: map[uintptr]*CompiledCode{}, + escapeKey: true, + }) + if err != nil { + return nil, err + } + noescapeKeyCode = copyOpcode(noescapeKeyCode) + escapeKeyCode = copyOpcode(escapeKeyCode) + setTotalLengthToInterfaceOp(noescapeKeyCode) + setTotalLengthToInterfaceOp(escapeKeyCode) + interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode) + interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode) + codeLength := noescapeKeyCode.TotalLength() + codeSet := &OpcodeSet{ + Type: copiedType, + NoescapeKeyCode: noescapeKeyCode, + EscapeKeyCode: escapeKeyCode, + InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode, + InterfaceEscapeKeyCode: interfaceEscapeKeyCode, + CodeLength: codeLength, + EndCode: ToEndCode(interfaceNoescapeKeyCode), + } + storeOpcodeSet(typeptr, codeSet, opcodeMap) + return codeSet, nil +} + +func compileHead(ctx *compileContext) (*Opcode, error) { + typ := ctx.typ + switch { + case implementsMarshalJSON(typ): + return compileMarshalJSON(ctx) + case implementsMarshalText(typ): + return compileMarshalText(ctx) + } + + isPtr := false + orgType := typ + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() + isPtr = true + } + switch { + case implementsMarshalJSON(typ): + return compileMarshalJSON(ctx) + case implementsMarshalText(typ): + return compileMarshalText(ctx) + } + switch typ.Kind() { + case reflect.Slice: + ctx := ctx.withType(typ) + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + p := runtime.PtrTo(elem) + if !implementsMarshalJSONType(p) && !p.Implements(marshalTextType) { + if isPtr { + return compileBytesPtr(ctx) + } + return compileBytes(ctx) + } + } + code, err := compileSlice(ctx) + if err != nil { + return nil, err + } + optimizeStructEnd(code) + linkRecursiveCode(code) + return code, nil + case reflect.Map: + if isPtr { + return compilePtr(ctx.withType(runtime.PtrTo(typ))) + } + code, err := compileMap(ctx.withType(typ)) + if err != nil { + return nil, err + } + optimizeStructEnd(code) + linkRecursiveCode(code) + return code, nil + case reflect.Struct: + code, err := compileStruct(ctx.withType(typ), isPtr) + if err != nil { + return nil, err + } + optimizeStructEnd(code) + linkRecursiveCode(code) + return code, nil + case reflect.Int: + ctx := ctx.withType(typ) + if isPtr { + return compileIntPtr(ctx) + } + return compileInt(ctx) + case reflect.Int8: + ctx := ctx.withType(typ) + if isPtr { + return compileInt8Ptr(ctx) + } + return compileInt8(ctx) + case reflect.Int16: + ctx := ctx.withType(typ) + if isPtr { + return compileInt16Ptr(ctx) + } + return compileInt16(ctx) + case reflect.Int32: + ctx := ctx.withType(typ) + if isPtr { + return compileInt32Ptr(ctx) + } + return compileInt32(ctx) + case reflect.Int64: + ctx := ctx.withType(typ) + if isPtr { + return compileInt64Ptr(ctx) + } + return compileInt64(ctx) + case reflect.Uint, reflect.Uintptr: + ctx := ctx.withType(typ) + if isPtr { + return compileUintPtr(ctx) + } + return compileUint(ctx) + case reflect.Uint8: + ctx := ctx.withType(typ) + if isPtr { + return compileUint8Ptr(ctx) + } + return compileUint8(ctx) + case reflect.Uint16: + ctx := ctx.withType(typ) + if isPtr { + return compileUint16Ptr(ctx) + } + return compileUint16(ctx) + case reflect.Uint32: + ctx := ctx.withType(typ) + if isPtr { + return compileUint32Ptr(ctx) + } + return compileUint32(ctx) + case reflect.Uint64: + ctx := ctx.withType(typ) + if isPtr { + return compileUint64Ptr(ctx) + } + return compileUint64(ctx) + case reflect.Float32: + ctx := ctx.withType(typ) + if isPtr { + return compileFloat32Ptr(ctx) + } + return compileFloat32(ctx) + case reflect.Float64: + ctx := ctx.withType(typ) + if isPtr { + return compileFloat64Ptr(ctx) + } + return compileFloat64(ctx) + case reflect.String: + ctx := ctx.withType(typ) + if isPtr { + return compileStringPtr(ctx) + } + return compileString(ctx) + case reflect.Bool: + ctx := ctx.withType(typ) + if isPtr { + return compileBoolPtr(ctx) + } + return compileBool(ctx) + case reflect.Interface: + ctx := ctx.withType(typ) + if isPtr { + return compileInterfacePtr(ctx) + } + return compileInterface(ctx) + default: + if isPtr && typ.Implements(marshalTextType) { + typ = orgType + } + code, err := compile(ctx.withType(typ), isPtr) + if err != nil { + return nil, err + } + optimizeStructEnd(code) + linkRecursiveCode(code) + return code, nil + } +} + +func linkRecursiveCode(c *Opcode) { + for code := c; code.Op != OpEnd && code.Op != OpRecursiveEnd; { + switch code.Op { + case OpRecursive, OpRecursivePtr: + if code.Jmp.Linked { + code = code.Next + continue + } + code.Jmp.Code = copyOpcode(code.Jmp.Code) + + c := code.Jmp.Code + c.End.Next = newEndOp(&compileContext{}) + c.Op = c.Op.PtrHeadToHead() + + beforeLastCode := c.End + lastCode := beforeLastCode.Next + + lastCode.Idx = beforeLastCode.Idx + uintptrSize + lastCode.ElemIdx = lastCode.Idx + uintptrSize + lastCode.Length = lastCode.Idx + 2*uintptrSize + + // extend length to alloc slot for elemIdx + length + totalLength := uintptr(code.TotalLength() + 3) + nextTotalLength := uintptr(c.TotalLength() + 3) + + c.End.Next.Op = OpRecursiveEnd + + code.Jmp.CurLen = totalLength + code.Jmp.NextLen = nextTotalLength + code.Jmp.Linked = true + + linkRecursiveCode(code.Jmp.Code) + + code = code.Next + continue + } + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + code = code.End + default: + code = code.Next + } + } +} + +func optimizeStructEnd(c *Opcode) { + for code := c; code.Op != OpEnd; { + if code.Op == OpRecursive || code.Op == OpRecursivePtr { + // ignore if exists recursive operation + return + } + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + code = code.End + default: + code = code.Next + } + } + + for code := c; code.Op != OpEnd; { + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + code = code.End + case CodeStructEnd: + switch code.Op { + case OpStructEnd: + prev := code.PrevField + prevOp := prev.Op.String() + if strings.Contains(prevOp, "Head") || + strings.Contains(prevOp, "Slice") || + strings.Contains(prevOp, "Array") || + strings.Contains(prevOp, "Map") || + strings.Contains(prevOp, "MarshalJSON") || + strings.Contains(prevOp, "MarshalText") { + // not exists field + code = code.Next + break + } + if prev.Op != prev.Op.FieldToEnd() { + prev.Op = prev.Op.FieldToEnd() + prev.Next = code.Next + } + code = code.Next + default: + code = code.Next + } + default: + code = code.Next + } + } +} + +func implementsMarshalJSON(typ *runtime.Type) bool { + if !implementsMarshalJSONType(typ) { + return false + } + if typ.Kind() != reflect.Ptr { + return true + } + // type kind is reflect.Ptr + if !implementsMarshalJSONType(typ.Elem()) { + return true + } + // needs to dereference + return false +} + +func implementsMarshalText(typ *runtime.Type) bool { + if !typ.Implements(marshalTextType) { + return false + } + if typ.Kind() != reflect.Ptr { + return true + } + // type kind is reflect.Ptr + if !typ.Elem().Implements(marshalTextType) { + return true + } + // needs to dereference + return false +} + +func compile(ctx *compileContext, isPtr bool) (*Opcode, error) { + typ := ctx.typ + switch { + case implementsMarshalJSON(typ): + return compileMarshalJSON(ctx) + case implementsMarshalText(typ): + return compileMarshalText(ctx) + } + switch typ.Kind() { + case reflect.Ptr: + return compilePtr(ctx) + case reflect.Slice: + elem := typ.Elem() + if elem.Kind() == reflect.Uint8 { + p := runtime.PtrTo(elem) + if !implementsMarshalJSONType(p) && !p.Implements(marshalTextType) { + return compileBytes(ctx) + } + } + return compileSlice(ctx) + case reflect.Array: + return compileArray(ctx) + case reflect.Map: + return compileMap(ctx) + case reflect.Struct: + return compileStruct(ctx, isPtr) + case reflect.Interface: + return compileInterface(ctx) + case reflect.Int: + return compileInt(ctx) + case reflect.Int8: + return compileInt8(ctx) + case reflect.Int16: + return compileInt16(ctx) + case reflect.Int32: + return compileInt32(ctx) + case reflect.Int64: + return compileInt64(ctx) + case reflect.Uint: + return compileUint(ctx) + case reflect.Uint8: + return compileUint8(ctx) + case reflect.Uint16: + return compileUint16(ctx) + case reflect.Uint32: + return compileUint32(ctx) + case reflect.Uint64: + return compileUint64(ctx) + case reflect.Uintptr: + return compileUint(ctx) + case reflect.Float32: + return compileFloat32(ctx) + case reflect.Float64: + return compileFloat64(ctx) + case reflect.String: + return compileString(ctx) + case reflect.Bool: + return compileBool(ctx) + } + return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)} +} + +func convertPtrOp(code *Opcode) OpType { + ptrHeadOp := code.Op.HeadToPtrHead() + if code.Op != ptrHeadOp { + if code.PtrNum > 0 { + // ptr field and ptr head + code.PtrNum-- + } + return ptrHeadOp + } + switch code.Op { + case OpInt: + return OpIntPtr + case OpUint: + return OpUintPtr + case OpFloat32: + return OpFloat32Ptr + case OpFloat64: + return OpFloat64Ptr + case OpString: + return OpStringPtr + case OpBool: + return OpBoolPtr + case OpBytes: + return OpBytesPtr + case OpNumber: + return OpNumberPtr + case OpArray: + return OpArrayPtr + case OpSlice: + return OpSlicePtr + case OpMap: + return OpMapPtr + case OpMarshalJSON: + return OpMarshalJSONPtr + case OpMarshalText: + return OpMarshalTextPtr + case OpInterface: + return OpInterfacePtr + case OpRecursive: + return OpRecursivePtr + } + return code.Op +} + +func compileKey(ctx *compileContext) (*Opcode, error) { + typ := ctx.typ + switch { + case implementsMarshalJSON(typ): + return compileMarshalJSON(ctx) + case implementsMarshalText(typ): + return compileMarshalText(ctx) + } + switch typ.Kind() { + case reflect.Ptr: + return compilePtr(ctx) + case reflect.String: + return compileString(ctx) + case reflect.Int: + return compileIntString(ctx) + case reflect.Int8: + return compileInt8String(ctx) + case reflect.Int16: + return compileInt16String(ctx) + case reflect.Int32: + return compileInt32String(ctx) + case reflect.Int64: + return compileInt64String(ctx) + case reflect.Uint: + return compileUintString(ctx) + case reflect.Uint8: + return compileUint8String(ctx) + case reflect.Uint16: + return compileUint16String(ctx) + case reflect.Uint32: + return compileUint32String(ctx) + case reflect.Uint64: + return compileUint64String(ctx) + case reflect.Uintptr: + return compileUintString(ctx) + } + return nil, &errors.UnsupportedTypeError{Type: runtime.RType2Type(typ)} +} + +func compilePtr(ctx *compileContext) (*Opcode, error) { + code, err := compile(ctx.withType(ctx.typ.Elem()), true) + if err != nil { + return nil, err + } + code.Op = convertPtrOp(code) + code.PtrNum++ + return code, nil +} + +func compileMarshalJSON(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpMarshalJSON) + typ := ctx.typ + if isPtrMarshalJSONType(typ) { + code.Flags |= AddrForMarshalerFlags + } + if typ.Implements(marshalJSONContextType) || runtime.PtrTo(typ).Implements(marshalJSONContextType) { + code.Flags |= MarshalerContextFlags + } + if isNilableType(typ) { + code.Flags |= IsNilableTypeFlags + } else { + code.Flags &= ^IsNilableTypeFlags + } + ctx.incIndex() + return code, nil +} + +func compileMarshalText(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpMarshalText) + typ := ctx.typ + if !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) { + code.Flags |= AddrForMarshalerFlags + } + if isNilableType(typ) { + code.Flags |= IsNilableTypeFlags + } else { + code.Flags &= ^IsNilableTypeFlags + } + ctx.incIndex() + return code, nil +} + +const intSize = 32 << (^uint(0) >> 63) + +func compileInt(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpInt) + code.NumBitSize = intSize + ctx.incIndex() + return code, nil +} + +func compileIntPtr(ctx *compileContext) (*Opcode, error) { + code, err := compileInt(ctx) + if err != nil { + return nil, err + } + code.Op = OpIntPtr + return code, nil +} + +func compileInt8(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpInt) + code.NumBitSize = 8 + ctx.incIndex() + return code, nil +} + +func compileInt8Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileInt8(ctx) + if err != nil { + return nil, err + } + code.Op = OpIntPtr + return code, nil +} + +func compileInt16(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpInt) + code.NumBitSize = 16 + ctx.incIndex() + return code, nil +} + +func compileInt16Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileInt16(ctx) + if err != nil { + return nil, err + } + code.Op = OpIntPtr + return code, nil +} + +func compileInt32(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpInt) + code.NumBitSize = 32 + ctx.incIndex() + return code, nil +} + +func compileInt32Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileInt32(ctx) + if err != nil { + return nil, err + } + code.Op = OpIntPtr + return code, nil +} + +func compileInt64(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpInt) + code.NumBitSize = 64 + ctx.incIndex() + return code, nil +} + +func compileInt64Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileInt64(ctx) + if err != nil { + return nil, err + } + code.Op = OpIntPtr + return code, nil +} + +func compileUint(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUint) + code.NumBitSize = intSize + ctx.incIndex() + return code, nil +} + +func compileUintPtr(ctx *compileContext) (*Opcode, error) { + code, err := compileUint(ctx) + if err != nil { + return nil, err + } + code.Op = OpUintPtr + return code, nil +} + +func compileUint8(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUint) + code.NumBitSize = 8 + ctx.incIndex() + return code, nil +} + +func compileUint8Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileUint8(ctx) + if err != nil { + return nil, err + } + code.Op = OpUintPtr + return code, nil +} + +func compileUint16(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUint) + code.NumBitSize = 16 + ctx.incIndex() + return code, nil +} + +func compileUint16Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileUint16(ctx) + if err != nil { + return nil, err + } + code.Op = OpUintPtr + return code, nil +} + +func compileUint32(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUint) + code.NumBitSize = 32 + ctx.incIndex() + return code, nil +} + +func compileUint32Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileUint32(ctx) + if err != nil { + return nil, err + } + code.Op = OpUintPtr + return code, nil +} + +func compileUint64(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUint) + code.NumBitSize = 64 + ctx.incIndex() + return code, nil +} + +func compileUint64Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileUint64(ctx) + if err != nil { + return nil, err + } + code.Op = OpUintPtr + return code, nil +} + +func compileIntString(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpIntString) + code.NumBitSize = intSize + ctx.incIndex() + return code, nil +} + +func compileInt8String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpIntString) + code.NumBitSize = 8 + ctx.incIndex() + return code, nil +} + +func compileInt16String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpIntString) + code.NumBitSize = 16 + ctx.incIndex() + return code, nil +} + +func compileInt32String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpIntString) + code.NumBitSize = 32 + ctx.incIndex() + return code, nil +} + +func compileInt64String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpIntString) + code.NumBitSize = 64 + ctx.incIndex() + return code, nil +} + +func compileUintString(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUintString) + code.NumBitSize = intSize + ctx.incIndex() + return code, nil +} + +func compileUint8String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUintString) + code.NumBitSize = 8 + ctx.incIndex() + return code, nil +} + +func compileUint16String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUintString) + code.NumBitSize = 16 + ctx.incIndex() + return code, nil +} + +func compileUint32String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUintString) + code.NumBitSize = 32 + ctx.incIndex() + return code, nil +} + +func compileUint64String(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpUintString) + code.NumBitSize = 64 + ctx.incIndex() + return code, nil +} + +func compileFloat32(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpFloat32) + ctx.incIndex() + return code, nil +} + +func compileFloat32Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileFloat32(ctx) + if err != nil { + return nil, err + } + code.Op = OpFloat32Ptr + return code, nil +} + +func compileFloat64(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpFloat64) + ctx.incIndex() + return code, nil +} + +func compileFloat64Ptr(ctx *compileContext) (*Opcode, error) { + code, err := compileFloat64(ctx) + if err != nil { + return nil, err + } + code.Op = OpFloat64Ptr + return code, nil +} + +func compileString(ctx *compileContext) (*Opcode, error) { + var op OpType + if ctx.typ == runtime.Type2RType(jsonNumberType) { + op = OpNumber + } else { + op = OpString + } + code := newOpCode(ctx, op) + ctx.incIndex() + return code, nil +} + +func compileStringPtr(ctx *compileContext) (*Opcode, error) { + code, err := compileString(ctx) + if err != nil { + return nil, err + } + if code.Op == OpNumber { + code.Op = OpNumberPtr + } else { + code.Op = OpStringPtr + } + return code, nil +} + +func compileBool(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpBool) + ctx.incIndex() + return code, nil +} + +func compileBoolPtr(ctx *compileContext) (*Opcode, error) { + code, err := compileBool(ctx) + if err != nil { + return nil, err + } + code.Op = OpBoolPtr + return code, nil +} + +func compileBytes(ctx *compileContext) (*Opcode, error) { + code := newOpCode(ctx, OpBytes) + ctx.incIndex() + return code, nil +} + +func compileBytesPtr(ctx *compileContext) (*Opcode, error) { + code, err := compileBytes(ctx) + if err != nil { + return nil, err + } + code.Op = OpBytesPtr + return code, nil +} + +func compileInterface(ctx *compileContext) (*Opcode, error) { + code := newInterfaceCode(ctx) + ctx.incIndex() + return code, nil +} + +func compileInterfacePtr(ctx *compileContext) (*Opcode, error) { + code, err := compileInterface(ctx) + if err != nil { + return nil, err + } + code.Op = OpInterfacePtr + return code, nil +} + +func compileSlice(ctx *compileContext) (*Opcode, error) { + elem := ctx.typ.Elem() + size := elem.Size() + + header := newSliceHeaderCode(ctx) + ctx.incIndex() + + code, err := compileListElem(ctx.withType(elem).incIndent()) + if err != nil { + return nil, err + } + code.Flags |= IndirectFlags + + // header => opcode => elem => end + // ^ | + // |________| + + elemCode := newSliceElemCode(ctx, header, size) + ctx.incIndex() + + end := newOpCode(ctx, OpSliceEnd) + ctx.incIndex() + + header.End = end + header.Next = code + code.BeforeLastCode().Next = (*Opcode)(unsafe.Pointer(elemCode)) + elemCode.Next = code + elemCode.End = end + return (*Opcode)(unsafe.Pointer(header)), nil +} + +func compileListElem(ctx *compileContext) (*Opcode, error) { + typ := ctx.typ + switch { + case isPtrMarshalJSONType(typ): + return compileMarshalJSON(ctx) + case !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType): + return compileMarshalText(ctx) + case typ.Kind() == reflect.Map: + return compilePtr(ctx.withType(runtime.PtrTo(typ))) + default: + code, err := compile(ctx, false) + if err != nil { + return nil, err + } + if code.Op == OpMapPtr { + code.PtrNum++ + } + return code, nil + } +} + +func compileArray(ctx *compileContext) (*Opcode, error) { + typ := ctx.typ + elem := typ.Elem() + alen := typ.Len() + size := elem.Size() + + header := newArrayHeaderCode(ctx, alen) + ctx.incIndex() + + code, err := compileListElem(ctx.withType(elem).incIndent()) + if err != nil { + return nil, err + } + code.Flags |= IndirectFlags + // header => opcode => elem => end + // ^ | + // |________| + + elemCode := newArrayElemCode(ctx, header, alen, size) + ctx.incIndex() + + end := newOpCode(ctx, OpArrayEnd) + ctx.incIndex() + + header.End = end + header.Next = code + code.BeforeLastCode().Next = (*Opcode)(unsafe.Pointer(elemCode)) + elemCode.Next = code + elemCode.End = end + return (*Opcode)(unsafe.Pointer(header)), nil +} + +func compileMap(ctx *compileContext) (*Opcode, error) { + // header => code => value => code => key => code => value => code => end + // ^ | + // |_______________________| + ctx = ctx.incIndent() + header := newMapHeaderCode(ctx) + ctx.incIndex() + + typ := ctx.typ + keyType := ctx.typ.Key() + keyCode, err := compileKey(ctx.withType(keyType)) + if err != nil { + return nil, err + } + + value := newMapValueCode(ctx, header) + ctx.incIndex() + + valueCode, err := compileMapValue(ctx.withType(typ.Elem())) + if err != nil { + return nil, err + } + valueCode.Flags |= IndirectFlags + + key := newMapKeyCode(ctx, header) + ctx.incIndex() + + ctx = ctx.decIndent() + + end := newMapEndCode(ctx, header) + ctx.incIndex() + + header.Next = keyCode + keyCode.BeforeLastCode().Next = (*Opcode)(unsafe.Pointer(value)) + value.Next = valueCode + valueCode.BeforeLastCode().Next = (*Opcode)(unsafe.Pointer(key)) + key.Next = keyCode + + header.End = end + key.End = end + value.End = end + + return (*Opcode)(unsafe.Pointer(header)), nil +} + +func compileMapValue(ctx *compileContext) (*Opcode, error) { + switch ctx.typ.Kind() { + case reflect.Map: + return compilePtr(ctx.withType(runtime.PtrTo(ctx.typ))) + default: + code, err := compile(ctx, false) + if err != nil { + return nil, err + } + if code.Op == OpMapPtr { + code.PtrNum++ + } + return code, nil + } +} + +func optimizeStructHeader(code *Opcode, tag *runtime.StructTag) OpType { + headType := code.ToHeaderType(tag.IsString) + if tag.IsOmitEmpty { + headType = headType.HeadToOmitEmptyHead() + } + return headType +} + +func optimizeStructField(code *Opcode, tag *runtime.StructTag) OpType { + fieldType := code.ToFieldType(tag.IsString) + if tag.IsOmitEmpty { + fieldType = fieldType.FieldToOmitEmptyField() + } + return fieldType +} + +func recursiveCode(ctx *compileContext, jmp *CompiledCode) *Opcode { + code := newRecursiveCode(ctx, jmp) + ctx.incIndex() + return code +} + +func compiledCode(ctx *compileContext) *Opcode { + typ := ctx.typ + typeptr := uintptr(unsafe.Pointer(typ)) + if cc, exists := ctx.structTypeToCompiledCode[typeptr]; exists { + return recursiveCode(ctx, cc) + } + return nil +} + +func structHeader(ctx *compileContext, fieldCode *Opcode, valueCode *Opcode, tag *runtime.StructTag) *Opcode { + op := optimizeStructHeader(valueCode, tag) + fieldCode.Op = op + fieldCode.NumBitSize = valueCode.NumBitSize + fieldCode.PtrNum = valueCode.PtrNum + if op.IsMultipleOpHead() { + return valueCode.BeforeLastCode() + } + ctx.decOpcodeIndex() + return fieldCode +} + +func structField(ctx *compileContext, fieldCode *Opcode, valueCode *Opcode, tag *runtime.StructTag) *Opcode { + op := optimizeStructField(valueCode, tag) + fieldCode.Op = op + fieldCode.NumBitSize = valueCode.NumBitSize + fieldCode.PtrNum = valueCode.PtrNum + if op.IsMultipleOpField() { + return valueCode.BeforeLastCode() + } + ctx.decIndex() + return fieldCode +} + +func isNotExistsField(head *Opcode) bool { + if head == nil { + return false + } + if head.Op != OpStructHead { + return false + } + if (head.Flags & AnonymousHeadFlags) == 0 { + return false + } + if head.Next == nil { + return false + } + if head.NextField == nil { + return false + } + if head.NextField.Op != OpStructAnonymousEnd { + return false + } + if head.Next.Op == OpStructAnonymousEnd { + return true + } + if head.Next.Op.CodeType() != CodeStructField { + return false + } + return isNotExistsField(head.Next) +} + +func optimizeAnonymousFields(head *Opcode) { + code := head + var prev *Opcode + removedFields := map[*Opcode]struct{}{} + for { + if code.Op == OpStructEnd { + break + } + if code.Op == OpStructField { + codeType := code.Next.Op.CodeType() + if codeType == CodeStructField { + if isNotExistsField(code.Next) { + code.Next = code.NextField + diff := code.Next.DisplayIdx - code.DisplayIdx + for i := uint32(0); i < diff; i++ { + code.Next.decOpcodeIndex() + } + linkPrevToNextField(code, removedFields) + code = prev + } + } + } + prev = code + code = code.NextField + } +} + +type structFieldPair struct { + prevField *Opcode + curField *Opcode + isTaggedKey bool + linked bool +} + +func anonymousStructFieldPairMap(tags runtime.StructTags, named string, valueCode *Opcode) map[string][]structFieldPair { + anonymousFields := map[string][]structFieldPair{} + f := valueCode + var prevAnonymousField *Opcode + removedFields := map[*Opcode]struct{}{} + for { + existsKey := tags.ExistsKey(f.DisplayKey) + isHeadOp := strings.Contains(f.Op.String(), "Head") + if existsKey && f.Next != nil && strings.Contains(f.Next.Op.String(), "Recursive") { + // through + } else if isHeadOp && (f.Flags&AnonymousHeadFlags) == 0 { + if existsKey { + // TODO: need to remove this head + f.Op = OpStructHead + f.Flags |= AnonymousKeyFlags + f.Flags |= AnonymousHeadFlags + } else if named == "" { + f.Flags |= AnonymousHeadFlags + } + } else if named == "" && f.Op == OpStructEnd { + f.Op = OpStructAnonymousEnd + } else if existsKey { + diff := f.NextField.DisplayIdx - f.DisplayIdx + for i := uint32(0); i < diff; i++ { + f.NextField.decOpcodeIndex() + } + linkPrevToNextField(f, removedFields) + } + + if f.DisplayKey == "" { + if f.NextField == nil { + break + } + prevAnonymousField = f + f = f.NextField + continue + } + + key := fmt.Sprintf("%s.%s", named, f.DisplayKey) + anonymousFields[key] = append(anonymousFields[key], structFieldPair{ + prevField: prevAnonymousField, + curField: f, + isTaggedKey: (f.Flags & IsTaggedKeyFlags) != 0, + }) + if f.Next != nil && f.NextField != f.Next && f.Next.Op.CodeType() == CodeStructField { + for k, v := range anonymousFieldPairRecursively(named, f.Next) { + anonymousFields[k] = append(anonymousFields[k], v...) + } + } + if f.NextField == nil { + break + } + prevAnonymousField = f + f = f.NextField + } + return anonymousFields +} + +func anonymousFieldPairRecursively(named string, valueCode *Opcode) map[string][]structFieldPair { + anonymousFields := map[string][]structFieldPair{} + f := valueCode + var prevAnonymousField *Opcode + for { + if f.DisplayKey != "" && (f.Flags&AnonymousHeadFlags) != 0 { + key := fmt.Sprintf("%s.%s", named, f.DisplayKey) + anonymousFields[key] = append(anonymousFields[key], structFieldPair{ + prevField: prevAnonymousField, + curField: f, + isTaggedKey: (f.Flags & IsTaggedKeyFlags) != 0, + }) + if f.Next != nil && f.NextField != f.Next && f.Next.Op.CodeType() == CodeStructField { + for k, v := range anonymousFieldPairRecursively(named, f.Next) { + anonymousFields[k] = append(anonymousFields[k], v...) + } + } + } + if f.NextField == nil { + break + } + prevAnonymousField = f + f = f.NextField + } + return anonymousFields +} + +func optimizeConflictAnonymousFields(anonymousFields map[string][]structFieldPair) { + removedFields := map[*Opcode]struct{}{} + for _, fieldPairs := range anonymousFields { + if len(fieldPairs) == 1 { + continue + } + // conflict anonymous fields + taggedPairs := []structFieldPair{} + for _, fieldPair := range fieldPairs { + if fieldPair.isTaggedKey { + taggedPairs = append(taggedPairs, fieldPair) + } else { + if !fieldPair.linked { + if fieldPair.prevField == nil { + // head operation + fieldPair.curField.Op = OpStructHead + fieldPair.curField.Flags |= AnonymousHeadFlags + fieldPair.curField.Flags |= AnonymousKeyFlags + } else { + diff := fieldPair.curField.NextField.DisplayIdx - fieldPair.curField.DisplayIdx + for i := uint32(0); i < diff; i++ { + fieldPair.curField.NextField.decOpcodeIndex() + } + removedFields[fieldPair.curField] = struct{}{} + linkPrevToNextField(fieldPair.curField, removedFields) + } + fieldPair.linked = true + } + } + } + if len(taggedPairs) > 1 { + for _, fieldPair := range taggedPairs { + if !fieldPair.linked { + if fieldPair.prevField == nil { + // head operation + fieldPair.curField.Op = OpStructHead + fieldPair.curField.Flags |= AnonymousHeadFlags + fieldPair.curField.Flags |= AnonymousKeyFlags + } else { + diff := fieldPair.curField.NextField.DisplayIdx - fieldPair.curField.DisplayIdx + removedFields[fieldPair.curField] = struct{}{} + for i := uint32(0); i < diff; i++ { + fieldPair.curField.NextField.decOpcodeIndex() + } + linkPrevToNextField(fieldPair.curField, removedFields) + } + fieldPair.linked = true + } + } + } else { + for _, fieldPair := range taggedPairs { + fieldPair.curField.Flags &= ^IsTaggedKeyFlags + } + } + } +} + +func isNilableType(typ *runtime.Type) bool { + switch typ.Kind() { + case reflect.Ptr: + return true + case reflect.Map: + return true + case reflect.Func: + return true + default: + return false + } +} + +func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) { + if code := compiledCode(ctx); code != nil { + return code, nil + } + typ := ctx.typ + typeptr := uintptr(unsafe.Pointer(typ)) + compiled := &CompiledCode{} + ctx.structTypeToCompiledCode[typeptr] = compiled + // header => code => structField => code => end + // ^ | + // |__________| + fieldNum := typ.NumField() + indirect := runtime.IfaceIndir(typ) + fieldIdx := 0 + disableIndirectConversion := false + var ( + head *Opcode + code *Opcode + prevField *Opcode + ) + ctx = ctx.incIndent() + tags := runtime.StructTags{} + anonymousFields := map[string][]structFieldPair{} + for i := 0; i < fieldNum; i++ { + field := typ.Field(i) + if runtime.IsIgnoredStructField(field) { + continue + } + tags = append(tags, runtime.StructTagFromField(field)) + } + for i, tag := range tags { + field := tag.Field + fieldType := runtime.Type2RType(field.Type) + fieldOpcodeIndex := ctx.opcodeIndex + fieldPtrIndex := ctx.ptrIndex + ctx.incIndex() + + nilcheck := true + addrForMarshaler := false + isIndirectSpecialCase := isPtr && i == 0 && fieldNum == 1 + isNilableType := isNilableType(fieldType) + + var valueCode *Opcode + switch { + case isIndirectSpecialCase && !isNilableType && isPtrMarshalJSONType(fieldType): + // *struct{ field T } => struct { field *T } + // func (*T) MarshalJSON() ([]byte, error) + // move pointer position from head to first field + code, err := compileMarshalJSON(ctx.withType(fieldType)) + if err != nil { + return nil, err + } + addrForMarshaler = true + valueCode = code + nilcheck = false + indirect = false + disableIndirectConversion = true + case isIndirectSpecialCase && !isNilableType && isPtrMarshalTextType(fieldType): + // *struct{ field T } => struct { field *T } + // func (*T) MarshalText() ([]byte, error) + // move pointer position from head to first field + code, err := compileMarshalText(ctx.withType(fieldType)) + if err != nil { + return nil, err + } + addrForMarshaler = true + valueCode = code + nilcheck = false + indirect = false + disableIndirectConversion = true + case isPtr && isPtrMarshalJSONType(fieldType): + // *struct{ field T } + // func (*T) MarshalJSON() ([]byte, error) + code, err := compileMarshalJSON(ctx.withType(fieldType)) + if err != nil { + return nil, err + } + addrForMarshaler = true + nilcheck = false + valueCode = code + case isPtr && isPtrMarshalTextType(fieldType): + // *struct{ field T } + // func (*T) MarshalText() ([]byte, error) + code, err := compileMarshalText(ctx.withType(fieldType)) + if err != nil { + return nil, err + } + addrForMarshaler = true + nilcheck = false + valueCode = code + default: + code, err := compile(ctx.withType(fieldType), isPtr) + if err != nil { + return nil, err + } + valueCode = code + } + + if field.Anonymous { + tagKey := "" + if tag.IsTaggedKey { + tagKey = tag.Key + } + for k, v := range anonymousStructFieldPairMap(tags, tagKey, valueCode) { + anonymousFields[k] = append(anonymousFields[k], v...) + } + valueCode.decIndent() + + // fix issue144 + if !(isPtr && strings.Contains(valueCode.Op.String(), "Marshal")) { + if indirect { + valueCode.Flags |= IndirectFlags + } else { + valueCode.Flags &= ^IndirectFlags + } + } + } else { + if indirect { + // if parent is indirect type, set child indirect property to true + valueCode.Flags |= IndirectFlags + } else { + // if parent is not indirect type, set child indirect property to false. + // but if parent's indirect is false and isPtr is true, then indirect must be true. + // Do this only if indirectConversion is enabled at the end of compileStruct. + if i == 0 { + valueCode.Flags &= ^IndirectFlags + } + } + } + var flags OpFlags + if indirect { + flags |= IndirectFlags + } + if field.Anonymous { + flags |= AnonymousKeyFlags + } + if tag.IsTaggedKey { + flags |= IsTaggedKeyFlags + } + if nilcheck { + flags |= NilCheckFlags + } + if addrForMarshaler { + flags |= AddrForMarshalerFlags + } + if strings.Contains(valueCode.Op.String(), "Ptr") || valueCode.Op == OpInterface { + flags |= IsNextOpPtrTypeFlags + } + if isNilableType { + flags |= IsNilableTypeFlags + } + var key string + if ctx.escapeKey { + rctx := &RuntimeContext{Option: &Option{Flag: HTMLEscapeOption}} + key = fmt.Sprintf(`%s:`, string(AppendString(rctx, []byte{}, tag.Key))) + } else { + key = fmt.Sprintf(`"%s":`, tag.Key) + } + fieldCode := &Opcode{ + Idx: opcodeOffset(fieldPtrIndex), + Next: valueCode, + Flags: flags, + Key: key, + Offset: uint32(field.Offset), + Type: valueCode.Type, + DisplayIdx: fieldOpcodeIndex, + Indent: ctx.indent, + DisplayKey: tag.Key, + } + if fieldIdx == 0 { + code = structHeader(ctx, fieldCode, valueCode, tag) + head = fieldCode + prevField = fieldCode + } else { + fieldCode.Idx = head.Idx + code.Next = fieldCode + code = structField(ctx, fieldCode, valueCode, tag) + prevField.NextField = fieldCode + fieldCode.PrevField = prevField + prevField = fieldCode + } + fieldIdx++ + } + + structEndCode := &Opcode{ + Op: OpStructEnd, + Next: newEndOp(ctx), + Type: nil, + Indent: ctx.indent, + } + + ctx = ctx.decIndent() + + // no struct field + if head == nil { + head = &Opcode{ + Op: OpStructHead, + Idx: opcodeOffset(ctx.ptrIndex), + NextField: structEndCode, + Type: typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } + structEndCode.PrevField = head + ctx.incIndex() + code = head + } + + structEndCode.DisplayIdx = ctx.opcodeIndex + structEndCode.Idx = opcodeOffset(ctx.ptrIndex) + ctx.incIndex() + + if prevField != nil && prevField.NextField == nil { + prevField.NextField = structEndCode + structEndCode.PrevField = prevField + } + + head.End = structEndCode + code.Next = structEndCode + optimizeConflictAnonymousFields(anonymousFields) + optimizeAnonymousFields(head) + ret := (*Opcode)(unsafe.Pointer(head)) + compiled.Code = ret + + delete(ctx.structTypeToCompiledCode, typeptr) + + if !disableIndirectConversion && (head.Flags&IndirectFlags == 0) && isPtr { + headCode := head + for strings.Contains(headCode.Op.String(), "Head") { + headCode.Flags |= IndirectFlags + headCode = headCode.Next + } + } + + return ret, nil +} + +func implementsMarshalJSONType(typ *runtime.Type) bool { + return typ.Implements(marshalJSONType) || typ.Implements(marshalJSONContextType) +} + +func isPtrMarshalJSONType(typ *runtime.Type) bool { + return !implementsMarshalJSONType(typ) && implementsMarshalJSONType(runtime.PtrTo(typ)) +} + +func isPtrMarshalTextType(typ *runtime.Type) bool { + return !typ.Implements(marshalTextType) && runtime.PtrTo(typ).Implements(marshalTextType) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go new file mode 100644 index 000000000..9d337f12b --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_norace.go @@ -0,0 +1,56 @@ +// +build !race + +package encoder + +import ( + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) { + if typeptr > typeAddr.MaxTypeAddr { + return compileToGetCodeSetSlowPath(typeptr) + } + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + if codeSet := cachedOpcodeSets[index]; codeSet != nil { + return codeSet, nil + } + + // noescape trick for header.typ ( reflect.*rtype ) + copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr)) + + noescapeKeyCode, err := compileHead(&compileContext{ + typ: copiedType, + structTypeToCompiledCode: map[uintptr]*CompiledCode{}, + }) + if err != nil { + return nil, err + } + escapeKeyCode, err := compileHead(&compileContext{ + typ: copiedType, + structTypeToCompiledCode: map[uintptr]*CompiledCode{}, + escapeKey: true, + }) + if err != nil { + return nil, err + } + noescapeKeyCode = copyOpcode(noescapeKeyCode) + escapeKeyCode = copyOpcode(escapeKeyCode) + setTotalLengthToInterfaceOp(noescapeKeyCode) + setTotalLengthToInterfaceOp(escapeKeyCode) + interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode) + interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode) + codeLength := noescapeKeyCode.TotalLength() + codeSet := &OpcodeSet{ + Type: copiedType, + NoescapeKeyCode: noescapeKeyCode, + EscapeKeyCode: escapeKeyCode, + InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode, + InterfaceEscapeKeyCode: interfaceEscapeKeyCode, + CodeLength: codeLength, + EndCode: ToEndCode(interfaceNoescapeKeyCode), + } + cachedOpcodeSets[index] = codeSet + return codeSet, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go new file mode 100644 index 000000000..3a239e9d9 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/compiler_race.go @@ -0,0 +1,65 @@ +// +build race + +package encoder + +import ( + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +var setsMu sync.RWMutex + +func CompileToGetCodeSet(typeptr uintptr) (*OpcodeSet, error) { + if typeptr > typeAddr.MaxTypeAddr { + return compileToGetCodeSetSlowPath(typeptr) + } + index := (typeptr - typeAddr.BaseTypeAddr) >> typeAddr.AddrShift + setsMu.RLock() + if codeSet := cachedOpcodeSets[index]; codeSet != nil { + setsMu.RUnlock() + return codeSet, nil + } + setsMu.RUnlock() + + // noescape trick for header.typ ( reflect.*rtype ) + copiedType := *(**runtime.Type)(unsafe.Pointer(&typeptr)) + + noescapeKeyCode, err := compileHead(&compileContext{ + typ: copiedType, + structTypeToCompiledCode: map[uintptr]*CompiledCode{}, + }) + if err != nil { + return nil, err + } + escapeKeyCode, err := compileHead(&compileContext{ + typ: copiedType, + structTypeToCompiledCode: map[uintptr]*CompiledCode{}, + escapeKey: true, + }) + if err != nil { + return nil, err + } + + noescapeKeyCode = copyOpcode(noescapeKeyCode) + escapeKeyCode = copyOpcode(escapeKeyCode) + setTotalLengthToInterfaceOp(noescapeKeyCode) + setTotalLengthToInterfaceOp(escapeKeyCode) + interfaceNoescapeKeyCode := copyToInterfaceOpcode(noescapeKeyCode) + interfaceEscapeKeyCode := copyToInterfaceOpcode(escapeKeyCode) + codeLength := noescapeKeyCode.TotalLength() + codeSet := &OpcodeSet{ + Type: copiedType, + NoescapeKeyCode: noescapeKeyCode, + EscapeKeyCode: escapeKeyCode, + InterfaceNoescapeKeyCode: interfaceNoescapeKeyCode, + InterfaceEscapeKeyCode: interfaceEscapeKeyCode, + CodeLength: codeLength, + EndCode: ToEndCode(interfaceNoescapeKeyCode), + } + setsMu.Lock() + cachedOpcodeSets[index] = codeSet + setsMu.Unlock() + return codeSet, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/context.go b/vendor/github.com/goccy/go-json/internal/encoder/context.go new file mode 100644 index 000000000..61b890806 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/context.go @@ -0,0 +1,141 @@ +package encoder + +import ( + "context" + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +type compileContext struct { + typ *runtime.Type + opcodeIndex uint32 + ptrIndex int + indent uint32 + escapeKey bool + structTypeToCompiledCode map[uintptr]*CompiledCode + + parent *compileContext +} + +func (c *compileContext) context() *compileContext { + return &compileContext{ + typ: c.typ, + opcodeIndex: c.opcodeIndex, + ptrIndex: c.ptrIndex, + indent: c.indent, + escapeKey: c.escapeKey, + structTypeToCompiledCode: c.structTypeToCompiledCode, + parent: c, + } +} + +func (c *compileContext) withType(typ *runtime.Type) *compileContext { + ctx := c.context() + ctx.typ = typ + return ctx +} + +func (c *compileContext) incIndent() *compileContext { + ctx := c.context() + ctx.indent++ + return ctx +} + +func (c *compileContext) decIndent() *compileContext { + ctx := c.context() + ctx.indent-- + return ctx +} + +func (c *compileContext) incIndex() { + c.incOpcodeIndex() + c.incPtrIndex() +} + +func (c *compileContext) decIndex() { + c.decOpcodeIndex() + c.decPtrIndex() +} + +func (c *compileContext) incOpcodeIndex() { + c.opcodeIndex++ + if c.parent != nil { + c.parent.incOpcodeIndex() + } +} + +func (c *compileContext) decOpcodeIndex() { + c.opcodeIndex-- + if c.parent != nil { + c.parent.decOpcodeIndex() + } +} + +func (c *compileContext) incPtrIndex() { + c.ptrIndex++ + if c.parent != nil { + c.parent.incPtrIndex() + } +} + +func (c *compileContext) decPtrIndex() { + c.ptrIndex-- + if c.parent != nil { + c.parent.decPtrIndex() + } +} + +const ( + bufSize = 1024 +) + +var ( + runtimeContextPool = sync.Pool{ + New: func() interface{} { + return &RuntimeContext{ + Buf: make([]byte, 0, bufSize), + Ptrs: make([]uintptr, 128), + KeepRefs: make([]unsafe.Pointer, 0, 8), + Option: &Option{}, + } + }, + } +) + +type RuntimeContext struct { + Context context.Context + Buf []byte + MarshalBuf []byte + Ptrs []uintptr + KeepRefs []unsafe.Pointer + SeenPtr []uintptr + BaseIndent uint32 + Prefix []byte + IndentStr []byte + Option *Option +} + +func (c *RuntimeContext) Init(p uintptr, codelen int) { + if len(c.Ptrs) < codelen { + c.Ptrs = make([]uintptr, codelen) + } + c.Ptrs[0] = p + c.KeepRefs = c.KeepRefs[:0] + c.SeenPtr = c.SeenPtr[:0] + c.BaseIndent = 0 +} + +func (c *RuntimeContext) Ptr() uintptr { + header := (*runtime.SliceHeader)(unsafe.Pointer(&c.Ptrs)) + return uintptr(header.Data) +} + +func TakeRuntimeContext() *RuntimeContext { + return runtimeContextPool.Get().(*RuntimeContext) +} + +func ReleaseRuntimeContext(ctx *RuntimeContext) { + runtimeContextPool.Put(ctx) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/encoder.go b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go new file mode 100644 index 000000000..b7fa99a96 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/encoder.go @@ -0,0 +1,551 @@ +package encoder + +import ( + "bytes" + "encoding" + "encoding/base64" + "encoding/json" + "fmt" + "math" + "reflect" + "strconv" + "strings" + "sync" + "unsafe" + + "github.com/goccy/go-json/internal/errors" + "github.com/goccy/go-json/internal/runtime" +) + +func (t OpType) IsMultipleOpHead() bool { + switch t { + case OpStructHead: + return true + case OpStructHeadSlice: + return true + case OpStructHeadArray: + return true + case OpStructHeadMap: + return true + case OpStructHeadStruct: + return true + case OpStructHeadOmitEmpty: + return true + case OpStructHeadOmitEmptySlice: + return true + case OpStructHeadOmitEmptyArray: + return true + case OpStructHeadOmitEmptyMap: + return true + case OpStructHeadOmitEmptyStruct: + return true + case OpStructHeadSlicePtr: + return true + case OpStructHeadOmitEmptySlicePtr: + return true + case OpStructHeadArrayPtr: + return true + case OpStructHeadOmitEmptyArrayPtr: + return true + case OpStructHeadMapPtr: + return true + case OpStructHeadOmitEmptyMapPtr: + return true + } + return false +} + +func (t OpType) IsMultipleOpField() bool { + switch t { + case OpStructField: + return true + case OpStructFieldSlice: + return true + case OpStructFieldArray: + return true + case OpStructFieldMap: + return true + case OpStructFieldStruct: + return true + case OpStructFieldOmitEmpty: + return true + case OpStructFieldOmitEmptySlice: + return true + case OpStructFieldOmitEmptyArray: + return true + case OpStructFieldOmitEmptyMap: + return true + case OpStructFieldOmitEmptyStruct: + return true + case OpStructFieldSlicePtr: + return true + case OpStructFieldOmitEmptySlicePtr: + return true + case OpStructFieldArrayPtr: + return true + case OpStructFieldOmitEmptyArrayPtr: + return true + case OpStructFieldMapPtr: + return true + case OpStructFieldOmitEmptyMapPtr: + return true + } + return false +} + +type OpcodeSet struct { + Type *runtime.Type + NoescapeKeyCode *Opcode + EscapeKeyCode *Opcode + InterfaceNoescapeKeyCode *Opcode + InterfaceEscapeKeyCode *Opcode + CodeLength int + EndCode *Opcode +} + +type CompiledCode struct { + Code *Opcode + Linked bool // whether recursive code already have linked + CurLen uintptr + NextLen uintptr +} + +const StartDetectingCyclesAfter = 1000 + +func Load(base uintptr, idx uintptr) uintptr { + addr := base + idx + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func Store(base uintptr, idx uintptr, p uintptr) { + addr := base + idx + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func LoadNPtr(base uintptr, idx uintptr, ptrNum int) uintptr { + addr := base + idx + p := **(**uintptr)(unsafe.Pointer(&addr)) + if p == 0 { + return 0 + } + return PtrToPtr(p) + /* + for i := 0; i < ptrNum; i++ { + if p == 0 { + return p + } + p = PtrToPtr(p) + } + return p + */ +} + +func PtrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func PtrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func PtrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func PtrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func PtrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func PtrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func PtrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func PtrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func PtrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func PtrToNPtr(p uintptr, ptrNum int) uintptr { + for i := 0; i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = PtrToPtr(p) + } + return p +} + +func PtrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func PtrToInterface(code *Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func ErrUnsupportedValue(code *Opcode, ptr uintptr) *errors.UnsupportedValueError { + v := *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&ptr)), + })) + return &errors.UnsupportedValueError{ + Value: reflect.ValueOf(v), + Str: fmt.Sprintf("encountered a cycle via %s", code.Type), + } +} + +func ErrUnsupportedFloat(v float64) *errors.UnsupportedValueError { + return &errors.UnsupportedValueError{ + Value: reflect.ValueOf(v), + Str: strconv.FormatFloat(v, 'g', -1, 64), + } +} + +func ErrMarshalerWithCode(code *Opcode, err error) *errors.MarshalerError { + return &errors.MarshalerError{ + Type: runtime.RType2Type(code.Type), + Err: err, + } +} + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +type MapItem struct { + Key []byte + Value []byte +} + +type Mapslice struct { + Items []MapItem +} + +func (m *Mapslice) Len() int { + return len(m.Items) +} + +func (m *Mapslice) Less(i, j int) bool { + return bytes.Compare(m.Items[i].Key, m.Items[j].Key) < 0 +} + +func (m *Mapslice) Swap(i, j int) { + m.Items[i], m.Items[j] = m.Items[j], m.Items[i] +} + +type MapContext struct { + Pos []int + Slice *Mapslice + Buf []byte +} + +var mapContextPool = sync.Pool{ + New: func() interface{} { + return &MapContext{} + }, +} + +func NewMapContext(mapLen int) *MapContext { + ctx := mapContextPool.Get().(*MapContext) + if ctx.Slice == nil { + ctx.Slice = &Mapslice{ + Items: make([]MapItem, 0, mapLen), + } + } + if cap(ctx.Pos) < (mapLen*2 + 1) { + ctx.Pos = make([]int, 0, mapLen*2+1) + ctx.Slice.Items = make([]MapItem, 0, mapLen) + } else { + ctx.Pos = ctx.Pos[:0] + ctx.Slice.Items = ctx.Slice.Items[:0] + } + ctx.Buf = ctx.Buf[:0] + return ctx +} + +func ReleaseMapContext(c *MapContext) { + mapContextPool.Put(c) +} + +//go:linkname MapIterInit reflect.mapiterinit +//go:noescape +func MapIterInit(mapType *runtime.Type, m unsafe.Pointer) unsafe.Pointer + +//go:linkname MapIterKey reflect.mapiterkey +//go:noescape +func MapIterKey(it unsafe.Pointer) unsafe.Pointer + +//go:linkname MapIterNext reflect.mapiternext +//go:noescape +func MapIterNext(it unsafe.Pointer) + +//go:linkname MapLen reflect.maplen +//go:noescape +func MapLen(m unsafe.Pointer) int + +func AppendByteSlice(_ *RuntimeContext, b []byte, src []byte) []byte { + if src == nil { + return append(b, `null`...) + } + encodedLen := base64.StdEncoding.EncodedLen(len(src)) + b = append(b, '"') + pos := len(b) + remainLen := cap(b[pos:]) + var buf []byte + if remainLen > encodedLen { + buf = b[pos : pos+encodedLen] + } else { + buf = make([]byte, encodedLen) + } + base64.StdEncoding.Encode(buf, src) + return append(append(b, buf...), '"') +} + +func AppendFloat32(_ *RuntimeContext, b []byte, v float32) []byte { + f64 := float64(v) + abs := math.Abs(f64) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + f32 := float32(abs) + if f32 < 1e-6 || f32 >= 1e21 { + fmt = 'e' + } + } + return strconv.AppendFloat(b, f64, fmt, -1, 32) +} + +func AppendFloat64(_ *RuntimeContext, b []byte, v float64) []byte { + abs := math.Abs(v) + fmt := byte('f') + // Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right. + if abs != 0 { + if abs < 1e-6 || abs >= 1e21 { + fmt = 'e' + } + } + return strconv.AppendFloat(b, v, fmt, -1, 64) +} + +func AppendBool(_ *RuntimeContext, b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +var ( + floatTable = [256]bool{ + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + '.': true, + 'e': true, + 'E': true, + '+': true, + '-': true, + } +) + +func AppendNumber(_ *RuntimeContext, b []byte, n json.Number) ([]byte, error) { + if len(n) == 0 { + return append(b, '0'), nil + } + for i := 0; i < len(n); i++ { + if !floatTable[n[i]] { + return nil, fmt.Errorf("json: invalid number literal %q", n) + } + } + b = append(b, n...) + return b, nil +} + +func AppendMarshalJSON(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + var bb []byte + if (code.Flags & MarshalerContextFlags) != 0 { + marshaler, ok := v.(marshalerContext) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON(ctx.Option.Context) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } else { + marshaler, ok := v.(json.Marshaler) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } + marshalBuf := ctx.MarshalBuf[:0] + marshalBuf = append(append(marshalBuf, bb...), nul) + compactedBuf, err := compact(b, marshalBuf, (ctx.Option.Flag&HTMLEscapeOption) != 0) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + ctx.MarshalBuf = marshalBuf + return compactedBuf, nil +} + +func AppendMarshalJSONIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + var bb []byte + if (code.Flags & MarshalerContextFlags) != 0 { + marshaler, ok := v.(marshalerContext) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON(ctx.Option.Context) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } else { + marshaler, ok := v.(json.Marshaler) + if !ok { + return AppendNull(ctx, b), nil + } + b, err := marshaler.MarshalJSON() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + bb = b + } + marshalBuf := ctx.MarshalBuf[:0] + marshalBuf = append(append(marshalBuf, bb...), nul) + indentedBuf, err := doIndent( + b, + marshalBuf, + string(ctx.Prefix)+strings.Repeat(string(ctx.IndentStr), int(ctx.BaseIndent+code.Indent)), + string(ctx.IndentStr), + (ctx.Option.Flag&HTMLEscapeOption) != 0, + ) + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + ctx.MarshalBuf = marshalBuf + return indentedBuf, nil +} + +func AppendMarshalText(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + marshaler, ok := v.(encoding.TextMarshaler) + if !ok { + return AppendNull(ctx, b), nil + } + bytes, err := marshaler.MarshalText() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil +} + +func AppendMarshalTextIndent(ctx *RuntimeContext, code *Opcode, b []byte, v interface{}) ([]byte, error) { + rv := reflect.ValueOf(v) // convert by dynamic interface type + if (code.Flags & AddrForMarshalerFlags) != 0 { + if rv.CanAddr() { + rv = rv.Addr() + } else { + newV := reflect.New(rv.Type()) + newV.Elem().Set(rv) + rv = newV + } + } + v = rv.Interface() + marshaler, ok := v.(encoding.TextMarshaler) + if !ok { + return AppendNull(ctx, b), nil + } + bytes, err := marshaler.MarshalText() + if err != nil { + return nil, &errors.MarshalerError{Type: reflect.TypeOf(v), Err: err} + } + return AppendString(ctx, b, *(*string)(unsafe.Pointer(&bytes))), nil +} + +func AppendNull(_ *RuntimeContext, b []byte) []byte { + return append(b, "null"...) +} + +func AppendComma(_ *RuntimeContext, b []byte) []byte { + return append(b, ',') +} + +func AppendCommaIndent(_ *RuntimeContext, b []byte) []byte { + return append(b, ',', '\n') +} + +func AppendStructEnd(_ *RuntimeContext, b []byte) []byte { + return append(b, '}', ',') +} + +func AppendStructEndIndent(ctx *RuntimeContext, code *Opcode, b []byte) []byte { + b = append(b, '\n') + b = append(b, ctx.Prefix...) + indentNum := ctx.BaseIndent + code.Indent - 1 + for i := uint32(0); i < indentNum; i++ { + b = append(b, ctx.IndentStr...) + } + return append(b, '}', ',', '\n') +} + +func AppendIndent(ctx *RuntimeContext, b []byte, indent uint32) []byte { + b = append(b, ctx.Prefix...) + indentNum := ctx.BaseIndent + indent + for i := uint32(0); i < indentNum; i++ { + b = append(b, ctx.IndentStr...) + } + return b +} + +func IsNilForMarshaler(v interface{}) bool { + rv := reflect.ValueOf(v) + switch rv.Kind() { + case reflect.Bool: + return !rv.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return rv.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return rv.Uint() == 0 + case reflect.Float32, reflect.Float64: + return math.Float64bits(rv.Float()) == 0 + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Func: + return rv.IsNil() + case reflect.Slice: + return rv.IsNil() || rv.Len() == 0 + } + return false +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/indent.go b/vendor/github.com/goccy/go-json/internal/encoder/indent.go new file mode 100644 index 000000000..dfe04b5e3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/indent.go @@ -0,0 +1,211 @@ +package encoder + +import ( + "bytes" + "fmt" + + "github.com/goccy/go-json/internal/errors" +) + +func takeIndentSrcRuntimeContext(src []byte) (*RuntimeContext, []byte) { + ctx := TakeRuntimeContext() + buf := ctx.Buf[:0] + buf = append(append(buf, src...), nul) + ctx.Buf = buf + return ctx, buf +} + +func Indent(buf *bytes.Buffer, src []byte, prefix, indentStr string) error { + if len(src) == 0 { + return errors.ErrUnexpectedEndOfJSON("", 0) + } + + srcCtx, srcBuf := takeIndentSrcRuntimeContext(src) + dstCtx := TakeRuntimeContext() + dst := dstCtx.Buf[:0] + + dst, err := indentAndWrite(buf, dst, srcBuf, prefix, indentStr) + if err != nil { + ReleaseRuntimeContext(srcCtx) + ReleaseRuntimeContext(dstCtx) + return err + } + dstCtx.Buf = dst + ReleaseRuntimeContext(srcCtx) + ReleaseRuntimeContext(dstCtx) + return nil +} + +func indentAndWrite(buf *bytes.Buffer, dst []byte, src []byte, prefix, indentStr string) ([]byte, error) { + dst, err := doIndent(dst, src, prefix, indentStr, false) + if err != nil { + return nil, err + } + if _, err := buf.Write(dst); err != nil { + return nil, err + } + return dst, nil +} + +func doIndent(dst, src []byte, prefix, indentStr string, escape bool) ([]byte, error) { + buf, cursor, err := indentValue(dst, src, 0, 0, []byte(prefix), []byte(indentStr), escape) + if err != nil { + return nil, err + } + if err := validateEndBuf(src, cursor); err != nil { + return nil, err + } + return buf, nil +} + +func indentValue( + dst []byte, + src []byte, + indentNum int, + cursor int64, + prefix []byte, + indentBytes []byte, + escape bool) ([]byte, int64, error) { + for { + switch src[cursor] { + case ' ', '\t', '\n', '\r': + cursor++ + continue + case '{': + return indentObject(dst, src, indentNum, cursor, prefix, indentBytes, escape) + case '}': + return nil, 0, errors.ErrSyntax("unexpected character '}'", cursor) + case '[': + return indentArray(dst, src, indentNum, cursor, prefix, indentBytes, escape) + case ']': + return nil, 0, errors.ErrSyntax("unexpected character ']'", cursor) + case '"': + return compactString(dst, src, cursor, escape) + case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + return compactNumber(dst, src, cursor) + case 't': + return compactTrue(dst, src, cursor) + case 'f': + return compactFalse(dst, src, cursor) + case 'n': + return compactNull(dst, src, cursor) + default: + return nil, 0, errors.ErrSyntax(fmt.Sprintf("unexpected character '%c'", src[cursor]), cursor) + } + } +} + +func indentObject( + dst []byte, + src []byte, + indentNum int, + cursor int64, + prefix []byte, + indentBytes []byte, + escape bool) ([]byte, int64, error) { + if src[cursor] == '{' { + dst = append(dst, '{') + } else { + return nil, 0, errors.ErrExpected("expected { character for object value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == '}' { + dst = append(dst, '}') + return dst, cursor + 1, nil + } + indentNum++ + var err error + for { + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum; i++ { + dst = append(dst, indentBytes...) + } + cursor = skipWhiteSpace(src, cursor) + dst, cursor, err = compactString(dst, src, cursor, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + if src[cursor] != ':' { + return nil, 0, errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after object key", src[cursor]), + cursor+1, + ) + } + dst = append(dst, ':', ' ') + dst, cursor, err = indentValue(dst, src, indentNum, cursor+1, prefix, indentBytes, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case '}': + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum-1; i++ { + dst = append(dst, indentBytes...) + } + dst = append(dst, '}') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after object key:value pair", src[cursor]), + cursor+1, + ) + } + cursor++ + } +} + +func indentArray( + dst []byte, + src []byte, + indentNum int, + cursor int64, + prefix []byte, + indentBytes []byte, + escape bool) ([]byte, int64, error) { + if src[cursor] == '[' { + dst = append(dst, '[') + } else { + return nil, 0, errors.ErrExpected("expected [ character for array value", cursor) + } + cursor = skipWhiteSpace(src, cursor+1) + if src[cursor] == ']' { + dst = append(dst, ']') + return dst, cursor + 1, nil + } + indentNum++ + var err error + for { + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum; i++ { + dst = append(dst, indentBytes...) + } + dst, cursor, err = indentValue(dst, src, indentNum, cursor, prefix, indentBytes, escape) + if err != nil { + return nil, 0, err + } + cursor = skipWhiteSpace(src, cursor) + switch src[cursor] { + case ']': + dst = append(append(dst, '\n'), prefix...) + for i := 0; i < indentNum-1; i++ { + dst = append(dst, indentBytes...) + } + dst = append(dst, ']') + cursor++ + return dst, cursor, nil + case ',': + dst = append(dst, ',') + default: + return nil, 0, errors.ErrSyntax( + fmt.Sprintf("invalid character '%c' after array value", src[cursor]), + cursor+1, + ) + } + cursor++ + } +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/int.go b/vendor/github.com/goccy/go-json/internal/encoder/int.go new file mode 100644 index 000000000..3a3482d5b --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/int.go @@ -0,0 +1,130 @@ +package encoder + +import ( + "unsafe" +) + +var endianness int + +func init() { + var b [2]byte + *(*uint16)(unsafe.Pointer(&b)) = uint16(0xABCD) + + switch b[0] { + case 0xCD: + endianness = 0 // LE + case 0xAB: + endianness = 1 // BE + default: + panic("could not determine endianness") + } +} + +// "00010203...96979899" cast to []uint16 +var intLELookup = [100]uint16{ + 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, 0x3830, 0x3930, + 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, 0x3831, 0x3931, + 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, 0x3832, 0x3932, + 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, 0x3833, 0x3933, + 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, 0x3834, 0x3934, + 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, 0x3835, 0x3935, + 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, 0x3836, 0x3936, + 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, 0x3837, 0x3937, + 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, 0x3838, 0x3938, + 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, 0x3839, 0x3939, +} + +var intBELookup = [100]uint16{ + 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, + 0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139, + 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239, + 0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339, + 0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439, + 0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539, + 0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639, + 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, + 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839, + 0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, +} + +var intLookup = [2]*[100]uint16{&intLELookup, &intBELookup} + +func numMask(numBitSize uint8) uint64 { + return 1<>(code.NumBitSize-1))&1 == 1 + if !negative { + if n < 10 { + return append(out, byte(n+'0')) + } else if n < 100 { + u := intLELookup[n] + return append(out, byte(u), byte(u>>8)) + } + } else { + n = -n & mask + } + + lookup := intLookup[endianness] + + var b [22]byte + u := (*[11]uint16)(unsafe.Pointer(&b)) + i := 11 + + for n >= 100 { + j := n % 100 + n /= 100 + i-- + u[i] = lookup[j] + } + + i-- + u[i] = lookup[n] + + i *= 2 // convert to byte index + if n < 10 { + i++ // remove leading zero + } + if negative { + i-- + b[i] = '-' + } + + return append(out, b[i:]...) +} + +func AppendUint(_ *RuntimeContext, out []byte, u64 uint64, code *Opcode) []byte { + mask := numMask(code.NumBitSize) + n := u64 & mask + if n < 10 { + return append(out, byte(n+'0')) + } else if n < 100 { + u := intLELookup[n] + return append(out, byte(u), byte(u>>8)) + } + + lookup := intLookup[endianness] + + var b [22]byte + u := (*[11]uint16)(unsafe.Pointer(&b)) + i := 11 + + for n >= 100 { + j := n % 100 + n /= 100 + i-- + u[i] = lookup[j] + } + + i-- + u[i] = lookup[n] + + i *= 2 // convert to byte index + if n < 10 { + i++ // remove leading zero + } + return append(out, b[i:]...) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map112.go b/vendor/github.com/goccy/go-json/internal/encoder/map112.go new file mode 100644 index 000000000..31858d000 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/map112.go @@ -0,0 +1,8 @@ +// +build !go1.13 + +package encoder + +import "unsafe" + +//go:linkname MapIterValue reflect.mapitervalue +func MapIterValue(it unsafe.Pointer) unsafe.Pointer diff --git a/vendor/github.com/goccy/go-json/internal/encoder/map113.go b/vendor/github.com/goccy/go-json/internal/encoder/map113.go new file mode 100644 index 000000000..f49c27bed --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/map113.go @@ -0,0 +1,8 @@ +// +build go1.13 + +package encoder + +import "unsafe" + +//go:linkname MapIterValue reflect.mapiterelem +func MapIterValue(it unsafe.Pointer) unsafe.Pointer diff --git a/vendor/github.com/goccy/go-json/internal/encoder/opcode.go b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go new file mode 100644 index 000000000..c23a90b2e --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/opcode.go @@ -0,0 +1,766 @@ +package encoder + +import ( + "fmt" + "strings" + "unsafe" + + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +type OpFlags uint16 + +const ( + AnonymousHeadFlags OpFlags = 1 << 0 + AnonymousKeyFlags OpFlags = 1 << 1 + IndirectFlags OpFlags = 1 << 2 + IsTaggedKeyFlags OpFlags = 1 << 3 + NilCheckFlags OpFlags = 1 << 4 + AddrForMarshalerFlags OpFlags = 1 << 5 + IsNextOpPtrTypeFlags OpFlags = 1 << 6 + IsNilableTypeFlags OpFlags = 1 << 7 + MarshalerContextFlags OpFlags = 1 << 8 +) + +type Opcode struct { + Op OpType // operation type + Idx uint32 // offset to access ptr + Next *Opcode // next opcode + End *Opcode // array/slice/struct/map end + NextField *Opcode // next struct field + Key string // struct field key + Offset uint32 // offset size from struct header + PtrNum uint8 // pointer number: e.g. double pointer is 2. + NumBitSize uint8 + Flags OpFlags + + Type *runtime.Type // go type + PrevField *Opcode // prev struct field + Jmp *CompiledCode // for recursive call + ElemIdx uint32 // offset to access array/slice/map elem + Length uint32 // offset to access slice/map length or array length + MapIter uint32 // offset to access map iterator + MapPos uint32 // offset to access position list for sorted map + Indent uint32 // indent number + Size uint32 // array/slice elem size + DisplayIdx uint32 // opcode index + DisplayKey string // key text to display +} + +func (c *Opcode) MaxIdx() uint32 { + max := uint32(0) + for _, value := range []uint32{ + c.Idx, + c.ElemIdx, + c.Length, + c.MapIter, + c.MapPos, + c.Size, + } { + if max < value { + max = value + } + } + return max +} + +func (c *Opcode) ToHeaderType(isString bool) OpType { + switch c.Op { + case OpInt: + if isString { + return OpStructHeadIntString + } + return OpStructHeadInt + case OpIntPtr: + if isString { + return OpStructHeadIntPtrString + } + return OpStructHeadIntPtr + case OpUint: + if isString { + return OpStructHeadUintString + } + return OpStructHeadUint + case OpUintPtr: + if isString { + return OpStructHeadUintPtrString + } + return OpStructHeadUintPtr + case OpFloat32: + if isString { + return OpStructHeadFloat32String + } + return OpStructHeadFloat32 + case OpFloat32Ptr: + if isString { + return OpStructHeadFloat32PtrString + } + return OpStructHeadFloat32Ptr + case OpFloat64: + if isString { + return OpStructHeadFloat64String + } + return OpStructHeadFloat64 + case OpFloat64Ptr: + if isString { + return OpStructHeadFloat64PtrString + } + return OpStructHeadFloat64Ptr + case OpString: + if isString { + return OpStructHeadStringString + } + return OpStructHeadString + case OpStringPtr: + if isString { + return OpStructHeadStringPtrString + } + return OpStructHeadStringPtr + case OpNumber: + if isString { + return OpStructHeadNumberString + } + return OpStructHeadNumber + case OpNumberPtr: + if isString { + return OpStructHeadNumberPtrString + } + return OpStructHeadNumberPtr + case OpBool: + if isString { + return OpStructHeadBoolString + } + return OpStructHeadBool + case OpBoolPtr: + if isString { + return OpStructHeadBoolPtrString + } + return OpStructHeadBoolPtr + case OpBytes: + return OpStructHeadBytes + case OpBytesPtr: + return OpStructHeadBytesPtr + case OpMap: + return OpStructHeadMap + case OpMapPtr: + c.Op = OpMap + return OpStructHeadMapPtr + case OpArray: + return OpStructHeadArray + case OpArrayPtr: + c.Op = OpArray + return OpStructHeadArrayPtr + case OpSlice: + return OpStructHeadSlice + case OpSlicePtr: + c.Op = OpSlice + return OpStructHeadSlicePtr + case OpMarshalJSON: + return OpStructHeadMarshalJSON + case OpMarshalJSONPtr: + return OpStructHeadMarshalJSONPtr + case OpMarshalText: + return OpStructHeadMarshalText + case OpMarshalTextPtr: + return OpStructHeadMarshalTextPtr + } + return OpStructHead +} + +func (c *Opcode) ToFieldType(isString bool) OpType { + switch c.Op { + case OpInt: + if isString { + return OpStructFieldIntString + } + return OpStructFieldInt + case OpIntPtr: + if isString { + return OpStructFieldIntPtrString + } + return OpStructFieldIntPtr + case OpUint: + if isString { + return OpStructFieldUintString + } + return OpStructFieldUint + case OpUintPtr: + if isString { + return OpStructFieldUintPtrString + } + return OpStructFieldUintPtr + case OpFloat32: + if isString { + return OpStructFieldFloat32String + } + return OpStructFieldFloat32 + case OpFloat32Ptr: + if isString { + return OpStructFieldFloat32PtrString + } + return OpStructFieldFloat32Ptr + case OpFloat64: + if isString { + return OpStructFieldFloat64String + } + return OpStructFieldFloat64 + case OpFloat64Ptr: + if isString { + return OpStructFieldFloat64PtrString + } + return OpStructFieldFloat64Ptr + case OpString: + if isString { + return OpStructFieldStringString + } + return OpStructFieldString + case OpStringPtr: + if isString { + return OpStructFieldStringPtrString + } + return OpStructFieldStringPtr + case OpNumber: + if isString { + return OpStructFieldNumberString + } + return OpStructFieldNumber + case OpNumberPtr: + if isString { + return OpStructFieldNumberPtrString + } + return OpStructFieldNumberPtr + case OpBool: + if isString { + return OpStructFieldBoolString + } + return OpStructFieldBool + case OpBoolPtr: + if isString { + return OpStructFieldBoolPtrString + } + return OpStructFieldBoolPtr + case OpBytes: + return OpStructFieldBytes + case OpBytesPtr: + return OpStructFieldBytesPtr + case OpMap: + return OpStructFieldMap + case OpMapPtr: + c.Op = OpMap + return OpStructFieldMapPtr + case OpArray: + return OpStructFieldArray + case OpArrayPtr: + c.Op = OpArray + return OpStructFieldArrayPtr + case OpSlice: + return OpStructFieldSlice + case OpSlicePtr: + c.Op = OpSlice + return OpStructFieldSlicePtr + case OpMarshalJSON: + return OpStructFieldMarshalJSON + case OpMarshalJSONPtr: + return OpStructFieldMarshalJSONPtr + case OpMarshalText: + return OpStructFieldMarshalText + case OpMarshalTextPtr: + return OpStructFieldMarshalTextPtr + } + return OpStructField +} + +func newOpCode(ctx *compileContext, op OpType) *Opcode { + return newOpCodeWithNext(ctx, op, newEndOp(ctx)) +} + +func opcodeOffset(idx int) uint32 { + return uint32(idx) * uintptrSize +} + +func copyOpcode(code *Opcode) *Opcode { + codeMap := map[uintptr]*Opcode{} + return code.copy(codeMap) +} + +func setTotalLengthToInterfaceOp(code *Opcode) { + c := code + for c.Op != OpEnd && c.Op != OpInterfaceEnd { + if c.Op == OpInterface { + c.Length = uint32(code.TotalLength()) + } + switch c.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + c = c.End + default: + c = c.Next + } + } +} + +func ToEndCode(code *Opcode) *Opcode { + c := code + for c.Op != OpEnd && c.Op != OpInterfaceEnd { + switch c.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + c = c.End + default: + c = c.Next + } + } + return c +} + +func copyToInterfaceOpcode(code *Opcode) *Opcode { + copied := copyOpcode(code) + c := copied + c = ToEndCode(c) + c.Idx += uintptrSize + c.ElemIdx = c.Idx + uintptrSize + c.Length = c.Idx + 2*uintptrSize + c.Op = OpInterfaceEnd + return copied +} + +func newOpCodeWithNext(ctx *compileContext, op OpType, next *Opcode) *Opcode { + return &Opcode{ + Op: op, + Idx: opcodeOffset(ctx.ptrIndex), + Next: next, + Type: ctx.typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } +} + +func newEndOp(ctx *compileContext) *Opcode { + return newOpCodeWithNext(ctx, OpEnd, nil) +} + +func (c *Opcode) copy(codeMap map[uintptr]*Opcode) *Opcode { + if c == nil { + return nil + } + addr := uintptr(unsafe.Pointer(c)) + if code, exists := codeMap[addr]; exists { + return code + } + copied := &Opcode{ + Op: c.Op, + Key: c.Key, + PtrNum: c.PtrNum, + NumBitSize: c.NumBitSize, + Flags: c.Flags, + Idx: c.Idx, + Offset: c.Offset, + Type: c.Type, + DisplayIdx: c.DisplayIdx, + DisplayKey: c.DisplayKey, + ElemIdx: c.ElemIdx, + Length: c.Length, + MapIter: c.MapIter, + MapPos: c.MapPos, + Size: c.Size, + Indent: c.Indent, + } + codeMap[addr] = copied + copied.End = c.End.copy(codeMap) + copied.PrevField = c.PrevField.copy(codeMap) + copied.NextField = c.NextField.copy(codeMap) + copied.Next = c.Next.copy(codeMap) + copied.Jmp = c.Jmp + return copied +} + +func (c *Opcode) BeforeLastCode() *Opcode { + code := c + for { + var nextCode *Opcode + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + nextCode = code.End + default: + nextCode = code.Next + } + if nextCode.Op == OpEnd { + return code + } + code = nextCode + } +} + +func (c *Opcode) TotalLength() int { + var idx int + code := c + for code.Op != OpEnd && code.Op != OpInterfaceEnd { + maxIdx := int(code.MaxIdx() / uintptrSize) + if idx < maxIdx { + idx = maxIdx + } + if code.Op == OpRecursiveEnd { + break + } + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + code = code.End + default: + code = code.Next + } + } + maxIdx := int(code.MaxIdx() / uintptrSize) + if idx < maxIdx { + idx = maxIdx + } + return idx + 1 +} + +func (c *Opcode) decOpcodeIndex() { + for code := c; code.Op != OpEnd; { + code.DisplayIdx-- + if code.Idx > 0 { + code.Idx -= uintptrSize + } + if code.ElemIdx > 0 { + code.ElemIdx -= uintptrSize + } + if code.MapIter > 0 { + code.MapIter -= uintptrSize + } + if code.Length > 0 && code.Op.CodeType() != CodeArrayHead && code.Op.CodeType() != CodeArrayElem { + code.Length -= uintptrSize + } + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + code = code.End + default: + code = code.Next + } + } +} + +func (c *Opcode) decIndent() { + for code := c; code.Op != OpEnd; { + code.Indent-- + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + code = code.End + default: + code = code.Next + } + } +} + +func (c *Opcode) dumpHead(code *Opcode) string { + var length uint32 + if code.Op.CodeType() == CodeArrayHead { + length = code.Length + } else { + length = code.Length / uintptrSize + } + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.ElemIdx/uintptrSize, + length, + ) +} + +func (c *Opcode) dumpMapHead(code *Opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][mapIter:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.ElemIdx/uintptrSize, + code.Length/uintptrSize, + code.MapIter/uintptrSize, + ) +} + +func (c *Opcode) dumpMapEnd(code *Opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][mapPos:%d][length:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.MapPos/uintptrSize, + code.Length/uintptrSize, + ) +} + +func (c *Opcode) dumpElem(code *Opcode) string { + var length uint32 + if code.Op.CodeType() == CodeArrayElem { + length = code.Length + } else { + length = code.Length / uintptrSize + } + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][size:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.ElemIdx/uintptrSize, + length, + code.Size, + ) +} + +func (c *Opcode) dumpField(code *Opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][key:%s][offset:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.DisplayKey, + code.Offset, + ) +} + +func (c *Opcode) dumpKey(code *Opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][elemIdx:%d][length:%d][mapIter:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.ElemIdx/uintptrSize, + code.Length/uintptrSize, + code.MapIter/uintptrSize, + ) +} + +func (c *Opcode) dumpValue(code *Opcode) string { + return fmt.Sprintf( + `[%d]%s%s ([idx:%d][mapIter:%d])`, + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + code.MapIter/uintptrSize, + ) +} + +func (c *Opcode) Dump() string { + codes := []string{} + for code := c; code.Op != OpEnd && code.Op != OpInterfaceEnd; { + switch code.Op.CodeType() { + case CodeSliceHead: + codes = append(codes, c.dumpHead(code)) + code = code.Next + case CodeMapHead: + codes = append(codes, c.dumpMapHead(code)) + code = code.Next + case CodeArrayElem, CodeSliceElem: + codes = append(codes, c.dumpElem(code)) + code = code.End + case CodeMapKey: + codes = append(codes, c.dumpKey(code)) + code = code.End + case CodeMapValue: + codes = append(codes, c.dumpValue(code)) + code = code.Next + case CodeMapEnd: + codes = append(codes, c.dumpMapEnd(code)) + code = code.Next + case CodeStructField: + codes = append(codes, c.dumpField(code)) + code = code.Next + case CodeStructEnd: + codes = append(codes, c.dumpField(code)) + code = code.Next + default: + codes = append(codes, fmt.Sprintf( + "[%d]%s%s ([idx:%d])", + code.DisplayIdx, + strings.Repeat("-", int(code.Indent)), + code.Op, + code.Idx/uintptrSize, + )) + code = code.Next + } + } + return strings.Join(codes, "\n") +} + +func prevField(code *Opcode, removedFields map[*Opcode]struct{}) *Opcode { + if _, exists := removedFields[code]; exists { + return prevField(code.PrevField, removedFields) + } + return code +} + +func nextField(code *Opcode, removedFields map[*Opcode]struct{}) *Opcode { + if _, exists := removedFields[code]; exists { + return nextField(code.NextField, removedFields) + } + return code +} + +func linkPrevToNextField(cur *Opcode, removedFields map[*Opcode]struct{}) { + prev := prevField(cur.PrevField, removedFields) + prev.NextField = nextField(cur.NextField, removedFields) + code := prev + fcode := cur + for { + var nextCode *Opcode + switch code.Op.CodeType() { + case CodeArrayElem, CodeSliceElem, CodeMapKey: + nextCode = code.End + default: + nextCode = code.Next + } + if nextCode == fcode { + code.Next = fcode.Next + break + } else if nextCode.Op == OpEnd { + break + } + code = nextCode + } +} + +func newSliceHeaderCode(ctx *compileContext) *Opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + length := opcodeOffset(ctx.ptrIndex) + return &Opcode{ + Op: OpSlice, + Idx: idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: elemIdx, + Length: length, + Indent: ctx.indent, + } +} + +func newSliceElemCode(ctx *compileContext, head *Opcode, size uintptr) *Opcode { + return &Opcode{ + Op: OpSliceElem, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: head.ElemIdx, + Length: head.Length, + Indent: ctx.indent, + Size: uint32(size), + } +} + +func newArrayHeaderCode(ctx *compileContext, alen int) *Opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + return &Opcode{ + Op: OpArray, + Idx: idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: elemIdx, + Indent: ctx.indent, + Length: uint32(alen), + } +} + +func newArrayElemCode(ctx *compileContext, head *Opcode, length int, size uintptr) *Opcode { + return &Opcode{ + Op: OpArrayElem, + Idx: head.Idx, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: head.ElemIdx, + Length: uint32(length), + Indent: ctx.indent, + Size: uint32(size), + } +} + +func newMapHeaderCode(ctx *compileContext) *Opcode { + idx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + elemIdx := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + length := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + mapIter := opcodeOffset(ctx.ptrIndex) + return &Opcode{ + Op: OpMap, + Idx: idx, + Type: ctx.typ, + DisplayIdx: ctx.opcodeIndex, + ElemIdx: elemIdx, + Length: length, + MapIter: mapIter, + Indent: ctx.indent, + } +} + +func newMapKeyCode(ctx *compileContext, head *Opcode) *Opcode { + return &Opcode{ + Op: OpMapKey, + Idx: opcodeOffset(ctx.ptrIndex), + DisplayIdx: ctx.opcodeIndex, + ElemIdx: head.ElemIdx, + Length: head.Length, + MapIter: head.MapIter, + Indent: ctx.indent, + } +} + +func newMapValueCode(ctx *compileContext, head *Opcode) *Opcode { + return &Opcode{ + Op: OpMapValue, + Idx: opcodeOffset(ctx.ptrIndex), + DisplayIdx: ctx.opcodeIndex, + ElemIdx: head.ElemIdx, + Length: head.Length, + MapIter: head.MapIter, + Indent: ctx.indent, + } +} + +func newMapEndCode(ctx *compileContext, head *Opcode) *Opcode { + mapPos := opcodeOffset(ctx.ptrIndex) + ctx.incPtrIndex() + idx := opcodeOffset(ctx.ptrIndex) + return &Opcode{ + Op: OpMapEnd, + Idx: idx, + Next: newEndOp(ctx), + DisplayIdx: ctx.opcodeIndex, + Length: head.Length, + MapPos: mapPos, + Indent: ctx.indent, + } +} + +func newInterfaceCode(ctx *compileContext) *Opcode { + return &Opcode{ + Op: OpInterface, + Idx: opcodeOffset(ctx.ptrIndex), + Next: newEndOp(ctx), + Type: ctx.typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + } +} + +func newRecursiveCode(ctx *compileContext, jmp *CompiledCode) *Opcode { + return &Opcode{ + Op: OpRecursive, + Idx: opcodeOffset(ctx.ptrIndex), + Next: newEndOp(ctx), + Type: ctx.typ, + DisplayIdx: ctx.opcodeIndex, + Indent: ctx.indent, + Jmp: jmp, + } +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/option.go b/vendor/github.com/goccy/go-json/internal/encoder/option.go new file mode 100644 index 000000000..f5f1f044e --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/option.go @@ -0,0 +1,41 @@ +package encoder + +import "context" + +type OptionFlag uint8 + +const ( + HTMLEscapeOption OptionFlag = 1 << iota + IndentOption + UnorderedMapOption + DebugOption + ColorizeOption + ContextOption +) + +type Option struct { + Flag OptionFlag + ColorScheme *ColorScheme + Context context.Context +} + +type EncodeFormat struct { + Header string + Footer string +} + +type EncodeFormatScheme struct { + Int EncodeFormat + Uint EncodeFormat + Float EncodeFormat + Bool EncodeFormat + String EncodeFormat + Binary EncodeFormat + ObjectKey EncodeFormat + Null EncodeFormat +} + +type ( + ColorScheme = EncodeFormatScheme + ColorFormat = EncodeFormat +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/optype.go b/vendor/github.com/goccy/go-json/internal/encoder/optype.go new file mode 100644 index 000000000..335fc043e --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/optype.go @@ -0,0 +1,934 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package encoder + +import ( + "strings" +) + +type CodeType int + +const ( + CodeOp CodeType = 0 + CodeArrayHead CodeType = 1 + CodeArrayElem CodeType = 2 + CodeSliceHead CodeType = 3 + CodeSliceElem CodeType = 4 + CodeMapHead CodeType = 5 + CodeMapKey CodeType = 6 + CodeMapValue CodeType = 7 + CodeMapEnd CodeType = 8 + CodeRecursive CodeType = 9 + CodeStructField CodeType = 10 + CodeStructEnd CodeType = 11 +) + +var opTypeStrings = [401]string{ + "End", + "Interface", + "Ptr", + "SliceElem", + "SliceEnd", + "ArrayElem", + "ArrayEnd", + "MapKey", + "MapValue", + "MapEnd", + "Recursive", + "RecursivePtr", + "RecursiveEnd", + "InterfaceEnd", + "StructAnonymousEnd", + "Int", + "Uint", + "Float32", + "Float64", + "Bool", + "String", + "Bytes", + "Number", + "Array", + "Map", + "Slice", + "Struct", + "MarshalJSON", + "MarshalText", + "IntString", + "UintString", + "Float32String", + "Float64String", + "BoolString", + "StringString", + "NumberString", + "IntPtr", + "UintPtr", + "Float32Ptr", + "Float64Ptr", + "BoolPtr", + "StringPtr", + "BytesPtr", + "NumberPtr", + "ArrayPtr", + "MapPtr", + "SlicePtr", + "MarshalJSONPtr", + "MarshalTextPtr", + "InterfacePtr", + "IntPtrString", + "UintPtrString", + "Float32PtrString", + "Float64PtrString", + "BoolPtrString", + "StringPtrString", + "NumberPtrString", + "StructHeadInt", + "StructHeadOmitEmptyInt", + "StructPtrHeadInt", + "StructPtrHeadOmitEmptyInt", + "StructHeadUint", + "StructHeadOmitEmptyUint", + "StructPtrHeadUint", + "StructPtrHeadOmitEmptyUint", + "StructHeadFloat32", + "StructHeadOmitEmptyFloat32", + "StructPtrHeadFloat32", + "StructPtrHeadOmitEmptyFloat32", + "StructHeadFloat64", + "StructHeadOmitEmptyFloat64", + "StructPtrHeadFloat64", + "StructPtrHeadOmitEmptyFloat64", + "StructHeadBool", + "StructHeadOmitEmptyBool", + "StructPtrHeadBool", + "StructPtrHeadOmitEmptyBool", + "StructHeadString", + "StructHeadOmitEmptyString", + "StructPtrHeadString", + "StructPtrHeadOmitEmptyString", + "StructHeadBytes", + "StructHeadOmitEmptyBytes", + "StructPtrHeadBytes", + "StructPtrHeadOmitEmptyBytes", + "StructHeadNumber", + "StructHeadOmitEmptyNumber", + "StructPtrHeadNumber", + "StructPtrHeadOmitEmptyNumber", + "StructHeadArray", + "StructHeadOmitEmptyArray", + "StructPtrHeadArray", + "StructPtrHeadOmitEmptyArray", + "StructHeadMap", + "StructHeadOmitEmptyMap", + "StructPtrHeadMap", + "StructPtrHeadOmitEmptyMap", + "StructHeadSlice", + "StructHeadOmitEmptySlice", + "StructPtrHeadSlice", + "StructPtrHeadOmitEmptySlice", + "StructHeadStruct", + "StructHeadOmitEmptyStruct", + "StructPtrHeadStruct", + "StructPtrHeadOmitEmptyStruct", + "StructHeadMarshalJSON", + "StructHeadOmitEmptyMarshalJSON", + "StructPtrHeadMarshalJSON", + "StructPtrHeadOmitEmptyMarshalJSON", + "StructHeadMarshalText", + "StructHeadOmitEmptyMarshalText", + "StructPtrHeadMarshalText", + "StructPtrHeadOmitEmptyMarshalText", + "StructHeadIntString", + "StructHeadOmitEmptyIntString", + "StructPtrHeadIntString", + "StructPtrHeadOmitEmptyIntString", + "StructHeadUintString", + "StructHeadOmitEmptyUintString", + "StructPtrHeadUintString", + "StructPtrHeadOmitEmptyUintString", + "StructHeadFloat32String", + "StructHeadOmitEmptyFloat32String", + "StructPtrHeadFloat32String", + "StructPtrHeadOmitEmptyFloat32String", + "StructHeadFloat64String", + "StructHeadOmitEmptyFloat64String", + "StructPtrHeadFloat64String", + "StructPtrHeadOmitEmptyFloat64String", + "StructHeadBoolString", + "StructHeadOmitEmptyBoolString", + "StructPtrHeadBoolString", + "StructPtrHeadOmitEmptyBoolString", + "StructHeadStringString", + "StructHeadOmitEmptyStringString", + "StructPtrHeadStringString", + "StructPtrHeadOmitEmptyStringString", + "StructHeadNumberString", + "StructHeadOmitEmptyNumberString", + "StructPtrHeadNumberString", + "StructPtrHeadOmitEmptyNumberString", + "StructHeadIntPtr", + "StructHeadOmitEmptyIntPtr", + "StructPtrHeadIntPtr", + "StructPtrHeadOmitEmptyIntPtr", + "StructHeadUintPtr", + "StructHeadOmitEmptyUintPtr", + "StructPtrHeadUintPtr", + "StructPtrHeadOmitEmptyUintPtr", + "StructHeadFloat32Ptr", + "StructHeadOmitEmptyFloat32Ptr", + "StructPtrHeadFloat32Ptr", + "StructPtrHeadOmitEmptyFloat32Ptr", + "StructHeadFloat64Ptr", + "StructHeadOmitEmptyFloat64Ptr", + "StructPtrHeadFloat64Ptr", + "StructPtrHeadOmitEmptyFloat64Ptr", + "StructHeadBoolPtr", + "StructHeadOmitEmptyBoolPtr", + "StructPtrHeadBoolPtr", + "StructPtrHeadOmitEmptyBoolPtr", + "StructHeadStringPtr", + "StructHeadOmitEmptyStringPtr", + "StructPtrHeadStringPtr", + "StructPtrHeadOmitEmptyStringPtr", + "StructHeadBytesPtr", + "StructHeadOmitEmptyBytesPtr", + "StructPtrHeadBytesPtr", + "StructPtrHeadOmitEmptyBytesPtr", + "StructHeadNumberPtr", + "StructHeadOmitEmptyNumberPtr", + "StructPtrHeadNumberPtr", + "StructPtrHeadOmitEmptyNumberPtr", + "StructHeadArrayPtr", + "StructHeadOmitEmptyArrayPtr", + "StructPtrHeadArrayPtr", + "StructPtrHeadOmitEmptyArrayPtr", + "StructHeadMapPtr", + "StructHeadOmitEmptyMapPtr", + "StructPtrHeadMapPtr", + "StructPtrHeadOmitEmptyMapPtr", + "StructHeadSlicePtr", + "StructHeadOmitEmptySlicePtr", + "StructPtrHeadSlicePtr", + "StructPtrHeadOmitEmptySlicePtr", + "StructHeadMarshalJSONPtr", + "StructHeadOmitEmptyMarshalJSONPtr", + "StructPtrHeadMarshalJSONPtr", + "StructPtrHeadOmitEmptyMarshalJSONPtr", + "StructHeadMarshalTextPtr", + "StructHeadOmitEmptyMarshalTextPtr", + "StructPtrHeadMarshalTextPtr", + "StructPtrHeadOmitEmptyMarshalTextPtr", + "StructHeadInterfacePtr", + "StructHeadOmitEmptyInterfacePtr", + "StructPtrHeadInterfacePtr", + "StructPtrHeadOmitEmptyInterfacePtr", + "StructHeadIntPtrString", + "StructHeadOmitEmptyIntPtrString", + "StructPtrHeadIntPtrString", + "StructPtrHeadOmitEmptyIntPtrString", + "StructHeadUintPtrString", + "StructHeadOmitEmptyUintPtrString", + "StructPtrHeadUintPtrString", + "StructPtrHeadOmitEmptyUintPtrString", + "StructHeadFloat32PtrString", + "StructHeadOmitEmptyFloat32PtrString", + "StructPtrHeadFloat32PtrString", + "StructPtrHeadOmitEmptyFloat32PtrString", + "StructHeadFloat64PtrString", + "StructHeadOmitEmptyFloat64PtrString", + "StructPtrHeadFloat64PtrString", + "StructPtrHeadOmitEmptyFloat64PtrString", + "StructHeadBoolPtrString", + "StructHeadOmitEmptyBoolPtrString", + "StructPtrHeadBoolPtrString", + "StructPtrHeadOmitEmptyBoolPtrString", + "StructHeadStringPtrString", + "StructHeadOmitEmptyStringPtrString", + "StructPtrHeadStringPtrString", + "StructPtrHeadOmitEmptyStringPtrString", + "StructHeadNumberPtrString", + "StructHeadOmitEmptyNumberPtrString", + "StructPtrHeadNumberPtrString", + "StructPtrHeadOmitEmptyNumberPtrString", + "StructHead", + "StructHeadOmitEmpty", + "StructPtrHead", + "StructPtrHeadOmitEmpty", + "StructFieldInt", + "StructFieldOmitEmptyInt", + "StructEndInt", + "StructEndOmitEmptyInt", + "StructFieldUint", + "StructFieldOmitEmptyUint", + "StructEndUint", + "StructEndOmitEmptyUint", + "StructFieldFloat32", + "StructFieldOmitEmptyFloat32", + "StructEndFloat32", + "StructEndOmitEmptyFloat32", + "StructFieldFloat64", + "StructFieldOmitEmptyFloat64", + "StructEndFloat64", + "StructEndOmitEmptyFloat64", + "StructFieldBool", + "StructFieldOmitEmptyBool", + "StructEndBool", + "StructEndOmitEmptyBool", + "StructFieldString", + "StructFieldOmitEmptyString", + "StructEndString", + "StructEndOmitEmptyString", + "StructFieldBytes", + "StructFieldOmitEmptyBytes", + "StructEndBytes", + "StructEndOmitEmptyBytes", + "StructFieldNumber", + "StructFieldOmitEmptyNumber", + "StructEndNumber", + "StructEndOmitEmptyNumber", + "StructFieldArray", + "StructFieldOmitEmptyArray", + "StructEndArray", + "StructEndOmitEmptyArray", + "StructFieldMap", + "StructFieldOmitEmptyMap", + "StructEndMap", + "StructEndOmitEmptyMap", + "StructFieldSlice", + "StructFieldOmitEmptySlice", + "StructEndSlice", + "StructEndOmitEmptySlice", + "StructFieldStruct", + "StructFieldOmitEmptyStruct", + "StructEndStruct", + "StructEndOmitEmptyStruct", + "StructFieldMarshalJSON", + "StructFieldOmitEmptyMarshalJSON", + "StructEndMarshalJSON", + "StructEndOmitEmptyMarshalJSON", + "StructFieldMarshalText", + "StructFieldOmitEmptyMarshalText", + "StructEndMarshalText", + "StructEndOmitEmptyMarshalText", + "StructFieldIntString", + "StructFieldOmitEmptyIntString", + "StructEndIntString", + "StructEndOmitEmptyIntString", + "StructFieldUintString", + "StructFieldOmitEmptyUintString", + "StructEndUintString", + "StructEndOmitEmptyUintString", + "StructFieldFloat32String", + "StructFieldOmitEmptyFloat32String", + "StructEndFloat32String", + "StructEndOmitEmptyFloat32String", + "StructFieldFloat64String", + "StructFieldOmitEmptyFloat64String", + "StructEndFloat64String", + "StructEndOmitEmptyFloat64String", + "StructFieldBoolString", + "StructFieldOmitEmptyBoolString", + "StructEndBoolString", + "StructEndOmitEmptyBoolString", + "StructFieldStringString", + "StructFieldOmitEmptyStringString", + "StructEndStringString", + "StructEndOmitEmptyStringString", + "StructFieldNumberString", + "StructFieldOmitEmptyNumberString", + "StructEndNumberString", + "StructEndOmitEmptyNumberString", + "StructFieldIntPtr", + "StructFieldOmitEmptyIntPtr", + "StructEndIntPtr", + "StructEndOmitEmptyIntPtr", + "StructFieldUintPtr", + "StructFieldOmitEmptyUintPtr", + "StructEndUintPtr", + "StructEndOmitEmptyUintPtr", + "StructFieldFloat32Ptr", + "StructFieldOmitEmptyFloat32Ptr", + "StructEndFloat32Ptr", + "StructEndOmitEmptyFloat32Ptr", + "StructFieldFloat64Ptr", + "StructFieldOmitEmptyFloat64Ptr", + "StructEndFloat64Ptr", + "StructEndOmitEmptyFloat64Ptr", + "StructFieldBoolPtr", + "StructFieldOmitEmptyBoolPtr", + "StructEndBoolPtr", + "StructEndOmitEmptyBoolPtr", + "StructFieldStringPtr", + "StructFieldOmitEmptyStringPtr", + "StructEndStringPtr", + "StructEndOmitEmptyStringPtr", + "StructFieldBytesPtr", + "StructFieldOmitEmptyBytesPtr", + "StructEndBytesPtr", + "StructEndOmitEmptyBytesPtr", + "StructFieldNumberPtr", + "StructFieldOmitEmptyNumberPtr", + "StructEndNumberPtr", + "StructEndOmitEmptyNumberPtr", + "StructFieldArrayPtr", + "StructFieldOmitEmptyArrayPtr", + "StructEndArrayPtr", + "StructEndOmitEmptyArrayPtr", + "StructFieldMapPtr", + "StructFieldOmitEmptyMapPtr", + "StructEndMapPtr", + "StructEndOmitEmptyMapPtr", + "StructFieldSlicePtr", + "StructFieldOmitEmptySlicePtr", + "StructEndSlicePtr", + "StructEndOmitEmptySlicePtr", + "StructFieldMarshalJSONPtr", + "StructFieldOmitEmptyMarshalJSONPtr", + "StructEndMarshalJSONPtr", + "StructEndOmitEmptyMarshalJSONPtr", + "StructFieldMarshalTextPtr", + "StructFieldOmitEmptyMarshalTextPtr", + "StructEndMarshalTextPtr", + "StructEndOmitEmptyMarshalTextPtr", + "StructFieldInterfacePtr", + "StructFieldOmitEmptyInterfacePtr", + "StructEndInterfacePtr", + "StructEndOmitEmptyInterfacePtr", + "StructFieldIntPtrString", + "StructFieldOmitEmptyIntPtrString", + "StructEndIntPtrString", + "StructEndOmitEmptyIntPtrString", + "StructFieldUintPtrString", + "StructFieldOmitEmptyUintPtrString", + "StructEndUintPtrString", + "StructEndOmitEmptyUintPtrString", + "StructFieldFloat32PtrString", + "StructFieldOmitEmptyFloat32PtrString", + "StructEndFloat32PtrString", + "StructEndOmitEmptyFloat32PtrString", + "StructFieldFloat64PtrString", + "StructFieldOmitEmptyFloat64PtrString", + "StructEndFloat64PtrString", + "StructEndOmitEmptyFloat64PtrString", + "StructFieldBoolPtrString", + "StructFieldOmitEmptyBoolPtrString", + "StructEndBoolPtrString", + "StructEndOmitEmptyBoolPtrString", + "StructFieldStringPtrString", + "StructFieldOmitEmptyStringPtrString", + "StructEndStringPtrString", + "StructEndOmitEmptyStringPtrString", + "StructFieldNumberPtrString", + "StructFieldOmitEmptyNumberPtrString", + "StructEndNumberPtrString", + "StructEndOmitEmptyNumberPtrString", + "StructField", + "StructFieldOmitEmpty", + "StructEnd", + "StructEndOmitEmpty", +} + +type OpType uint16 + +const ( + OpEnd OpType = 0 + OpInterface OpType = 1 + OpPtr OpType = 2 + OpSliceElem OpType = 3 + OpSliceEnd OpType = 4 + OpArrayElem OpType = 5 + OpArrayEnd OpType = 6 + OpMapKey OpType = 7 + OpMapValue OpType = 8 + OpMapEnd OpType = 9 + OpRecursive OpType = 10 + OpRecursivePtr OpType = 11 + OpRecursiveEnd OpType = 12 + OpInterfaceEnd OpType = 13 + OpStructAnonymousEnd OpType = 14 + OpInt OpType = 15 + OpUint OpType = 16 + OpFloat32 OpType = 17 + OpFloat64 OpType = 18 + OpBool OpType = 19 + OpString OpType = 20 + OpBytes OpType = 21 + OpNumber OpType = 22 + OpArray OpType = 23 + OpMap OpType = 24 + OpSlice OpType = 25 + OpStruct OpType = 26 + OpMarshalJSON OpType = 27 + OpMarshalText OpType = 28 + OpIntString OpType = 29 + OpUintString OpType = 30 + OpFloat32String OpType = 31 + OpFloat64String OpType = 32 + OpBoolString OpType = 33 + OpStringString OpType = 34 + OpNumberString OpType = 35 + OpIntPtr OpType = 36 + OpUintPtr OpType = 37 + OpFloat32Ptr OpType = 38 + OpFloat64Ptr OpType = 39 + OpBoolPtr OpType = 40 + OpStringPtr OpType = 41 + OpBytesPtr OpType = 42 + OpNumberPtr OpType = 43 + OpArrayPtr OpType = 44 + OpMapPtr OpType = 45 + OpSlicePtr OpType = 46 + OpMarshalJSONPtr OpType = 47 + OpMarshalTextPtr OpType = 48 + OpInterfacePtr OpType = 49 + OpIntPtrString OpType = 50 + OpUintPtrString OpType = 51 + OpFloat32PtrString OpType = 52 + OpFloat64PtrString OpType = 53 + OpBoolPtrString OpType = 54 + OpStringPtrString OpType = 55 + OpNumberPtrString OpType = 56 + OpStructHeadInt OpType = 57 + OpStructHeadOmitEmptyInt OpType = 58 + OpStructPtrHeadInt OpType = 59 + OpStructPtrHeadOmitEmptyInt OpType = 60 + OpStructHeadUint OpType = 61 + OpStructHeadOmitEmptyUint OpType = 62 + OpStructPtrHeadUint OpType = 63 + OpStructPtrHeadOmitEmptyUint OpType = 64 + OpStructHeadFloat32 OpType = 65 + OpStructHeadOmitEmptyFloat32 OpType = 66 + OpStructPtrHeadFloat32 OpType = 67 + OpStructPtrHeadOmitEmptyFloat32 OpType = 68 + OpStructHeadFloat64 OpType = 69 + OpStructHeadOmitEmptyFloat64 OpType = 70 + OpStructPtrHeadFloat64 OpType = 71 + OpStructPtrHeadOmitEmptyFloat64 OpType = 72 + OpStructHeadBool OpType = 73 + OpStructHeadOmitEmptyBool OpType = 74 + OpStructPtrHeadBool OpType = 75 + OpStructPtrHeadOmitEmptyBool OpType = 76 + OpStructHeadString OpType = 77 + OpStructHeadOmitEmptyString OpType = 78 + OpStructPtrHeadString OpType = 79 + OpStructPtrHeadOmitEmptyString OpType = 80 + OpStructHeadBytes OpType = 81 + OpStructHeadOmitEmptyBytes OpType = 82 + OpStructPtrHeadBytes OpType = 83 + OpStructPtrHeadOmitEmptyBytes OpType = 84 + OpStructHeadNumber OpType = 85 + OpStructHeadOmitEmptyNumber OpType = 86 + OpStructPtrHeadNumber OpType = 87 + OpStructPtrHeadOmitEmptyNumber OpType = 88 + OpStructHeadArray OpType = 89 + OpStructHeadOmitEmptyArray OpType = 90 + OpStructPtrHeadArray OpType = 91 + OpStructPtrHeadOmitEmptyArray OpType = 92 + OpStructHeadMap OpType = 93 + OpStructHeadOmitEmptyMap OpType = 94 + OpStructPtrHeadMap OpType = 95 + OpStructPtrHeadOmitEmptyMap OpType = 96 + OpStructHeadSlice OpType = 97 + OpStructHeadOmitEmptySlice OpType = 98 + OpStructPtrHeadSlice OpType = 99 + OpStructPtrHeadOmitEmptySlice OpType = 100 + OpStructHeadStruct OpType = 101 + OpStructHeadOmitEmptyStruct OpType = 102 + OpStructPtrHeadStruct OpType = 103 + OpStructPtrHeadOmitEmptyStruct OpType = 104 + OpStructHeadMarshalJSON OpType = 105 + OpStructHeadOmitEmptyMarshalJSON OpType = 106 + OpStructPtrHeadMarshalJSON OpType = 107 + OpStructPtrHeadOmitEmptyMarshalJSON OpType = 108 + OpStructHeadMarshalText OpType = 109 + OpStructHeadOmitEmptyMarshalText OpType = 110 + OpStructPtrHeadMarshalText OpType = 111 + OpStructPtrHeadOmitEmptyMarshalText OpType = 112 + OpStructHeadIntString OpType = 113 + OpStructHeadOmitEmptyIntString OpType = 114 + OpStructPtrHeadIntString OpType = 115 + OpStructPtrHeadOmitEmptyIntString OpType = 116 + OpStructHeadUintString OpType = 117 + OpStructHeadOmitEmptyUintString OpType = 118 + OpStructPtrHeadUintString OpType = 119 + OpStructPtrHeadOmitEmptyUintString OpType = 120 + OpStructHeadFloat32String OpType = 121 + OpStructHeadOmitEmptyFloat32String OpType = 122 + OpStructPtrHeadFloat32String OpType = 123 + OpStructPtrHeadOmitEmptyFloat32String OpType = 124 + OpStructHeadFloat64String OpType = 125 + OpStructHeadOmitEmptyFloat64String OpType = 126 + OpStructPtrHeadFloat64String OpType = 127 + OpStructPtrHeadOmitEmptyFloat64String OpType = 128 + OpStructHeadBoolString OpType = 129 + OpStructHeadOmitEmptyBoolString OpType = 130 + OpStructPtrHeadBoolString OpType = 131 + OpStructPtrHeadOmitEmptyBoolString OpType = 132 + OpStructHeadStringString OpType = 133 + OpStructHeadOmitEmptyStringString OpType = 134 + OpStructPtrHeadStringString OpType = 135 + OpStructPtrHeadOmitEmptyStringString OpType = 136 + OpStructHeadNumberString OpType = 137 + OpStructHeadOmitEmptyNumberString OpType = 138 + OpStructPtrHeadNumberString OpType = 139 + OpStructPtrHeadOmitEmptyNumberString OpType = 140 + OpStructHeadIntPtr OpType = 141 + OpStructHeadOmitEmptyIntPtr OpType = 142 + OpStructPtrHeadIntPtr OpType = 143 + OpStructPtrHeadOmitEmptyIntPtr OpType = 144 + OpStructHeadUintPtr OpType = 145 + OpStructHeadOmitEmptyUintPtr OpType = 146 + OpStructPtrHeadUintPtr OpType = 147 + OpStructPtrHeadOmitEmptyUintPtr OpType = 148 + OpStructHeadFloat32Ptr OpType = 149 + OpStructHeadOmitEmptyFloat32Ptr OpType = 150 + OpStructPtrHeadFloat32Ptr OpType = 151 + OpStructPtrHeadOmitEmptyFloat32Ptr OpType = 152 + OpStructHeadFloat64Ptr OpType = 153 + OpStructHeadOmitEmptyFloat64Ptr OpType = 154 + OpStructPtrHeadFloat64Ptr OpType = 155 + OpStructPtrHeadOmitEmptyFloat64Ptr OpType = 156 + OpStructHeadBoolPtr OpType = 157 + OpStructHeadOmitEmptyBoolPtr OpType = 158 + OpStructPtrHeadBoolPtr OpType = 159 + OpStructPtrHeadOmitEmptyBoolPtr OpType = 160 + OpStructHeadStringPtr OpType = 161 + OpStructHeadOmitEmptyStringPtr OpType = 162 + OpStructPtrHeadStringPtr OpType = 163 + OpStructPtrHeadOmitEmptyStringPtr OpType = 164 + OpStructHeadBytesPtr OpType = 165 + OpStructHeadOmitEmptyBytesPtr OpType = 166 + OpStructPtrHeadBytesPtr OpType = 167 + OpStructPtrHeadOmitEmptyBytesPtr OpType = 168 + OpStructHeadNumberPtr OpType = 169 + OpStructHeadOmitEmptyNumberPtr OpType = 170 + OpStructPtrHeadNumberPtr OpType = 171 + OpStructPtrHeadOmitEmptyNumberPtr OpType = 172 + OpStructHeadArrayPtr OpType = 173 + OpStructHeadOmitEmptyArrayPtr OpType = 174 + OpStructPtrHeadArrayPtr OpType = 175 + OpStructPtrHeadOmitEmptyArrayPtr OpType = 176 + OpStructHeadMapPtr OpType = 177 + OpStructHeadOmitEmptyMapPtr OpType = 178 + OpStructPtrHeadMapPtr OpType = 179 + OpStructPtrHeadOmitEmptyMapPtr OpType = 180 + OpStructHeadSlicePtr OpType = 181 + OpStructHeadOmitEmptySlicePtr OpType = 182 + OpStructPtrHeadSlicePtr OpType = 183 + OpStructPtrHeadOmitEmptySlicePtr OpType = 184 + OpStructHeadMarshalJSONPtr OpType = 185 + OpStructHeadOmitEmptyMarshalJSONPtr OpType = 186 + OpStructPtrHeadMarshalJSONPtr OpType = 187 + OpStructPtrHeadOmitEmptyMarshalJSONPtr OpType = 188 + OpStructHeadMarshalTextPtr OpType = 189 + OpStructHeadOmitEmptyMarshalTextPtr OpType = 190 + OpStructPtrHeadMarshalTextPtr OpType = 191 + OpStructPtrHeadOmitEmptyMarshalTextPtr OpType = 192 + OpStructHeadInterfacePtr OpType = 193 + OpStructHeadOmitEmptyInterfacePtr OpType = 194 + OpStructPtrHeadInterfacePtr OpType = 195 + OpStructPtrHeadOmitEmptyInterfacePtr OpType = 196 + OpStructHeadIntPtrString OpType = 197 + OpStructHeadOmitEmptyIntPtrString OpType = 198 + OpStructPtrHeadIntPtrString OpType = 199 + OpStructPtrHeadOmitEmptyIntPtrString OpType = 200 + OpStructHeadUintPtrString OpType = 201 + OpStructHeadOmitEmptyUintPtrString OpType = 202 + OpStructPtrHeadUintPtrString OpType = 203 + OpStructPtrHeadOmitEmptyUintPtrString OpType = 204 + OpStructHeadFloat32PtrString OpType = 205 + OpStructHeadOmitEmptyFloat32PtrString OpType = 206 + OpStructPtrHeadFloat32PtrString OpType = 207 + OpStructPtrHeadOmitEmptyFloat32PtrString OpType = 208 + OpStructHeadFloat64PtrString OpType = 209 + OpStructHeadOmitEmptyFloat64PtrString OpType = 210 + OpStructPtrHeadFloat64PtrString OpType = 211 + OpStructPtrHeadOmitEmptyFloat64PtrString OpType = 212 + OpStructHeadBoolPtrString OpType = 213 + OpStructHeadOmitEmptyBoolPtrString OpType = 214 + OpStructPtrHeadBoolPtrString OpType = 215 + OpStructPtrHeadOmitEmptyBoolPtrString OpType = 216 + OpStructHeadStringPtrString OpType = 217 + OpStructHeadOmitEmptyStringPtrString OpType = 218 + OpStructPtrHeadStringPtrString OpType = 219 + OpStructPtrHeadOmitEmptyStringPtrString OpType = 220 + OpStructHeadNumberPtrString OpType = 221 + OpStructHeadOmitEmptyNumberPtrString OpType = 222 + OpStructPtrHeadNumberPtrString OpType = 223 + OpStructPtrHeadOmitEmptyNumberPtrString OpType = 224 + OpStructHead OpType = 225 + OpStructHeadOmitEmpty OpType = 226 + OpStructPtrHead OpType = 227 + OpStructPtrHeadOmitEmpty OpType = 228 + OpStructFieldInt OpType = 229 + OpStructFieldOmitEmptyInt OpType = 230 + OpStructEndInt OpType = 231 + OpStructEndOmitEmptyInt OpType = 232 + OpStructFieldUint OpType = 233 + OpStructFieldOmitEmptyUint OpType = 234 + OpStructEndUint OpType = 235 + OpStructEndOmitEmptyUint OpType = 236 + OpStructFieldFloat32 OpType = 237 + OpStructFieldOmitEmptyFloat32 OpType = 238 + OpStructEndFloat32 OpType = 239 + OpStructEndOmitEmptyFloat32 OpType = 240 + OpStructFieldFloat64 OpType = 241 + OpStructFieldOmitEmptyFloat64 OpType = 242 + OpStructEndFloat64 OpType = 243 + OpStructEndOmitEmptyFloat64 OpType = 244 + OpStructFieldBool OpType = 245 + OpStructFieldOmitEmptyBool OpType = 246 + OpStructEndBool OpType = 247 + OpStructEndOmitEmptyBool OpType = 248 + OpStructFieldString OpType = 249 + OpStructFieldOmitEmptyString OpType = 250 + OpStructEndString OpType = 251 + OpStructEndOmitEmptyString OpType = 252 + OpStructFieldBytes OpType = 253 + OpStructFieldOmitEmptyBytes OpType = 254 + OpStructEndBytes OpType = 255 + OpStructEndOmitEmptyBytes OpType = 256 + OpStructFieldNumber OpType = 257 + OpStructFieldOmitEmptyNumber OpType = 258 + OpStructEndNumber OpType = 259 + OpStructEndOmitEmptyNumber OpType = 260 + OpStructFieldArray OpType = 261 + OpStructFieldOmitEmptyArray OpType = 262 + OpStructEndArray OpType = 263 + OpStructEndOmitEmptyArray OpType = 264 + OpStructFieldMap OpType = 265 + OpStructFieldOmitEmptyMap OpType = 266 + OpStructEndMap OpType = 267 + OpStructEndOmitEmptyMap OpType = 268 + OpStructFieldSlice OpType = 269 + OpStructFieldOmitEmptySlice OpType = 270 + OpStructEndSlice OpType = 271 + OpStructEndOmitEmptySlice OpType = 272 + OpStructFieldStruct OpType = 273 + OpStructFieldOmitEmptyStruct OpType = 274 + OpStructEndStruct OpType = 275 + OpStructEndOmitEmptyStruct OpType = 276 + OpStructFieldMarshalJSON OpType = 277 + OpStructFieldOmitEmptyMarshalJSON OpType = 278 + OpStructEndMarshalJSON OpType = 279 + OpStructEndOmitEmptyMarshalJSON OpType = 280 + OpStructFieldMarshalText OpType = 281 + OpStructFieldOmitEmptyMarshalText OpType = 282 + OpStructEndMarshalText OpType = 283 + OpStructEndOmitEmptyMarshalText OpType = 284 + OpStructFieldIntString OpType = 285 + OpStructFieldOmitEmptyIntString OpType = 286 + OpStructEndIntString OpType = 287 + OpStructEndOmitEmptyIntString OpType = 288 + OpStructFieldUintString OpType = 289 + OpStructFieldOmitEmptyUintString OpType = 290 + OpStructEndUintString OpType = 291 + OpStructEndOmitEmptyUintString OpType = 292 + OpStructFieldFloat32String OpType = 293 + OpStructFieldOmitEmptyFloat32String OpType = 294 + OpStructEndFloat32String OpType = 295 + OpStructEndOmitEmptyFloat32String OpType = 296 + OpStructFieldFloat64String OpType = 297 + OpStructFieldOmitEmptyFloat64String OpType = 298 + OpStructEndFloat64String OpType = 299 + OpStructEndOmitEmptyFloat64String OpType = 300 + OpStructFieldBoolString OpType = 301 + OpStructFieldOmitEmptyBoolString OpType = 302 + OpStructEndBoolString OpType = 303 + OpStructEndOmitEmptyBoolString OpType = 304 + OpStructFieldStringString OpType = 305 + OpStructFieldOmitEmptyStringString OpType = 306 + OpStructEndStringString OpType = 307 + OpStructEndOmitEmptyStringString OpType = 308 + OpStructFieldNumberString OpType = 309 + OpStructFieldOmitEmptyNumberString OpType = 310 + OpStructEndNumberString OpType = 311 + OpStructEndOmitEmptyNumberString OpType = 312 + OpStructFieldIntPtr OpType = 313 + OpStructFieldOmitEmptyIntPtr OpType = 314 + OpStructEndIntPtr OpType = 315 + OpStructEndOmitEmptyIntPtr OpType = 316 + OpStructFieldUintPtr OpType = 317 + OpStructFieldOmitEmptyUintPtr OpType = 318 + OpStructEndUintPtr OpType = 319 + OpStructEndOmitEmptyUintPtr OpType = 320 + OpStructFieldFloat32Ptr OpType = 321 + OpStructFieldOmitEmptyFloat32Ptr OpType = 322 + OpStructEndFloat32Ptr OpType = 323 + OpStructEndOmitEmptyFloat32Ptr OpType = 324 + OpStructFieldFloat64Ptr OpType = 325 + OpStructFieldOmitEmptyFloat64Ptr OpType = 326 + OpStructEndFloat64Ptr OpType = 327 + OpStructEndOmitEmptyFloat64Ptr OpType = 328 + OpStructFieldBoolPtr OpType = 329 + OpStructFieldOmitEmptyBoolPtr OpType = 330 + OpStructEndBoolPtr OpType = 331 + OpStructEndOmitEmptyBoolPtr OpType = 332 + OpStructFieldStringPtr OpType = 333 + OpStructFieldOmitEmptyStringPtr OpType = 334 + OpStructEndStringPtr OpType = 335 + OpStructEndOmitEmptyStringPtr OpType = 336 + OpStructFieldBytesPtr OpType = 337 + OpStructFieldOmitEmptyBytesPtr OpType = 338 + OpStructEndBytesPtr OpType = 339 + OpStructEndOmitEmptyBytesPtr OpType = 340 + OpStructFieldNumberPtr OpType = 341 + OpStructFieldOmitEmptyNumberPtr OpType = 342 + OpStructEndNumberPtr OpType = 343 + OpStructEndOmitEmptyNumberPtr OpType = 344 + OpStructFieldArrayPtr OpType = 345 + OpStructFieldOmitEmptyArrayPtr OpType = 346 + OpStructEndArrayPtr OpType = 347 + OpStructEndOmitEmptyArrayPtr OpType = 348 + OpStructFieldMapPtr OpType = 349 + OpStructFieldOmitEmptyMapPtr OpType = 350 + OpStructEndMapPtr OpType = 351 + OpStructEndOmitEmptyMapPtr OpType = 352 + OpStructFieldSlicePtr OpType = 353 + OpStructFieldOmitEmptySlicePtr OpType = 354 + OpStructEndSlicePtr OpType = 355 + OpStructEndOmitEmptySlicePtr OpType = 356 + OpStructFieldMarshalJSONPtr OpType = 357 + OpStructFieldOmitEmptyMarshalJSONPtr OpType = 358 + OpStructEndMarshalJSONPtr OpType = 359 + OpStructEndOmitEmptyMarshalJSONPtr OpType = 360 + OpStructFieldMarshalTextPtr OpType = 361 + OpStructFieldOmitEmptyMarshalTextPtr OpType = 362 + OpStructEndMarshalTextPtr OpType = 363 + OpStructEndOmitEmptyMarshalTextPtr OpType = 364 + OpStructFieldInterfacePtr OpType = 365 + OpStructFieldOmitEmptyInterfacePtr OpType = 366 + OpStructEndInterfacePtr OpType = 367 + OpStructEndOmitEmptyInterfacePtr OpType = 368 + OpStructFieldIntPtrString OpType = 369 + OpStructFieldOmitEmptyIntPtrString OpType = 370 + OpStructEndIntPtrString OpType = 371 + OpStructEndOmitEmptyIntPtrString OpType = 372 + OpStructFieldUintPtrString OpType = 373 + OpStructFieldOmitEmptyUintPtrString OpType = 374 + OpStructEndUintPtrString OpType = 375 + OpStructEndOmitEmptyUintPtrString OpType = 376 + OpStructFieldFloat32PtrString OpType = 377 + OpStructFieldOmitEmptyFloat32PtrString OpType = 378 + OpStructEndFloat32PtrString OpType = 379 + OpStructEndOmitEmptyFloat32PtrString OpType = 380 + OpStructFieldFloat64PtrString OpType = 381 + OpStructFieldOmitEmptyFloat64PtrString OpType = 382 + OpStructEndFloat64PtrString OpType = 383 + OpStructEndOmitEmptyFloat64PtrString OpType = 384 + OpStructFieldBoolPtrString OpType = 385 + OpStructFieldOmitEmptyBoolPtrString OpType = 386 + OpStructEndBoolPtrString OpType = 387 + OpStructEndOmitEmptyBoolPtrString OpType = 388 + OpStructFieldStringPtrString OpType = 389 + OpStructFieldOmitEmptyStringPtrString OpType = 390 + OpStructEndStringPtrString OpType = 391 + OpStructEndOmitEmptyStringPtrString OpType = 392 + OpStructFieldNumberPtrString OpType = 393 + OpStructFieldOmitEmptyNumberPtrString OpType = 394 + OpStructEndNumberPtrString OpType = 395 + OpStructEndOmitEmptyNumberPtrString OpType = 396 + OpStructField OpType = 397 + OpStructFieldOmitEmpty OpType = 398 + OpStructEnd OpType = 399 + OpStructEndOmitEmpty OpType = 400 +) + +func (t OpType) String() string { + if int(t) >= 401 { + return "" + } + return opTypeStrings[int(t)] +} + +func (t OpType) CodeType() CodeType { + if strings.Contains(t.String(), "Struct") { + if strings.Contains(t.String(), "End") { + return CodeStructEnd + } + return CodeStructField + } + switch t { + case OpArray, OpArrayPtr: + return CodeArrayHead + case OpArrayElem: + return CodeArrayElem + case OpSlice, OpSlicePtr: + return CodeSliceHead + case OpSliceElem: + return CodeSliceElem + case OpMap, OpMapPtr: + return CodeMapHead + case OpMapKey: + return CodeMapKey + case OpMapValue: + return CodeMapValue + case OpMapEnd: + return CodeMapEnd + } + + return CodeOp +} + +func (t OpType) HeadToPtrHead() OpType { + if strings.Index(t.String(), "PtrHead") > 0 { + return t + } + + idx := strings.Index(t.String(), "Head") + if idx == -1 { + return t + } + suffix := "PtrHead" + t.String()[idx+len("Head"):] + + const toPtrOffset = 2 + if strings.Contains(OpType(int(t)+toPtrOffset).String(), suffix) { + return OpType(int(t) + toPtrOffset) + } + return t +} + +func (t OpType) HeadToOmitEmptyHead() OpType { + const toOmitEmptyOffset = 1 + if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") { + return OpType(int(t) + toOmitEmptyOffset) + } + + return t +} + +func (t OpType) PtrHeadToHead() OpType { + idx := strings.Index(t.String(), "Ptr") + if idx == -1 { + return t + } + suffix := t.String()[idx+len("Ptr"):] + + const toPtrOffset = 2 + if strings.Contains(OpType(int(t)-toPtrOffset).String(), suffix) { + return OpType(int(t) - toPtrOffset) + } + return t +} + +func (t OpType) FieldToEnd() OpType { + idx := strings.Index(t.String(), "Field") + if idx == -1 { + return t + } + suffix := t.String()[idx+len("Field"):] + if suffix == "" || suffix == "OmitEmpty" { + return t + } + const toEndOffset = 2 + if strings.Contains(OpType(int(t)+toEndOffset).String(), "End"+suffix) { + return OpType(int(t) + toEndOffset) + } + return t +} + +func (t OpType) FieldToOmitEmptyField() OpType { + const toOmitEmptyOffset = 1 + if strings.Contains(OpType(int(t)+toOmitEmptyOffset).String(), "OmitEmpty") { + return OpType(int(t) + toOmitEmptyOffset) + } + return t +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/string.go b/vendor/github.com/goccy/go-json/internal/encoder/string.go new file mode 100644 index 000000000..a699dba19 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/string.go @@ -0,0 +1,640 @@ +package encoder + +import ( + "math/bits" + "reflect" + "unicode/utf8" + "unsafe" +) + +const ( + lsb = 0x0101010101010101 + msb = 0x8080808080808080 +) + +var needEscapeWithHTML = [256]bool{ + '"': true, + '&': true, + '<': true, + '>': true, + '\\': true, + 0x00: true, + 0x01: true, + 0x02: true, + 0x03: true, + 0x04: true, + 0x05: true, + 0x06: true, + 0x07: true, + 0x08: true, + 0x09: true, + 0x0a: true, + 0x0b: true, + 0x0c: true, + 0x0d: true, + 0x0e: true, + 0x0f: true, + 0x10: true, + 0x11: true, + 0x12: true, + 0x13: true, + 0x14: true, + 0x15: true, + 0x16: true, + 0x17: true, + 0x18: true, + 0x19: true, + 0x1a: true, + 0x1b: true, + 0x1c: true, + 0x1d: true, + 0x1e: true, + 0x1f: true, + /* 0x20 - 0x7f */ + 0x80: true, + 0x81: true, + 0x82: true, + 0x83: true, + 0x84: true, + 0x85: true, + 0x86: true, + 0x87: true, + 0x88: true, + 0x89: true, + 0x8a: true, + 0x8b: true, + 0x8c: true, + 0x8d: true, + 0x8e: true, + 0x8f: true, + 0x90: true, + 0x91: true, + 0x92: true, + 0x93: true, + 0x94: true, + 0x95: true, + 0x96: true, + 0x97: true, + 0x98: true, + 0x99: true, + 0x9a: true, + 0x9b: true, + 0x9c: true, + 0x9d: true, + 0x9e: true, + 0x9f: true, + 0xa0: true, + 0xa1: true, + 0xa2: true, + 0xa3: true, + 0xa4: true, + 0xa5: true, + 0xa6: true, + 0xa7: true, + 0xa8: true, + 0xa9: true, + 0xaa: true, + 0xab: true, + 0xac: true, + 0xad: true, + 0xae: true, + 0xaf: true, + 0xb0: true, + 0xb1: true, + 0xb2: true, + 0xb3: true, + 0xb4: true, + 0xb5: true, + 0xb6: true, + 0xb7: true, + 0xb8: true, + 0xb9: true, + 0xba: true, + 0xbb: true, + 0xbc: true, + 0xbd: true, + 0xbe: true, + 0xbf: true, + 0xc0: true, + 0xc1: true, + 0xc2: true, + 0xc3: true, + 0xc4: true, + 0xc5: true, + 0xc6: true, + 0xc7: true, + 0xc8: true, + 0xc9: true, + 0xca: true, + 0xcb: true, + 0xcc: true, + 0xcd: true, + 0xce: true, + 0xcf: true, + 0xd0: true, + 0xd1: true, + 0xd2: true, + 0xd3: true, + 0xd4: true, + 0xd5: true, + 0xd6: true, + 0xd7: true, + 0xd8: true, + 0xd9: true, + 0xda: true, + 0xdb: true, + 0xdc: true, + 0xdd: true, + 0xde: true, + 0xdf: true, + 0xe0: true, + 0xe1: true, + 0xe2: true, + 0xe3: true, + 0xe4: true, + 0xe5: true, + 0xe6: true, + 0xe7: true, + 0xe8: true, + 0xe9: true, + 0xea: true, + 0xeb: true, + 0xec: true, + 0xed: true, + 0xee: true, + 0xef: true, + 0xf0: true, + 0xf1: true, + 0xf2: true, + 0xf3: true, + 0xf4: true, + 0xf5: true, + 0xf6: true, + 0xf7: true, + 0xf8: true, + 0xf9: true, + 0xfa: true, + 0xfb: true, + 0xfc: true, + 0xfd: true, + 0xfe: true, + 0xff: true, +} + +var needEscape = [256]bool{ + '"': true, + '\\': true, + 0x00: true, + 0x01: true, + 0x02: true, + 0x03: true, + 0x04: true, + 0x05: true, + 0x06: true, + 0x07: true, + 0x08: true, + 0x09: true, + 0x0a: true, + 0x0b: true, + 0x0c: true, + 0x0d: true, + 0x0e: true, + 0x0f: true, + 0x10: true, + 0x11: true, + 0x12: true, + 0x13: true, + 0x14: true, + 0x15: true, + 0x16: true, + 0x17: true, + 0x18: true, + 0x19: true, + 0x1a: true, + 0x1b: true, + 0x1c: true, + 0x1d: true, + 0x1e: true, + 0x1f: true, + /* 0x20 - 0x7f */ + 0x80: true, + 0x81: true, + 0x82: true, + 0x83: true, + 0x84: true, + 0x85: true, + 0x86: true, + 0x87: true, + 0x88: true, + 0x89: true, + 0x8a: true, + 0x8b: true, + 0x8c: true, + 0x8d: true, + 0x8e: true, + 0x8f: true, + 0x90: true, + 0x91: true, + 0x92: true, + 0x93: true, + 0x94: true, + 0x95: true, + 0x96: true, + 0x97: true, + 0x98: true, + 0x99: true, + 0x9a: true, + 0x9b: true, + 0x9c: true, + 0x9d: true, + 0x9e: true, + 0x9f: true, + 0xa0: true, + 0xa1: true, + 0xa2: true, + 0xa3: true, + 0xa4: true, + 0xa5: true, + 0xa6: true, + 0xa7: true, + 0xa8: true, + 0xa9: true, + 0xaa: true, + 0xab: true, + 0xac: true, + 0xad: true, + 0xae: true, + 0xaf: true, + 0xb0: true, + 0xb1: true, + 0xb2: true, + 0xb3: true, + 0xb4: true, + 0xb5: true, + 0xb6: true, + 0xb7: true, + 0xb8: true, + 0xb9: true, + 0xba: true, + 0xbb: true, + 0xbc: true, + 0xbd: true, + 0xbe: true, + 0xbf: true, + 0xc0: true, + 0xc1: true, + 0xc2: true, + 0xc3: true, + 0xc4: true, + 0xc5: true, + 0xc6: true, + 0xc7: true, + 0xc8: true, + 0xc9: true, + 0xca: true, + 0xcb: true, + 0xcc: true, + 0xcd: true, + 0xce: true, + 0xcf: true, + 0xd0: true, + 0xd1: true, + 0xd2: true, + 0xd3: true, + 0xd4: true, + 0xd5: true, + 0xd6: true, + 0xd7: true, + 0xd8: true, + 0xd9: true, + 0xda: true, + 0xdb: true, + 0xdc: true, + 0xdd: true, + 0xde: true, + 0xdf: true, + 0xe0: true, + 0xe1: true, + 0xe2: true, + 0xe3: true, + 0xe4: true, + 0xe5: true, + 0xe6: true, + 0xe7: true, + 0xe8: true, + 0xe9: true, + 0xea: true, + 0xeb: true, + 0xec: true, + 0xed: true, + 0xee: true, + 0xef: true, + 0xf0: true, + 0xf1: true, + 0xf2: true, + 0xf3: true, + 0xf4: true, + 0xf5: true, + 0xf6: true, + 0xf7: true, + 0xf8: true, + 0xf9: true, + 0xfa: true, + 0xfb: true, + 0xfc: true, + 0xfd: true, + 0xfe: true, + 0xff: true, +} + +var hex = "0123456789abcdef" + +// escapeIndex finds the index of the first char in `s` that requires escaping. +// A char requires escaping if it's outside of the range of [0x20, 0x7F] or if +// it includes a double quote or backslash. +// If no chars in `s` require escaping, the return value is -1. +func escapeIndex(s string) int { + chunks := stringToUint64Slice(s) + for _, n := range chunks { + // combine masks before checking for the MSB of each byte. We include + // `n` in the mask to check whether any of the *input* byte MSBs were + // set (i.e. the byte was outside the ASCII range). + mask := n | below(n, 0x20) | contains(n, '"') | contains(n, '\\') + if (mask & msb) != 0 { + return bits.TrailingZeros64(mask&msb) / 8 + } + } + + valLen := len(s) + for i := len(chunks) * 8; i < valLen; i++ { + if needEscape[s[i]] { + return i + } + } + + return -1 +} + +// below return a mask that can be used to determine if any of the bytes +// in `n` are below `b`. If a byte's MSB is set in the mask then that byte was +// below `b`. The result is only valid if `b`, and each byte in `n`, is below +// 0x80. +func below(n uint64, b byte) uint64 { + return n - expand(b) +} + +// contains returns a mask that can be used to determine if any of the +// bytes in `n` are equal to `b`. If a byte's MSB is set in the mask then +// that byte is equal to `b`. The result is only valid if `b`, and each +// byte in `n`, is below 0x80. +func contains(n uint64, b byte) uint64 { + return (n ^ expand(b)) - lsb +} + +// expand puts the specified byte into each of the 8 bytes of a uint64. +func expand(b byte) uint64 { + return lsb * uint64(b) +} + +//nolint:govet +func stringToUint64Slice(s string) []uint64 { + return *(*[]uint64)(unsafe.Pointer(&reflect.SliceHeader{ + Data: ((*reflect.StringHeader)(unsafe.Pointer(&s))).Data, + Len: len(s) / 8, + Cap: len(s) / 8, + })) +} + +func AppendString(ctx *RuntimeContext, buf []byte, s string) []byte { + if ctx.Option.Flag&HTMLEscapeOption == 0 { + return appendString(buf, s) + } + valLen := len(s) + if valLen == 0 { + return append(buf, `""`...) + } + buf = append(buf, '"') + var ( + i, j int + ) + if valLen >= 8 { + chunks := stringToUint64Slice(s) + for _, n := range chunks { + // combine masks before checking for the MSB of each byte. We include + // `n` in the mask to check whether any of the *input* byte MSBs were + // set (i.e. the byte was outside the ASCII range). + mask := n | (n - (lsb * 0x20)) | + ((n ^ (lsb * '"')) - lsb) | + ((n ^ (lsb * '\\')) - lsb) | + ((n ^ (lsb * '<')) - lsb) | + ((n ^ (lsb * '>')) - lsb) | + ((n ^ (lsb * '&')) - lsb) + if (mask & msb) != 0 { + j = bits.TrailingZeros64(mask&msb) / 8 + goto ESCAPE_END + } + } + for i := len(chunks) * 8; i < valLen; i++ { + if needEscapeWithHTML[s[i]] { + j = i + goto ESCAPE_END + } + } + // no found any escape characters. + return append(append(buf, s...), '"') + } +ESCAPE_END: + for j < valLen { + c := s[j] + + if !needEscapeWithHTML[c] { + // fast path: most of the time, printable ascii characters are used + j++ + continue + } + + switch c { + case '\\', '"': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', c) + i = j + 1 + j = j + 1 + continue + + case '\n': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'n') + i = j + 1 + j = j + 1 + continue + + case '\r': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'r') + i = j + 1 + j = j + 1 + continue + + case '\t': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 't') + i = j + 1 + j = j + 1 + continue + + case '<', '>', '&': + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + + // This encodes bytes < 0x20 except for \t, \n and \r. + if c < 0x20 { + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + + r, size := utf8.DecodeRuneInString(s[j:]) + + if r == utf8.RuneError && size == 1 { + buf = append(buf, s[i:j]...) + buf = append(buf, `\ufffd`...) + i = j + size + j = j + size + continue + } + + switch r { + case '\u2028', '\u2029': + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + buf = append(buf, s[i:j]...) + buf = append(buf, `\u202`...) + buf = append(buf, hex[r&0xF]) + i = j + size + j = j + size + continue + } + + j += size + } + + return append(append(buf, s[i:]...), '"') +} + +func appendString(buf []byte, s string) []byte { + valLen := len(s) + if valLen == 0 { + return append(buf, `""`...) + } + buf = append(buf, '"') + var escapeIdx int + if valLen >= 8 { + if escapeIdx = escapeIndex(s); escapeIdx < 0 { + return append(append(buf, s...), '"') + } + } + + i := 0 + j := escapeIdx + for j < valLen { + c := s[j] + + if c >= 0x20 && c <= 0x7f && c != '\\' && c != '"' { + // fast path: most of the time, printable ascii characters are used + j++ + continue + } + + switch c { + case '\\', '"': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', c) + i = j + 1 + j = j + 1 + continue + + case '\n': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'n') + i = j + 1 + j = j + 1 + continue + + case '\r': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 'r') + i = j + 1 + j = j + 1 + continue + + case '\t': + buf = append(buf, s[i:j]...) + buf = append(buf, '\\', 't') + i = j + 1 + j = j + 1 + continue + + case '<', '>', '&': + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + + // This encodes bytes < 0x20 except for \t, \n and \r. + if c < 0x20 { + buf = append(buf, s[i:j]...) + buf = append(buf, `\u00`...) + buf = append(buf, hex[c>>4], hex[c&0xF]) + i = j + 1 + j = j + 1 + continue + } + + r, size := utf8.DecodeRuneInString(s[j:]) + + if r == utf8.RuneError && size == 1 { + buf = append(buf, s[i:j]...) + buf = append(buf, `\ufffd`...) + i = j + size + j = j + size + continue + } + + switch r { + case '\u2028', '\u2029': + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + buf = append(buf, s[i:j]...) + buf = append(buf, `\u202`...) + buf = append(buf, hex[r&0xF]) + i = j + size + j = j + size + continue + } + + j += size + } + + return append(append(buf, s[i:]...), '"') +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go new file mode 100644 index 000000000..05509feda --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/debug_vm.go @@ -0,0 +1,34 @@ +package vm + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + defer func() { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + if err := recover(); err != nil { + fmt.Println("=============[DEBUG]===============") + fmt.Println("* [TYPE]") + fmt.Println(codeSet.Type) + fmt.Printf("\n") + fmt.Println("* [ALL OPCODE]") + fmt.Println(code.Dump()) + fmt.Printf("\n") + fmt.Println("* [CONTEXT]") + fmt.Printf("%+v\n", ctx) + fmt.Println("===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go new file mode 100644 index 000000000..65252b4a5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/hack.go @@ -0,0 +1,9 @@ +package vm + +import ( + // HACK: compile order + // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, + // so forcibly make dependencies and avoid compiling in concurrent. + // dependency order: vm => vm_indent => vm_color => vm_color_indent + _ "github.com/goccy/go-json/internal/encoder/vm_indent" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go new file mode 100644 index 000000000..c55944794 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/util.go @@ -0,0 +1,182 @@ +package vm + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + appendInt = encoder.AppendInt + appendUint = encoder.AppendUint + appendFloat32 = encoder.AppendFloat32 + appendFloat64 = encoder.AppendFloat64 + appendString = encoder.AppendString + appendByteSlice = encoder.AppendByteSlice + appendNumber = encoder.AppendNumber + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder: opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + last := len(b) - 1 + b[last] = ':' + return b +} + +func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte { + b = append(b, key...) + b[len(b)-1] = ':' + return append(b, value...) +} + +func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + b[len(b)-1] = '}' + b = append(b, ',') + return b +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSON(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalText(ctx, code, b, v) +} + +func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '[') +} + +func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = ']' + return append(b, ',') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',') +} + +func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '}' + return append(b, ',') +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{') +} + +func appendStructKey(_ *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return append(b, code.Key...) +} + +func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '}', ',') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last] == ',' { + b[last] = '}' + return appendComma(ctx, b) + } + return appendStructEnd(ctx, code, b) +} + +func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {} +func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {} +func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } +func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go new file mode 100644 index 000000000..78da5e449 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm/vm.go @@ -0,0 +1,5041 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm + +import ( + "math" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + iface := (*emptyInterface)(ptrToUnsafePtr(p)) + if iface.ptr == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface)) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(iface.ptr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + iter := mapiterinit(code.Type, uptr) + ctx.KeepRefs = append(ctx.KeepRefs, iter) + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(mlen)) + store(ctxptr, code.MapIter, uintptr(iter)) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx := encoder.NewMapContext(mlen) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + store(ctxptr, code.End.MapPos, uintptr(unsafe.Pointer(mapCtx))) + } + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < length { + b = appendMapKeyIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + code = code.End.Next + } + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + if idx < length { + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + store(ctxptr, code.ElemIdx, idx) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + } + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + value := mapitervalue(iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + length := int(load(ctxptr, code.Length)) + ptr := load(ctxptr, code.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + pos := mapCtx.Pos + for i := 0; i < length; i++ { + startKey := pos[i*2] + startValue := pos[i*2+1] + var endValue int + if i+1 < length { + endValue = pos[i*2+2] + } else { + endValue = len(b) + } + mapCtx.Slice.Items = append(mapCtx.Slice.Items, encoder.MapItem{ + Key: b[startKey:startValue], + Value: b[startValue:endValue], + }) + } + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:pos[0]] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags&encoder.AnonymousKeyFlags) == 0 && len(code.Key) > 0 { + b = appendStructKey(ctx, code, b) + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructAnonymousEnd: + code = code.Next + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go new file mode 100644 index 000000000..6a6a33d22 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/debug_vm.go @@ -0,0 +1,34 @@ +package vm_color + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + defer func() { + if err := recover(); err != nil { + fmt.Println("=============[DEBUG]===============") + fmt.Println("* [TYPE]") + fmt.Println(codeSet.Type) + fmt.Printf("\n") + fmt.Println("* [ALL OPCODE]") + fmt.Println(code.Dump()) + fmt.Printf("\n") + fmt.Println("* [CONTEXT]") + fmt.Printf("%+v\n", ctx) + fmt.Println("===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go new file mode 100644 index 000000000..12ec56c5b --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/hack.go @@ -0,0 +1,9 @@ +package vm_color + +import ( + // HACK: compile order + // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, + // so forcibly make dependencies and avoid compiling in concurrent. + // dependency order: vm => vm_indent => vm_color => vm_color_indent + _ "github.com/goccy/go-json/internal/encoder/vm_color_indent" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go new file mode 100644 index 000000000..516536d74 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/util.go @@ -0,0 +1,246 @@ +package vm_color + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder: opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendInt(ctx *encoder.RuntimeContext, b []byte, v uint64, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + b = encoder.AppendInt(ctx, b, v, code) + return append(b, format.Footer...) +} + +func appendUint(ctx *encoder.RuntimeContext, b []byte, v uint64, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Uint + b = append(b, format.Header...) + b = encoder.AppendUint(ctx, b, v, code) + return append(b, format.Footer...) +} + +func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat32(ctx, b, v) + return append(b, format.Footer...) +} + +func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat64(ctx, b, v) + return append(b, format.Footer...) +} + +func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + b = encoder.AppendString(ctx, b, v) + return append(b, format.Footer...) +} + +func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte { + format := ctx.Option.ColorScheme.Binary + b = append(b, format.Header...) + b = encoder.AppendByteSlice(ctx, b, src) + return append(b, format.Footer...) +} + +func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + bb, err := encoder.AppendNumber(ctx, b, n) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte { + format := ctx.Option.ColorScheme.Bool + b = append(b, format.Header...) + if v { + b = append(b, "true"...) + } else { + b = append(b, "false"...) + } + return append(b, format.Footer...) +} + +func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte { + format := ctx.Option.ColorScheme.Null + b = append(b, format.Header...) + b = append(b, "null"...) + return append(b, format.Footer...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + last := len(b) - 1 + b[last] = ':' + return b +} + +func appendMapKeyValue(_ *encoder.RuntimeContext, _ *encoder.Opcode, b, key, value []byte) []byte { + b = append(b, key[:len(key)-1]...) + b = append(b, ':') + return append(b, value...) +} + +func appendMapEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '}' + b = append(b, ',') + return b +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSON(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + bb, err := encoder.AppendMarshalText(ctx, code, b, v) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendArrayHead(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '[') +} + +func appendArrayEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = ']' + return append(b, ',') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',') +} + +func appendObjectEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '}' + return append(b, ',') +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + format := ctx.Option.ColorScheme.ObjectKey + b = append(b, format.Header...) + b = append(b, code.Key[:len(code.Key)-1]...) + b = append(b, format.Footer...) + + return append(b, ':') +} + +func appendStructEnd(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { + return append(b, '}', ',') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last] == ',' { + b[last] = '}' + return appendComma(ctx, b) + } + return appendStructEnd(ctx, code, b) +} + +func restoreIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, _ uintptr) {} +func storeIndent(_ uintptr, _ *encoder.Opcode, _ uintptr) {} +func appendMapKeyIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } +func appendArrayElemIndent(_ *encoder.RuntimeContext, _ *encoder.Opcode, b []byte) []byte { return b } diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go new file mode 100644 index 000000000..0d4c472a5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color/vm.go @@ -0,0 +1,5041 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_color + +import ( + "math" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + iface := (*emptyInterface)(ptrToUnsafePtr(p)) + if iface.ptr == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface)) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(iface.ptr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + iter := mapiterinit(code.Type, uptr) + ctx.KeepRefs = append(ctx.KeepRefs, iter) + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(mlen)) + store(ctxptr, code.MapIter, uintptr(iter)) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx := encoder.NewMapContext(mlen) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + store(ctxptr, code.End.MapPos, uintptr(unsafe.Pointer(mapCtx))) + } + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < length { + b = appendMapKeyIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + code = code.End.Next + } + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + if idx < length { + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + store(ctxptr, code.ElemIdx, idx) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + } + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + value := mapitervalue(iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + length := int(load(ctxptr, code.Length)) + ptr := load(ctxptr, code.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + pos := mapCtx.Pos + for i := 0; i < length; i++ { + startKey := pos[i*2] + startValue := pos[i*2+1] + var endValue int + if i+1 < length { + endValue = pos[i*2+2] + } else { + endValue = len(b) + } + mapCtx.Slice.Items = append(mapCtx.Slice.Items, encoder.MapItem{ + Key: b[startKey:startValue], + Value: b[startValue:endValue], + }) + } + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:pos[0]] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags&encoder.AnonymousKeyFlags) == 0 && len(code.Key) > 0 { + b = appendStructKey(ctx, code, b) + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructAnonymousEnd: + code = code.Next + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go new file mode 100644 index 000000000..a68bbf6bf --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/debug_vm.go @@ -0,0 +1,34 @@ +package vm_color_indent + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + defer func() { + if err := recover(); err != nil { + fmt.Println("=============[DEBUG]===============") + fmt.Println("* [TYPE]") + fmt.Println(codeSet.Type) + fmt.Printf("\n") + fmt.Println("* [ALL OPCODE]") + fmt.Println(code.Dump()) + fmt.Printf("\n") + fmt.Println("* [CONTEXT]") + fmt.Printf("%+v\n", ctx) + fmt.Println("===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go new file mode 100644 index 000000000..9f98781b8 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/util.go @@ -0,0 +1,267 @@ +package vm_color_indent + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + appendIndent = encoder.AppendIndent + appendStructEnd = encoder.AppendStructEndIndent + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendInt(ctx *encoder.RuntimeContext, b []byte, v uint64, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + b = encoder.AppendInt(ctx, b, v, code) + return append(b, format.Footer...) +} + +func appendUint(ctx *encoder.RuntimeContext, b []byte, v uint64, code *encoder.Opcode) []byte { + format := ctx.Option.ColorScheme.Uint + b = append(b, format.Header...) + b = encoder.AppendUint(ctx, b, v, code) + return append(b, format.Footer...) +} + +func appendFloat32(ctx *encoder.RuntimeContext, b []byte, v float32) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat32(ctx, b, v) + return append(b, format.Footer...) +} + +func appendFloat64(ctx *encoder.RuntimeContext, b []byte, v float64) []byte { + format := ctx.Option.ColorScheme.Float + b = append(b, format.Header...) + b = encoder.AppendFloat64(ctx, b, v) + return append(b, format.Footer...) +} + +func appendString(ctx *encoder.RuntimeContext, b []byte, v string) []byte { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + b = encoder.AppendString(ctx, b, v) + return append(b, format.Footer...) +} + +func appendByteSlice(ctx *encoder.RuntimeContext, b []byte, src []byte) []byte { + format := ctx.Option.ColorScheme.Binary + b = append(b, format.Header...) + b = encoder.AppendByteSlice(ctx, b, src) + return append(b, format.Footer...) +} + +func appendNumber(ctx *encoder.RuntimeContext, b []byte, n json.Number) ([]byte, error) { + format := ctx.Option.ColorScheme.Int + b = append(b, format.Header...) + bb, err := encoder.AppendNumber(ctx, b, n) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendBool(ctx *encoder.RuntimeContext, b []byte, v bool) []byte { + format := ctx.Option.ColorScheme.Bool + b = append(b, format.Header...) + if v { + b = append(b, "true"...) + } else { + b = append(b, "false"...) + } + return append(b, format.Footer...) +} + +func appendNull(ctx *encoder.RuntimeContext, b []byte) []byte { + format := ctx.Option.ColorScheme.Null + b = append(b, format.Header...) + b = append(b, "null"...) + return append(b, format.Footer...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',', '\n') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ':', ' ') +} + +func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { + b = appendIndent(ctx, b, code.Indent+1) + b = append(b, key...) + b[len(b)-2] = ':' + b[len(b)-1] = ' ' + return append(b, value...) +} + +func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, '}', ',', '\n') +} + +func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = append(b, '[', '\n') + return appendIndent(ctx, b, code.Indent+1) +} + +func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, ']', ',', '\n') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',', '\n') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',', '\n') +} + +func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '\n' + b = appendIndent(ctx, b, code.Indent-1) + return append(b, '}', ',', '\n') +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSONIndent(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + format := ctx.Option.ColorScheme.String + b = append(b, format.Header...) + bb, err := encoder.AppendMarshalTextIndent(ctx, code, b, v) + if err != nil { + return nil, err + } + return append(bb, format.Footer...), nil +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '\n') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = appendIndent(ctx, b, code.Indent) + + format := ctx.Option.ColorScheme.ObjectKey + b = append(b, format.Header...) + b = append(b, code.Key[:len(code.Key)-1]...) + b = append(b, format.Footer...) + + return append(b, ':', ' ') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last-1] == '{' { + b[last] = '}' + } else { + if b[last] == '\n' { + // to remove ',' and '\n' characters + b = b[:len(b)-2] + } + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent-1) + b = append(b, '}') + } + return appendComma(ctx, b) +} + +func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) { + ctx.BaseIndent = uint32(load(ctxptr, code.Length)) +} + +func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { + store(ctxptr, code.Length, indent) +} + +func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent+1) +} + +func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go new file mode 100644 index 000000000..de8b858f9 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_color_indent/vm.go @@ -0,0 +1,5041 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_color_indent + +import ( + "math" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + iface := (*emptyInterface)(ptrToUnsafePtr(p)) + if iface.ptr == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface)) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(iface.ptr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + iter := mapiterinit(code.Type, uptr) + ctx.KeepRefs = append(ctx.KeepRefs, iter) + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(mlen)) + store(ctxptr, code.MapIter, uintptr(iter)) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx := encoder.NewMapContext(mlen) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + store(ctxptr, code.End.MapPos, uintptr(unsafe.Pointer(mapCtx))) + } + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < length { + b = appendMapKeyIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + code = code.End.Next + } + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + if idx < length { + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + store(ctxptr, code.ElemIdx, idx) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + } + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + value := mapitervalue(iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + length := int(load(ctxptr, code.Length)) + ptr := load(ctxptr, code.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + pos := mapCtx.Pos + for i := 0; i < length; i++ { + startKey := pos[i*2] + startValue := pos[i*2+1] + var endValue int + if i+1 < length { + endValue = pos[i*2+2] + } else { + endValue = len(b) + } + mapCtx.Slice.Items = append(mapCtx.Slice.Items, encoder.MapItem{ + Key: b[startKey:startValue], + Value: b[startValue:endValue], + }) + } + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:pos[0]] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags&encoder.AnonymousKeyFlags) == 0 && len(code.Key) > 0 { + b = appendStructKey(ctx, code, b) + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructAnonymousEnd: + code = code.Next + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go new file mode 100644 index 000000000..4cfd17ab2 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/debug_vm.go @@ -0,0 +1,34 @@ +package vm_indent + +import ( + "fmt" + + "github.com/goccy/go-json/internal/encoder" +) + +func DebugRun(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + defer func() { + if err := recover(); err != nil { + fmt.Println("=============[DEBUG]===============") + fmt.Println("* [TYPE]") + fmt.Println(codeSet.Type) + fmt.Printf("\n") + fmt.Println("* [ALL OPCODE]") + fmt.Println(code.Dump()) + fmt.Printf("\n") + fmt.Println("* [CONTEXT]") + fmt.Printf("%+v\n", ctx) + fmt.Println("===================================") + panic(err) + } + }() + + return Run(ctx, b, codeSet) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go new file mode 100644 index 000000000..9e245bfe5 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/hack.go @@ -0,0 +1,9 @@ +package vm_indent + +import ( + // HACK: compile order + // `vm`, `vm_indent`, `vm_color`, `vm_color_indent` packages uses a lot of memory to compile, + // so forcibly make dependencies and avoid compiling in concurrent. + // dependency order: vm => vm_indent => vm_color => vm_color_indent + _ "github.com/goccy/go-json/internal/encoder/vm_color" +) diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go new file mode 100644 index 000000000..5f5d8a58f --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/util.go @@ -0,0 +1,204 @@ +package vm_indent + +import ( + "encoding/json" + "fmt" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" + "github.com/goccy/go-json/internal/runtime" +) + +const uintptrSize = 4 << (^uintptr(0) >> 63) + +var ( + appendInt = encoder.AppendInt + appendUint = encoder.AppendUint + appendFloat32 = encoder.AppendFloat32 + appendFloat64 = encoder.AppendFloat64 + appendString = encoder.AppendString + appendByteSlice = encoder.AppendByteSlice + appendNumber = encoder.AppendNumber + appendStructEnd = encoder.AppendStructEndIndent + appendIndent = encoder.AppendIndent + errUnsupportedValue = encoder.ErrUnsupportedValue + errUnsupportedFloat = encoder.ErrUnsupportedFloat + mapiterinit = encoder.MapIterInit + mapiterkey = encoder.MapIterKey + mapitervalue = encoder.MapIterValue + mapiternext = encoder.MapIterNext + maplen = encoder.MapLen +) + +type emptyInterface struct { + typ *runtime.Type + ptr unsafe.Pointer +} + +func errUnimplementedOp(op encoder.OpType) error { + return fmt.Errorf("encoder (indent): opcode %s has not been implemented", op) +} + +func load(base uintptr, idx uint32) uintptr { + addr := base + uintptr(idx) + return **(**uintptr)(unsafe.Pointer(&addr)) +} + +func store(base uintptr, idx uint32, p uintptr) { + addr := base + uintptr(idx) + **(**uintptr)(unsafe.Pointer(&addr)) = p +} + +func loadNPtr(base uintptr, idx uint32, ptrNum uint8) uintptr { + addr := base + uintptr(idx) + p := **(**uintptr)(unsafe.Pointer(&addr)) + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUint64(p uintptr) uint64 { return **(**uint64)(unsafe.Pointer(&p)) } +func ptrToFloat32(p uintptr) float32 { return **(**float32)(unsafe.Pointer(&p)) } +func ptrToFloat64(p uintptr) float64 { return **(**float64)(unsafe.Pointer(&p)) } +func ptrToBool(p uintptr) bool { return **(**bool)(unsafe.Pointer(&p)) } +func ptrToBytes(p uintptr) []byte { return **(**[]byte)(unsafe.Pointer(&p)) } +func ptrToNumber(p uintptr) json.Number { return **(**json.Number)(unsafe.Pointer(&p)) } +func ptrToString(p uintptr) string { return **(**string)(unsafe.Pointer(&p)) } +func ptrToSlice(p uintptr) *runtime.SliceHeader { return *(**runtime.SliceHeader)(unsafe.Pointer(&p)) } +func ptrToPtr(p uintptr) uintptr { + return uintptr(**(**unsafe.Pointer)(unsafe.Pointer(&p))) +} +func ptrToNPtr(p uintptr, ptrNum uint8) uintptr { + for i := uint8(0); i < ptrNum; i++ { + if p == 0 { + return 0 + } + p = ptrToPtr(p) + } + return p +} + +func ptrToUnsafePtr(p uintptr) unsafe.Pointer { + return *(*unsafe.Pointer)(unsafe.Pointer(&p)) +} +func ptrToInterface(code *encoder.Opcode, p uintptr) interface{} { + return *(*interface{})(unsafe.Pointer(&emptyInterface{ + typ: code.Type, + ptr: *(*unsafe.Pointer)(unsafe.Pointer(&p)), + })) +} + +func appendBool(_ *encoder.RuntimeContext, b []byte, v bool) []byte { + if v { + return append(b, "true"...) + } + return append(b, "false"...) +} + +func appendNull(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, "null"...) +} + +func appendComma(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ',', '\n') +} + +func appendColon(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, ':', ' ') +} + +func appendMapKeyValue(ctx *encoder.RuntimeContext, code *encoder.Opcode, b, key, value []byte) []byte { + b = appendIndent(ctx, b, code.Indent+1) + b = append(b, key...) + b[len(b)-2] = ':' + b[len(b)-1] = ' ' + return append(b, value...) +} + +func appendMapEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, '}', ',', '\n') +} + +func appendArrayHead(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = append(b, '[', '\n') + return appendIndent(ctx, b, code.Indent+1) +} + +func appendArrayEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = b[:len(b)-2] + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent) + return append(b, ']', ',', '\n') +} + +func appendEmptyArray(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '[', ']', ',', '\n') +} + +func appendEmptyObject(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '}', ',', '\n') +} + +func appendObjectEnd(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + b[last] = '\n' + b = appendIndent(ctx, b, code.Indent-1) + return append(b, '}', ',', '\n') +} + +func appendMarshalJSON(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalJSONIndent(ctx, code, b, v) +} + +func appendMarshalText(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte, v interface{}) ([]byte, error) { + return encoder.AppendMarshalTextIndent(ctx, code, b, v) +} + +func appendStructHead(_ *encoder.RuntimeContext, b []byte) []byte { + return append(b, '{', '\n') +} + +func appendStructKey(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + b = appendIndent(ctx, b, code.Indent) + b = append(b, code.Key...) + return append(b, ' ') +} + +func appendStructEndSkipLast(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + last := len(b) - 1 + if b[last-1] == '{' { + b[last] = '}' + } else { + if b[last] == '\n' { + // to remove ',' and '\n' characters + b = b[:len(b)-2] + } + b = append(b, '\n') + b = appendIndent(ctx, b, code.Indent-1) + b = append(b, '}') + } + return appendComma(ctx, b) +} + +func restoreIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, ctxptr uintptr) { + ctx.BaseIndent = uint32(load(ctxptr, code.Length)) +} + +func storeIndent(ctxptr uintptr, code *encoder.Opcode, indent uintptr) { + store(ctxptr, code.Length, indent) +} + +func appendArrayElemIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent+1) +} + +func appendMapKeyIndent(ctx *encoder.RuntimeContext, code *encoder.Opcode, b []byte) []byte { + return appendIndent(ctx, b, code.Indent) +} diff --git a/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go new file mode 100644 index 000000000..d10ce75c2 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/encoder/vm_indent/vm.go @@ -0,0 +1,5041 @@ +// Code generated by internal/cmd/generator. DO NOT EDIT! +package vm_indent + +import ( + "math" + "sort" + "unsafe" + + "github.com/goccy/go-json/internal/encoder" +) + +func Run(ctx *encoder.RuntimeContext, b []byte, codeSet *encoder.OpcodeSet) ([]byte, error) { + recursiveLevel := 0 + ptrOffset := uintptr(0) + ctxptr := ctx.Ptr() + var code *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + code = codeSet.EscapeKeyCode + } else { + code = codeSet.NoescapeKeyCode + } + + for { + switch code.Op { + default: + return nil, errUnimplementedOp(code.Op) + case encoder.OpPtr: + p := load(ctxptr, code.Idx) + code = code.Next + store(ctxptr, code.Idx, ptrToPtr(p)) + case encoder.OpIntPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInt: + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpUint: + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpIntString: + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpUintString: + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(load(ctxptr, code.Idx)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat32Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat32: + b = appendFloat32(ctx, b, ptrToFloat32(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpFloat64Ptr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpFloat64: + v := ptrToFloat64(load(ctxptr, code.Idx)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStringPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpString: + b = appendString(ctx, b, ptrToString(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBoolPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBool: + b = appendBool(ctx, b, ptrToBool(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpBytesPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpBytes: + b = appendByteSlice(ctx, b, ptrToBytes(load(ctxptr, code.Idx))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpNumberPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpNumber: + bb, err := appendNumber(ctx, b, ptrToNumber(load(ctxptr, code.Idx))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpInterfacePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpInterface: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if p == seen { + return nil, errUnsupportedValue(code, p) + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, p) + iface := (*emptyInterface)(ptrToUnsafePtr(p)) + if iface.ptr == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(iface)) + ifaceCodeSet, err := encoder.CompileToGetCodeSet(uintptr(unsafe.Pointer(iface.typ))) + if err != nil { + return nil, err + } + + totalLength := uintptr(code.Length) + 3 + nextTotalLength := uintptr(ifaceCodeSet.CodeLength) + 3 + + var c *encoder.Opcode + if (ctx.Option.Flag & encoder.HTMLEscapeOption) != 0 { + c = ifaceCodeSet.InterfaceEscapeKeyCode + } else { + c = ifaceCodeSet.InterfaceNoescapeKeyCode + } + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += totalLength * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + totalLength + nextTotalLength + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + end := ifaceCodeSet.EndCode + store(ctxptr, c.Idx, uintptr(iface.ptr)) + store(ctxptr, end.Idx, oldOffset) + store(ctxptr, end.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, end, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpInterfaceEnd: + recursiveLevel-- + + // restore ctxptr + offset := load(ctxptr, code.Idx) + restoreIndent(ctx, code, ctxptr) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToPtr(p)) + fallthrough + case encoder.OpMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + b = append(b, `""`...) + b = appendComma(ctx, b) + code = code.Next + break + } + if (code.Flags&encoder.IsNilableTypeFlags) != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p) + } + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpSlicePtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpSlice: + p := load(ctxptr, code.Idx) + slice := ptrToSlice(p) + if p == 0 || slice.Data == nil { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(slice.Len)) + store(ctxptr, code.Idx, uintptr(slice.Data)) + if slice.Len > 0 { + b = appendArrayHead(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, uintptr(slice.Data)) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpSliceElem: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if idx < length { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + data := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, data+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpArrayPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpArray: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + if code.Length > 0 { + b = appendArrayHead(ctx, code, b) + store(ctxptr, code.ElemIdx, 0) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + b = appendEmptyArray(ctx, b) + code = code.End.Next + } + case encoder.OpArrayElem: + idx := load(ctxptr, code.ElemIdx) + idx++ + if idx < uintptr(code.Length) { + b = appendArrayElemIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + p := load(ctxptr, code.Idx) + size := uintptr(code.Size) + code = code.Next + store(ctxptr, code.Idx, p+idx*size) + } else { + b = appendArrayEnd(ctx, code, b) + code = code.End.Next + } + case encoder.OpMapPtr: + p := loadNPtr(ctxptr, code.Idx, code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + store(ctxptr, code.Idx, p) + fallthrough + case encoder.OpMap: + p := load(ctxptr, code.Idx) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.End.Next + break + } + uptr := ptrToUnsafePtr(p) + mlen := maplen(uptr) + if mlen <= 0 { + b = appendEmptyObject(ctx, b) + code = code.End.Next + break + } + b = appendStructHead(ctx, b) + iter := mapiterinit(code.Type, uptr) + ctx.KeepRefs = append(ctx.KeepRefs, iter) + store(ctxptr, code.ElemIdx, 0) + store(ctxptr, code.Length, uintptr(mlen)) + store(ctxptr, code.MapIter, uintptr(iter)) + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendMapKeyIndent(ctx, code.Next, b) + } else { + mapCtx := encoder.NewMapContext(mlen) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + ctx.KeepRefs = append(ctx.KeepRefs, unsafe.Pointer(mapCtx)) + store(ctxptr, code.End.MapPos, uintptr(unsafe.Pointer(mapCtx))) + } + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + case encoder.OpMapKey: + idx := load(ctxptr, code.ElemIdx) + length := load(ctxptr, code.Length) + idx++ + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + if idx < length { + b = appendMapKeyIndent(ctx, code, b) + store(ctxptr, code.ElemIdx, idx) + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + b = appendObjectEnd(ctx, code, b) + code = code.End.Next + } + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + if idx < length { + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + store(ctxptr, code.ElemIdx, idx) + key := mapiterkey(iter) + store(ctxptr, code.Next.Idx, uintptr(key)) + code = code.Next + } else { + code = code.End + } + } + case encoder.OpMapValue: + if (ctx.Option.Flag & encoder.UnorderedMapOption) != 0 { + b = appendColon(ctx, b) + } else { + ptr := load(ctxptr, code.End.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + mapCtx.Pos = append(mapCtx.Pos, len(b)) + } + ptr := load(ctxptr, code.MapIter) + iter := ptrToUnsafePtr(ptr) + value := mapitervalue(iter) + store(ctxptr, code.Next.Idx, uintptr(value)) + mapiternext(iter) + code = code.Next + case encoder.OpMapEnd: + // this operation only used by sorted map. + length := int(load(ctxptr, code.Length)) + ptr := load(ctxptr, code.MapPos) + mapCtx := (*encoder.MapContext)(ptrToUnsafePtr(ptr)) + pos := mapCtx.Pos + for i := 0; i < length; i++ { + startKey := pos[i*2] + startValue := pos[i*2+1] + var endValue int + if i+1 < length { + endValue = pos[i*2+2] + } else { + endValue = len(b) + } + mapCtx.Slice.Items = append(mapCtx.Slice.Items, encoder.MapItem{ + Key: b[startKey:startValue], + Value: b[startValue:endValue], + }) + } + sort.Sort(mapCtx.Slice) + buf := mapCtx.Buf + for _, item := range mapCtx.Slice.Items { + buf = appendMapKeyValue(ctx, code, buf, item.Key, item.Value) + } + buf = appendMapEnd(ctx, code, buf) + b = b[:pos[0]] + b = append(b, buf...) + mapCtx.Buf = buf + encoder.ReleaseMapContext(mapCtx) + code = code.Next + case encoder.OpRecursivePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + code = code.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpRecursive: + ptr := load(ctxptr, code.Idx) + if ptr != 0 { + if recursiveLevel > encoder.StartDetectingCyclesAfter { + for _, seen := range ctx.SeenPtr { + if ptr == seen { + return nil, errUnsupportedValue(code, ptr) + } + } + } + } + ctx.SeenPtr = append(ctx.SeenPtr, ptr) + c := code.Jmp.Code + curlen := uintptr(len(ctx.Ptrs)) + offsetNum := ptrOffset / uintptrSize + oldOffset := ptrOffset + ptrOffset += code.Jmp.CurLen * uintptrSize + oldBaseIndent := ctx.BaseIndent + indentDiffFromTop := c.Indent - 1 + ctx.BaseIndent += code.Indent - indentDiffFromTop + + newLen := offsetNum + code.Jmp.CurLen + code.Jmp.NextLen + if curlen < newLen { + ctx.Ptrs = append(ctx.Ptrs, make([]uintptr, newLen-curlen)...) + } + ctxptr = ctx.Ptr() + ptrOffset // assign new ctxptr + + store(ctxptr, c.Idx, ptr) + store(ctxptr, c.End.Next.Idx, oldOffset) + store(ctxptr, c.End.Next.ElemIdx, uintptr(unsafe.Pointer(code.Next))) + storeIndent(ctxptr, c.End.Next, uintptr(oldBaseIndent)) + code = c + recursiveLevel++ + case encoder.OpRecursiveEnd: + recursiveLevel-- + + // restore ctxptr + restoreIndent(ctx, code, ctxptr) + offset := load(ctxptr, code.Idx) + ctx.SeenPtr = ctx.SeenPtr[:len(ctx.SeenPtr)-1] + + codePtr := load(ctxptr, code.ElemIdx) + code = (*encoder.Opcode)(ptrToUnsafePtr(codePtr)) + ctxptr = ctx.Ptr() + offset + ptrOffset = offset + case encoder.OpStructPtrHead: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHead: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags&encoder.AnonymousKeyFlags) == 0 && len(code.Key) > 0 { + b = appendStructKey(ctx, code, b) + } + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmpty: + p := load(ctxptr, code.Idx) + if p == 0 && ((code.Flags&encoder.IndirectFlags) != 0 || code.Next.Op == encoder.OpStructEnd) { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + if p == 0 || (ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyInt: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyInt: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyIntString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUint: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUint: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyUintString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat32(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64String: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToFloat64(p + uintptr(code.Offset)) + if v == 0 { + code = code.NextField + } else { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p+uintptr(code.Offset))))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyStringString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToString(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBool: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBool: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + } else { + code = code.NextField + } + case encoder.OpStructPtrHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytes: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyBytes: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumber: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumber: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + } + case encoder.OpStructPtrHeadNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberString: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + v := ptrToNumber(p + uintptr(code.Offset)) + if v == "" { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructPtrHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructPtrHeadArray, encoder.OpStructPtrHeadSlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadArray, encoder.OpStructHeadSlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyArray: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyArray: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptySlice: + if (code.Flags & encoder.IndirectFlags) != 0 { + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptySlice: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadArrayPtr, encoder.OpStructPtrHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadArrayPtr, encoder.OpStructHeadSlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyArrayPtr, encoder.OpStructPtrHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyArrayPtr, encoder.OpStructHeadOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructPtrHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMap: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p != 0 && (code.Flags&encoder.IndirectFlags) != 0 { + p = ptrToPtr(p + uintptr(code.Offset)) + } + if maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + break + } + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 { + code = code.NextField + } else { + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructPtrHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalJSON { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + } + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + if (code.Flags&encoder.IndirectFlags) != 0 || code.Op == encoder.OpStructPtrHeadOmitEmptyMarshalText { + p = ptrToPtr(p + uintptr(code.Offset)) + } + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructPtrHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + b = appendStructKey(ctx, code, b) + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructPtrHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + store(ctxptr, code.Idx, ptrToNPtr(p, code.PtrNum)) + fallthrough + case encoder.OpStructHeadOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + if p == 0 && (code.Flags&encoder.IndirectFlags) != 0 { + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + } + code = code.End.Next + break + } + if (code.Flags & encoder.IndirectFlags) != 0 { + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + } + if code.Flags&encoder.AnonymousHeadFlags == 0 { + b = appendStructHead(ctx, b) + } + if p == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + b = appendComma(ctx, b) + code = code.Next + } + case encoder.OpStructField: + if code.Flags&encoder.AnonymousKeyFlags == 0 { + b = appendStructKey(ctx, code, b) + } + p := load(ctxptr, code.Idx) + uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmpty: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + b = appendComma(ctx, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringString: + p := load(ctxptr, code.Idx) + s := ptrToString(p + uintptr(code.Offset)) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + b = appendStructKey(ctx, code, b) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendComma(ctx, b) + } + code = code.Next + case encoder.OpStructFieldMarshalJSON: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSON: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + iface := ptrToInterface(code, p) + if (code.Flags&encoder.NilCheckFlags) != 0 && encoder.IsNilForMarshaler(iface) { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, iface) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalJSONPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalJSONPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalJSON(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldMarshalText: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalText: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if (code.Flags & encoder.IsNilableTypeFlags) != 0 { + p = ptrToPtr(p) + } + if p == 0 && (code.Flags&encoder.NilCheckFlags) != 0 { + code = code.NextField + break + } + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + code = code.Next + case encoder.OpStructFieldMarshalTextPtr: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendComma(ctx, b) + code = code.Next + case encoder.OpStructFieldOmitEmptyMarshalTextPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendMarshalText(ctx, code, b, ptrToInterface(code, p)) + if err != nil { + return nil, err + } + b = appendComma(ctx, bb) + } + code = code.Next + case encoder.OpStructFieldArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArray: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldArrayPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyArrayPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldSlice: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlice: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + slice := ptrToSlice(p) + if slice.Len == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldSlicePtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptySlicePtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldMap: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMap: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p == 0 || maplen(ptrToUnsafePtr(p)) == 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructFieldMapPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyMapPtr: + p := load(ctxptr, code.Idx) + p = ptrToPtr(p + uintptr(code.Offset)) + if p != 0 { + p = ptrToNPtr(p, code.PtrNum) + } + if p != 0 { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } else { + code = code.NextField + } + case encoder.OpStructFieldStruct: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + code = code.Next + store(ctxptr, code.Idx, p) + case encoder.OpStructFieldOmitEmptyStruct: + p := load(ctxptr, code.Idx) + p += uintptr(code.Offset) + if ptrToPtr(p) == 0 && (code.Flags&encoder.IsNextOpPtrTypeFlags) != 0 { + code = code.NextField + } else { + b = appendStructKey(ctx, code, b) + code = code.Next + store(ctxptr, code.Idx, p) + } + case encoder.OpStructAnonymousEnd: + code = code.Next + case encoder.OpStructEnd: + b = appendStructEndSkipLast(ctx, code, b) + code = code.Next + case encoder.OpStructEndInt: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyInt: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendInt(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendInt(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndIntPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyIntPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendInt(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUint: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUint: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, u64, code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p+uintptr(code.Offset)), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintString: + p := load(ctxptr, code.Idx) + u64 := ptrToUint64(p + uintptr(code.Offset)) + v := u64 & ((1 << code.NumBitSize) - 1) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, u64, code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendUint(ctx, b, ptrToUint64(p), code) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendUint(ctx, b, ptrToUint64(p), code) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndUintPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyUintPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendUint(ctx, b, ptrToUint64(p), code) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32String: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32String: + p := load(ctxptr, code.Idx) + v := ptrToFloat32(p + uintptr(code.Offset)) + if v != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendFloat32(ctx, b, ptrToFloat32(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat32PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat32PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat32(ctx, b, ptrToFloat32(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64String: + p := load(ctxptr, code.Idx) + v := ptrToFloat64(p + uintptr(code.Offset)) + if v != 0 { + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64Ptr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + b = appendStructEnd(ctx, code, b) + code = code.Next + break + } + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64Ptr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndFloat64PtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = appendFloat64(ctx, b, v) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyFloat64PtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + v := ptrToFloat64(p) + if math.IsInf(v, 0) || math.IsNaN(v) { + return nil, errUnsupportedFloat(v) + } + b = append(b, '"') + b = appendFloat64(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + s := ptrToString(p + uintptr(code.Offset)) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, s))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringString: + p := load(ctxptr, code.Idx) + v := ptrToString(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, v))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, ptrToString(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, ptrToString(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndStringPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyStringPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendString(ctx, b, string(appendString(ctx, []byte{}, ptrToString(p)))) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBool: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBool: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p+uintptr(code.Offset))) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolString: + p := load(ctxptr, code.Idx) + v := ptrToBool(p + uintptr(code.Offset)) + if v { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, v) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendBool(ctx, b, ptrToBool(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendBool(ctx, b, ptrToBool(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBoolPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBoolPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + b = appendBool(ctx, b, ptrToBool(p)) + b = append(b, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytes: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p+uintptr(code.Offset))) + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytes: + p := load(ctxptr, code.Idx) + v := ptrToBytes(p + uintptr(code.Offset)) + if len(v) > 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, v) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndBytesPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = appendByteSlice(ctx, b, ptrToBytes(p)) + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyBytesPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = appendByteSlice(ctx, b, ptrToBytes(p)) + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumber: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + code = code.Next + case encoder.OpStructEndOmitEmptyNumber: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberString: + p := load(ctxptr, code.Idx) + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p+uintptr(code.Offset))) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberString: + p := load(ctxptr, code.Idx) + v := ptrToNumber(p + uintptr(code.Offset)) + if v != "" { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, v) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtr: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = bb + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtr: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = appendStructEnd(ctx, code, bb) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpStructEndNumberPtrString: + b = appendStructKey(ctx, code, b) + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p == 0 { + b = appendNull(ctx, b) + } else { + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + } + b = appendStructEnd(ctx, code, b) + code = code.Next + case encoder.OpStructEndOmitEmptyNumberPtrString: + p := load(ctxptr, code.Idx) + p = ptrToNPtr(p+uintptr(code.Offset), code.PtrNum) + if p != 0 { + b = appendStructKey(ctx, code, b) + b = append(b, '"') + bb, err := appendNumber(ctx, b, ptrToNumber(p)) + if err != nil { + return nil, err + } + b = append(bb, '"') + b = appendStructEnd(ctx, code, b) + } else { + b = appendStructEndSkipLast(ctx, code, b) + } + code = code.Next + case encoder.OpEnd: + goto END + } + } +END: + return b, nil +} diff --git a/vendor/github.com/goccy/go-json/internal/errors/error.go b/vendor/github.com/goccy/go-json/internal/errors/error.go new file mode 100644 index 000000000..329e2f12d --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/errors/error.go @@ -0,0 +1,157 @@ +package errors + +import ( + "fmt" + "reflect" + "strconv" +) + +type InvalidUTF8Error struct { + S string // the whole string value that caused the error +} + +func (e *InvalidUTF8Error) Error() string { + return fmt.Sprintf("json: invalid UTF-8 in string: %s", strconv.Quote(e.S)) +} + +type InvalidUnmarshalError struct { + Type reflect.Type +} + +func (e *InvalidUnmarshalError) Error() string { + if e.Type == nil { + return "json: Unmarshal(nil)" + } + + if e.Type.Kind() != reflect.Ptr { + return fmt.Sprintf("json: Unmarshal(non-pointer %s)", e.Type) + } + return fmt.Sprintf("json: Unmarshal(nil %s)", e.Type) +} + +// A MarshalerError represents an error from calling a MarshalJSON or MarshalText method. +type MarshalerError struct { + Type reflect.Type + Err error + sourceFunc string +} + +func (e *MarshalerError) Error() string { + srcFunc := e.sourceFunc + if srcFunc == "" { + srcFunc = "MarshalJSON" + } + return fmt.Sprintf("json: error calling %s for type %s: %s", srcFunc, e.Type, e.Err.Error()) +} + +// Unwrap returns the underlying error. +func (e *MarshalerError) Unwrap() error { return e.Err } + +// A SyntaxError is a description of a JSON syntax error. +type SyntaxError struct { + msg string // description of error + Offset int64 // error occurred after reading Offset bytes +} + +func (e *SyntaxError) Error() string { return e.msg } + +// An UnmarshalFieldError describes a JSON object key that +// led to an unexported (and therefore unwritable) struct field. +// +// Deprecated: No longer used; kept for compatibility. +type UnmarshalFieldError struct { + Key string + Type reflect.Type + Field reflect.StructField +} + +func (e *UnmarshalFieldError) Error() string { + return fmt.Sprintf("json: cannot unmarshal object key %s into unexported field %s of type %s", + strconv.Quote(e.Key), e.Field.Name, e.Type.String(), + ) +} + +// An UnmarshalTypeError describes a JSON value that was +// not appropriate for a value of a specific Go type. +type UnmarshalTypeError struct { + Value string // description of JSON value - "bool", "array", "number -5" + Type reflect.Type // type of Go value it could not be assigned to + Offset int64 // error occurred after reading Offset bytes + Struct string // name of the struct type containing the field + Field string // the full path from root node to the field +} + +func (e *UnmarshalTypeError) Error() string { + if e.Struct != "" || e.Field != "" { + return fmt.Sprintf("json: cannot unmarshal %s into Go struct field %s.%s of type %s", + e.Value, e.Struct, e.Field, e.Type, + ) + } + return fmt.Sprintf("json: cannot unmarshal %s into Go value of type %s", e.Value, e.Type) +} + +// An UnsupportedTypeError is returned by Marshal when attempting +// to encode an unsupported value type. +type UnsupportedTypeError struct { + Type reflect.Type +} + +func (e *UnsupportedTypeError) Error() string { + return fmt.Sprintf("json: unsupported type: %s", e.Type) +} + +type UnsupportedValueError struct { + Value reflect.Value + Str string +} + +func (e *UnsupportedValueError) Error() string { + return fmt.Sprintf("json: unsupported value: %s", e.Str) +} + +func ErrSyntax(msg string, offset int64) *SyntaxError { + return &SyntaxError{msg: msg, Offset: offset} +} + +func ErrMarshaler(typ reflect.Type, err error, msg string) *MarshalerError { + return &MarshalerError{ + Type: typ, + Err: err, + sourceFunc: msg, + } +} + +func ErrExceededMaxDepth(c byte, cursor int64) *SyntaxError { + return &SyntaxError{ + msg: fmt.Sprintf(`invalid character "%c" exceeded max depth`, c), + Offset: cursor, + } +} + +func ErrNotAtBeginningOfValue(cursor int64) *SyntaxError { + return &SyntaxError{msg: "not at beginning of value", Offset: cursor} +} + +func ErrUnexpectedEndOfJSON(msg string, cursor int64) *SyntaxError { + return &SyntaxError{ + msg: fmt.Sprintf("json: %s unexpected end of JSON input", msg), + Offset: cursor, + } +} + +func ErrExpected(msg string, cursor int64) *SyntaxError { + return &SyntaxError{msg: fmt.Sprintf("expected %s", msg), Offset: cursor} +} + +func ErrInvalidCharacter(c byte, context string, cursor int64) *SyntaxError { + if c == 0 { + return &SyntaxError{ + msg: fmt.Sprintf("json: invalid character as %s", context), + Offset: cursor, + } + } + return &SyntaxError{ + msg: fmt.Sprintf("json: invalid character %c as %s", c, context), + Offset: cursor, + } +} diff --git a/vendor/github.com/goccy/go-json/internal/runtime/rtype.go b/vendor/github.com/goccy/go-json/internal/runtime/rtype.go new file mode 100644 index 000000000..4db10debe --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/runtime/rtype.go @@ -0,0 +1,263 @@ +package runtime + +import ( + "reflect" + "unsafe" +) + +// Type representing reflect.rtype for noescape trick +type Type struct{} + +//go:linkname rtype_Align reflect.(*rtype).Align +//go:noescape +func rtype_Align(*Type) int + +func (t *Type) Align() int { + return rtype_Align(t) +} + +//go:linkname rtype_FieldAlign reflect.(*rtype).FieldAlign +//go:noescape +func rtype_FieldAlign(*Type) int + +func (t *Type) FieldAlign() int { + return rtype_FieldAlign(t) +} + +//go:linkname rtype_Method reflect.(*rtype).Method +//go:noescape +func rtype_Method(*Type, int) reflect.Method + +func (t *Type) Method(a0 int) reflect.Method { + return rtype_Method(t, a0) +} + +//go:linkname rtype_MethodByName reflect.(*rtype).MethodByName +//go:noescape +func rtype_MethodByName(*Type, string) (reflect.Method, bool) + +func (t *Type) MethodByName(a0 string) (reflect.Method, bool) { + return rtype_MethodByName(t, a0) +} + +//go:linkname rtype_NumMethod reflect.(*rtype).NumMethod +//go:noescape +func rtype_NumMethod(*Type) int + +func (t *Type) NumMethod() int { + return rtype_NumMethod(t) +} + +//go:linkname rtype_Name reflect.(*rtype).Name +//go:noescape +func rtype_Name(*Type) string + +func (t *Type) Name() string { + return rtype_Name(t) +} + +//go:linkname rtype_PkgPath reflect.(*rtype).PkgPath +//go:noescape +func rtype_PkgPath(*Type) string + +func (t *Type) PkgPath() string { + return rtype_PkgPath(t) +} + +//go:linkname rtype_Size reflect.(*rtype).Size +//go:noescape +func rtype_Size(*Type) uintptr + +func (t *Type) Size() uintptr { + return rtype_Size(t) +} + +//go:linkname rtype_String reflect.(*rtype).String +//go:noescape +func rtype_String(*Type) string + +func (t *Type) String() string { + return rtype_String(t) +} + +//go:linkname rtype_Kind reflect.(*rtype).Kind +//go:noescape +func rtype_Kind(*Type) reflect.Kind + +func (t *Type) Kind() reflect.Kind { + return rtype_Kind(t) +} + +//go:linkname rtype_Implements reflect.(*rtype).Implements +//go:noescape +func rtype_Implements(*Type, reflect.Type) bool + +func (t *Type) Implements(u reflect.Type) bool { + return rtype_Implements(t, u) +} + +//go:linkname rtype_AssignableTo reflect.(*rtype).AssignableTo +//go:noescape +func rtype_AssignableTo(*Type, reflect.Type) bool + +func (t *Type) AssignableTo(u reflect.Type) bool { + return rtype_AssignableTo(t, u) +} + +//go:linkname rtype_ConvertibleTo reflect.(*rtype).ConvertibleTo +//go:noescape +func rtype_ConvertibleTo(*Type, reflect.Type) bool + +func (t *Type) ConvertibleTo(u reflect.Type) bool { + return rtype_ConvertibleTo(t, u) +} + +//go:linkname rtype_Comparable reflect.(*rtype).Comparable +//go:noescape +func rtype_Comparable(*Type) bool + +func (t *Type) Comparable() bool { + return rtype_Comparable(t) +} + +//go:linkname rtype_Bits reflect.(*rtype).Bits +//go:noescape +func rtype_Bits(*Type) int + +func (t *Type) Bits() int { + return rtype_Bits(t) +} + +//go:linkname rtype_ChanDir reflect.(*rtype).ChanDir +//go:noescape +func rtype_ChanDir(*Type) reflect.ChanDir + +func (t *Type) ChanDir() reflect.ChanDir { + return rtype_ChanDir(t) +} + +//go:linkname rtype_IsVariadic reflect.(*rtype).IsVariadic +//go:noescape +func rtype_IsVariadic(*Type) bool + +func (t *Type) IsVariadic() bool { + return rtype_IsVariadic(t) +} + +//go:linkname rtype_Elem reflect.(*rtype).Elem +//go:noescape +func rtype_Elem(*Type) reflect.Type + +func (t *Type) Elem() *Type { + return Type2RType(rtype_Elem(t)) +} + +//go:linkname rtype_Field reflect.(*rtype).Field +//go:noescape +func rtype_Field(*Type, int) reflect.StructField + +func (t *Type) Field(i int) reflect.StructField { + return rtype_Field(t, i) +} + +//go:linkname rtype_FieldByIndex reflect.(*rtype).FieldByIndex +//go:noescape +func rtype_FieldByIndex(*Type, []int) reflect.StructField + +func (t *Type) FieldByIndex(index []int) reflect.StructField { + return rtype_FieldByIndex(t, index) +} + +//go:linkname rtype_FieldByName reflect.(*rtype).FieldByName +//go:noescape +func rtype_FieldByName(*Type, string) (reflect.StructField, bool) + +func (t *Type) FieldByName(name string) (reflect.StructField, bool) { + return rtype_FieldByName(t, name) +} + +//go:linkname rtype_FieldByNameFunc reflect.(*rtype).FieldByNameFunc +//go:noescape +func rtype_FieldByNameFunc(*Type, func(string) bool) (reflect.StructField, bool) + +func (t *Type) FieldByNameFunc(match func(string) bool) (reflect.StructField, bool) { + return rtype_FieldByNameFunc(t, match) +} + +//go:linkname rtype_In reflect.(*rtype).In +//go:noescape +func rtype_In(*Type, int) reflect.Type + +func (t *Type) In(i int) reflect.Type { + return rtype_In(t, i) +} + +//go:linkname rtype_Key reflect.(*rtype).Key +//go:noescape +func rtype_Key(*Type) reflect.Type + +func (t *Type) Key() *Type { + return Type2RType(rtype_Key(t)) +} + +//go:linkname rtype_Len reflect.(*rtype).Len +//go:noescape +func rtype_Len(*Type) int + +func (t *Type) Len() int { + return rtype_Len(t) +} + +//go:linkname rtype_NumField reflect.(*rtype).NumField +//go:noescape +func rtype_NumField(*Type) int + +func (t *Type) NumField() int { + return rtype_NumField(t) +} + +//go:linkname rtype_NumIn reflect.(*rtype).NumIn +//go:noescape +func rtype_NumIn(*Type) int + +func (t *Type) NumIn() int { + return rtype_NumIn(t) +} + +//go:linkname rtype_NumOut reflect.(*rtype).NumOut +//go:noescape +func rtype_NumOut(*Type) int + +func (t *Type) NumOut() int { + return rtype_NumOut(t) +} + +//go:linkname rtype_Out reflect.(*rtype).Out +//go:noescape +func rtype_Out(*Type, int) reflect.Type + +//go:linkname PtrTo reflect.(*rtype).ptrTo +//go:noescape +func PtrTo(*Type) *Type + +func (t *Type) Out(i int) reflect.Type { + return rtype_Out(t, i) +} + +//go:linkname IfaceIndir reflect.ifaceIndir +//go:noescape +func IfaceIndir(*Type) bool + +//go:linkname RType2Type reflect.toType +//go:noescape +func RType2Type(t *Type) reflect.Type + +//go:nolint structcheck +type emptyInterface struct { + _ *Type + ptr unsafe.Pointer +} + +func Type2RType(t reflect.Type) *Type { + return (*Type)(((*emptyInterface)(unsafe.Pointer(&t))).ptr) +} diff --git a/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go b/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go new file mode 100644 index 000000000..c321180a3 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/runtime/struct_field.go @@ -0,0 +1,87 @@ +package runtime + +import ( + "reflect" + "strings" + "unicode" +) + +func getTag(field reflect.StructField) string { + return field.Tag.Get("json") +} + +func IsIgnoredStructField(field reflect.StructField) bool { + if field.PkgPath != "" { + if field.Anonymous { + if !(field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct) && field.Type.Kind() != reflect.Struct { + return true + } + } else { + // private field + return true + } + } + tag := getTag(field) + return tag == "-" +} + +type StructTag struct { + Key string + IsTaggedKey bool + IsOmitEmpty bool + IsString bool + Field reflect.StructField +} + +type StructTags []*StructTag + +func (t StructTags) ExistsKey(key string) bool { + for _, tt := range t { + if tt.Key == key { + return true + } + } + return false +} + +func isValidTag(s string) bool { + if s == "" { + return false + } + for _, c := range s { + switch { + case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + // Backslash and quote chars are reserved, but + // otherwise any punctuation chars are allowed + // in a tag name. + case !unicode.IsLetter(c) && !unicode.IsDigit(c): + return false + } + } + return true +} + +func StructTagFromField(field reflect.StructField) *StructTag { + keyName := field.Name + tag := getTag(field) + st := &StructTag{Field: field} + opts := strings.Split(tag, ",") + if len(opts) > 0 { + if opts[0] != "" && isValidTag(opts[0]) { + keyName = opts[0] + st.IsTaggedKey = true + } + } + st.Key = keyName + if len(opts) > 1 { + for _, opt := range opts[1:] { + switch opt { + case "omitempty": + st.IsOmitEmpty = true + case "string": + st.IsString = true + } + } + } + return st +} diff --git a/vendor/github.com/goccy/go-json/internal/runtime/type.go b/vendor/github.com/goccy/go-json/internal/runtime/type.go new file mode 100644 index 000000000..0167cd2c0 --- /dev/null +++ b/vendor/github.com/goccy/go-json/internal/runtime/type.go @@ -0,0 +1,100 @@ +package runtime + +import ( + "reflect" + "unsafe" +) + +type SliceHeader struct { + Data unsafe.Pointer + Len int + Cap int +} + +const ( + maxAcceptableTypeAddrRange = 1024 * 1024 * 2 // 2 Mib +) + +type TypeAddr struct { + BaseTypeAddr uintptr + MaxTypeAddr uintptr + AddrRange uintptr + AddrShift uintptr +} + +var ( + typeAddr *TypeAddr + alreadyAnalyzed bool +) + +//go:linkname typelinks reflect.typelinks +func typelinks() ([]unsafe.Pointer, [][]int32) + +//go:linkname rtypeOff reflect.rtypeOff +func rtypeOff(unsafe.Pointer, int32) unsafe.Pointer + +func AnalyzeTypeAddr() *TypeAddr { + defer func() { + alreadyAnalyzed = true + }() + if alreadyAnalyzed { + return typeAddr + } + sections, offsets := typelinks() + if len(sections) != 1 { + return nil + } + if len(offsets) != 1 { + return nil + } + section := sections[0] + offset := offsets[0] + var ( + min uintptr = uintptr(^uint(0)) + max uintptr = 0 + isAligned64 = true + isAligned32 = true + ) + for i := 0; i < len(offset); i++ { + typ := (*Type)(rtypeOff(section, offset[i])) + addr := uintptr(unsafe.Pointer(typ)) + if min > addr { + min = addr + } + if max < addr { + max = addr + } + if typ.Kind() == reflect.Ptr { + addr = uintptr(unsafe.Pointer(typ.Elem())) + if min > addr { + min = addr + } + if max < addr { + max = addr + } + } + isAligned64 = isAligned64 && (addr-min)&63 == 0 + isAligned32 = isAligned32 && (addr-min)&31 == 0 + } + addrRange := max - min + if addrRange == 0 { + return nil + } + var addrShift uintptr + if isAligned64 { + addrShift = 6 + } else if isAligned32 { + addrShift = 5 + } + cacheSize := addrRange >> addrShift + if cacheSize > maxAcceptableTypeAddrRange { + return nil + } + typeAddr = &TypeAddr{ + BaseTypeAddr: min, + MaxTypeAddr: max, + AddrRange: addrRange, + AddrShift: addrShift, + } + return typeAddr +} diff --git a/vendor/github.com/goccy/go-json/json.go b/vendor/github.com/goccy/go-json/json.go new file mode 100644 index 000000000..5c9448d8c --- /dev/null +++ b/vendor/github.com/goccy/go-json/json.go @@ -0,0 +1,366 @@ +package json + +import ( + "bytes" + "context" + "encoding/json" + + "github.com/goccy/go-json/internal/encoder" +) + +// Marshaler is the interface implemented by types that +// can marshal themselves into valid JSON. +type Marshaler interface { + MarshalJSON() ([]byte, error) +} + +// MarshalerContext is the interface implemented by types that +// can marshal themselves into valid JSON with context.Context. +type MarshalerContext interface { + MarshalJSON(context.Context) ([]byte, error) +} + +// Unmarshaler is the interface implemented by types +// that can unmarshal a JSON description of themselves. +// The input can be assumed to be a valid encoding of +// a JSON value. UnmarshalJSON must copy the JSON data +// if it wishes to retain the data after returning. +// +// By convention, to approximate the behavior of Unmarshal itself, +// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op. +type Unmarshaler interface { + UnmarshalJSON([]byte) error +} + +// UnmarshalerContext is the interface implemented by types +// that can unmarshal with context.Context a JSON description of themselves. +type UnmarshalerContext interface { + UnmarshalJSON(context.Context, []byte) error +} + +// Marshal returns the JSON encoding of v. +// +// Marshal traverses the value v recursively. +// If an encountered value implements the Marshaler interface +// and is not a nil pointer, Marshal calls its MarshalJSON method +// to produce JSON. If no MarshalJSON method is present but the +// value implements encoding.TextMarshaler instead, Marshal calls +// its MarshalText method and encodes the result as a JSON string. +// The nil pointer exception is not strictly necessary +// but mimics a similar, necessary exception in the behavior of +// UnmarshalJSON. +// +// Otherwise, Marshal uses the following type-dependent default encodings: +// +// Boolean values encode as JSON booleans. +// +// Floating point, integer, and Number values encode as JSON numbers. +// +// String values encode as JSON strings coerced to valid UTF-8, +// replacing invalid bytes with the Unicode replacement rune. +// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" +// to keep some browsers from misinterpreting JSON output as HTML. +// Ampersand "&" is also escaped to "\u0026" for the same reason. +// This escaping can be disabled using an Encoder that had SetEscapeHTML(false) +// called on it. +// +// Array and slice values encode as JSON arrays, except that +// []byte encodes as a base64-encoded string, and a nil slice +// encodes as the null JSON value. +// +// Struct values encode as JSON objects. +// Each exported struct field becomes a member of the object, using the +// field name as the object key, unless the field is omitted for one of the +// reasons given below. +// +// The encoding of each struct field can be customized by the format string +// stored under the "json" key in the struct field's tag. +// The format string gives the name of the field, possibly followed by a +// comma-separated list of options. The name may be empty in order to +// specify options without overriding the default field name. +// +// The "omitempty" option specifies that the field should be omitted +// from the encoding if the field has an empty value, defined as +// false, 0, a nil pointer, a nil interface value, and any empty array, +// slice, map, or string. +// +// As a special case, if the field tag is "-", the field is always omitted. +// Note that a field with name "-" can still be generated using the tag "-,". +// +// Examples of struct field tags and their meanings: +// +// // Field appears in JSON as key "myName". +// Field int `json:"myName"` +// +// // Field appears in JSON as key "myName" and +// // the field is omitted from the object if its value is empty, +// // as defined above. +// Field int `json:"myName,omitempty"` +// +// // Field appears in JSON as key "Field" (the default), but +// // the field is skipped if empty. +// // Note the leading comma. +// Field int `json:",omitempty"` +// +// // Field is ignored by this package. +// Field int `json:"-"` +// +// // Field appears in JSON as key "-". +// Field int `json:"-,"` +// +// The "string" option signals that a field is stored as JSON inside a +// JSON-encoded string. It applies only to fields of string, floating point, +// integer, or boolean types. This extra level of encoding is sometimes used +// when communicating with JavaScript programs: +// +// Int64String int64 `json:",string"` +// +// The key name will be used if it's a non-empty string consisting of +// only Unicode letters, digits, and ASCII punctuation except quotation +// marks, backslash, and comma. +// +// Anonymous struct fields are usually marshaled as if their inner exported fields +// were fields in the outer struct, subject to the usual Go visibility rules amended +// as described in the next paragraph. +// An anonymous struct field with a name given in its JSON tag is treated as +// having that name, rather than being anonymous. +// An anonymous struct field of interface type is treated the same as having +// that type as its name, rather than being anonymous. +// +// The Go visibility rules for struct fields are amended for JSON when +// deciding which field to marshal or unmarshal. If there are +// multiple fields at the same level, and that level is the least +// nested (and would therefore be the nesting level selected by the +// usual Go rules), the following extra rules apply: +// +// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, +// even if there are multiple untagged fields that would otherwise conflict. +// +// 2) If there is exactly one field (tagged or not according to the first rule), that is selected. +// +// 3) Otherwise there are multiple fields, and all are ignored; no error occurs. +// +// Handling of anonymous struct fields is new in Go 1.1. +// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of +// an anonymous struct field in both current and earlier versions, give the field +// a JSON tag of "-". +// +// Map values encode as JSON objects. The map's key type must either be a +// string, an integer type, or implement encoding.TextMarshaler. The map keys +// are sorted and used as JSON object keys by applying the following rules, +// subject to the UTF-8 coercion described for string values above: +// - string keys are used directly +// - encoding.TextMarshalers are marshaled +// - integer keys are converted to strings +// +// Pointer values encode as the value pointed to. +// A nil pointer encodes as the null JSON value. +// +// Interface values encode as the value contained in the interface. +// A nil interface value encodes as the null JSON value. +// +// Channel, complex, and function values cannot be encoded in JSON. +// Attempting to encode such a value causes Marshal to return +// an UnsupportedTypeError. +// +// JSON cannot represent cyclic data structures and Marshal does not +// handle them. Passing cyclic structures to Marshal will result in +// an infinite recursion. +// +func Marshal(v interface{}) ([]byte, error) { + return MarshalWithOption(v) +} + +// MarshalNoEscape returns the JSON encoding of v and doesn't escape v. +func MarshalNoEscape(v interface{}) ([]byte, error) { + return marshalNoEscape(v) +} + +// MarshalContext returns the JSON encoding of v with context.Context and EncodeOption. +func MarshalContext(ctx context.Context, v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + return marshalContext(ctx, v, optFuncs...) +} + +// MarshalWithOption returns the JSON encoding of v with EncodeOption. +func MarshalWithOption(v interface{}, optFuncs ...EncodeOptionFunc) ([]byte, error) { + return marshal(v, optFuncs...) +} + +// MarshalIndent is like Marshal but applies Indent to format the output. +// Each JSON element in the output will begin on a new line beginning with prefix +// followed by one or more copies of indent according to the indentation nesting. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + return MarshalIndentWithOption(v, prefix, indent) +} + +// MarshalIndentWithOption is like Marshal but applies Indent to format the output with EncodeOption. +func MarshalIndentWithOption(v interface{}, prefix, indent string, optFuncs ...EncodeOptionFunc) ([]byte, error) { + return marshalIndent(v, prefix, indent, optFuncs...) +} + +// Unmarshal parses the JSON-encoded data and stores the result +// in the value pointed to by v. If v is nil or not a pointer, +// Unmarshal returns an InvalidUnmarshalError. +// +// Unmarshal uses the inverse of the encodings that +// Marshal uses, allocating maps, slices, and pointers as necessary, +// with the following additional rules: +// +// To unmarshal JSON into a pointer, Unmarshal first handles the case of +// the JSON being the JSON literal null. In that case, Unmarshal sets +// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into +// the value pointed at by the pointer. If the pointer is nil, Unmarshal +// allocates a new value for it to point to. +// +// To unmarshal JSON into a value implementing the Unmarshaler interface, +// Unmarshal calls that value's UnmarshalJSON method, including +// when the input is a JSON null. +// Otherwise, if the value implements encoding.TextUnmarshaler +// and the input is a JSON quoted string, Unmarshal calls that value's +// UnmarshalText method with the unquoted form of the string. +// +// To unmarshal JSON into a struct, Unmarshal matches incoming object +// keys to the keys used by Marshal (either the struct field name or its tag), +// preferring an exact match but also accepting a case-insensitive match. By +// default, object keys which don't have a corresponding struct field are +// ignored (see Decoder.DisallowUnknownFields for an alternative). +// +// To unmarshal JSON into an interface value, +// Unmarshal stores one of these in the interface value: +// +// bool, for JSON booleans +// float64, for JSON numbers +// string, for JSON strings +// []interface{}, for JSON arrays +// map[string]interface{}, for JSON objects +// nil for JSON null +// +// To unmarshal a JSON array into a slice, Unmarshal resets the slice length +// to zero and then appends each element to the slice. +// As a special case, to unmarshal an empty JSON array into a slice, +// Unmarshal replaces the slice with a new empty slice. +// +// To unmarshal a JSON array into a Go array, Unmarshal decodes +// JSON array elements into corresponding Go array elements. +// If the Go array is smaller than the JSON array, +// the additional JSON array elements are discarded. +// If the JSON array is smaller than the Go array, +// the additional Go array elements are set to zero values. +// +// To unmarshal a JSON object into a map, Unmarshal first establishes a map to +// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal +// reuses the existing map, keeping existing entries. Unmarshal then stores +// key-value pairs from the JSON object into the map. The map's key type must +// either be any string type, an integer, implement json.Unmarshaler, or +// implement encoding.TextUnmarshaler. +// +// If a JSON value is not appropriate for a given target type, +// or if a JSON number overflows the target type, Unmarshal +// skips that field and completes the unmarshaling as best it can. +// If no more serious errors are encountered, Unmarshal returns +// an UnmarshalTypeError describing the earliest such error. In any +// case, it's not guaranteed that all the remaining fields following +// the problematic one will be unmarshaled into the target object. +// +// The JSON null value unmarshals into an interface, map, pointer, or slice +// by setting that Go value to nil. Because null is often used in JSON to mean +// ``not present,'' unmarshaling a JSON null into any other Go type has no effect +// on the value and produces no error. +// +// When unmarshaling quoted strings, invalid UTF-8 or +// invalid UTF-16 surrogate pairs are not treated as an error. +// Instead, they are replaced by the Unicode replacement +// character U+FFFD. +// +func Unmarshal(data []byte, v interface{}) error { + return unmarshal(data, v) +} + +// UnmarshalContext parses the JSON-encoded data and stores the result +// in the value pointed to by v. If you implement the UnmarshalerContext interface, +// call it with ctx as an argument. +func UnmarshalContext(ctx context.Context, data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + return unmarshalContext(ctx, data, v) +} + +func UnmarshalWithOption(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + return unmarshal(data, v, optFuncs...) +} + +func UnmarshalNoEscape(data []byte, v interface{}, optFuncs ...DecodeOptionFunc) error { + return unmarshalNoEscape(data, v, optFuncs...) +} + +// A Token holds a value of one of these types: +// +// Delim, for the four JSON delimiters [ ] { } +// bool, for JSON booleans +// float64, for JSON numbers +// Number, for JSON numbers +// string, for JSON string literals +// nil, for JSON null +// +type Token = json.Token + +// A Number represents a JSON number literal. +type Number = json.Number + +// RawMessage is a raw encoded JSON value. +// It implements Marshaler and Unmarshaler and can +// be used to delay JSON decoding or precompute a JSON encoding. +type RawMessage = json.RawMessage + +// A Delim is a JSON array or object delimiter, one of [ ] { or }. +type Delim = json.Delim + +// Compact appends to dst the JSON-encoded src with +// insignificant space characters elided. +func Compact(dst *bytes.Buffer, src []byte) error { + return encoder.Compact(dst, src, false) +} + +// Indent appends to dst an indented form of the JSON-encoded src. +// Each element in a JSON object or array begins on a new, +// indented line beginning with prefix followed by one or more +// copies of indent according to the indentation nesting. +// The data appended to dst does not begin with the prefix nor +// any indentation, to make it easier to embed inside other formatted JSON data. +// Although leading space characters (space, tab, carriage return, newline) +// at the beginning of src are dropped, trailing space characters +// at the end of src are preserved and copied to dst. +// For example, if src has no trailing spaces, neither will dst; +// if src ends in a trailing newline, so will dst. +func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error { + return encoder.Indent(dst, src, prefix, indent) +} + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML