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 editions, required fields, and groups #45

Merged
merged 2 commits into from
Aug 28, 2024

Conversation

jhump
Copy link
Member

@jhump jhump commented Aug 28, 2024

The issues I discovered with editions support were actually just the handling of required fields and groups (which are also proto2 features, but were absent in proto3). Group syntax is still disallowed in editions, but group encoding can be enabled via a feature.

@jhump jhump force-pushed the jh/properly-support-group-encoding branch from 057a786 to fc1ad83 Compare August 28, 2024 13:21
@@ -243,32 +247,32 @@ func (u *unmarshaler) unmarshalScalar(
node *yaml.Node,
field protoreflect.FieldDescriptor,
forKey bool,
) protoreflect.Value {
) (protoreflect.Value, bool) {
Copy link
Member Author

Choose a reason for hiding this comment

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

The caller previously had to check value.IsValid() before using the returned value. None of the callers actually did, so they all had potential panic bugs (which I encountered when trying to use a group field).

To make it more explicit and more easily require that the caller check the value, it now also returns a bool that is false when the value is invalid.

@@ -550,10 +554,12 @@ func (u *unmarshaler) unmarshalField(node *yaml.Node, field protoreflect.FieldDe
u.unmarshalList(node, field, message.ProtoReflect().Mutable(field).List())
case field.IsMap():
u.unmarshalMap(node, field, message.ProtoReflect().Mutable(field).Map())
case field.Kind() == protoreflect.MessageKind:
case field.Message() != nil:
Copy link
Member Author

Choose a reason for hiding this comment

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

shorthand way of checking if kind is either message or group

Comment on lines +590 to +592
if !u.checkKind(node, yaml.MappingNode) {
return
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry for the noisy diff here. If you change diff settings in GitHub UI to ignore whitespace diff, it will look better. To be more idiomatic Go, I changed this to early return so I could un-indent the main logic.

Comment on lines +58 to +60
// If AllowPartial is set, input for messages that will result in missing
// required fields will not return an error.
AllowPartial bool
Copy link
Member Author

Choose a reason for hiding this comment

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

When I added an test editions file, and used features to toggle use of groups and required fields, I discovered that required fields weren't correctly enforced. This comment and field name come directly from corresponding fields in proto.UnmarshalOptions and protojson.UnmarshalOptions. So, by default, this will complain if the message has required fields that the YAML contents failed to set.

@jhump jhump requested a review from Alfus August 28, 2024 13:36
@jhump jhump marked this pull request as ready for review August 28, 2024 13:36
@jhump jhump force-pushed the jh/properly-support-group-encoding branch from 4a12b2f to 60d4769 Compare August 28, 2024 13:37
@jhump jhump force-pushed the jh/properly-support-group-encoding branch from 60d4769 to fb9769e Compare August 28, 2024 14:47
@@ -79,11 +79,11 @@ $(BIN):
@mkdir -p $(BIN)

$(BIN)/buf: $(BIN) Makefile
go install github.com/bufbuild/buf/cmd/buf@latest
go install github.com/bufbuild/buf/cmd/buf@v1.36.0
Copy link
Member Author

Choose a reason for hiding this comment

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

I pinned all these so that CI could pass. In a separate PR, we can update this repo to require at least go 1.21 and then also update all of the new lint violations (latest golangci-lint has new checks). Then we can update these versions to the latest. (Though I'd still recommend keeping them pinned for more hermetic/reproducible CI results.)

@jhump
Copy link
Member Author

jhump commented Aug 28, 2024

@Alfus, I was about to merge this when it occurred to me that proto.CheckInitialized is a recursive check. So we don't need to call it for every message and nested message that was unmarshaled from a YAML document as that will perform a lot of redundant work (repeating validation of a message for each of its containers/ancestors). We only need to call it once at the very end. So I've moved the invocation. PTAL.

@jhump jhump merged commit cb54552 into main Aug 28, 2024
4 checks passed
@jhump jhump deleted the jh/properly-support-group-encoding branch August 28, 2024 16:53
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