-
Notifications
You must be signed in to change notification settings - Fork 13
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
Add timestamp.valid evaluator #53
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good - just had a few minor comments. I know this is waiting for upstream PRs to be unblocked.
* allowing access to the message fields. | ||
*/ | ||
class TimestampEvaluator implements Evaluator { | ||
private final long maxTimestamp = +253402300799L; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private final long maxTimestamp = +253402300799L; | |
private static final long MAX_TIMESTAMP = ZonedDateTime.parse("9999-12-31T23:59:59Z").toEpochSecond(); |
We should make these static constants but I also think it improves readability if we use the timestamp strings instead of the epoch second here.
ValueEvaluator valueEvaluatorEval) { | ||
if (fieldDescriptor.getType() != FieldDescriptor.Type.MESSAGE | ||
|| !fieldDescriptor.getMessageType().getFullName().equals("google.protobuf.Timestamp")) { | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about returning early if !fieldConstraints.getTimestamp.getValid()
? I don't see any sense in creating the evaluator in that case since there is only one rule and otherwise it is a no-op.
Descriptors.FieldDescriptor secondsDescriptor, | ||
Descriptors.FieldDescriptor nanosDescriptor, | ||
boolean valid) { | ||
this.secondsDescriptor = secondsDescriptor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.secondsDescriptor = secondsDescriptor; | |
this.secondsDescriptor = Objects.requireNonNull(secondsDescriptor, "secondsDescriptor"); |
Descriptors.FieldDescriptor nanosDescriptor, | ||
boolean valid) { | ||
this.secondsDescriptor = secondsDescriptor; | ||
this.nanosDescriptor = nanosDescriptor; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.nanosDescriptor = nanosDescriptor; | |
this.nanosDescriptor = Objects.requireNonNull(nanosDescriptor, "nanosDescriptor"); |
Violation.newBuilder() | ||
.setConstraintId("timestamp.valid") | ||
.setMessage(errorMessage) | ||
.build(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should set the field path on the violation as well.
.setMessage(errorMessage) | ||
.build(); | ||
violationList.add(violation); | ||
if (failFast) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't looping over anything here, so I think we can just remove this if statement.
} else if (seconds > maxTimestamp) { | ||
errorMessage = "timestamp after 9999-12-31"; | ||
} else if (nanos < 0 || nanos >= 1e9) { | ||
errorMessage = "timestamp has out-of-range nanos"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be useful if the error message included details of all parts of the timestamp which are invalid. So if both the seconds and nanos values are invalid, we should return that in the error message.
Do we also want to include in the error message the expected range of the timestamp nanos?
See bufbuild/protovalidate#101 for details.
This depends on bufbuild/protovalidate#114 being merged. However, locally I was able to build & run conformance tests using some edits to the
build.gradle.kts
andMakefile
. (After the merge on the main repo, I would best re-generate the generated stubs.)