-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rename DecoratedField to ProtoBoeuf::CodeGen::Field
- Loading branch information
1 parent
99ad480
commit 3b111ab
Showing
7 changed files
with
220 additions
and
203 deletions.
There are no files selected for viewing
This file contains 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 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 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,70 @@ | ||
# frozen_string_literal: true | ||
|
||
require "forwardable" | ||
|
||
# Adds some convenience methods to Google::Protobuf::FieldDescriptorProto | ||
module ProtoBoeuf | ||
class CodeGen | ||
class Field | ||
attr_reader :original_field, :message, :syntax | ||
|
||
extend Forwardable | ||
|
||
def_delegators :@original_field, | ||
:name, | ||
:label, | ||
:type_name, | ||
:type, | ||
:number, | ||
:options, | ||
:oneof_index, | ||
:has_oneof_index? | ||
|
||
def initialize(field:, message:, syntax:) | ||
@original_field = field | ||
@message = message | ||
@syntax = syntax | ||
end | ||
|
||
def optional? | ||
original_field.proto3_optional || (label == :LABEL_OPTIONAL && !proto3?) | ||
end | ||
|
||
def repeated? | ||
label == :LABEL_REPEATED | ||
end | ||
|
||
def map_field? | ||
return false unless repeated? | ||
|
||
map_name = type_name.split(".").last | ||
message.nested_type.any? { |type| type.name == map_name && type.options&.map_entry } | ||
end | ||
|
||
class MapType < Struct.new(:key, :value); end | ||
|
||
def map_type | ||
return false unless repeated? | ||
|
||
map_name = type_name.split(".").last | ||
message.nested_type.find { |type| type.name == map_name && type.options&.map_entry }.tap do |descriptor| | ||
raise ArgumentError, "Not a map field" if descriptor.nil? | ||
|
||
return MapType.new( | ||
key: self.class.new(field: descriptor.field[0], message:, syntax:), | ||
value: self.class.new(field: descriptor.field[1], message:, syntax:), | ||
) | ||
end | ||
end | ||
|
||
def proto3? | ||
"proto3" == syntax | ||
end | ||
|
||
# Return an instance variable name for use in generated code | ||
def iv_name | ||
"@#{name}" | ||
end | ||
end | ||
end | ||
end |
File renamed without changes.
This file was deleted.
Oops, something went wrong.
This file contains 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,143 @@ | ||
# frozen_string_literal: true | ||
|
||
require "helper" | ||
require "protoboeuf/codegen/field" | ||
|
||
module ProtoBoeuf | ||
class CodeGen | ||
class FieldTest < ProtoBoeuf::Test | ||
def test_delegates_common_methods | ||
fields = fields_for_proto_message(<<~PROTO) | ||
syntax = "proto3"; | ||
message MyMessage { | ||
optional int32 field1 = 1 [deprecated=true]; | ||
} | ||
PROTO | ||
|
||
field = fields["field1"] | ||
|
||
[:name, :label, :type_name, :type, :number, :options, :oneof_index, :has_oneof_index?].each do |method_name| | ||
assert_equal( | ||
field.send(method_name), | ||
field.original_field.send(method_name), | ||
"expected CodeGen::Field to delegate ##{method_name}", | ||
) | ||
end | ||
end | ||
|
||
def test_proto2_optional | ||
fields = fields_for_proto_message(<<~PROTO) | ||
message MyMessage { | ||
optional int32 field1 = 1; | ||
required int32 field2 = 2; | ||
} | ||
PROTO | ||
|
||
assert(fields["field1"].optional?, "field1 should be optional") | ||
refute(fields["field2"].optional?, "field2 should not be optional") | ||
end | ||
|
||
def test_proto3_optional | ||
fields = fields_for_proto_message(<<~PROTO) | ||
syntax = "proto3"; | ||
message MyMessage { | ||
optional int32 field1 = 1; | ||
int32 field2 = 2; | ||
} | ||
PROTO | ||
|
||
assert(fields["field1"].optional?, "field1 should be optional") | ||
refute(fields["field2"].optional?, "field2 should not be optional") | ||
end | ||
|
||
def test_repeated | ||
fields = fields_for_proto_message(<<~PROTO) | ||
syntax = "proto3"; | ||
message MyMessage { | ||
repeated int32 field1 = 1; | ||
int32 field2 = 2; | ||
} | ||
PROTO | ||
|
||
assert(fields["field1"].repeated?, "field1 should be repeated") | ||
refute(fields["field2"].repeated?, "field2 should not be repeated") | ||
end | ||
|
||
def test_map_field? | ||
fields = fields_for_proto_message(<<~PROTO) | ||
syntax = "proto3"; | ||
message MyMessage { | ||
map<string, string> field1 = 1; | ||
int32 field2 = 2; | ||
} | ||
PROTO | ||
|
||
assert(fields["field1"].map_field?, "field1 should be a map field") | ||
refute(fields["field2"].map_field?, "field2 should not be a map field") | ||
end | ||
|
||
def test_map_type | ||
fields = fields_for_proto_message(<<~PROTO) | ||
syntax = "proto3"; | ||
message MyMessage { | ||
map<string, int32> field1 = 1; | ||
int32 field2 = 2; | ||
} | ||
PROTO | ||
|
||
map_type = fields["field1"].map_type | ||
assert_kind_of(CodeGen::Field::MapType, map_type) | ||
|
||
assert_kind_of(CodeGen::Field, map_type.key) | ||
assert_equal(:TYPE_STRING, map_type.key.type) | ||
|
||
assert_kind_of(CodeGen::Field, map_type.value) | ||
assert_equal(:TYPE_INT32, map_type.value.type) | ||
|
||
refute(fields["field2"].map_field?, "field2 should not have a map_type") | ||
end | ||
|
||
def test_proto3? | ||
proto_2_fields = fields_for_proto_message(<<~PROTO) | ||
message MyMessage { | ||
map<string, int32> field1 = 1; | ||
} | ||
PROTO | ||
|
||
refute(proto_2_fields["field1"].proto3?, "CodeGen::Field#proto3? should return false for proto2") | ||
|
||
proto_3_fields = fields_for_proto_message(<<~PROTO) | ||
syntax = "proto3"; | ||
message MyMessage { | ||
map<string, int32> field1 = 1; | ||
} | ||
PROTO | ||
|
||
assert(proto_3_fields["field1"].proto3?, "CodeGen::Field#proto3? should return true for proto3") | ||
end | ||
|
||
private | ||
|
||
def fields_for_proto_message(proto_string) | ||
unit = parse_proto_string(proto_string) | ||
|
||
syntax = unit.file.first.syntax | ||
message = unit.file.first.message_type.first | ||
|
||
message.field.group_by(&:name).transform_values do |fields| | ||
CodeGen::Field.new( | ||
field: fields.first, | ||
message:, | ||
syntax:, | ||
) | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.