Skip to content

Schema Serde Document type & Codec Settings - #3947

Open
sbaluja wants to merge 13 commits into
mainfrom
document-type
Open

sbaluja wants to merge 13 commits into
mainfrom
document-type

Conversation

@sbaluja

@sbaluja sbaluja commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Issue #, if available:

Description of changes:

  • Added smithy::schema::Document (open-content value). JSON builds and serializes it, CBOR/XML/Query reject or ignore it per protocol.
  • JSON document coercion: base64 string to blob, string/number to timestamp, plus numeric overflow/UB guards (ReadLong clamps, AsFloat/AsLong range-guarded).
  • Added CodecSettings: per-protocol default @timestampFormat. Format is required (no default construction, explicit ctor).
  • Threaded CodecSettings through the JSON, XML, and Query serializers and deserializers. Removed the scattered hardcoded date-time/epoch literals so there's one source per protocol.
  • Gated document string/number to timestamp coercion by the configured format (SEP): string only under date-time/http-date, number only under epoch.
  • CBOR ignores @timestampFormat (epoch only), locked in with a test.
  • JSON floats serialize at float precision, doubles keep a .0 marker so the type round-trips.

Check all that applies:

  • Did a review by yourself.
  • Added proper tests to cover this PR. (If tests are not applicable, explain.)
  • Checked if this PR is a breaking (APIs have been changed) change.
  • Checked if this PR will not introduce cross-platform inconsistent behavior.
  • Checked if this PR would require a ReadMe/Wiki update.

Check which platforms you have built SDK on to verify the correctness of this PR.

  • Linux
  • Windows
  • Android
  • MacOS
  • IOS
  • Other Platforms

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Adds an open-content document value type to the schema-serde runtime and
wires it through the JSON/CBOR/XML/Query serializers and deserializers.

- smithy::schema::Document: a copyable value handle over a polymorphic,
  AWS_CORE_LOCAL DocumentImpl. The agnostic base serves serialize-built (and
  future CBOR) documents; JsonDocumentImpl adds JSON string->blob and
  string/number->timestamp coercion, parameterized by the protocol-default
  timestamp format threaded from JsonCodec.
- Serialization: JSON and CBOR emit documents; REST-XML, AWS/Query, and
  EC2/Query reject with a SerializationException.
- Deserialization: JSON builds the document tree; CBOR and XML reject (CBOR
  ReadDocument consumes the value so sibling members stay aligned).
- JSON numeric safety: ReadLong's double fallback rejects non-finite /
  out-of-range doubles instead of casting them (undefined behavior), while a
  plain-integer overflow still clamps to INT64_MAX/MIN; open-content document
  integer overflow preserves magnitude as a double; Document::AsFloat rejects
  finite doubles beyond float range (out-of-range double->float is undefined
  behavior).
- JSON floats and doubles serialize with shortest-round-trip precision (float
  precision for floats, not the double expansion of their imprecision) and a
  decimal marker, so a document float or double round-trips without losing
  precision or type.

Deferred (documented): map insertion order, int/bigInteger reporting,
unsigned 64-bit, a nesting depth cap of 64, and the tagged-union node layout.
Comment thread src/aws-cpp-sdk-core/include/smithy/client/schema/Codec.h Outdated
Comment thread src/aws-cpp-sdk-core/source/smithy/client/schema/JsonShapeDeserializer.cpp Outdated
Comment thread src/aws-cpp-sdk-core/source/smithy/client/schema/Document.cpp Outdated
Comment thread src/aws-cpp-sdk-core/include/smithy/client/schema/Codec.h Outdated
Comment thread src/aws-cpp-sdk-core/source/smithy/client/schema/Document.cpp Outdated
Comment thread src/aws-cpp-sdk-core/source/smithy/client/schema/JsonShapeDeserializer.cpp Outdated
Comment thread src/aws-cpp-sdk-core/include/smithy/client/schema/Document.h Outdated
Document was shaped like a PIMPL but was not one: DocumentImpl was a public
header, AsList/AsMap handed back pointers into its storage, and
detail::MakeDocument let any caller build a Document over any impl. Coercion
behavior was therefore smuggled through a hidden interface -- two documents
could compare equal yet disagree on AsBlob().

Document is now a public abstract interface. AbstractDocument (internal, not
installed) holds the tagged storage and the protocol-independent behavior,
leaving AsBlob/AsTimestamp pure so a node cannot exist without a coercion
rule. The concrete leaves live in Document.cpp's anonymous namespace:
PlainDocument applies no reinterpretation and backs the From* factories,
while JsonDocument base64-decodes strings and gates timestamp coercion on
the configured format. The JSON deserializer builds its nodes through
NewJsonDocument, so neither leaf is nameable outside that translation unit.

ReadDocument now returns shared_ptr<const Document> and document collections
carry shared_ptr<const Document>. Coercion, timestamp-format gating, CBOR
trait-ignore adherence, and the numeric overflow guards are unchanged.
@sbaluja
sbaluja marked this pull request as ready for review October 6, 2026 15:10

@sbiscigl sbiscigl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix and or not, and ship

public:
explicit CodecSettings(TimestampFormatTrait::Format defaultTimestampFormat) : m_defaultTimestampFormat(defaultTimestampFormat) {}

// Payload defaults per the SEP's codec-settings-by-protocol table.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per the SEP's

nit: language leaking in comments

const Aws::String token = ReadNumberToken();
char* end = nullptr;
if (token.find_first_of(".eE") != Aws::String::npos) {
const double d = std::strtod(token.c_str(), &end);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use StringUtils::ConvertToDouble instead to hide the std implementation and we already have that

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants