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

Add structured field and rule paths to Violation #265

Merged
merged 15 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 62 additions & 1 deletion proto/protovalidate/buf/validate/validate.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4770,8 +4770,19 @@ message Violations {
// }
// ```
message Violation {
// `field_path` is a machine-readable identifier that points to the specific field that failed the validation.
// `field` is a machine-readable path to the field that failed validation.
// This could be a nested field, in which case the path will include all the parent fields leading to the actual field that caused the violation.
optional FieldPath field = 5;

// `rule` is a machine-readable path that points to the specific constraint rule that failed validation.
// This will be a nested field starting from the FieldConstraints of the field that failed validation.
// This field is not present when there is no corresponding rule field, e.g. for custom constraints.
jchadwick-buf marked this conversation as resolved.
Show resolved Hide resolved
optional FieldPath rule = 6;
jchadwick-buf marked this conversation as resolved.
Show resolved Hide resolved

// `field_path` is a human-readable identifier that points to the specific field that failed the validation.
// This could be a nested field, in which case the path will include all the parent fields leading to the actual field that caused the violation.
//
// Deprecated: use the `field` instead.
jchadwick-buf marked this conversation as resolved.
Show resolved Hide resolved
optional string field_path = 1;

// `constraint_id` is the unique identifier of the `Constraint` that was not fulfilled.
Expand All @@ -4785,3 +4796,53 @@ message Violation {
// `for_key` indicates whether the violation was caused by a map key, rather than a value.
optional bool for_key = 4;
}

// `FieldPath` provides a path to a nested protobuf field.
//
// This message provides enough information to render a dotted field path even without protobuf descriptors.
// It also provides enough information to resolve a nested field through unknown wire data.
message FieldPath {
// `elements` contains each element of the path, starting from the root and recursing downward.
repeated FieldPathElement elements = 1;
}

// `FieldPathElement` provides enough information to nest through a single protobuf field.
//
// If the selected field is a map or repeated field, the `subscript` value selects a specific element from it.
// A path that refers to a map or repeated field and not an element under it will not have a `subscript` value.
jchadwick-buf marked this conversation as resolved.
Show resolved Hide resolved
// The `field_type` field allows unambiguous resolution of a field even if descriptors are not available.
message FieldPathElement {
// `field_number` is the field number this path element refers to.
optional int32 field_number = 1;

// `field_name` contains the field name this path element refers to.
// This can be used to display a human-readable path even if the field number is unknown.
optional string field_name = 2;

// `field_type` specifies the type of this field. When using reflection, this value is not needed.
//
// This value is provided to make it possible to traverse unknown fields through wire data.
// When traversing wire data, be mindful of both packed and delimited encoding schemes.
jchadwick-buf marked this conversation as resolved.
Show resolved Hide resolved
optional google.protobuf.FieldDescriptorProto.Type field_type = 3;

// `subscript` contains a repeated index or map key, if this path element nests into a repeated or map field.
Copy link
Collaborator

Choose a reason for hiding this comment

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

repeated?

Copy link
Member Author

@jchadwick-buf jchadwick-buf Nov 27, 2024

Choose a reason for hiding this comment

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

FieldPathElement is meant to be logically equivalent to a path segment, e.g. repeated[1] or map["key"]. The subscript contains either a repeated field index or a map key. If this wording is confusing, I'm happy to update the documentation.

WDYT about this? (would "list index" be better?)

Suggested change
// `subscript` contains a repeated index or map key, if this path element nests into a repeated or map field.
// `subscript` contains a repeated field index or map key, if this path element nests into a repeated or map field.

oneof subscript {
// `index` specifies a 0-based index into a repeated field.
uint64 index = 4;

// `bool_key` specifies a map key of type bool.
bool bool_key = 5;

// `int_key` specifies a map key of type int32, int64, sfixed32 or sfixed64.
int64 int_key = 6;

// `sint_key` specifies a map key of type sint32 or sint64.
sint64 sint_key = 7;

// `uint_key` specifies a map key of type uint32, uint64, fixed32 or fixed64.
uint64 uint_key = 8;

// `string_key` specifies a map key of type string.
string string_key = 9;
}
}
Loading