Skip to content

Commit

Permalink
Fix >500 conformance tests
Browse files Browse the repository at this point in the history
- Makes proto2 also support json_name. This alone fixes >200 tests
- Ensures JSON encoder decides correctly when to emit or not emit fields (at the
very least, more correctly than before :))
  • Loading branch information
v0idpwn committed Dec 29, 2024
1 parent b1cfa5f commit 0d414ab
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 22 deletions.
33 changes: 14 additions & 19 deletions lib/protobuf/json/encode.ex
Original file line number Diff line number Diff line change
Expand Up @@ -159,22 +159,14 @@ defmodule Protobuf.JSON.Encode do
:maps.from_list(regular ++ oneofs)
end

defp encode_regular_fields(struct, %{field_props: field_props}, opts) do
defp encode_regular_fields(struct, %{field_props: field_props, syntax: syntax}, opts) do
for {_field_num, %{name_atom: name, oneof: nil} = prop} <- field_props,
%{^name => value} = struct,
emit?(prop, value) || opts[:emit_unpopulated] do
emit?(syntax, prop, value) || opts[:emit_unpopulated] do
encode_field(prop, value, opts)
end
end

defp emit?(_prop, nil) do
false
end

defp emit?(prop, value) do
if default?(prop, value), do: prop.proto3_optional?, else: true
end

defp encode_oneof_fields(struct, message_props, opts) do
%{field_tags: field_tags, field_props: field_props, oneof: oneofs} = message_props

Expand Down Expand Up @@ -309,15 +301,18 @@ defmodule Protobuf.JSON.Encode do
defp maybe_repeat(%{repeated?: false}, val, fun), do: fun.(val)
defp maybe_repeat(%{repeated?: true}, val, fun), do: Enum.map(val, fun)

defp default?(_prop, +0.0), do: true
defp default?(_prop, nil), do: true
defp default?(_prop, 0), do: true
defp default?(_prop, false), do: true
defp default?(_prop, []), do: true
defp default?(_prop, ""), do: true
defp default?(_prop, %{} = map) when map_size(map) == 0, do: true
defp default?(%{type: {:enum, enum}}, key) when is_atom(key), do: enum.value(key) == 0
defp default?(_prop, _value), do: false
defp emit?(:proto2, %{default: value}, value), do: false
defp emit?(:proto2, %{optional?: true}, val), do: not is_nil(val)
defp emit?(:proto3, %{proto3_optional?: true}, val), do: not is_nil(val)
defp emit?(_syntax, _prop, +0.0), do: false
defp emit?(_syntax, _prop, nil), do: false
defp emit?(_syntax, _prop, 0), do: false
defp emit?(_syntax, _prop, false), do: false
defp emit?(_syntax, _prop, []), do: false
defp emit?(_syntax, _prop, ""), do: false
defp emit?(_syntax, _prop, %{} = map) when map_size(map) == 0, do: false
defp emit?(_syntax, %{type: {:enum, enum}}, key) when is_atom(key), do: enum.value(key) != 0
defp emit?(_syntax, _prop, _value), do: true

defp transform_module(message, module) do
if transform_module = module.transform_module() do
Expand Down
6 changes: 3 additions & 3 deletions lib/protobuf/protoc/generator/message.ex
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,10 @@ defmodule Protobuf.Protoc.Generator.Message do
end

# Omit `json_name` from the options list when it matches the original field
# name to keep the list small. Only Proto3 has JSON support for now.
defp add_json_name_to_opts(opts, :proto3, %{name: name, json_name: name}), do: opts
# name to keep the list small.
defp add_json_name_to_opts(opts, _, %{name: name, json_name: name}), do: opts

defp add_json_name_to_opts(opts, :proto3, %{json_name: json_name}),
defp add_json_name_to_opts(opts, _, %{json_name: json_name}),
do: Keyword.put(opts, :json_name, json_name)

defp add_json_name_to_opts(opts, _syntax, _props), do: opts
Expand Down

0 comments on commit 0d414ab

Please sign in to comment.