lib/tapioca/dsl/compilers/protobuf.rb in tapioca-0.11.6 vs lib/tapioca/dsl/compilers/protobuf.rb in tapioca-0.11.7

- old
+ new

@@ -76,11 +76,11 @@ prop :default, String end extend T::Sig - ConstantType = type_member { { fixed: Module } } + ConstantType = type_member { { fixed: T::Class[T.anything] } } FIELD_RE = /^[a-z_][a-zA-Z0-9_]*$/ sig { override.void } def decorate @@ -204,11 +204,11 @@ # > value is known, or a number if it is unknown. Since proto3 uses # > open enum semantics, any number may be assigned to an enum # > field, even if it was not defined in the enum. "T.any(Symbol, Integer)" when :message - descriptor.subtype.msgclass.name + descriptor.subtype.msgclass.name || "T.untyped" when :int32, :int64, :uint32, :uint64 "Integer" when :double, :float "Float" when :bool @@ -223,17 +223,27 @@ sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(T::Boolean) } def nilable_descriptor?(descriptor) descriptor.label == :optional && descriptor.type == :message end + sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(T::Boolean) } + def map_type?(descriptor) + # Defensively make sure that we are dealing with a repeated field + return false unless descriptor.label == :repeated + + # Try to create a new instance with the field that maps to the descriptor name + # being assinged a hash value. If this goes through, then it's a map type. + constant.new(**{ descriptor.name => {} }) + true + rescue ArgumentError + # This means the descriptor is not a map type + false + end + sig { params(descriptor: Google::Protobuf::FieldDescriptor).returns(Field) } def field_of(descriptor) if descriptor.label == :repeated - # Here we're going to check if the submsg_name is named according to - # how Google names map entries. - # https://github.com/protocolbuffers/protobuf/blob/f82e26/ruby/ext/google/protobuf_c/defs.c#L1963-L1966 - if descriptor.submsg_name.to_s.end_with?("_MapEntry_#{descriptor.name}") || - descriptor.submsg_name.to_s.end_with?("FieldsEntry") + if map_type?(descriptor) key = descriptor.subtype.lookup("key") value = descriptor.subtype.lookup("value") key_type = type_of(key) value_type = type_of(value)