class Tapioca::Dsl::Compilers::Protobuf
def decorate
@override
def decorate root.create_path(constant) do |klass| if constant == Google::Protobuf::RepeatedField create_type_members(klass, "Elem") elsif constant == Google::Protobuf::Map create_type_members(klass, "Key", "Value") else descriptor = T.unsafe(constant).descriptor case descriptor when Google::Protobuf::EnumDescriptor descriptor.to_h.each do |sym, val| # For each enum value, create a namespaced constant on the root rather than an un-namespaced # constant within the class. This is because un-namespaced constants might conflict with reserved # Ruby words, such as "BEGIN." By namespacing them, we avoid this problem. # # Invalid syntax: # class Foo # BEGIN = 3 # end # # Valid syntax: # Foo::BEGIN = 3 root.create_constant("#{constant}::#{sym}", value: val.to_s) end klass.create_method( "lookup", parameters: [create_param("number", type: "Integer")], return_type: "T.nilable(Symbol)", class_method: true, ) klass.create_method( "resolve", parameters: [create_param("symbol", type: "Symbol")], return_type: "T.nilable(Integer)", class_method: true, ) klass.create_method( "descriptor", return_type: "Google::Protobuf::EnumDescriptor", class_method: true, ) when Google::Protobuf::Descriptor raise "#{klass} is not a RBI::Class" unless klass.is_a?(RBI::Class) klass.superclass_name = "Google::Protobuf::AbstractMessage" descriptor.each_oneof { |oneof| create_oneof_method(klass, oneof) } fields = descriptor.map { |desc| create_descriptor_method(klass, desc) } fields.sort_by!(&:name) parameters = fields.map do |field| create_kw_opt_param(field.name, type: field.init_type, default: field.default) end if fields.all? { |field| FIELD_RE.match?(field.name) } klass.create_method("initialize", parameters: parameters, return_type: "void") else # One of the fields has an incorrect name for a named parameter so creating the default initialize for # it would create a RBI with a syntax error. # The workaround is to create an initialize that takes a **kwargs instead. kwargs_parameter = create_kw_rest_param("fields", type: "T.untyped") klass.create_method("initialize", parameters: [kwargs_parameter], return_type: "void") end else add_error(<<~MSG.strip) Unexpected descriptor class `#{descriptor.class.name}` for `#{constant}` MSG end end end end