-
Notifications
You must be signed in to change notification settings - Fork 153
Create Protobuf.Text, create Protobuf.field_presence/2
#398
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
Open
v0idpwn
wants to merge
8
commits into
main
Choose a base branch
from
feat/text-encoding
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
9644bd9
Add Protobuf.Text
v0idpwn 50642e9
Create Protobuf.Presence module (#403)
v0idpwn 1cb4cb0
Bump google protos version
v0idpwn 248a8de
Move the `field_presence` function to the `Protobuf` module
v0idpwn 7560e91
Add @doc since to Protobuf.Text
v0idpwn 2e91c8a
Doc improvement in Protobuf.field_presence/2
v0idpwn b525845
Consistent map handling
v0idpwn f76e03a
format
v0idpwn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| # We do a best effort for printing unknown values but don't try to expand them | ||
| Recommended.Proto3.ProtobufInput.GroupUnknownFields_Print.TextFormatOutput | ||
| Recommended.Proto3.ProtobufInput.MessageUnknownFields_Print.TextFormatOutput | ||
| Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Print.TextFormatOutput |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| defmodule Protobuf.Presence do | ||
| @moduledoc false | ||
|
|
||
| alias Protobuf.FieldProps | ||
|
|
||
| @spec field_presence(message :: struct(), field :: atom()) :: :present | :not_present | :maybe | ||
| def field_presence(%mod{} = message, field) do | ||
| message_props = mod.__message_props__() | ||
| transformed_message = transform_module(message, mod) | ||
| fnum = Map.fetch!(message_props.field_tags, field) | ||
| field_prop = Map.fetch!(message_props.field_props, fnum) | ||
| value = get_oneof_value(transformed_message, message_props, field, field_prop) | ||
|
|
||
| transformed_value = | ||
| case field_prop do | ||
| %{embedded: true, type: mod} -> transform_module(value, mod) | ||
| _ -> value | ||
| end | ||
|
|
||
| get_field_presence(message_props.syntax, transformed_value, field_prop) | ||
| end | ||
|
|
||
| defp get_oneof_value(message, message_props, field, field_prop) do | ||
| case field_prop.oneof do | ||
| nil -> | ||
| Map.fetch!(message, field) | ||
|
|
||
| oneof_num -> | ||
| {oneof_field, _} = Enum.find(message_props.oneof, fn {_name, tag} -> tag == oneof_num end) | ||
|
|
||
| case Map.fetch!(message, oneof_field) do | ||
| {^field, value} -> value | ||
| _ -> nil | ||
| end | ||
| end | ||
| end | ||
|
|
||
| defp transform_module(message, module) do | ||
| if transform_module = module.transform_module() do | ||
| transform_module.encode(message, module) | ||
| else | ||
| message | ||
| end | ||
| end | ||
|
|
||
| # We probably want to make this public eventually, but it makes sense to hold | ||
| # it until we add editions support, since we definitely don't want to add | ||
| # `syntax` in a public API | ||
| @doc false | ||
| @spec get_field_presence(:proto2 | :proto3, term(), FieldProps.t()) :: :present | :not_present | :maybe | ||
| def get_field_presence(syntax, value, field_prop) | ||
|
|
||
| # Repeated and maps are always implicit. | ||
| def get_field_presence(_syntax, [], _prop) do | ||
| :maybe | ||
| end | ||
|
|
||
| def get_field_presence(_syntax, val, _prop) when is_map(val) do | ||
| if map_size(val) == 0 do | ||
| :maybe | ||
| else | ||
| :present | ||
| end | ||
| end | ||
|
|
||
| # For proto2 singular cardinality fields: | ||
| # | ||
| # - Non-one_of fields with default values have implicit presence | ||
| # - Others have explicit presence | ||
| def get_field_presence(:proto2, nil, _prop) do | ||
| :not_present | ||
| end | ||
|
|
||
| def get_field_presence(:proto2, value, %FieldProps{default: value, oneof: nil}) do | ||
| :maybe | ||
| end | ||
|
|
||
| def get_field_presence(:proto2, _value, _props) do | ||
| :present | ||
| end | ||
|
|
||
| # For proto3 singular cardinality fields: | ||
| # | ||
| # - Optional and Oneof fields have explicit presence tracking | ||
| # - Other fields have implicit presence tracking | ||
| def get_field_presence(:proto3, nil, %FieldProps{proto3_optional?: true}) do | ||
| :not_present | ||
| end | ||
|
|
||
| def get_field_presence(:proto3, _, %FieldProps{proto3_optional?: true}) do | ||
| :present | ||
| end | ||
|
|
||
| def get_field_presence(_syntax, value, %FieldProps{oneof: oneof}) when not is_nil(oneof) do | ||
| if is_nil(value) do | ||
| :not_present | ||
| else | ||
| :present | ||
| end | ||
| end | ||
|
|
||
| # Messages have explicit presence tracking in proto3 | ||
| def get_field_presence(:proto3, nil, _prop) do | ||
| :not_present | ||
| end | ||
|
|
||
| # Defaults for different field types: implicit presence means they are maybe set | ||
| def get_field_presence(:proto3, 0, _prop) do | ||
| :maybe | ||
| end | ||
|
|
||
| def get_field_presence(:proto3, +0.0, _prop) do | ||
| :maybe | ||
| end | ||
|
|
||
| def get_field_presence(:proto3, "", _prop) do | ||
| :maybe | ||
| end | ||
|
|
||
| def get_field_presence(:proto3, false, _prop) do | ||
| :maybe | ||
| end | ||
|
|
||
| def get_field_presence(_syntax, value, %FieldProps{type: {:enum, enum_mod}}) do | ||
| if enum_default?(enum_mod, value) do | ||
| :maybe | ||
| else | ||
| :present | ||
| end | ||
| end | ||
|
|
||
| # Finally, everything else. | ||
| def get_field_presence(_syntax, _val, _prop) do | ||
| :present | ||
| end | ||
|
|
||
| defp enum_default?(enum_mod, val) when is_atom(val), do: enum_mod.value(val) == 0 | ||
| defp enum_default?(_enum_mod, val) when is_integer(val), do: val == 0 | ||
| defp enum_default?(_enum_mod, list) when is_list(list), do: false | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.