From 9dd400efc80074c6be6f418f409cd04fd1c96b2f Mon Sep 17 00:00:00 2001 From: dysonreturns <173946744+dysonreturns@users.noreply.github.com> Date: Tue, 4 Feb 2025 12:38:51 -0800 Subject: [PATCH] Fixes optional Enum generation --- lib/protoboeuf/codegen.rb | 18 ++- lib/protoboeuf/google/protobuf/descriptor.rb | 146 ++++++++++++++++--- 2 files changed, 135 insertions(+), 29 deletions(-) diff --git a/lib/protoboeuf/codegen.rb b/lib/protoboeuf/codegen.rb index 705707f..85e5f6b 100644 --- a/lib/protoboeuf/codegen.rb +++ b/lib/protoboeuf/codegen.rb @@ -113,7 +113,6 @@ def initialize(message, toplevel_enums, generate_types:, requires:, syntax:, opt if optional_field?(field) if field.type == :TYPE_ENUM @enum_fields << field - @optional_fields << field end @optional_fields << field @optional_field_bit_lut[field.number] = optional_field_count @@ -691,10 +690,11 @@ def required_readers end def optional_readers - return "" if optional_fields.empty? + fields = optional_fields.reject { |field| field.type == :TYPE_ENUM } + return "" if fields.empty? "# optional field readers\n" + - optional_fields.map do |field| + fields.map do |field| "#{reader_type_signature(field)}\nattr_reader :#{field.name}\n" end.join("\n") + "\n\n" @@ -729,7 +729,12 @@ def enum_writers "# enum writers\n" + fields.map do |field| - "def #{field.name}=(v); #{iv_name(field)} = #{enum_name(field)}.resolve(v) || v; end" + writer = "def #{field.name}=(v); #{iv_name(field)} = #{enum_name(field)}.resolve(v) || v;" + if @optional_fields.include?(fields) + writer << "#{set_bitmask(field)}; " + end + writer << "end" + writer end.join("\n") + "\n\n" end @@ -750,10 +755,11 @@ def #{field.name}=(v) end def optional_writers - return "" if optional_fields.empty? + fields = optional_fields.reject { |field| field.type == :TYPE_ENUM } + return "" if fields.empty? "# BEGIN writers for optional fields\n" + - optional_fields.map { |field| + fields.map { |field| <<~RUBY #{type_signature(params: { v: convert_field_type(field) })} def #{field.name}=(v) diff --git a/lib/protoboeuf/google/protobuf/descriptor.rb b/lib/protoboeuf/google/protobuf/descriptor.rb index 1f6f8d9..de783eb 100644 --- a/lib/protoboeuf/google/protobuf/descriptor.rb +++ b/lib/protoboeuf/google/protobuf/descriptor.rb @@ -745,6 +745,10 @@ def has_syntax? (@_bitmask & 0x0000000000000010) == 0x0000000000000010 end + def has_edition? + (@_bitmask & 0x0000000000000020) == 0x0000000000000020 + end + def decode_from(buff, index, len) @_bitmask = 0 @@ -3345,7 +3349,7 @@ def _encode(buff) end val = @edition - if val != 0 + if has_edition? buff << 0x70 loop do @@ -8166,6 +8170,10 @@ def has_features? (@_bitmask & 0x0000000000000001) == 0x0000000000000001 end + def has_verification? + (@_bitmask & 0x0000000000000002) == 0x0000000000000002 + end + def decode_from(buff, index, len) @_bitmask = 0 @@ -9112,7 +9120,7 @@ def _encode(buff) end val = @verification - if val != 0 + if has_verification? buff << 0x18 loop do @@ -9454,6 +9462,14 @@ def has_number? (@_bitmask & 0x0000000000000002) == 0x0000000000000002 end + def has_label? + (@_bitmask & 0x0000000000000004) == 0x0000000000000004 + end + + def has_type? + (@_bitmask & 0x0000000000000008) == 0x0000000000000008 + end + def has_type_name? (@_bitmask & 0x0000000000000010) == 0x0000000000000010 end @@ -11108,7 +11124,7 @@ def _encode(buff) end val = @label - if val != 0 + if has_label? buff << 0x20 loop do @@ -11127,7 +11143,7 @@ def _encode(buff) end val = @type - if val != 0 + if has_type? buff << 0x28 loop do @@ -16932,6 +16948,10 @@ def has_java_string_check_utf8? (@_bitmask & 0x0000000000000010) == 0x0000000000000010 end + def has_optimize_for? + (@_bitmask & 0x0000000000000020) == 0x0000000000000020 + end + def has_go_package? (@_bitmask & 0x0000000000000040) == 0x0000000000000040 end @@ -19486,7 +19506,7 @@ def _encode(buff) end val = @optimize_for - if val != 0 + if has_optimize_for? buff << 0x48 loop do @@ -21065,6 +21085,10 @@ def to_proto(_options = {}) self.class.encode(self) end + def has_edition? + (@_bitmask & 0x0000000000000001) == 0x0000000000000001 + end + def has_value? (@_bitmask & 0x0000000000000002) == 0x0000000000000002 end @@ -21574,7 +21598,7 @@ def decode_from(buff, index, len) end def _encode(buff) val = @edition - if val != 0 + if has_edition? buff << 0x18 loop do @@ -21718,10 +21742,22 @@ def to_proto(_options = {}) self.class.encode(self) end + def has_edition_introduced? + (@_bitmask & 0x0000000000000001) == 0x0000000000000001 + end + + def has_edition_deprecated? + (@_bitmask & 0x0000000000000002) == 0x0000000000000002 + end + def has_deprecation_warning? (@_bitmask & 0x0000000000000004) == 0x0000000000000004 end + def has_edition_removed? + (@_bitmask & 0x0000000000000008) == 0x0000000000000008 + end + def decode_from(buff, index, len) @_bitmask = 0 @@ -22491,7 +22527,7 @@ def decode_from(buff, index, len) end def _encode(buff) val = @edition_introduced - if val != 0 + if has_edition_introduced? buff << 0x08 loop do @@ -22510,7 +22546,7 @@ def _encode(buff) end val = @edition_deprecated - if val != 0 + if has_edition_deprecated? buff << 0x10 loop do @@ -22543,7 +22579,7 @@ def _encode(buff) end val = @edition_removed - if val != 0 + if has_edition_removed? buff << 0x20 loop do @@ -22900,10 +22936,18 @@ def to_proto(_options = {}) self.class.encode(self) end + def has_ctype? + (@_bitmask & 0x0000000000000001) == 0x0000000000000001 + end + def has_packed? (@_bitmask & 0x0000000000000002) == 0x0000000000000002 end + def has_jstype? + (@_bitmask & 0x0000000000000004) == 0x0000000000000004 + end + def has_lazy? (@_bitmask & 0x0000000000000008) == 0x0000000000000008 end @@ -22924,6 +22968,10 @@ def has_debug_redact? (@_bitmask & 0x0000000000000080) == 0x0000000000000080 end + def has_retention? + (@_bitmask & 0x0000000000000100) == 0x0000000000000100 + end + def has_features? (@_bitmask & 0x0000000000000200) == 0x0000000000000200 end @@ -24651,7 +24699,7 @@ def decode_from(buff, index, len) end def _encode(buff) val = @ctype - if val != 0 + if has_ctype? buff << 0x08 loop do @@ -24681,7 +24729,7 @@ def _encode(buff) end val = @jstype - if val != 0 + if has_jstype? buff << 0x30 loop do @@ -24756,7 +24804,7 @@ def _encode(buff) end val = @retention - if val != 0 + if has_retention? buff << 0x88 buff << 0x01 @@ -28652,6 +28700,10 @@ def has_deprecated? (@_bitmask & 0x0000000000000001) == 0x0000000000000001 end + def has_idempotency_level? + (@_bitmask & 0x0000000000000002) == 0x0000000000000002 + end + def has_features? (@_bitmask & 0x0000000000000004) == 0x0000000000000004 end @@ -29377,7 +29429,7 @@ def _encode(buff) end val = @idempotency_level - if val != 0 + if has_idempotency_level? buff << 0x90 buff << 0x02 @@ -31608,6 +31660,8 @@ def initialize( message_encoding: nil, json_format: nil ) + @_bitmask = 0 + if field_presence == nil @field_presence = 0 else @@ -31673,7 +31727,33 @@ def to_proto(_options = {}) self.class.encode(self) end + def has_field_presence? + (@_bitmask & 0x0000000000000001) == 0x0000000000000001 + end + + def has_enum_type? + (@_bitmask & 0x0000000000000002) == 0x0000000000000002 + end + + def has_repeated_field_encoding? + (@_bitmask & 0x0000000000000004) == 0x0000000000000004 + end + + def has_utf8_validation? + (@_bitmask & 0x0000000000000008) == 0x0000000000000008 + end + + def has_message_encoding? + (@_bitmask & 0x0000000000000010) == 0x0000000000000010 + end + + def has_json_format? + (@_bitmask & 0x0000000000000020) == 0x0000000000000020 + end + def decode_from(buff, index, len) + @_bitmask = 0 + @field_presence = 0 @enum_type = 0 @repeated_field_encoding = 0 @@ -32705,7 +32785,7 @@ def decode_from(buff, index, len) end def _encode(buff) val = @field_presence - if val != 0 + if has_field_presence? buff << 0x08 loop do @@ -32724,7 +32804,7 @@ def _encode(buff) end val = @enum_type - if val != 0 + if has_enum_type? buff << 0x10 loop do @@ -32743,7 +32823,7 @@ def _encode(buff) end val = @repeated_field_encoding - if val != 0 + if has_repeated_field_encoding? buff << 0x18 loop do @@ -32762,7 +32842,7 @@ def _encode(buff) end val = @utf8_validation - if val != 0 + if has_utf8_validation? buff << 0x20 loop do @@ -32781,7 +32861,7 @@ def _encode(buff) end val = @message_encoding - if val != 0 + if has_message_encoding? buff << 0x28 loop do @@ -32800,7 +32880,7 @@ def _encode(buff) end val = @json_format - if val != 0 + if has_json_format? buff << 0x30 loop do @@ -32913,6 +32993,10 @@ def to_proto(_options = {}) self.class.encode(self) end + def has_edition? + (@_bitmask & 0x0000000000000001) == 0x0000000000000001 + end + def has_overridable_features? (@_bitmask & 0x0000000000000002) == 0x0000000000000002 end @@ -33561,7 +33645,7 @@ def decode_from(buff, index, len) end def _encode(buff) val = @edition - if val != 0 + if has_edition? buff << 0x18 loop do @@ -33715,6 +33799,8 @@ def maximum_edition=(v) end def initialize(defaults: [], minimum_edition: nil, maximum_edition: nil) + @_bitmask = 0 + @defaults = defaults if minimum_edition == nil @@ -33742,7 +33828,17 @@ def to_proto(_options = {}) self.class.encode(self) end + def has_minimum_edition? + (@_bitmask & 0x0000000000000001) == 0x0000000000000001 + end + + def has_maximum_edition? + (@_bitmask & 0x0000000000000002) == 0x0000000000000002 + end + def decode_from(buff, index, len) + @_bitmask = 0 + @defaults = [] @minimum_edition = 0 @maximum_edition = 0 @@ -34442,7 +34538,7 @@ def _encode(buff) end val = @minimum_edition - if val != 0 + if has_minimum_edition? buff << 0x20 loop do @@ -34461,7 +34557,7 @@ def _encode(buff) end val = @maximum_edition - if val != 0 + if has_maximum_edition? buff << 0x28 loop do @@ -36455,6 +36551,10 @@ def has_end? (@_bitmask & 0x0000000000000004) == 0x0000000000000004 end + def has_semantic? + (@_bitmask & 0x0000000000000008) == 0x0000000000000008 + end + def decode_from(buff, index, len) @_bitmask = 0 @@ -37534,7 +37634,7 @@ def _encode(buff) end val = @semantic - if val != 0 + if has_semantic? buff << 0x28 loop do