Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
43 changes: 39 additions & 4 deletions lib/proto_plugin/field_descriptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,56 @@ def value
#
# @return [Boolean]
def message?
type == :TYPE_MESSAGE && !map?
type == :message && !map?
end

# Returns true if the field is an enum type.
#
# @return [Boolean]
def enum?
type == :TYPE_ENUM
type == :enum
end

# Returns true if the field is a group type.
#
# @return [Boolean]
def group?
type == :TYPE_GROUP
type == :group
end

# The field's type as a plain symbol.
#
# Normalizes the underlying `type` enum by removing its `TYPE_` prefix and
# downcasing, e.g. `:TYPE_INT32` becomes `:int32` and `:TYPE_MESSAGE`
# becomes `:message`. For `:message` and `:enum` fields, use
# {#type_descriptor} (or {#key}/{#value} for maps) to resolve the referenced
# type.
#
# @example
# field.type #=> :int32
# field.type #=> :message
#
# @return [Symbol]
def type
descriptor.type.to_s.delete_prefix("TYPE_").downcase.to_sym
end

# The JSON name of the field, as computed by `protoc` (the lowerCamelCase
# form unless overridden with the `json_name` option).
#
# @return [String]
def json_name
descriptor.json_name
end

# The explicit default value declared for the field (proto2 only), as a
# string. Proto3 fields do not carry defaults.
#
# @return [String] the declared default
# @return [nil] if no default was declared
def default_value
value = descriptor.default_value
value unless value.nil? || value.empty?
end

# Returns true if the field is a scalar type (i.e. not a message, enum,
Expand Down Expand Up @@ -183,7 +218,7 @@ def repeated_label?
def map_entry
return @map_entry if defined?(@map_entry)

@map_entry = if repeated_label? && type == :TYPE_MESSAGE
@map_entry = if repeated_label? && type == :message
name = type_name.split(".").last
proto = message.descriptor.nested_type.find do |n|
n.name == name && n.options&.map_entry
Expand Down
30 changes: 30 additions & 0 deletions test/proto_plugin/field_descriptor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,36 @@ def test_synthetic_map_entries_excluded_from_messages
assert_empty(digest.messages)
end

def test_type_normalizes_the_enum
assert_equal(:uint64, @fields["id"].type)
assert_equal(:string, @fields["title"].type)
assert_equal(:message, @fields["author"].type)
assert_equal(:message, @fields["comments"].type) # repeated message
end

def test_json_name
assert_equal("publishedAt", @fields["published_at"].json_name)
assert_equal("title", @fields["title"].json_name)
end

def test_default_value
field = FieldDescriptor.new(
Google::Protobuf::FieldDescriptorProto.new(
name: "count",
type: :TYPE_INT32,
default_value: "42",
),
@article,
@context,
)

assert_equal("42", field.default_value)
end

def test_default_value_nil_when_absent
assert_nil(@fields["title"].default_value)
end

def test_oneof_membership
event = @context.type_by_proto_name(".proto_plugin.fixtures.CommentEvent")
fields = event.fields.each_with_object({}) do |field, hash|
Expand Down
Loading