Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support unknown field retention trait #1409

Draft
wants to merge 19 commits into
base: series/0.18
Choose a base branch
from

Conversation

dhpiggott
Copy link
Contributor

PR Checklist (not all items are relevant to all PRs)

  • Added unit-tests (for runtime code)
  • Added bootstrapped code + smoke tests (when the rendering logic is modified)
  • Added build-plugins integration tests (when reflection loading is required at codegen-time)
  • Added alloy compliance tests (when simpleRestJson protocol behaviour is expanded/updated)
  • Updated dynamic module to match generated-code behaviour
  • Added documentation
  • Updated changelog

@dhpiggott dhpiggott force-pushed the support-unknown-field-retention-trait branch from 0e907a9 to 485a43a Compare March 6, 2024 11:33
@dhpiggott dhpiggott force-pushed the support-unknown-field-retention-trait branch from a7de7a5 to 6728eb9 Compare March 7, 2024 17:14
@dhpiggott dhpiggott force-pushed the support-unknown-field-retention-trait branch 2 times, most recently from 8f48bc4 to 44b76f3 Compare March 11, 2024 11:18
@dhpiggott dhpiggott force-pushed the support-unknown-field-retention-trait branch from 44b76f3 to 0430424 Compare March 11, 2024 11:55
field.hints.get(JsonName) match {
case None => field.label
case Some(x) => x.value
}

trait UnknownFieldsDecoder[A] { self =>
Copy link
Contributor

Choose a reason for hiding this comment

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

rather than creating a bespoke trait (which implies having to create a schema visitor for it), I'd just delegate to Document.Decoder, turning the Hashmap into a Document.DObject

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 59e0d22.

@@ -1299,35 +1336,81 @@ private[smithy4s] class SchemaVisitorJCodec(
)
}

trait UnknownFieldsEncoder[A] {
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than creating a bespoke trait, I'd delegate to the Document.Encoder to produce a document representation. I'd then match the document to check if it's a DObject and would call upon a function to inline its fields, that I'd factor out of the encoder implementation for documents.

Copy link
Contributor Author

@dhpiggott dhpiggott Mar 11, 2024

Choose a reason for hiding this comment

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

Done in 59e0d22. Wasn't sure what you meant by this:

I'd factor out of the encoder implementation for documents

I think you're referring to this:

          case Document.DObject(values) =>
            values.foreach { case (key, value) =>
              out.writeKey(key)
              documentJCodec.encodeValue(value, out)
            }

but it seems too small to be worth factoring out to me - can you confirm?

@@ -181,6 +182,42 @@ class DocumentEncoderSchemaVisitor(
from(e => DString(total(e).stringValue))
}

trait UnknownFieldsEncoder[A] {
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for a bespoke trait : just compile the DocumentEncoder for A, and inline its fields if the result is a DObject

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 59e0d22.

@@ -451,16 +506,16 @@ class DocumentDecoderSchemaVisitor(
alternatives: Vector[Alt[U, _]],
dispatch: Alt.Dispatcher[U]
): DocumentDecoder[U] = {
def jsonLabel[A](alt: Alt[U, A]): String =
def jsonLabelOrLabel[A](alt: Alt[U, A]): String =
Copy link
Contributor

Choose a reason for hiding this comment

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

... I mean ... why ?

Comment on lines 371 to 379
val unknownFieldsDecoder = UnknownFieldsDecoder(field.schema)
(
pp: List[PayloadPath.Segment],
buffer: Any => Unit,
fields: Map[String, Document]
) => {
val unknownFields = fields -- knownFieldLabels
buffer(unknownFieldsDecoder(pp, unknownFields))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like this bit to be extracted in a private method.

@@ -307,66 +308,120 @@ class DocumentDecoderSchemaVisitor(
}
}

trait UnknownFieldsDecoder[A] { self =>
Copy link
Contributor

Choose a reason for hiding this comment

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

This one could be removed too : just compile the document decoder for A and pass it a DObject containing the unknownFields

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in 59e0d22.

@dhpiggott dhpiggott force-pushed the support-unknown-field-retention-trait branch from 3942bb2 to 59e0d22 Compare March 11, 2024 15:32
fields.foreach { case (field, jsonLabel, default) =>
values += {
if (isForUnknownFieldRetention(field)) {
// TODO: Lift out.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently working on a refactor to avoid re-creating this decoder on each call. Will move on to the remaining feedback actions once I've done this.

@Baccata
Copy link
Contributor

Baccata commented Mar 11, 2024

Please refrain from force-pushing once you've opened a PR. It prevents the review of the latest changes, and also makes it extremely annoying if someone was branching out from your work to help out or not. We tend to squash PRs anyway at the end.

@dhpiggott
Copy link
Contributor Author

Please refrain from force-pushing once you've opened a PR. It prevents the review of the latest changes, and also makes it extremely annoying if someone was branching out from your work to help out or not. We tend to squash PRs anyway at the end.

I thought you were OK with it so long as the change is in draft state, not PR. I wouldn't have done it it with PRs. I'll try to remember not to with drafts now, apologies if I forget occasionally while I adjust.

@Baccata
Copy link
Contributor

Baccata commented Mar 12, 2024

I thought you were OK with it so long as the change is in draft state, not PR

It's not about whether it's a draft or not. I switch to not being OK with it at the point when you ask me to have a look at it. Generally speaking I'll avoid looking at drafts unless asked to, but once you ask, you're essentially opening the Schrödinger box.

@dhpiggott
Copy link
Contributor Author

I switch to not being OK with it at the point when you ask me to have a look at it.

Ok yeah I get that.

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.

2 participants