diff --git a/doc.go b/doc.go index 3fbfc18..5d58fe5 100644 --- a/doc.go +++ b/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package core exposes basic building blocks // to work with json and yaml documents, such // as json schemas and OpenAPI specifications. diff --git a/json/benchmarks/doc.go b/json/benchmarks/doc.go index ff1d6b2..12ee2fd 100644 --- a/json/benchmarks/doc.go +++ b/json/benchmarks/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package benchmarks hosts comparative benchmarks for the json building blocks. // // It is a separate Go module so that the heavy external dependencies pulled in diff --git a/json/benchmarks/lexers/comparative/bench_test.go b/json/benchmarks/lexers/comparative/bench_test.go index 40349ce..0923f80 100644 --- a/json/benchmarks/lexers/comparative/bench_test.go +++ b/json/benchmarks/lexers/comparative/bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package comparative import ( diff --git a/json/benchmarks/lexers/comparative/doc.go b/json/benchmarks/lexers/comparative/doc.go index 255b851..ad96217 100644 --- a/json/benchmarks/lexers/comparative/doc.go +++ b/json/benchmarks/lexers/comparative/doc.go @@ -1,2 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package comparative contains various benchmarks of our suite of JSON & YAML lexers. package comparative diff --git a/json/benchmarks/lexers/comparative/easyjson/walk.go b/json/benchmarks/lexers/comparative/easyjson/walk.go index 70e0186..1a6d7cd 100644 --- a/json/benchmarks/lexers/comparative/easyjson/walk.go +++ b/json/benchmarks/lexers/comparative/easyjson/walk.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package easyjson drives mailru/easyjson's jlexer over a whole JSON document as // a generic recursive walk, so it can be benchmarked as a comparison point for // the default-lexer (both are pull-style, []byte-only lexers; easyjson is the diff --git a/json/benchmarks/lexers/comparative/iterator_bench_test.go b/json/benchmarks/lexers/comparative/iterator_bench_test.go index 9ff4ea5..8301074 100644 --- a/json/benchmarks/lexers/comparative/iterator_bench_test.go +++ b/json/benchmarks/lexers/comparative/iterator_bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package comparative import ( diff --git a/json/benchmarks/lexers/comparative/jsontext/walk.go b/json/benchmarks/lexers/comparative/jsontext/walk.go index 267f5b7..020e578 100644 --- a/json/benchmarks/lexers/comparative/jsontext/walk.go +++ b/json/benchmarks/lexers/comparative/jsontext/walk.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package jsontext drives the go-json-experiment (encoding/json/v2) jsontext // tokenizer over a whole JSON document, so it can be benchmarked as a comparison // point for the default-lexer. diff --git a/json/benchmarks/lexers/comparative/profile_test.go b/json/benchmarks/lexers/comparative/profile_test.go index 59fa756..ce29072 100644 --- a/json/benchmarks/lexers/comparative/profile_test.go +++ b/json/benchmarks/lexers/comparative/profile_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package comparative import ( diff --git a/json/benchmarks/lexers/comparative/stdlib/lexer.go b/json/benchmarks/lexers/comparative/stdlib/lexer.go index d41842f..dcdfbf6 100644 --- a/json/benchmarks/lexers/comparative/stdlib/lexer.go +++ b/json/benchmarks/lexers/comparative/stdlib/lexer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package stdlib provides a baseline [lexers.Lexer] implemented on top of the // standard library encoding/json tokenizer (v1). // diff --git a/json/benchmarks/lexers/comparative/stdlib/lexer_test.go b/json/benchmarks/lexers/comparative/stdlib/lexer_test.go index c8f56fc..f9a905c 100644 --- a/json/benchmarks/lexers/comparative/stdlib/lexer_test.go +++ b/json/benchmarks/lexers/comparative/stdlib/lexer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package stdlib import ( diff --git a/json/benchmarks/lexers/lanes/azure_lanes_bench_test.go b/json/benchmarks/lexers/lanes/azure_lanes_bench_test.go index 10bff65..f30db61 100644 --- a/json/benchmarks/lexers/lanes/azure_lanes_bench_test.go +++ b/json/benchmarks/lexers/lanes/azure_lanes_bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lane // Azure-lanes benchmark: a single payload (the merged go-openapi/azure OpenAPI spec) diff --git a/json/benchmarks/lexers/lanes/lexers_bench_test.go b/json/benchmarks/lexers/lanes/lexers_bench_test.go index 1624248..218e1ff 100644 --- a/json/benchmarks/lexers/lanes/lexers_bench_test.go +++ b/json/benchmarks/lexers/lanes/lexers_bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lane import ( diff --git a/json/benchmarks/lexers/lanes/modes_bench_test.go b/json/benchmarks/lexers/lanes/modes_bench_test.go index 8b1cefd..4142f68 100644 --- a/json/benchmarks/lexers/lanes/modes_bench_test.go +++ b/json/benchmarks/lexers/lanes/modes_bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lane // Compass benchmark (§10.5): a FAIR matrix of every way to drive the two lexers, diff --git a/json/benchmarks/lexers/lanes/utf8scratch_test.go b/json/benchmarks/lexers/lanes/utf8scratch_test.go index 7afef93..5dddb3b 100644 --- a/json/benchmarks/lexers/lanes/utf8scratch_test.go +++ b/json/benchmarks/lexers/lanes/utf8scratch_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lane // SCRATCH (utf-8 validation prototype): measures the cost of the three prototype diff --git a/json/benchmarks/lexers/lanes/walkers.go b/json/benchmarks/lexers/lanes/walkers.go index f5fb547..b137802 100644 --- a/json/benchmarks/lexers/lanes/walkers.go +++ b/json/benchmarks/lexers/lanes/walkers.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package lane prepares a benchmark on a single workload, but many execution paths (lanes) // for our lexer. // diff --git a/json/benchmarks/lexers/profile/alloc_test.go b/json/benchmarks/lexers/profile/alloc_test.go index 2cb26f0..a7ed5e5 100644 --- a/json/benchmarks/lexers/profile/alloc_test.go +++ b/json/benchmarks/lexers/profile/alloc_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package profile import ( diff --git a/json/benchmarks/lexers/profile/doc.go b/json/benchmarks/lexers/profile/doc.go index c1e2eef..d8a6e7d 100644 --- a/json/benchmarks/lexers/profile/doc.go +++ b/json/benchmarks/lexers/profile/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package profile explores the lexer // with profiling, tracing, examples and benchmark comparisons. package profile diff --git a/json/benchmarks/writers/doc.go b/json/benchmarks/writers/doc.go index df11952..855f18a 100644 --- a/json/benchmarks/writers/doc.go +++ b/json/benchmarks/writers/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package writers compares the throughput and allocations of the in-repo // default-writer implementations (unbuffered, buffered, YAML) against // mailru/easyjson's jwriter, the writer our design is inspired from. diff --git a/json/benchmarks/writers/writers_bench_test.go b/json/benchmarks/writers/writers_bench_test.go index b7f9a0c..f776f84 100644 --- a/json/benchmarks/writers/writers_bench_test.go +++ b/json/benchmarks/writers/writers_bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writers import ( diff --git a/json/doc.go b/json/doc.go index 03c51dc..e3e3dcc 100644 --- a/json/doc.go +++ b/json/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package json exposes an infrastructure // to work with JSON documents. package json diff --git a/json/expressions/pointer.go b/json/expressions/pointer.go index 8626691..985d427 100644 --- a/json/expressions/pointer.go +++ b/json/expressions/pointer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package expressions import ( diff --git a/json/internal/append_writer.go b/json/internal/append_writer.go index db930c0..b921ef0 100644 --- a/json/internal/append_writer.go +++ b/json/internal/append_writer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package internal import ( diff --git a/json/internal/pools.go b/json/internal/pools.go index 79629a6..ed206c6 100644 --- a/json/internal/pools.go +++ b/json/internal/pools.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package internal import ( diff --git a/json/internal/utf8x/_asm/asm.go b/json/internal/utf8x/_asm/asm.go index 8ab6259..ae8cf91 100644 --- a/json/internal/utf8x/_asm/asm.go +++ b/json/internal/utf8x/_asm/asm.go @@ -1,7 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:revive,mnd package main import ( + "bytes" + "flag" + "log" + "os" + "github.com/mmcloughlin/avo/attr" . "github.com/mmcloughlin/avo/build" . "github.com/mmcloughlin/avo/operand" @@ -11,6 +19,42 @@ func main() { validateUTF8() Generate() + prependLicense() +} + +// licenseHeader is the SPDX header every source file in this repository carries. +const licenseHeader = "// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers\n" + + "// SPDX-License-Identifier: Apache-2.0\n\n" + +// prependLicense adds [licenseHeader] to the assembly file avo has just written. +// +// avo emits only its own "Code generated by command:" warning, and printer.Config offers no hook +// for extra header lines, so a header added to the .s by hand is lost on the next go generate. +// Adding it here keeps it. The output path comes from avo's own -out flag, parsed by Generate. +func prependLicense() { + out := flag.Lookup("out") + if out == nil { + return + } + + name := out.Value.String() + if name == "" || name == "-" { + return + } + + body, err := os.ReadFile(name) + if err != nil { + log.Fatalf("reading %s: %v", name, err) + } + + if bytes.HasPrefix(body, []byte(licenseHeader)) { + return + } + + //nolint:gosec // name is avo's own -out path, fixed by the go:generate directive in this repo + if err := os.WriteFile(name, append([]byte(licenseHeader), body...), 0o600); err != nil { + log.Fatalf("writing %s: %v", name, err) + } } // table16 emits a 16-byte read-only lookup table for VPSHUFB. diff --git a/json/internal/utf8x/_asm/doc.go b/json/internal/utf8x/_asm/doc.go index 6fac4a5..0b7c4a1 100644 --- a/json/internal/utf8x/_asm/doc.go +++ b/json/internal/utf8x/_asm/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package _asm is a generator-only module for the AVX2 UTF-8 validation kernel. // // It isolates the avo build-time dependency: only `go generate` (see ../validate_amd64.go) runs it, and the generated diff --git a/json/internal/utf8x/bench_test.go b/json/internal/utf8x/bench_test.go index 27a888d..02707ad 100644 --- a/json/internal/utf8x/bench_test.go +++ b/json/internal/utf8x/bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package utf8x import ( diff --git a/json/internal/utf8x/cpuid_amd64.s b/json/internal/utf8x/cpuid_amd64.s index 1da73f9..74afd80 100644 --- a/json/internal/utf8x/cpuid_amd64.s +++ b/json/internal/utf8x/cpuid_amd64.s @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + #include "textflag.h" // func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) diff --git a/json/internal/utf8x/detect_amd64.go b/json/internal/utf8x/detect_amd64.go index f5020c1..65b166e 100644 --- a/json/internal/utf8x/detect_amd64.go +++ b/json/internal/utf8x/detect_amd64.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package utf8x diff --git a/json/internal/utf8x/utf8x.go b/json/internal/utf8x/utf8x.go index 3c3f61e..a98d853 100644 --- a/json/internal/utf8x/utf8x.go +++ b/json/internal/utf8x/utf8x.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package utf8x holds the UTF-8 validation and sanitization primitives shared by the JSON lexers and writers. // // It lives under json/internal (rather than under a lexer- or writer-private internal package) because it is the only diff --git a/json/internal/utf8x/utf8x_test.go b/json/internal/utf8x/utf8x_test.go index 330244b..62f5873 100644 --- a/json/internal/utf8x/utf8x_test.go +++ b/json/internal/utf8x/utf8x_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package utf8x import ( diff --git a/json/internal/utf8x/validate_amd64.go b/json/internal/utf8x/validate_amd64.go index 8f4e355..98dfd22 100644 --- a/json/internal/utf8x/validate_amd64.go +++ b/json/internal/utf8x/validate_amd64.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package utf8x diff --git a/json/internal/utf8x/validate_amd64.s b/json/internal/utf8x/validate_amd64.s index 031ff80..6c64e83 100644 --- a/json/internal/utf8x/validate_amd64.s +++ b/json/internal/utf8x/validate_amd64.s @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Code generated by command: go run asm.go -out ../validate_amd64.s. DO NOT EDIT. #include "textflag.h" diff --git a/json/internal/utf8x/validate_amd64_test.go b/json/internal/utf8x/validate_amd64_test.go index 483973c..dfac59f 100644 --- a/json/internal/utf8x/validate_amd64_test.go +++ b/json/internal/utf8x/validate_amd64_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package utf8x diff --git a/json/internal/utf8x/validate_noasm.go b/json/internal/utf8x/validate_noasm.go index 725e0f0..d4eff13 100644 --- a/json/internal/utf8x/validate_noasm.go +++ b/json/internal/utf8x/validate_noasm.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build !amd64 package utf8x diff --git a/json/lexers/default-lexer/conformance_lineendings_test.go b/json/lexers/default-lexer/conformance_lineendings_test.go index b102a40..90a5605 100644 --- a/json/lexers/default-lexer/conformance_lineendings_test.go +++ b/json/lexers/default-lexer/conformance_lineendings_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/conformance_test.go b/json/lexers/default-lexer/conformance_test.go index 6f2024b..52f5f01 100644 --- a/json/lexers/default-lexer/conformance_test.go +++ b/json/lexers/default-lexer/conformance_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/constants.go b/json/lexers/default-lexer/constants.go index b9f4c09..654cd96 100644 --- a/json/lexers/default-lexer/constants.go +++ b/json/lexers/default-lexer/constants.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer const ( diff --git a/json/lexers/default-lexer/core.go b/json/lexers/default-lexer/core.go index 255e30d..0fccbce 100644 --- a/json/lexers/default-lexer/core.go +++ b/json/lexers/default-lexer/core.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer //go:generate go run ./internal/lexgen diff --git a/json/lexers/default-lexer/core_pull_buffer.go b/json/lexers/default-lexer/core_pull_buffer.go index 788374f..8853b2a 100644 --- a/json/lexers/default-lexer/core_pull_buffer.go +++ b/json/lexers/default-lexer/core_pull_buffer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // these functions are duplicated by codegen to monomorphize (aka devirt). package lexer diff --git a/json/lexers/default-lexer/core_pull_stream.go b/json/lexers/default-lexer/core_pull_stream.go index c40a8ea..596edab 100644 --- a/json/lexers/default-lexer/core_pull_stream.go +++ b/json/lexers/default-lexer/core_pull_stream.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // these functions are duplicated by codegen to monomorphize (aka devirt). package lexer diff --git a/json/lexers/default-lexer/core_push_buffer.go b/json/lexers/default-lexer/core_push_buffer.go index 080bc83..81639e9 100644 --- a/json/lexers/default-lexer/core_push_buffer.go +++ b/json/lexers/default-lexer/core_push_buffer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // these functions are duplicated by codegen to monomorphize (aka devirt). package lexer diff --git a/json/lexers/default-lexer/core_push_stream.go b/json/lexers/default-lexer/core_push_stream.go index b031d4f..1f2f169 100644 --- a/json/lexers/default-lexer/core_push_stream.go +++ b/json/lexers/default-lexer/core_push_stream.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // these functions are duplicated by codegen to monomorphize (aka devirt). package lexer diff --git a/json/lexers/default-lexer/devirt_bench_test.go b/json/lexers/default-lexer/devirt_bench_test.go index d355972..7a57753 100644 --- a/json/lexers/default-lexer/devirt_bench_test.go +++ b/json/lexers/default-lexer/devirt_bench_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/devirt_test.go b/json/lexers/default-lexer/devirt_test.go index 37c0303..10190f2 100644 --- a/json/lexers/default-lexer/devirt_test.go +++ b/json/lexers/default-lexer/devirt_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/doc.go b/json/lexers/default-lexer/doc.go index 9e77bc8..f7b84e4 100644 --- a/json/lexers/default-lexer/doc.go +++ b/json/lexers/default-lexer/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package lexer provides a JSON lexer. // // The lexer splits a JSON input stream or a slice of bytes into tokens [token.T] (or [token.VT] for verbatim support). diff --git a/json/lexers/default-lexer/eof_reader.go b/json/lexers/default-lexer/eof_reader.go index 34f9a5f..ef2ef39 100644 --- a/json/lexers/default-lexer/eof_reader.go +++ b/json/lexers/default-lexer/eof_reader.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import "io" diff --git a/json/lexers/default-lexer/fuzz_test.go b/json/lexers/default-lexer/fuzz_test.go index 31bc898..5becbcf 100644 --- a/json/lexers/default-lexer/fuzz_test.go +++ b/json/lexers/default-lexer/fuzz_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer // Fuzz harness for the two lexers (L semantic, VL verbatim). diff --git a/json/lexers/default-lexer/internal/input/boolean.go b/json/lexers/default-lexer/internal/input/boolean.go index c52189f..8ca6a47 100644 --- a/json/lexers/default-lexer/internal/input/boolean.go +++ b/json/lexers/default-lexer/internal/input/boolean.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/input/constants.go b/json/lexers/default-lexer/internal/input/constants.go index 3be5976..6bd0a4d 100644 --- a/json/lexers/default-lexer/internal/input/constants.go +++ b/json/lexers/default-lexer/internal/input/constants.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input // Byte constants of the JSON grammar consulted by the value scanners. diff --git a/json/lexers/default-lexer/internal/input/input.go b/json/lexers/default-lexer/internal/input/input.go index 90e1e8c..11636c7 100644 --- a/json/lexers/default-lexer/internal/input/input.go +++ b/json/lexers/default-lexer/internal/input/input.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/input/number.go b/json/lexers/default-lexer/internal/input/number.go index 1e0f0b4..1a2c68e 100644 --- a/json/lexers/default-lexer/internal/input/number.go +++ b/json/lexers/default-lexer/internal/input/number.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/input/refill.go b/json/lexers/default-lexer/internal/input/refill.go index 69e9ed0..04a07ea 100644 --- a/json/lexers/default-lexer/internal/input/refill.go +++ b/json/lexers/default-lexer/internal/input/refill.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/input/string.go b/json/lexers/default-lexer/internal/input/string.go index 27fef47..f6fd034 100644 --- a/json/lexers/default-lexer/internal/input/string.go +++ b/json/lexers/default-lexer/internal/input/string.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/input/string_raw.go b/json/lexers/default-lexer/internal/input/string_raw.go index b0e988b..dae6636 100644 --- a/json/lexers/default-lexer/internal/input/string_raw.go +++ b/json/lexers/default-lexer/internal/input/string_raw.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/input/utf8.go b/json/lexers/default-lexer/internal/input/utf8.go index 78f5fd2..562a7b2 100644 --- a/json/lexers/default-lexer/internal/input/utf8.go +++ b/json/lexers/default-lexer/internal/input/utf8.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package input import ( diff --git a/json/lexers/default-lexer/internal/lexgen/main.go b/json/lexers/default-lexer/internal/lexgen/main.go index 0a6b1d8..4fbc36c 100644 --- a/json/lexers/default-lexer/internal/lexgen/main.go +++ b/json/lexers/default-lexer/internal/lexgen/main.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Command lexgen monomorphizes the lexer's generic scan cores onto each concrete policy, so the per-token policy calls // devirtualize and inline. // @@ -230,7 +233,10 @@ func run() error { return nil } -const header = `// Code generated by lexgen from the core_*.go sources; DO NOT EDIT. +const header = `// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +// Code generated by lexgen from the core_*.go sources; DO NOT EDIT. // // These are the generic scan cores (scanTokenBufferG / scanTokenStreamG / // scanPushG / scanPushStreamG / errCheckG) monomorphized onto each concrete policy: diff --git a/json/lexers/default-lexer/internal/strscan/_asm/asm.go b/json/lexers/default-lexer/internal/strscan/_asm/asm.go index 5de7b83..de7e801 100644 --- a/json/lexers/default-lexer/internal/strscan/_asm/asm.go +++ b/json/lexers/default-lexer/internal/strscan/_asm/asm.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Command asm generates the AVX2 string-stop kernel (../stringstop_amd64.s) via avo. // // Run through `go generate ./internal/strscan` (see ../scan_amd64.go). @@ -8,6 +11,11 @@ package main import ( + "bytes" + "flag" + "log" + "os" + . "github.com/mmcloughlin/avo/build" . "github.com/mmcloughlin/avo/operand" "github.com/mmcloughlin/avo/reg" @@ -17,6 +25,42 @@ func main() { stringStop() Generate() + prependLicense() +} + +// licenseHeader is the SPDX header every source file in this repository carries. +const licenseHeader = "// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers\n" + + "// SPDX-License-Identifier: Apache-2.0\n\n" + +// prependLicense adds [licenseHeader] to the assembly file avo has just written. +// +// avo emits only its own "Code generated by command:" warning, and printer.Config offers no hook +// for extra header lines, so a header added to the .s by hand is lost on the next go generate. +// Adding it here keeps it. The output path comes from avo's own -out flag, parsed by Generate. +func prependLicense() { + out := flag.Lookup("out") + if out == nil { + return + } + + name := out.Value.String() + if name == "" || name == "-" { + return + } + + body, err := os.ReadFile(name) + if err != nil { + log.Fatalf("reading %s: %v", name, err) + } + + if bytes.HasPrefix(body, []byte(licenseHeader)) { + return + } + + //nolint:gosec // name is avo's own -out path, fixed by the go:generate directive in this repo + if err := os.WriteFile(name, append([]byte(licenseHeader), body...), 0o600); err != nil { + log.Fatalf("writing %s: %v", name, err) + } } func stringStop() { diff --git a/json/lexers/default-lexer/internal/strscan/_asm/doc.go b/json/lexers/default-lexer/internal/strscan/_asm/doc.go index c68e95f..81a3cfc 100644 --- a/json/lexers/default-lexer/internal/strscan/_asm/doc.go +++ b/json/lexers/default-lexer/internal/strscan/_asm/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package _adm is a generator-only module for the AVX2 string-stop kernel. It isolates the avo // build-time dependency: only `go generate` (see ../scan_amd64.go) runs this, and // the generated ../stringstop_amd64.s has no avo import, so the parent json module diff --git a/json/lexers/default-lexer/internal/strscan/bench_amd64_test.go b/json/lexers/default-lexer/internal/strscan/bench_amd64_test.go index e2ef789..5a6706d 100644 --- a/json/lexers/default-lexer/internal/strscan/bench_amd64_test.go +++ b/json/lexers/default-lexer/internal/strscan/bench_amd64_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package strscan diff --git a/json/lexers/default-lexer/internal/strscan/cpuid_amd64.s b/json/lexers/default-lexer/internal/strscan/cpuid_amd64.s index 1da73f9..74afd80 100644 --- a/json/lexers/default-lexer/internal/strscan/cpuid_amd64.s +++ b/json/lexers/default-lexer/internal/strscan/cpuid_amd64.s @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + #include "textflag.h" // func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) diff --git a/json/lexers/default-lexer/internal/strscan/detect_amd64.go b/json/lexers/default-lexer/internal/strscan/detect_amd64.go index bef084b..1374b08 100644 --- a/json/lexers/default-lexer/internal/strscan/detect_amd64.go +++ b/json/lexers/default-lexer/internal/strscan/detect_amd64.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package strscan diff --git a/json/lexers/default-lexer/internal/strscan/detect_amd64_test.go b/json/lexers/default-lexer/internal/strscan/detect_amd64_test.go index 07c04d5..5567860 100644 --- a/json/lexers/default-lexer/internal/strscan/detect_amd64_test.go +++ b/json/lexers/default-lexer/internal/strscan/detect_amd64_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package strscan diff --git a/json/lexers/default-lexer/internal/strscan/scan_amd64.go b/json/lexers/default-lexer/internal/strscan/scan_amd64.go index 783dac9..50860b8 100644 --- a/json/lexers/default-lexer/internal/strscan/scan_amd64.go +++ b/json/lexers/default-lexer/internal/strscan/scan_amd64.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build amd64 package strscan diff --git a/json/lexers/default-lexer/internal/strscan/scan_noasm.go b/json/lexers/default-lexer/internal/strscan/scan_noasm.go index 104633f..4b63bfd 100644 --- a/json/lexers/default-lexer/internal/strscan/scan_noasm.go +++ b/json/lexers/default-lexer/internal/strscan/scan_noasm.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build !amd64 package strscan diff --git a/json/lexers/default-lexer/internal/strscan/stringstop_amd64.s b/json/lexers/default-lexer/internal/strscan/stringstop_amd64.s index 0f45e6f..803bbcb 100644 --- a/json/lexers/default-lexer/internal/strscan/stringstop_amd64.s +++ b/json/lexers/default-lexer/internal/strscan/stringstop_amd64.s @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Code generated by command: go run asm.go -out ../stringstop_amd64.s. DO NOT EDIT. #include "textflag.h" diff --git a/json/lexers/default-lexer/internal/strscan/strscan.go b/json/lexers/default-lexer/internal/strscan/strscan.go index 24b418f..50f3041 100644 --- a/json/lexers/default-lexer/internal/strscan/strscan.go +++ b/json/lexers/default-lexer/internal/strscan/strscan.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package strscan is the long-string scan gate for the lexer's string paths. // // The lexer probes the first 8-byte word of a string body inline with the [swar.StringStopMask] fast path (the diff --git a/json/lexers/default-lexer/internal/strscan/strscan_test.go b/json/lexers/default-lexer/internal/strscan/strscan_test.go index 162df27..12c9b1d 100644 --- a/json/lexers/default-lexer/internal/strscan/strscan_test.go +++ b/json/lexers/default-lexer/internal/strscan/strscan_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package strscan import ( diff --git a/json/lexers/default-lexer/internal/swar/swar.go b/json/lexers/default-lexer/internal/swar/swar.go index 4da0742..d228c5e 100644 --- a/json/lexers/default-lexer/internal/swar/swar.go +++ b/json/lexers/default-lexer/internal/swar/swar.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package swar provides inlinable SWAR (SIMD-within-a-register) byte-scanning primitives for the lexer's hot paths. // // Each mask function operates on one 8-byte little-endian word and returns a per-lane mask: the high bit (0x80) is set diff --git a/json/lexers/default-lexer/internal/swar/swar_test.go b/json/lexers/default-lexer/internal/swar/swar_test.go index bea228a..884a9d8 100644 --- a/json/lexers/default-lexer/internal/swar/swar_test.go +++ b/json/lexers/default-lexer/internal/swar/swar_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package swar import ( diff --git a/json/lexers/default-lexer/iterator_test.go b/json/lexers/default-lexer/iterator_test.go index 2291793..e6bfc5d 100644 --- a/json/lexers/default-lexer/iterator_test.go +++ b/json/lexers/default-lexer/iterator_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/lexer_norace_test.go b/json/lexers/default-lexer/lexer_norace_test.go index 261e9bc..494008a 100644 --- a/json/lexers/default-lexer/lexer_norace_test.go +++ b/json/lexers/default-lexer/lexer_norace_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build !race package lexer @@ -39,3 +42,57 @@ func TestBorrowRedeemAllocFree(t *testing.T) { }) require.Zerof(t, allocs, "borrow→lex→redeem of a small doc must not allocate, got %v", allocs) } + +// TestBorrowWithOptionsAllocFree pins that passing options to a borrow costs nothing: the variadic slice, the option +// closures it holds and the [options] struct they build all stay on the stack. +// +// [options] carries no pointer field, so applyWithDefaults seeds and returns it by value with no heap traffic — but +// that only holds while the option closures stay non-escaping, which is a property of inlining and escape analysis +// rather than of the source. This test fails if a future change (an option capturing a slice, a call site the compiler +// stops inlining) pushes them to the heap. +// +// The options chosen leave the zero-alloc paths intact. WithJSONPointer(true) is deliberately absent: it forfeits the +// guarantee by design, since the path stack allocates and object keys are copied out of the value buffer. +// +// Gated to non-race builds for the same reason as [TestBorrowRedeemAllocFree]. +func TestBorrowWithOptionsAllocFree(t *testing.T) { + if pools.DebugBuild { + t.Skip("the poolsdebug build allocates a per-borrow redeemer to track redemptions") + } + + docA := []byte(`{"a":[1,-2,3.5e2],"b":true}`) + opts := func() []Option { + return []Option{ + WithBufferSize(8192), + WithMaxContainerStack(64), + WithMaxValueBytes(1 << 20), + WithoutAVX2(true), + WithUTF8Policy(UTF8Replace), + WithElideSeparator(false), + } + } + + // warm the pool so the first Borrow does not allocate the lexer itself + _, redeem := BorrowLexerWithBytes(docA, opts()...) + redeem() + + allocs := testing.AllocsPerRun(100, func() { + l, redeem := BorrowLexerWithBytes( + docA, + WithBufferSize(8192), + WithMaxContainerStack(64), + WithMaxValueBytes(1<<20), + WithoutAVX2(true), + WithUTF8Policy(UTF8Replace), + WithElideSeparator(false), + ) + for { + tk := l.NextToken() + if tk.IsEOF() || !l.Ok() { + break + } + } + redeem() + }) + require.Zerof(t, allocs, "borrowing with options must not allocate, got %v", allocs) +} diff --git a/json/lexers/default-lexer/options.go b/json/lexers/default-lexer/options.go index ca3fbf0..ec9b226 100644 --- a/json/lexers/default-lexer/options.go +++ b/json/lexers/default-lexer/options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import "github.com/go-openapi/core/json/lexers/default-lexer/internal/input" @@ -96,9 +99,16 @@ var defaultOptions = options{ //nolint:gochecknoglobals // okay to preallocate i elideSeparator: true, } -//nolint:staticcheck,unparam // we force defaults options here - the o parameter is only here to avoid any allocation -func applyWithDefaults(o options, opts []Option) options { - o = defaultOptions +// applyWithDefaults resolves the effective configuration: it seeds [defaultOptions], then applies opts left to right. +// +// It always starts from the defaults, so a lexer borrowed from the pool never inherits the options of the previous +// borrower. +// +// The options struct holds no pointer, so the seed copy and the returned value stay on the stack: building it costs no +// allocation. +func applyWithDefaults(opts []Option) options { + o := defaultOptions + for _, apply := range opts { o = apply(o) } diff --git a/json/lexers/default-lexer/options_test.go b/json/lexers/default-lexer/options_test.go index 1f3cbd7..b376125 100644 --- a/json/lexers/default-lexer/options_test.go +++ b/json/lexers/default-lexer/options_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( @@ -42,8 +45,7 @@ func TestBufferSizeAlignment(t *testing.T) { // non-positive sizes are ignored: the option keeps the (aligned) default. for _, bad := range []int{0, -1, -32} { - var o options - o = applyWithDefaults(o, []Option{WithBufferSize(bad)}) + o := applyWithDefaults([]Option{WithBufferSize(bad)}) if o.bufferSize != defaultBufferBytes { t.Errorf( "WithBufferSize(%d): bufferSize = %d, want default %d", diff --git a/json/lexers/default-lexer/pointer.go b/json/lexers/default-lexer/pointer.go index e73db49..73dec55 100644 --- a/json/lexers/default-lexer/pointer.go +++ b/json/lexers/default-lexer/pointer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/pointer_norace_test.go b/json/lexers/default-lexer/pointer_norace_test.go index a96f5dd..c590b6c 100644 --- a/json/lexers/default-lexer/pointer_norace_test.go +++ b/json/lexers/default-lexer/pointer_norace_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build !race package lexer diff --git a/json/lexers/default-lexer/pointer_test.go b/json/lexers/default-lexer/pointer_test.go index e834171..45eb678 100644 --- a/json/lexers/default-lexer/pointer_test.go +++ b/json/lexers/default-lexer/pointer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/pools.go b/json/lexers/default-lexer/pools.go index 09f1071..b579424 100644 --- a/json/lexers/default-lexer/pools.go +++ b/json/lexers/default-lexer/pools.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( @@ -19,7 +22,7 @@ var lexersPool = poolOfLexers{ //nolint:gochecknoglobals // okay to have a pool func (p *poolOfLexers) borrowWithBytes(data []byte, opts ...Option) (*L, func()) { l, redeem := p.BorrowWithRedeem() - l.options = applyWithDefaults(l.options, opts) + l.options = applyWithDefaults(opts) l.in.R = noopReader l.in.Buffer = data l.in.Bufferized = len(data) @@ -34,7 +37,7 @@ func (p *poolOfLexers) borrowWithBytes(data []byte, opts ...Option) (*L, func()) func (p *poolOfLexers) borrowWithReader(r io.Reader, opts ...Option) (*L, func()) { l, redeem := p.BorrowWithRedeem() - l.options = applyWithDefaults(l.options, opts) + l.options = applyWithDefaults(opts) l.in.R = r l.in.Bufferized = 0 l.in.WholeBuffer = false // streaming: the buffer is refilled, values must be copied diff --git a/json/lexers/default-lexer/pull.go b/json/lexers/default-lexer/pull.go index 94d69ea..9029273 100644 --- a/json/lexers/default-lexer/pull.go +++ b/json/lexers/default-lexer/pull.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import "github.com/go-openapi/core/json/lexers/token" diff --git a/json/lexers/default-lexer/push.go b/json/lexers/default-lexer/push.go index 1a6bdbf..49a36c9 100644 --- a/json/lexers/default-lexer/push.go +++ b/json/lexers/default-lexer/push.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/push_pull_equivalence_test.go b/json/lexers/default-lexer/push_pull_equivalence_test.go index 82afc67..d674e7b 100644 --- a/json/lexers/default-lexer/push_pull_equivalence_test.go +++ b/json/lexers/default-lexer/push_pull_equivalence_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/scan_gen.go b/json/lexers/default-lexer/scan_gen.go index 2b1c096..412d5e9 100644 --- a/json/lexers/default-lexer/scan_gen.go +++ b/json/lexers/default-lexer/scan_gen.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Code generated by lexgen from the core_*.go sources; DO NOT EDIT. // // These are the generic scan cores (scanTokenBufferG / scanTokenStreamG / diff --git a/json/lexers/default-lexer/security_test.go b/json/lexers/default-lexer/security_test.go index 5adab42..b2d2bc1 100644 --- a/json/lexers/default-lexer/security_test.go +++ b/json/lexers/default-lexer/security_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/semantic_lexer.go b/json/lexers/default-lexer/semantic_lexer.go index 72667d7..668d91d 100644 --- a/json/lexers/default-lexer/semantic_lexer.go +++ b/json/lexers/default-lexer/semantic_lexer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( @@ -68,7 +71,7 @@ type L struct { // [BorrowLexerWithBytes] / [BorrowLexerWithReader] functions and the returned redeem closure. func New(r io.Reader, opts ...Option) *L { l := new(L) - l.options = applyWithDefaults(l.options, opts) + l.options = applyWithDefaults(opts) l.in.R = r l.in.Buffer = make([]byte, l.bufferSize) l.in.Bufferized = 0 @@ -88,7 +91,7 @@ func New(r io.Reader, opts ...Option) *L { // [BorrowLexerWithBytes] function and the returned redeem closure. func NewWithBytes(data []byte, opts ...Option) *L { l := new(L) - l.options = applyWithDefaults(l.options, opts) + l.options = applyWithDefaults(opts) l.in.R = noopReader l.in.Buffer = data l.in.Bufferized = len(data) diff --git a/json/lexers/default-lexer/semantic_lexer_test.go b/json/lexers/default-lexer/semantic_lexer_test.go index ea50b7e..34370d4 100644 --- a/json/lexers/default-lexer/semantic_lexer_test.go +++ b/json/lexers/default-lexer/semantic_lexer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/stack.go b/json/lexers/default-lexer/stack.go index 393ab8a..490be1f 100644 --- a/json/lexers/default-lexer/stack.go +++ b/json/lexers/default-lexer/stack.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/stack_test.go b/json/lexers/default-lexer/stack_test.go index 0486b8d..bd09499 100644 --- a/json/lexers/default-lexer/stack_test.go +++ b/json/lexers/default-lexer/stack_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/stream_test.go b/json/lexers/default-lexer/stream_test.go index b81a2b1..f74ef1c 100644 --- a/json/lexers/default-lexer/stream_test.go +++ b/json/lexers/default-lexer/stream_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/utf8_test.go b/json/lexers/default-lexer/utf8_test.go index b112626..a7f924f 100644 --- a/json/lexers/default-lexer/utf8_test.go +++ b/json/lexers/default-lexer/utf8_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/verbatim_lexer.go b/json/lexers/default-lexer/verbatim_lexer.go index f8dda08..e400cf8 100644 --- a/json/lexers/default-lexer/verbatim_lexer.go +++ b/json/lexers/default-lexer/verbatim_lexer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/verbatim_lexer_test.go b/json/lexers/default-lexer/verbatim_lexer_test.go index 8c90766..369eefb 100644 --- a/json/lexers/default-lexer/verbatim_lexer_test.go +++ b/json/lexers/default-lexer/verbatim_lexer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/default-lexer/zerocopy_test.go b/json/lexers/default-lexer/zerocopy_test.go index c9f818a..f249670 100644 --- a/json/lexers/default-lexer/zerocopy_test.go +++ b/json/lexers/default-lexer/zerocopy_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/doc.go b/json/lexers/doc.go index 5382e13..07834e8 100644 --- a/json/lexers/doc.go +++ b/json/lexers/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package lexers exposes interfaces for lexing JSON. // // The [Lexer] interface allows for picking a specific implementation of a JSON lexer. diff --git a/json/lexers/error-codes/context.go b/json/lexers/error-codes/context.go index 1094a08..de10404 100644 --- a/json/lexers/error-codes/context.go +++ b/json/lexers/error-codes/context.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package codes import ( diff --git a/json/lexers/error-codes/context_test.go b/json/lexers/error-codes/context_test.go index 655db4a..5af0445 100644 --- a/json/lexers/error-codes/context_test.go +++ b/json/lexers/error-codes/context_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package codes import ( diff --git a/json/lexers/error-codes/doc.go b/json/lexers/error-codes/doc.go index 6227b1a..887cb78 100644 --- a/json/lexers/error-codes/doc.go +++ b/json/lexers/error-codes/doc.go @@ -1,2 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package codes exposes common lexer errors. package codes diff --git a/json/lexers/error-codes/errors.go b/json/lexers/error-codes/errors.go index 72f3e10..f979415 100644 --- a/json/lexers/error-codes/errors.go +++ b/json/lexers/error-codes/errors.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package codes // LexerError is an error raised by a lexer. diff --git a/json/lexers/internal/scan/scan.go b/json/lexers/internal/scan/scan.go index f07ee84..1bacfac 100644 --- a/json/lexers/internal/scan/scan.go +++ b/json/lexers/internal/scan/scan.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package scan holds stateless JSON-scanning primitives shared across the lexer // subtree — the default lexer's hot cores and the token package's on-demand // unescaper: whitespace skipping and hex / \uXXXX digit decoding. diff --git a/json/lexers/lexers.go b/json/lexers/lexers.go index 47aa545..da44cd7 100644 --- a/json/lexers/lexers.go +++ b/json/lexers/lexers.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexers import ( diff --git a/json/lexers/token/doc.go b/json/lexers/token/doc.go index 4c32622..2ff0081 100644 --- a/json/lexers/token/doc.go +++ b/json/lexers/token/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package token defines the JSON token types with their kind. // // These data structures should be returned by all implementations of a JSON lexer. diff --git a/json/lexers/token/token.go b/json/lexers/token/token.go index 783928c..82a99a1 100644 --- a/json/lexers/token/token.go +++ b/json/lexers/token/token.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package token import ( diff --git a/json/lexers/token/unescape.go b/json/lexers/token/unescape.go index cfe6ed4..951649b 100644 --- a/json/lexers/token/unescape.go +++ b/json/lexers/token/unescape.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package token import ( diff --git a/json/lexers/token/unescape_test.go b/json/lexers/token/unescape_test.go index 2507563..9fd393a 100644 --- a/json/lexers/token/unescape_test.go +++ b/json/lexers/token/unescape_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package token import ( diff --git a/json/lexers/yaml-lexer/bom_test.go b/json/lexers/yaml-lexer/bom_test.go index acbeef6..8776bee 100644 --- a/json/lexers/yaml-lexer/bom_test.go +++ b/json/lexers/yaml-lexer/bom_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/conformance_golden_test.go b/json/lexers/yaml-lexer/conformance_golden_test.go index 289ec78..733064e 100644 --- a/json/lexers/yaml-lexer/conformance_golden_test.go +++ b/json/lexers/yaml-lexer/conformance_golden_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/conformance_lineendings_test.go b/json/lexers/yaml-lexer/conformance_lineendings_test.go index 480c74a..0eb36b7 100644 --- a/json/lexers/yaml-lexer/conformance_lineendings_test.go +++ b/json/lexers/yaml-lexer/conformance_lineendings_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/conformance_suite_test.go b/json/lexers/yaml-lexer/conformance_suite_test.go index 7ecddd8..91e3ad7 100644 --- a/json/lexers/yaml-lexer/conformance_suite_test.go +++ b/json/lexers/yaml-lexer/conformance_suite_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/conformance_test.go b/json/lexers/yaml-lexer/conformance_test.go index fd677a0..be1cc40 100644 --- a/json/lexers/yaml-lexer/conformance_test.go +++ b/json/lexers/yaml-lexer/conformance_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/conformance_xfail_test.go b/json/lexers/yaml-lexer/conformance_xfail_test.go index 9a25850..37813f2 100644 --- a/json/lexers/yaml-lexer/conformance_xfail_test.go +++ b/json/lexers/yaml-lexer/conformance_xfail_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test // conformanceXFail is the inventory of where YL stands against the YAML Test Suite: every case whose behavior diff --git a/json/lexers/yaml-lexer/errors.go b/json/lexers/yaml-lexer/errors.go index f8ca368..b4e2352 100644 --- a/json/lexers/yaml-lexer/errors.go +++ b/json/lexers/yaml-lexer/errors.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import "fmt" diff --git a/json/lexers/yaml-lexer/fuzz_test.go b/json/lexers/yaml-lexer/fuzz_test.go index d731f89..8ee47e9 100644 --- a/json/lexers/yaml-lexer/fuzz_test.go +++ b/json/lexers/yaml-lexer/fuzz_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test // Fuzz harness for the YAML lexer YL. diff --git a/json/lexers/yaml-lexer/go.mod b/json/lexers/yaml-lexer/go.mod index 4163092..947c638 100644 --- a/json/lexers/yaml-lexer/go.mod +++ b/json/lexers/yaml-lexer/go.mod @@ -4,13 +4,11 @@ go 1.25.0 require ( github.com/go-openapi/core/json v0.0.3 + github.com/go-openapi/swag/pools v0.29.0 github.com/go-openapi/testify/v2 v2.6.1 github.com/goccy/go-yaml v1.19.2 ) -require ( - github.com/go-openapi/swag/conv v0.29.0 // indirect - github.com/go-openapi/swag/pools v0.29.0 // indirect -) +require github.com/go-openapi/swag/conv v0.29.0 // indirect replace github.com/go-openapi/core/json => ../.. diff --git a/json/lexers/yaml-lexer/lexer.go b/json/lexers/yaml-lexer/lexer.go index 5e58972..49d4159 100644 --- a/json/lexers/yaml-lexer/lexer.go +++ b/json/lexers/yaml-lexer/lexer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( @@ -80,7 +83,7 @@ type emit struct { // consumed from an untrusted reader, wrap it with [io.LimitReader]. func New(r io.Reader, opts ...Option) *YL { l := &YL{} - l.options = applyWithDefaults(l.options, opts) + l.options = applyWithDefaults(opts) l.reset() l.setReader(r) @@ -93,7 +96,7 @@ func New(r io.Reader, opts ...Option) *YL { // stay stable until the lexer is done with it. func NewWithBytes(data []byte, opts ...Option) *YL { l := &YL{} - l.options = applyWithDefaults(l.options, opts) + l.options = applyWithDefaults(opts) l.data = data l.reset() @@ -191,7 +194,13 @@ func (l *YL) Err() error { return l.err } func (l *YL) SetErr(err error) { l.err = err } // Reset returns the lexer to a clean, source-less state so it can be recycled. It drops the -// reference to caller-supplied memory (the input buffer) so a pooled lexer does not pin it. +// references to caller-supplied memory — the input buffer, and the token values that alias it — so a +// pooled lexer does not pin them while it sits idle. +// +// Reset does NOT rebind an input: call [YL.ResetWithBytes] / [YL.ResetWithReader] (or a Borrow*/New* +// constructor) to lex a new source. +// +// Configured options are preserved, and the token slice keeps its capacity for reuse. func (l *YL) Reset() { l.data = nil l.reset() @@ -223,6 +232,10 @@ func (l *YL) setReader(r io.Reader) { // reset clears the per-input scanning state, preserving allocated capacity for reuse. func (l *YL) reset() { + // zero the entries before shortening: a token value aliases the source buffer, and an entry left + // behind in the retained capacity would keep the previous document's bytes alive. Clearing at + // len (not cap) is enough, since every entry a build appends is cleared by the next reset. + clear(l.toks) l.toks = l.toks[:0] l.pos = 0 l.built = false diff --git a/json/lexers/yaml-lexer/lexer_test.go b/json/lexers/yaml-lexer/lexer_test.go index e8f66dd..4f2a1d6 100644 --- a/json/lexers/yaml-lexer/lexer_test.go +++ b/json/lexers/yaml-lexer/lexer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/merge_cycle_test.go b/json/lexers/yaml-lexer/merge_cycle_test.go index 02a333f..10c0044 100644 --- a/json/lexers/yaml-lexer/merge_cycle_test.go +++ b/json/lexers/yaml-lexer/merge_cycle_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/number.go b/json/lexers/yaml-lexer/number.go index b0f68ab..ae0b415 100644 --- a/json/lexers/yaml-lexer/number.go +++ b/json/lexers/yaml-lexer/number.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/yaml-lexer/options.go b/json/lexers/yaml-lexer/options.go index 0d4f9de..9b8c0b5 100644 --- a/json/lexers/yaml-lexer/options.go +++ b/json/lexers/yaml-lexer/options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer type ( @@ -14,9 +17,13 @@ type ( var defaultOptions = options{} //nolint:gochecknoglobals // it's okay to keep defaults as a preallocated immutable global -//nolint:staticcheck,unparam // we force defaults options here - the o parameter is only here to avoid any allocation -func applyWithDefaults(o options, opts []Option) options { - o = defaultOptions +// applyWithDefaults resolves the effective configuration: it seeds [defaultOptions], then applies opts left to right. +// +// The options struct holds no pointer, so the seed copy and the returned value stay on the stack: building it costs no +// allocation. +func applyWithDefaults(opts []Option) options { + o := defaultOptions + for _, apply := range opts { o = apply(o) } diff --git a/json/lexers/yaml-lexer/pointer.go b/json/lexers/yaml-lexer/pointer.go index bfd08a8..66be495 100644 --- a/json/lexers/yaml-lexer/pointer.go +++ b/json/lexers/yaml-lexer/pointer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/lexers/yaml-lexer/pointer_test.go b/json/lexers/yaml-lexer/pointer_test.go index a209216..242b100 100644 --- a/json/lexers/yaml-lexer/pointer_test.go +++ b/json/lexers/yaml-lexer/pointer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/pools.go b/json/lexers/yaml-lexer/pools.go new file mode 100644 index 0000000..0a9f536 --- /dev/null +++ b/json/lexers/yaml-lexer/pools.go @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package lexer + +import ( + "io" + + "github.com/go-openapi/swag/pools" +) + +type poolOfLexers struct { + *pools.PoolRedeemable[YL] +} + +// lexersPool is a redeemable pool: borrowing yields a cached redeem closure (no per-borrow allocation), and under +// the poolsdebug build tag it detects double-redeem, foreign-redeem and leaks. +var lexersPool = poolOfLexers{ //nolint:gochecknoglobals // okay to have a pool as a global + PoolRedeemable: pools.NewRedeemable[YL](), +} + +func (p *poolOfLexers) borrowWithBytes(data []byte, opts ...Option) (*YL, func()) { + l, redeem := p.BorrowWithRedeem() + l.options = applyWithDefaults(opts) + l.data = data + l.reset() + + return l, redeem +} + +func (p *poolOfLexers) borrowWithReader(r io.Reader, opts ...Option) (*YL, func()) { + l, redeem := p.BorrowWithRedeem() + l.options = applyWithDefaults(opts) + l.reset() + l.setReader(r) + + return l, redeem +} + +// BorrowLexerWithReader borrows a YL(exer) from a global pool, together with the closure that redeems it back to +// the pool. +// +// This is equivalent to calling [New], but may recycle a previously allocated lexer if available from the pool. +// +// The redeem closure must be called exactly once when the lexer is no longer needed (typically via defer); after +// calling it, drop the reference to the lexer. +// Calling it more than once panics. +// To maximize the amortizing effect of the pool, make sure every borrowed lexer is eventually redeemed. +// +// Note that a reader is drained with [io.ReadAll], so each borrow allocates the buffer holding the source. +// [BorrowLexerWithBytes] avoids that. +func BorrowLexerWithReader(r io.Reader, opts ...Option) (*YL, func()) { + return lexersPool.borrowWithReader(r, opts...) +} + +// BorrowLexerWithBytes borrows a YL(exer) from a global pool, together with the closure that redeems it back to +// the pool. +// +// This is equivalent to calling [NewWithBytes], but may recycle a previously allocated lexer if available from the +// pool. +// +// The redeem closure must be called exactly once when the lexer is no longer needed (typically via defer); after +// calling it, drop the reference to the lexer. +// Calling it more than once panics. +// +// What the pool amortizes is the YL and the capacity of its token slice, NOT the parse: lexing hands the source to +// goccy/go-yaml, which builds a fresh AST every time. Borrowing therefore lowers the allocation count of a +// repeated lex, it does not bring it to zero the way [github.com/go-openapi/core/json/lexers/default-lexer]'s pool +// does. +func BorrowLexerWithBytes(data []byte, opts ...Option) (*YL, func()) { + return lexersPool.borrowWithBytes(data, opts...) +} diff --git a/json/lexers/yaml-lexer/pools_internal_test.go b/json/lexers/yaml-lexer/pools_internal_test.go new file mode 100644 index 0000000..c5c9115 --- /dev/null +++ b/json/lexers/yaml-lexer/pools_internal_test.go @@ -0,0 +1,70 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package lexer + +import ( + "testing" + + "github.com/go-openapi/testify/v2/require" +) + +// TestResetDropsReferences pins the non-pinning contract a pooled lexer relies on: once redeemed, a YL holds no +// reference to the caller's source buffer — neither directly (l.data) nor through the token values that alias it. +// +// The token slice keeps its capacity across a reset, so entries left behind by a LONGER previous document are the +// case that matters: they sit past the current length, where nothing overwrites them. +func TestResetDropsReferences(t *testing.T) { + const ( + long = "a: xxxxxxxx\nb:\n - 1\n - 2\n - 3\n" + short = "z: 1\n" + ) + + l := NewWithBytes([]byte(long)) + for range l.Tokens() { //nolint:revive // draining the stream is the point + } + require.NoError(t, l.Err()) + require.NotEmpty(t, l.toks) + longTokens := len(l.toks) + longCap := cap(l.toks) + + // a shorter document: its build leaves the long document's entries in the retained capacity + l.ResetWithBytes([]byte(short)) + for range l.Tokens() { //nolint:revive // draining the stream is the point + } + require.NoError(t, l.Err()) + require.Less( + t, + len(l.toks), + longTokens, + "the second document must be the shorter one for this test to bite", + ) + + l.Reset() + + require.Nil(t, l.data, "Reset must drop the caller's buffer") + require.Equal(t, longCap, cap(l.toks), "Reset must keep the token slice capacity for reuse") + + for i, e := range l.toks[:cap(l.toks)] { + require.Nilf(t, e.tok.Value(), + "toks[%d] still aliases a source buffer after Reset: a pooled lexer would pin it", i) + require.Zerof(t, e.off, "toks[%d] still holds a stale offset after Reset", i) + } +} + +// TestApplyWithDefaultsSeedsDefaults checks that options never leak between two builds: applyWithDefaults always +// starts from defaultOptions, so a lexer recycled through the pool cannot inherit the previous borrower's settings. +func TestApplyWithDefaultsSeedsDefaults(t *testing.T) { + require.Equal(t, defaultOptions, applyWithDefaults(nil)) + + o := applyWithDefaults([]Option{WithMaxTokens(3), WithJSONPointer(true)}) + require.Equal(t, 3, o.maxTokens) + require.True(t, o.jsonPointer) + + require.Equal( + t, + defaultOptions, + applyWithDefaults(nil), + "a later call must not see the previous options", + ) +} diff --git a/json/lexers/yaml-lexer/pools_norace_test.go b/json/lexers/yaml-lexer/pools_norace_test.go new file mode 100644 index 0000000..eb56a96 --- /dev/null +++ b/json/lexers/yaml-lexer/pools_norace_test.go @@ -0,0 +1,81 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +//go:build !race + +package lexer_test + +import ( + "testing" + + "github.com/go-openapi/swag/pools" + "github.com/go-openapi/testify/v2/require" + + yamllexer "github.com/go-openapi/core/json/lexers/yaml-lexer" +) + +// docPool is the small document the pool guards borrow. +const docPool = "a:\n - 1\n - -2\nb: true\n" + +// TestBorrowRedeemAllocFree pins that a borrow→redeem cycle allocates nothing: the pool amortizes the YL, and +// [pools.PoolRedeemable] hands out a cached redeem closure instead of building one per borrow. +// +// The cycle measured here stops short of lexing, and that is not an oversight. Unlike the JSON lexer, YL cannot make +// a full borrow→lex→redeem cycle allocation-free: build hands the source to goccy/go-yaml, which allocates a fresh +// AST for every parse. What the pool amortizes is the YL and the capacity of its token slice. +// +// It is gated to non-race builds: testing.AllocsPerRun is unreliable under -race (the race detector instruments +// allocations, inflating the count), so the 0-alloc property is enforced here, in the build that reflects production. +func TestBorrowRedeemAllocFree(t *testing.T) { + if pools.DebugBuild { + t.Skip("the poolsdebug build allocates a per-borrow redeemer to track redemptions") + } + + data := []byte(docPool) + + // warm the pool so the first Borrow does not allocate the lexer itself + _, redeem := yamllexer.BorrowLexerWithBytes(data) + redeem() + + allocs := testing.AllocsPerRun(100, func() { + _, redeem := yamllexer.BorrowLexerWithBytes(data) + redeem() + }) + require.Zerof(t, allocs, "borrow→redeem must not allocate, got %v", allocs) +} + +// TestBorrowWithOptionsAllocFree pins that passing options to a borrow costs nothing: the variadic slice, the option +// closures it holds and the options struct they build all stay on the stack. +// +// The options struct carries no pointer field, so applyWithDefaults seeds and returns it by value with no heap +// traffic — but that only holds while the option closures stay non-escaping, which is a property of inlining and +// escape analysis rather than of the source. This test fails if a future change (an option capturing a slice, a call +// site the compiler stops inlining) pushes them to the heap. +// +// WithJSONPointer(true) is deliberately absent: it forfeits the guarantee by design, since the path stack allocates +// and object keys are interned. +// +// Gated to non-race builds for the same reason as [TestBorrowRedeemAllocFree]. +func TestBorrowWithOptionsAllocFree(t *testing.T) { + if pools.DebugBuild { + t.Skip("the poolsdebug build allocates a per-borrow redeemer to track redemptions") + } + + data := []byte(docPool) + + // warm the pool so the first Borrow does not allocate the lexer itself + _, redeem := yamllexer.BorrowLexerWithBytes(data, yamllexer.WithMaxTokens(1000)) + redeem() + + allocs := testing.AllocsPerRun(100, func() { + _, redeem := yamllexer.BorrowLexerWithBytes( + data, + yamllexer.WithMaxContainerStack(64), + yamllexer.WithMaxValueBytes(1<<20), + yamllexer.WithMaxTokens(1000), + yamllexer.WithJSONPointer(false), + ) + redeem() + }) + require.Zerof(t, allocs, "borrowing with options must not allocate, got %v", allocs) +} diff --git a/json/lexers/yaml-lexer/pools_test.go b/json/lexers/yaml-lexer/pools_test.go new file mode 100644 index 0000000..2c1a3f5 --- /dev/null +++ b/json/lexers/yaml-lexer/pools_test.go @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + +package lexer_test + +import ( + "strings" + "testing" + + "github.com/go-openapi/swag/pools" + "github.com/go-openapi/testify/v2/require" + + yamllexer "github.com/go-openapi/core/json/lexers/yaml-lexer" +) + +func TestPoolReuse(t *testing.T) { + const ( + docA = "a:\n - 1\n - -2\n - 3.5e2\nb: true\n" + docB = "- null\n- x\n- 0.5\n" + ) + + drain := func(l *yamllexer.YL) ([]string, error) { + var out []string + for tok := range l.Tokens() { + out = append(out, repr(tok)) + } + + return out, l.Err() + } + + wantA, errA := drain(yamllexer.NewWithBytes([]byte(docA))) + require.NoError(t, errA) + wantB, errB := drain(yamllexer.NewWithBytes([]byte(docB))) + require.NoError(t, errB) + require.NotEmpty(t, wantA) + + t.Run("borrow/redeem reproduces the stream", func(t *testing.T) { + // alternating documents of different shapes and lengths: a recycled lexer must carry no state + // from the previous borrower, and must not truncate to the shorter of the two token streams. + for range 3 { + l, redeem := yamllexer.BorrowLexerWithBytes([]byte(docA)) + got, err := drain(l) + require.NoError(t, err) + require.Equal(t, wantA, got) + redeem() + + l, redeem = yamllexer.BorrowLexerWithBytes([]byte(docB)) + got, err = drain(l) + require.NoError(t, err) + require.Equal(t, wantB, got) + redeem() + } + }) + + t.Run("borrow with a reader", func(t *testing.T) { + l, redeem := yamllexer.BorrowLexerWithReader(strings.NewReader(docA)) + defer redeem() + + got, err := drain(l) + require.NoError(t, err) + require.Equal(t, wantA, got) + }) + + t.Run("options are honored, and do not survive the redeem", func(t *testing.T) { + l, redeem := yamllexer.BorrowLexerWithBytes([]byte(docA), yamllexer.WithMaxTokens(3)) + _, err := drain(l) + require.ErrorIs(t, err, yamllexer.ErrMaxTokens) + redeem() + + // the next borrower passes no option: it must get the defaults back, not WithMaxTokens(3) + l, redeem = yamllexer.BorrowLexerWithBytes([]byte(docA)) + defer redeem() + + got, err := drain(l) + require.NoError(t, err) + require.Equal(t, wantA, got) + }) + + // In the poolsdebug build, assert the pool tracker recorded no leaked borrows from this test (a no-op in + // release builds). + t.Cleanup(func() { pools.AssertNoLeaks(t) }) +} diff --git a/json/lexers/yaml-lexer/position_test.go b/json/lexers/yaml-lexer/position_test.go index 0c9eed8..49883d1 100644 --- a/json/lexers/yaml-lexer/position_test.go +++ b/json/lexers/yaml-lexer/position_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/resolved_key_test.go b/json/lexers/yaml-lexer/resolved_key_test.go index 17bcf8c..cc26593 100644 --- a/json/lexers/yaml-lexer/resolved_key_test.go +++ b/json/lexers/yaml-lexer/resolved_key_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer_test import ( diff --git a/json/lexers/yaml-lexer/walk.go b/json/lexers/yaml-lexer/walk.go index e5f1e19..b730243 100644 --- a/json/lexers/yaml-lexer/walk.go +++ b/json/lexers/yaml-lexer/walk.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package lexer import ( diff --git a/json/stores/default-store/alloc_test.go b/json/stores/default-store/alloc_test.go index cea5afb..2ddb41c 100644 --- a/json/stores/default-store/alloc_test.go +++ b/json/stores/default-store/alloc_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Allocation counting needs an un-instrumented build: the race detector and the pools // tracker (poolsdebug) both allocate per borrow, which would swamp the amortized counts // these tests assert. diff --git a/json/stores/default-store/appendvalue_test.go b/json/stores/default-store/appendvalue_test.go index 408a6f9..49f5b61 100644 --- a/json/stores/default-store/appendvalue_test.go +++ b/json/stores/default-store/appendvalue_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/assertions.go b/json/stores/default-store/assertions.go index 7f8ad58..8de0765 100644 --- a/json/stores/default-store/assertions.go +++ b/json/stores/default-store/assertions.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/compress.go b/json/stores/default-store/compress.go index 6421fa3..0b5e6de 100644 --- a/json/stores/default-store/compress.go +++ b/json/stores/default-store/compress.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/compress_dict_test.go b/json/stores/default-store/compress_dict_test.go index 542fa16..7c896ff 100644 --- a/json/stores/default-store/compress_dict_test.go +++ b/json/stores/default-store/compress_dict_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/compress_lazy_test.go b/json/stores/default-store/compress_lazy_test.go index ec785be..b6be79a 100644 --- a/json/stores/default-store/compress_lazy_test.go +++ b/json/stores/default-store/compress_lazy_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/compress_options.go b/json/stores/default-store/compress_options.go index e16b9fc..d5b4f31 100644 --- a/json/stores/default-store/compress_options.go +++ b/json/stores/default-store/compress_options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/compress_options_test.go b/json/stores/default-store/compress_options_test.go index 3189bb9..1958284 100644 --- a/json/stores/default-store/compress_options_test.go +++ b/json/stores/default-store/compress_options_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/compress_test.go b/json/stores/default-store/compress_test.go index a22b183..708143f 100644 --- a/json/stores/default-store/compress_test.go +++ b/json/stores/default-store/compress_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/concurrent_store.go b/json/stores/default-store/concurrent_store.go index b67f7c0..99e4d50 100644 --- a/json/stores/default-store/concurrent_store.go +++ b/json/stores/default-store/concurrent_store.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/concurrent_store_test.go b/json/stores/default-store/concurrent_store_test.go index eb0a6c5..c66c9b3 100644 --- a/json/stores/default-store/concurrent_store_test.go +++ b/json/stores/default-store/concurrent_store_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:gosec package store diff --git a/json/stores/default-store/concurrent_stress_test.go b/json/stores/default-store/concurrent_stress_test.go index 0668361..01d7bcd 100644 --- a/json/stores/default-store/concurrent_stress_test.go +++ b/json/stores/default-store/concurrent_stress_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/doc.go b/json/stores/default-store/doc.go index 9cb2146..7778873 100644 --- a/json/stores/default-store/doc.go +++ b/json/stores/default-store/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package store provides default implementations for [stores.Store]. // // It exposes a [Store] type to pack JSON values in memory. diff --git a/json/stores/default-store/errors.go b/json/stores/default-store/errors.go index 3f7996c..a622f1c 100644 --- a/json/stores/default-store/errors.go +++ b/json/stores/default-store/errors.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store type storeError string diff --git a/json/stores/default-store/gob.go b/json/stores/default-store/gob.go index 2b56f9e..05363fc 100644 --- a/json/stores/default-store/gob.go +++ b/json/stores/default-store/gob.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/gob_test.go b/json/stores/default-store/gob_test.go index 91d78b5..07ae090 100644 --- a/json/stores/default-store/gob_test.go +++ b/json/stores/default-store/gob_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/guards.go b/json/stores/default-store/guards.go index 8505cb3..bda264a 100644 --- a/json/stores/default-store/guards.go +++ b/json/stores/default-store/guards.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build guards || writerguards package store diff --git a/json/stores/default-store/header.go b/json/stores/default-store/header.go index 0e15576..cd8c9a9 100644 --- a/json/stores/default-store/header.go +++ b/json/stores/default-store/header.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store // The header of th uint64 that a [stores.Handle] gives us diff --git a/json/stores/default-store/inline.go b/json/stores/default-store/inline.go index e056c5d..1752570 100644 --- a/json/stores/default-store/inline.go +++ b/json/stores/default-store/inline.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/no_guards.go b/json/stores/default-store/no_guards.go index 9da37d2..af0f6a6 100644 --- a/json/stores/default-store/no_guards.go +++ b/json/stores/default-store/no_guards.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build !guards && !writerguards package store diff --git a/json/stores/default-store/options.go b/json/stores/default-store/options.go index 4a9e55d..880e90e 100644 --- a/json/stores/default-store/options.go +++ b/json/stores/default-store/options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store const ( diff --git a/json/stores/default-store/pools.go b/json/stores/default-store/pools.go index 1be4254..d65d538 100644 --- a/json/stores/default-store/pools.go +++ b/json/stores/default-store/pools.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:gochecknoglobals package store diff --git a/json/stores/default-store/store.go b/json/stores/default-store/store.go index fb2cbea..5b1503e 100644 --- a/json/stores/default-store/store.go +++ b/json/stores/default-store/store.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/store_test.go b/json/stores/default-store/store_test.go index 11000db..8cb75ca 100644 --- a/json/stores/default-store/store_test.go +++ b/json/stores/default-store/store_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/verbatim.go b/json/stores/default-store/verbatim.go index 52d9fa5..f3895fc 100644 --- a/json/stores/default-store/verbatim.go +++ b/json/stores/default-store/verbatim.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/default-store/verbatim_test.go b/json/stores/default-store/verbatim_test.go index e210471..ddeb68a 100644 --- a/json/stores/default-store/verbatim_test.go +++ b/json/stores/default-store/verbatim_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package store import ( diff --git a/json/stores/doc.go b/json/stores/doc.go index 84ffc6e..8f2d233 100644 --- a/json/stores/doc.go +++ b/json/stores/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package stores exposes the interface to work with a JSON [Store]. // // A JSON [Store] acts as an in-memory store for scalar [Value] s found in a JSON document. diff --git a/json/stores/internal/bcd/bcd.go b/json/stores/internal/bcd/bcd.go index 9668151..7676e5a 100644 --- a/json/stores/internal/bcd/bcd.go +++ b/json/stores/internal/bcd/bcd.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package bcd import "slices" diff --git a/json/stores/internal/bcd/bcd_test.go b/json/stores/internal/bcd/bcd_test.go index 1433754..8299fe2 100644 --- a/json/stores/internal/bcd/bcd_test.go +++ b/json/stores/internal/bcd/bcd_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package bcd import ( diff --git a/json/stores/internal/bcd/doc.go b/json/stores/internal/bcd/doc.go index d15c623..6c5f23e 100644 --- a/json/stores/internal/bcd/doc.go +++ b/json/stores/internal/bcd/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package bcd is a codec for our internal modified BCD encoding scheme. // // This is modified standard 8-4-2-1 BCD to account for decimal point and scientific notation in JSON numbers. diff --git a/json/stores/internal/bcd/guards.go b/json/stores/internal/bcd/guards.go index 50dc9f2..ce9ca7b 100644 --- a/json/stores/internal/bcd/guards.go +++ b/json/stores/internal/bcd/guards.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build guards || writerguards package bcd diff --git a/json/stores/internal/bcd/no_guards.go b/json/stores/internal/bcd/no_guards.go index 7ec11c2..8f8ed51 100644 --- a/json/stores/internal/bcd/no_guards.go +++ b/json/stores/internal/bcd/no_guards.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //go:build !guards && !writerguards package bcd diff --git a/json/stores/stores.go b/json/stores/stores.go index f44b989..ad0801b 100644 --- a/json/stores/stores.go +++ b/json/stores/stores.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package stores import ( diff --git a/json/stores/values/key.go b/json/stores/values/key.go index 8d333f9..b96a8b3 100644 --- a/json/stores/values/key.go +++ b/json/stores/values/key.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package values import "unique" diff --git a/json/stores/values/value.go b/json/stores/values/value.go index 7aa0fd6..e4e1c6a 100644 --- a/json/stores/values/value.go +++ b/json/stores/values/value.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package values import ( diff --git a/json/stores/values/verbatim.go b/json/stores/values/verbatim.go index e99cee6..f8c30fc 100644 --- a/json/stores/values/verbatim.go +++ b/json/stores/values/verbatim.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package values // VerbatimValue represents a JSON scalar value together with any non-significant blank space diff --git a/json/stores/verbatim.go b/json/stores/verbatim.go index 1a05c5a..3f87933 100644 --- a/json/stores/verbatim.go +++ b/json/stores/verbatim.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package stores import ( diff --git a/json/testdata/workloads/corpus.go b/json/testdata/workloads/corpus.go index db32340..e50826c 100644 --- a/json/testdata/workloads/corpus.go +++ b/json/testdata/workloads/corpus.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package workloads import ( diff --git a/json/testdata/workloads/workloads.go b/json/testdata/workloads/workloads.go index 977f500..906c0a7 100644 --- a/json/testdata/workloads/workloads.go +++ b/json/testdata/workloads/workloads.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package workloads generates deterministic JSON payloads used to stress the // lexer benchmarks along different axes (numbers, strings, escapes, nesting, // keys, whitespace, ...). diff --git a/json/types/convert.go b/json/types/convert.go index 94a7a1c..2a48e3d 100644 --- a/json/types/convert.go +++ b/json/types/convert.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package types import ( diff --git a/json/types/doc.go b/json/types/doc.go index 186b599..2829ece 100644 --- a/json/types/doc.go +++ b/json/types/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package types defines common types to work with json. // // The JSON grammar defines four primitive types: strings, numbers, booleans and null. diff --git a/json/types/interfaces.go b/json/types/interfaces.go index aa84878..c9b369a 100644 --- a/json/types/interfaces.go +++ b/json/types/interfaces.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package types import "github.com/go-openapi/swag/pools" diff --git a/json/types/numerical.go b/json/types/numerical.go index a00bfc2..18b180e 100644 --- a/json/types/numerical.go +++ b/json/types/numerical.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package types import ( diff --git a/json/types/numerical_test.go b/json/types/numerical_test.go index a707c95..e08d7ee 100644 --- a/json/types/numerical_test.go +++ b/json/types/numerical_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package types import ( diff --git a/json/types/types.go b/json/types/types.go index 50b2d89..188cab0 100644 --- a/json/types/types.go +++ b/json/types/types.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package types import "strconv" diff --git a/json/writers/default-writer/base_writer.go b/json/writers/default-writer/base_writer.go index 646d83b..bd348af 100644 --- a/json/writers/default-writer/base_writer.go +++ b/json/writers/default-writer/base_writer.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // writegen lifts commonWriter verbatim onto each concrete writer; the triplication is by design. package writer diff --git a/json/writers/default-writer/buffered.go b/json/writers/default-writer/buffered.go index 06aa403..60f1b34 100644 --- a/json/writers/default-writer/buffered.go +++ b/json/writers/default-writer/buffered.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // writegen lifts commonWriter verbatim onto each concrete writer; the triplication is by design. package writer diff --git a/json/writers/default-writer/buffered_options.go b/json/writers/default-writer/buffered_options.go index 5309560..adc1c8a 100644 --- a/json/writers/default-writer/buffered_options.go +++ b/json/writers/default-writer/buffered_options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer const ( diff --git a/json/writers/default-writer/constants.go b/json/writers/default-writer/constants.go index 8aa5cf6..bed39ae 100644 --- a/json/writers/default-writer/constants.go +++ b/json/writers/default-writer/constants.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer const ( diff --git a/json/writers/default-writer/doc.go b/json/writers/default-writer/doc.go index 698f212..57b1ef6 100644 --- a/json/writers/default-writer/doc.go +++ b/json/writers/default-writer/doc.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package writer exposes an implementation of the JSON writer interface [writers.Writer]. // // It knows how to write JSON tokens [token.T] or [token.VT], JSON values [values.Value] and [values.InternedKey], diff --git a/json/writers/default-writer/errors.go b/json/writers/default-writer/errors.go index 7bc347b..5db50b2 100644 --- a/json/writers/default-writer/errors.go +++ b/json/writers/default-writer/errors.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer // Error is a sentinel error type for all errors raised by this package. diff --git a/json/writers/default-writer/escape.go b/json/writers/default-writer/escape.go index dfe2bf0..c10329c 100644 --- a/json/writers/default-writer/escape.go +++ b/json/writers/default-writer/escape.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/escape_regression_test.go b/json/writers/default-writer/escape_regression_test.go index bd31393..a13b4a2 100644 --- a/json/writers/default-writer/escape_regression_test.go +++ b/json/writers/default-writer/escape_regression_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/indented.go b/json/writers/default-writer/indented.go index 69154e2..c408d85 100644 --- a/json/writers/default-writer/indented.go +++ b/json/writers/default-writer/indented.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/indented_options.go b/json/writers/default-writer/indented_options.go index f70eff7..42a22b8 100644 --- a/json/writers/default-writer/indented_options.go +++ b/json/writers/default-writer/indented_options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer var defaultIndent = []byte(" ") //nolint:gochecknoglobals diff --git a/json/writers/default-writer/internal/writegen/main.go b/json/writers/default-writer/internal/writegen/main.go index b58124d..40f264f 100644 --- a/json/writers/default-writer/internal/writegen/main.go +++ b/json/writers/default-writer/internal/writegen/main.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Command writegen lifts the generic commonWriter[T] methods onto a concrete writer type // (Buffered, Unbuffered) as verbatim copies with the receiver swapped. // diff --git a/json/writers/default-writer/latent_regression_test.go b/json/writers/default-writer/latent_regression_test.go index 88e40db..4ed7c28 100644 --- a/json/writers/default-writer/latent_regression_test.go +++ b/json/writers/default-writer/latent_regression_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/medium_regression_test.go b/json/writers/default-writer/medium_regression_test.go index f9db0d4..9042023 100644 --- a/json/writers/default-writer/medium_regression_test.go +++ b/json/writers/default-writer/medium_regression_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/pools.go b/json/writers/default-writer/pools.go index 90133b6..3ee47de 100644 --- a/json/writers/default-writer/pools.go +++ b/json/writers/default-writer/pools.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:gochecknoglobals // pools are globals package writer diff --git a/json/writers/default-writer/unbuffered.go b/json/writers/default-writer/unbuffered.go index 3a98ef1..8f7954c 100644 --- a/json/writers/default-writer/unbuffered.go +++ b/json/writers/default-writer/unbuffered.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + //nolint:dupl // writegen lifts commonWriter verbatim onto each concrete writer; the triplication is by design. package writer diff --git a/json/writers/default-writer/unbuffered_options.go b/json/writers/default-writer/unbuffered_options.go index 736cf06..a37d755 100644 --- a/json/writers/default-writer/unbuffered_options.go +++ b/json/writers/default-writer/unbuffered_options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer // UnbufferedOption configures the [Unbuffered] writer. Like the other writer options it threads the configuration diff --git a/json/writers/default-writer/utf8.go b/json/writers/default-writer/utf8.go index f9104e3..dc0aa8a 100644 --- a/json/writers/default-writer/utf8.go +++ b/json/writers/default-writer/utf8.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/utf8_test.go b/json/writers/default-writer/utf8_test.go index e76e7ba..fba2c10 100644 --- a/json/writers/default-writer/utf8_test.go +++ b/json/writers/default-writer/utf8_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/verbatim_roundtrip_test.go b/json/writers/default-writer/verbatim_roundtrip_test.go index 1e01846..5438076 100644 --- a/json/writers/default-writer/verbatim_roundtrip_test.go +++ b/json/writers/default-writer/verbatim_roundtrip_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/writer_norace_test.go b/json/writers/default-writer/writer_norace_test.go index 70bb6e4..414e67e 100644 --- a/json/writers/default-writer/writer_norace_test.go +++ b/json/writers/default-writer/writer_norace_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Allocation counting needs an un-instrumented build: the race detector and the pools // tracker (poolsdebug) both allocate per borrow, which would swamp the amortized counts // these tests assert. diff --git a/json/writers/default-writer/writer_test.go b/json/writers/default-writer/writer_test.go index 7392b05..8ffc4fc 100644 --- a/json/writers/default-writer/writer_test.go +++ b/json/writers/default-writer/writer_test.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/yaml.go b/json/writers/default-writer/yaml.go index a409880..57057fb 100644 --- a/json/writers/default-writer/yaml.go +++ b/json/writers/default-writer/yaml.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/default-writer/yaml_options.go b/json/writers/default-writer/yaml_options.go index 0bf7bec..002ca57 100644 --- a/json/writers/default-writer/yaml_options.go +++ b/json/writers/default-writer/yaml_options.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer var ( diff --git a/json/writers/default-writer/yaml_stack.go b/json/writers/default-writer/yaml_stack.go index 4780e47..33f7448 100644 --- a/json/writers/default-writer/yaml_stack.go +++ b/json/writers/default-writer/yaml_stack.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writer import ( diff --git a/json/writers/doc.go b/json/writers/doc.go index aec3a07..b52c7f6 100644 --- a/json/writers/doc.go +++ b/json/writers/doc.go @@ -1,2 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + // Package writers exposes interfaces to write JSON data. package writers diff --git a/json/writers/writers.go b/json/writers/writers.go index 9f16001..3a566a1 100644 --- a/json/writers/writers.go +++ b/json/writers/writers.go @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2015-2025 go-swagger maintainers +// SPDX-License-Identifier: Apache-2.0 + package writers import (