Skip to content

Ruby: generate dummy classes for IDE support#7593

Closed
qnighy wants to merge 1 commit intoprotocolbuffers:masterfrom
qnighy:dummy-class
Closed

Ruby: generate dummy classes for IDE support#7593
qnighy wants to merge 1 commit intoprotocolbuffers:masterfrom
qnighy:dummy-class

Conversation

@qnighy
Copy link
Contributor

@qnighy qnighy commented Jun 3, 2020

Currently, the Ruby implementation generates classes using reflection/metaprogramming from descriptors. Although this is idiomatic in Ruby, it is also helpful to have class declarations for better IDE support, such as completion.

This PR modifies the Ruby generator to generate the following code snippets:

# for documentation purpose
if false
  class MyMessage
    # ...
  end
  # ...
end

The class declarations can also serve the following purpose @haberman mentioned in #7381:

If the generated code simply embedded a binary descriptor, we would have perfect fidelity and we would never have to fix the DSL again. But we'd give up the readability of the DSL. Perhaps the .proto file could be embedded in comments?

@qnighy
Copy link
Contributor Author

qnighy commented Jun 3, 2020

An example (basic_test_pb.rb)
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: tests/basic_test.proto

require 'google/protobuf'

require 'google/protobuf/wrappers_pb'
require 'google/protobuf/timestamp_pb'
require 'google/protobuf/duration_pb'
require 'google/protobuf/struct_pb'
Google::Protobuf::DescriptorPool.generated_pool.build do
  add_file("tests/basic_test.proto", :syntax => :proto3) do
    add_message "basic_test.Foo" do
      optional :bar, :message, 1, "basic_test.Bar"
      repeated :baz, :message, 2, "basic_test.Baz"
    end
    add_message "basic_test.Bar" do
      optional :msg, :string, 1
    end
    add_message "basic_test.Baz" do
      optional :msg, :string, 1
    end
    add_message "basic_test.TestMessage" do
      proto3_optional :optional_int32, :int32, 1
      proto3_optional :optional_int64, :int64, 2
      proto3_optional :optional_uint32, :uint32, 3
      proto3_optional :optional_uint64, :uint64, 4
      proto3_optional :optional_bool, :bool, 5
      proto3_optional :optional_float, :float, 6
      proto3_optional :optional_double, :double, 7
      proto3_optional :optional_string, :string, 8
      proto3_optional :optional_bytes, :bytes, 9
      proto3_optional :optional_msg, :message, 10, "basic_test.TestMessage2"
      proto3_optional :optional_enum, :enum, 11, "basic_test.TestEnum"
      repeated :repeated_int32, :int32, 12
      repeated :repeated_int64, :int64, 13
      repeated :repeated_uint32, :uint32, 14
      repeated :repeated_uint64, :uint64, 15
      repeated :repeated_bool, :bool, 16
      repeated :repeated_float, :float, 17
      repeated :repeated_double, :double, 18
      repeated :repeated_string, :string, 19
      repeated :repeated_bytes, :bytes, 20
      repeated :repeated_msg, :message, 21, "basic_test.TestMessage2"
      repeated :repeated_enum, :enum, 22, "basic_test.TestEnum"
    end
    add_message "basic_test.TestSingularFields" do
      optional :singular_int32, :int32, 1
      optional :singular_int64, :int64, 2
      optional :singular_uint32, :uint32, 3
      optional :singular_uint64, :uint64, 4
      optional :singular_bool, :bool, 5
      optional :singular_float, :float, 6
      optional :singular_double, :double, 7
      optional :singular_string, :string, 8
      optional :singular_bytes, :bytes, 9
      optional :singular_msg, :message, 10, "basic_test.TestMessage2"
      optional :singular_enum, :enum, 11, "basic_test.TestEnum"
    end
    add_message "basic_test.TestMessage2" do
      optional :foo, :int32, 1
    end
    add_message "basic_test.TestEmbeddedMessageParent" do
      optional :child_msg, :message, 1, "basic_test.TestEmbeddedMessageChild"
      optional :number, :int32, 2
      repeated :repeated_msg, :message, 3, "basic_test.TestEmbeddedMessageChild"
      repeated :repeated_number, :int32, 4
    end
    add_message "basic_test.TestEmbeddedMessageChild" do
      optional :sub_child, :message, 1, "basic_test.TestMessage"
    end
    add_message "basic_test.Recursive1" do
      optional :foo, :message, 1, "basic_test.Recursive2"
    end
    add_message "basic_test.Recursive2" do
      optional :foo, :message, 1, "basic_test.Recursive1"
    end
    add_message "basic_test.MapMessage" do
      map :map_string_int32, :string, :int32, 1
      map :map_string_msg, :string, :message, 2, "basic_test.TestMessage2"
      map :map_string_enum, :string, :enum, 3, "basic_test.TestEnum"
    end
    add_message "basic_test.MapMessageWireEquiv" do
      repeated :map_string_int32, :message, 1, "basic_test.MapMessageWireEquiv_entry1"
      repeated :map_string_msg, :message, 2, "basic_test.MapMessageWireEquiv_entry2"
    end
    add_message "basic_test.MapMessageWireEquiv_entry1" do
      optional :key, :string, 1
      optional :value, :int32, 2
    end
    add_message "basic_test.MapMessageWireEquiv_entry2" do
      optional :key, :string, 1
      optional :value, :message, 2, "basic_test.TestMessage2"
    end
    add_message "basic_test.OneofMessage" do
      oneof :my_oneof do
        optional :a, :string, 1
        optional :b, :int32, 2
        optional :c, :message, 3, "basic_test.TestMessage2"
        optional :d, :enum, 4, "basic_test.TestEnum"
      end
    end
    add_message "basic_test.Outer" do
      map :items, :int32, :message, 1, "basic_test.Inner"
    end
    add_message "basic_test.Inner" do
    end
    add_message "basic_test.Wrapper" do
      optional :double, :message, 1, "google.protobuf.DoubleValue"
      optional :float, :message, 2, "google.protobuf.FloatValue"
      optional :int32, :message, 3, "google.protobuf.Int32Value"
      optional :int64, :message, 4, "google.protobuf.Int64Value"
      optional :uint32, :message, 5, "google.protobuf.UInt32Value"
      optional :uint64, :message, 6, "google.protobuf.UInt64Value"
      optional :bool, :message, 7, "google.protobuf.BoolValue"
      optional :string, :message, 8, "google.protobuf.StringValue"
      optional :bytes, :message, 9, "google.protobuf.BytesValue"
      optional :real_string, :string, 100
      repeated :repeated_double, :message, 11, "google.protobuf.DoubleValue"
      repeated :repeated_float, :message, 12, "google.protobuf.FloatValue"
      repeated :repeated_int32, :message, 13, "google.protobuf.Int32Value"
      repeated :repeated_int64, :message, 14, "google.protobuf.Int64Value"
      repeated :repeated_uint32, :message, 15, "google.protobuf.UInt32Value"
      repeated :repeated_uint64, :message, 16, "google.protobuf.UInt64Value"
      repeated :repeated_bool, :message, 17, "google.protobuf.BoolValue"
      repeated :repeated_string, :message, 18, "google.protobuf.StringValue"
      repeated :repeated_bytes, :message, 19, "google.protobuf.BytesValue"
      map :map_double, :int32, :message, 21, "google.protobuf.DoubleValue"
      map :map_float, :int32, :message, 22, "google.protobuf.FloatValue"
      map :map_int32, :int32, :message, 23, "google.protobuf.Int32Value"
      map :map_int64, :int32, :message, 24, "google.protobuf.Int64Value"
      map :map_uint32, :int32, :message, 25, "google.protobuf.UInt32Value"
      map :map_uint64, :int32, :message, 26, "google.protobuf.UInt64Value"
      map :map_bool, :int32, :message, 27, "google.protobuf.BoolValue"
      map :map_string, :int32, :message, 28, "google.protobuf.StringValue"
      map :map_bytes, :int32, :message, 29, "google.protobuf.BytesValue"
      oneof :a_oneof do
        optional :string_in_oneof, :string, 10
      end
      oneof :wrapper_oneof do
        optional :oneof_double, :message, 31, "google.protobuf.DoubleValue"
        optional :oneof_float, :message, 32, "google.protobuf.FloatValue"
        optional :oneof_int32, :message, 33, "google.protobuf.Int32Value"
        optional :oneof_int64, :message, 34, "google.protobuf.Int64Value"
        optional :oneof_uint32, :message, 35, "google.protobuf.UInt32Value"
        optional :oneof_uint64, :message, 36, "google.protobuf.UInt64Value"
        optional :oneof_bool, :message, 37, "google.protobuf.BoolValue"
        optional :oneof_string, :message, 38, "google.protobuf.StringValue"
        optional :oneof_bytes, :message, 39, "google.protobuf.BytesValue"
        optional :oneof_plain_string, :string, 101
      end
    end
    add_message "basic_test.TimeMessage" do
      optional :timestamp, :message, 1, "google.protobuf.Timestamp"
      optional :duration, :message, 2, "google.protobuf.Duration"
    end
    add_message "basic_test.Enumer" do
      optional :optional_enum, :enum, 1, "basic_test.TestEnum"
      repeated :repeated_enum, :enum, 2, "basic_test.TestEnum"
      optional :a_const, :string, 3
      oneof :a_oneof do
        optional :str, :string, 10
        optional :const, :enum, 11, "basic_test.TestEnum"
      end
    end
    add_message "basic_test.MyRepeatedStruct" do
      repeated :structs, :message, 1, "basic_test.MyStruct"
    end
    add_message "basic_test.MyStruct" do
      optional :string, :string, 1
      optional :struct, :message, 2, "google.protobuf.Struct"
    end
    add_enum "basic_test.TestEnum" do
      value :Default, 0
      value :A, 1
      value :B, 2
      value :C, 3
    end
  end
end

module BasicTest
  Foo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Foo").msgclass
  Bar = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Bar").msgclass
  Baz = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Baz").msgclass
  TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TestMessage").msgclass
  TestSingularFields = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TestSingularFields").msgclass
  TestMessage2 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TestMessage2").msgclass
  TestEmbeddedMessageParent = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TestEmbeddedMessageParent").msgclass
  TestEmbeddedMessageChild = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TestEmbeddedMessageChild").msgclass
  Recursive1 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Recursive1").msgclass
  Recursive2 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Recursive2").msgclass
  MapMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.MapMessage").msgclass
  MapMessageWireEquiv = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.MapMessageWireEquiv").msgclass
  MapMessageWireEquiv_entry1 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.MapMessageWireEquiv_entry1").msgclass
  MapMessageWireEquiv_entry2 = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.MapMessageWireEquiv_entry2").msgclass
  OneofMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.OneofMessage").msgclass
  Outer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Outer").msgclass
  Inner = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Inner").msgclass
  Wrapper = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Wrapper").msgclass
  TimeMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TimeMessage").msgclass
  Enumer = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.Enumer").msgclass
  MyRepeatedStruct = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.MyRepeatedStruct").msgclass
  MyStruct = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.MyStruct").msgclass
  TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("basic_test.TestEnum").enummodule

  # for documentation purpose
  if false
    class Foo
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [BasicTestT::Bar, nil]
      attr_accessor :bar
      def clear_bar; end
      # @return [Boolean]
      def has_bar?; end

      # @return [Array<BasicTestT::Baz>]
      attr_accessor :baz
      def clear_baz; end
      # @return [Boolean]
      def has_baz?; end

      # @param kwargs [Hash]
      # @option kwargs [BasicTestT::Bar, nil] :bar (nil)
      # @option kwargs [Array<BasicTestT::Baz>] :baz ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Foo]
      def self.decode(data); end
      # @param msg [Foo]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Foo]
      def self.decode_json(data, options = {}); end
      # @param msg [Foo]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Bar
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [String]
      attr_accessor :msg
      def clear_msg; end
      # @return [Boolean]
      def has_msg?; end

      # @param kwargs [Hash]
      # @option kwargs [String] :msg ("")
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Bar]
      def self.decode(data); end
      # @param msg [Bar]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Bar]
      def self.decode_json(data, options = {}); end
      # @param msg [Bar]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Baz
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [String]
      attr_accessor :msg
      def clear_msg; end
      # @return [Boolean]
      def has_msg?; end

      # @param kwargs [Hash]
      # @option kwargs [String] :msg ("")
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Baz]
      def self.decode(data); end
      # @param msg [Baz]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Baz]
      def self.decode_json(data, options = {}); end
      # @param msg [Baz]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class TestMessage
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Integer, nil]
      attr_accessor :optional_int32
      def clear_optional_int32; end
      # @return [Boolean]
      def has_optional_int32?; end

      # @return [Integer, nil]
      attr_accessor :optional_int64
      def clear_optional_int64; end
      # @return [Boolean]
      def has_optional_int64?; end

      # @return [Integer, nil]
      attr_accessor :optional_uint32
      def clear_optional_uint32; end
      # @return [Boolean]
      def has_optional_uint32?; end

      # @return [Integer, nil]
      attr_accessor :optional_uint64
      def clear_optional_uint64; end
      # @return [Boolean]
      def has_optional_uint64?; end

      # @return [Boolean, nil]
      attr_accessor :optional_bool
      def clear_optional_bool; end
      # @return [Boolean]
      def has_optional_bool?; end

      # @return [Float, nil]
      attr_accessor :optional_float
      def clear_optional_float; end
      # @return [Boolean]
      def has_optional_float?; end

      # @return [Float, nil]
      attr_accessor :optional_double
      def clear_optional_double; end
      # @return [Boolean]
      def has_optional_double?; end

      # @return [String, nil]
      attr_accessor :optional_string
      def clear_optional_string; end
      # @return [Boolean]
      def has_optional_string?; end

      # @return [String, nil]
      attr_accessor :optional_bytes
      def clear_optional_bytes; end
      # @return [Boolean]
      def has_optional_bytes?; end

      # @return [BasicTestT::TestMessage2, nil]
      attr_accessor :optional_msg
      def clear_optional_msg; end
      # @return [Boolean]
      def has_optional_msg?; end

      # @return [Symbol, Integer, nil]
      attr_accessor :optional_enum
      def clear_optional_enum; end
      # @return [Boolean]
      def has_optional_enum?; end
      # @return [Integer, nil]
      attr_reader :optional_enum_const

      # @return [Array<Integer>]
      attr_accessor :repeated_int32
      def clear_repeated_int32; end
      # @return [Boolean]
      def has_repeated_int32?; end

      # @return [Array<Integer>]
      attr_accessor :repeated_int64
      def clear_repeated_int64; end
      # @return [Boolean]
      def has_repeated_int64?; end

      # @return [Array<Integer>]
      attr_accessor :repeated_uint32
      def clear_repeated_uint32; end
      # @return [Boolean]
      def has_repeated_uint32?; end

      # @return [Array<Integer>]
      attr_accessor :repeated_uint64
      def clear_repeated_uint64; end
      # @return [Boolean]
      def has_repeated_uint64?; end

      # @return [Array<Boolean>]
      attr_accessor :repeated_bool
      def clear_repeated_bool; end
      # @return [Boolean]
      def has_repeated_bool?; end

      # @return [Array<Float>]
      attr_accessor :repeated_float
      def clear_repeated_float; end
      # @return [Boolean]
      def has_repeated_float?; end

      # @return [Array<Float>]
      attr_accessor :repeated_double
      def clear_repeated_double; end
      # @return [Boolean]
      def has_repeated_double?; end

      # @return [Array<String>]
      attr_accessor :repeated_string
      def clear_repeated_string; end
      # @return [Boolean]
      def has_repeated_string?; end

      # @return [Array<String>]
      attr_accessor :repeated_bytes
      def clear_repeated_bytes; end
      # @return [Boolean]
      def has_repeated_bytes?; end

      # @return [Array<BasicTestT::TestMessage2>]
      attr_accessor :repeated_msg
      def clear_repeated_msg; end
      # @return [Boolean]
      def has_repeated_msg?; end

      # @return [Array<Symbol, Integer>]
      attr_accessor :repeated_enum
      def clear_repeated_enum; end
      # @return [Boolean]
      def has_repeated_enum?; end
      # @return [Integer]
      attr_reader :repeated_enum_const

      # @return [Symbol, nil]
      attr_reader :_optional_int32

      # @return [Symbol, nil]
      attr_reader :_optional_int64

      # @return [Symbol, nil]
      attr_reader :_optional_uint32

      # @return [Symbol, nil]
      attr_reader :_optional_uint64

      # @return [Symbol, nil]
      attr_reader :_optional_bool

      # @return [Symbol, nil]
      attr_reader :_optional_float

      # @return [Symbol, nil]
      attr_reader :_optional_double

      # @return [Symbol, nil]
      attr_reader :_optional_string

      # @return [Symbol, nil]
      attr_reader :_optional_bytes

      # @return [Symbol, nil]
      attr_reader :_optional_msg

      # @return [Symbol, nil]
      attr_reader :_optional_enum

      # @param kwargs [Hash]
      # @option kwargs [Integer, nil] :optional_int32 (nil)
      # @option kwargs [Integer, nil] :optional_int64 (nil)
      # @option kwargs [Integer, nil] :optional_uint32 (nil)
      # @option kwargs [Integer, nil] :optional_uint64 (nil)
      # @option kwargs [Boolean, nil] :optional_bool (nil)
      # @option kwargs [Float, nil] :optional_float (nil)
      # @option kwargs [Float, nil] :optional_double (nil)
      # @option kwargs [String, nil] :optional_string (nil)
      # @option kwargs [String, nil] :optional_bytes (nil)
      # @option kwargs [BasicTestT::TestMessage2, nil] :optional_msg (nil)
      # @option kwargs [Symbol, Integer, nil] :optional_enum (nil)
      # @option kwargs [Array<Integer>] :repeated_int32 ([])
      # @option kwargs [Array<Integer>] :repeated_int64 ([])
      # @option kwargs [Array<Integer>] :repeated_uint32 ([])
      # @option kwargs [Array<Integer>] :repeated_uint64 ([])
      # @option kwargs [Array<Boolean>] :repeated_bool ([])
      # @option kwargs [Array<Float>] :repeated_float ([])
      # @option kwargs [Array<Float>] :repeated_double ([])
      # @option kwargs [Array<String>] :repeated_string ([])
      # @option kwargs [Array<String>] :repeated_bytes ([])
      # @option kwargs [Array<BasicTestT::TestMessage2>] :repeated_msg ([])
      # @option kwargs [Array<Symbol, Integer>] :repeated_enum ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [TestMessage]
      def self.decode(data); end
      # @param msg [TestMessage]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [TestMessage]
      def self.decode_json(data, options = {}); end
      # @param msg [TestMessage]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class TestSingularFields
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Integer]
      attr_accessor :singular_int32
      def clear_singular_int32; end
      # @return [Boolean]
      def has_singular_int32?; end

      # @return [Integer]
      attr_accessor :singular_int64
      def clear_singular_int64; end
      # @return [Boolean]
      def has_singular_int64?; end

      # @return [Integer]
      attr_accessor :singular_uint32
      def clear_singular_uint32; end
      # @return [Boolean]
      def has_singular_uint32?; end

      # @return [Integer]
      attr_accessor :singular_uint64
      def clear_singular_uint64; end
      # @return [Boolean]
      def has_singular_uint64?; end

      # @return [Boolean]
      attr_accessor :singular_bool
      def clear_singular_bool; end
      # @return [Boolean]
      def has_singular_bool?; end

      # @return [Float]
      attr_accessor :singular_float
      def clear_singular_float; end
      # @return [Boolean]
      def has_singular_float?; end

      # @return [Float]
      attr_accessor :singular_double
      def clear_singular_double; end
      # @return [Boolean]
      def has_singular_double?; end

      # @return [String]
      attr_accessor :singular_string
      def clear_singular_string; end
      # @return [Boolean]
      def has_singular_string?; end

      # @return [String]
      attr_accessor :singular_bytes
      def clear_singular_bytes; end
      # @return [Boolean]
      def has_singular_bytes?; end

      # @return [BasicTestT::TestMessage2, nil]
      attr_accessor :singular_msg
      def clear_singular_msg; end
      # @return [Boolean]
      def has_singular_msg?; end

      # @return [Symbol, Integer]
      attr_accessor :singular_enum
      def clear_singular_enum; end
      # @return [Boolean]
      def has_singular_enum?; end
      # @return [Integer]
      attr_reader :singular_enum_const

      # @param kwargs [Hash]
      # @option kwargs [Integer] :singular_int32 (0)
      # @option kwargs [Integer] :singular_int64 (0)
      # @option kwargs [Integer] :singular_uint32 (0)
      # @option kwargs [Integer] :singular_uint64 (0)
      # @option kwargs [Boolean] :singular_bool (false)
      # @option kwargs [Float] :singular_float (0)
      # @option kwargs [Float] :singular_double (0)
      # @option kwargs [String] :singular_string ("")
      # @option kwargs [String] :singular_bytes ("".force_encoding("ASCII-8BIT"))
      # @option kwargs [BasicTestT::TestMessage2, nil] :singular_msg (nil)
      # @option kwargs [Symbol, Integer] :singular_enum (0)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [TestSingularFields]
      def self.decode(data); end
      # @param msg [TestSingularFields]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [TestSingularFields]
      def self.decode_json(data, options = {}); end
      # @param msg [TestSingularFields]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class TestMessage2
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Integer]
      attr_accessor :foo
      def clear_foo; end
      # @return [Boolean]
      def has_foo?; end

      # @param kwargs [Hash]
      # @option kwargs [Integer] :foo (0)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [TestMessage2]
      def self.decode(data); end
      # @param msg [TestMessage2]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [TestMessage2]
      def self.decode_json(data, options = {}); end
      # @param msg [TestMessage2]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class TestEmbeddedMessageParent
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [BasicTestT::TestEmbeddedMessageChild, nil]
      attr_accessor :child_msg
      def clear_child_msg; end
      # @return [Boolean]
      def has_child_msg?; end

      # @return [Integer]
      attr_accessor :number
      def clear_number; end
      # @return [Boolean]
      def has_number?; end

      # @return [Array<BasicTestT::TestEmbeddedMessageChild>]
      attr_accessor :repeated_msg
      def clear_repeated_msg; end
      # @return [Boolean]
      def has_repeated_msg?; end

      # @return [Array<Integer>]
      attr_accessor :repeated_number
      def clear_repeated_number; end
      # @return [Boolean]
      def has_repeated_number?; end

      # @param kwargs [Hash]
      # @option kwargs [BasicTestT::TestEmbeddedMessageChild, nil] :child_msg (nil)
      # @option kwargs [Integer] :number (0)
      # @option kwargs [Array<BasicTestT::TestEmbeddedMessageChild>] :repeated_msg ([])
      # @option kwargs [Array<Integer>] :repeated_number ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [TestEmbeddedMessageParent]
      def self.decode(data); end
      # @param msg [TestEmbeddedMessageParent]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [TestEmbeddedMessageParent]
      def self.decode_json(data, options = {}); end
      # @param msg [TestEmbeddedMessageParent]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class TestEmbeddedMessageChild
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [BasicTestT::TestMessage, nil]
      attr_accessor :sub_child
      def clear_sub_child; end
      # @return [Boolean]
      def has_sub_child?; end

      # @param kwargs [Hash]
      # @option kwargs [BasicTestT::TestMessage, nil] :sub_child (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [TestEmbeddedMessageChild]
      def self.decode(data); end
      # @param msg [TestEmbeddedMessageChild]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [TestEmbeddedMessageChild]
      def self.decode_json(data, options = {}); end
      # @param msg [TestEmbeddedMessageChild]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Recursive1
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [BasicTestT::Recursive2, nil]
      attr_accessor :foo
      def clear_foo; end
      # @return [Boolean]
      def has_foo?; end

      # @param kwargs [Hash]
      # @option kwargs [BasicTestT::Recursive2, nil] :foo (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Recursive1]
      def self.decode(data); end
      # @param msg [Recursive1]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Recursive1]
      def self.decode_json(data, options = {}); end
      # @param msg [Recursive1]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Recursive2
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [BasicTestT::Recursive1, nil]
      attr_accessor :foo
      def clear_foo; end
      # @return [Boolean]
      def has_foo?; end

      # @param kwargs [Hash]
      # @option kwargs [BasicTestT::Recursive1, nil] :foo (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Recursive2]
      def self.decode(data); end
      # @param msg [Recursive2]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Recursive2]
      def self.decode_json(data, options = {}); end
      # @param msg [Recursive2]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class MapMessage
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Hash{String=>Integer}]
      attr_accessor :map_string_int32
      def clear_map_string_int32; end
      # @return [Boolean]
      def has_map_string_int32?; end

      # @return [Hash{String=>BasicTestT::TestMessage2, nil}]
      attr_accessor :map_string_msg
      def clear_map_string_msg; end
      # @return [Boolean]
      def has_map_string_msg?; end

      # @return [Hash{String=>Symbol, Integer}]
      attr_accessor :map_string_enum
      def clear_map_string_enum; end
      # @return [Boolean]
      def has_map_string_enum?; end

      # @param kwargs [Hash]
      # @option kwargs [Hash{String=>Integer}] :map_string_int32 ([])
      # @option kwargs [Hash{String=>BasicTestT::TestMessage2, nil}] :map_string_msg ([])
      # @option kwargs [Hash{String=>Symbol, Integer}] :map_string_enum ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [MapMessage]
      def self.decode(data); end
      # @param msg [MapMessage]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [MapMessage]
      def self.decode_json(data, options = {}); end
      # @param msg [MapMessage]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class MapMessageWireEquiv
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Array<BasicTestT::MapMessageWireEquiv_entry1>]
      attr_accessor :map_string_int32
      def clear_map_string_int32; end
      # @return [Boolean]
      def has_map_string_int32?; end

      # @return [Array<BasicTestT::MapMessageWireEquiv_entry2>]
      attr_accessor :map_string_msg
      def clear_map_string_msg; end
      # @return [Boolean]
      def has_map_string_msg?; end

      # @param kwargs [Hash]
      # @option kwargs [Array<BasicTestT::MapMessageWireEquiv_entry1>] :map_string_int32 ([])
      # @option kwargs [Array<BasicTestT::MapMessageWireEquiv_entry2>] :map_string_msg ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [MapMessageWireEquiv]
      def self.decode(data); end
      # @param msg [MapMessageWireEquiv]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [MapMessageWireEquiv]
      def self.decode_json(data, options = {}); end
      # @param msg [MapMessageWireEquiv]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class MapMessageWireEquiv_entry1
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [String]
      attr_accessor :key
      def clear_key; end
      # @return [Boolean]
      def has_key?; end

      # @return [Integer]
      attr_accessor :value
      def clear_value; end
      # @return [Boolean]
      def has_value?; end

      # @param kwargs [Hash]
      # @option kwargs [String] :key ("")
      # @option kwargs [Integer] :value (0)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [MapMessageWireEquiv_entry1]
      def self.decode(data); end
      # @param msg [MapMessageWireEquiv_entry1]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [MapMessageWireEquiv_entry1]
      def self.decode_json(data, options = {}); end
      # @param msg [MapMessageWireEquiv_entry1]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class MapMessageWireEquiv_entry2
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [String]
      attr_accessor :key
      def clear_key; end
      # @return [Boolean]
      def has_key?; end

      # @return [BasicTestT::TestMessage2, nil]
      attr_accessor :value
      def clear_value; end
      # @return [Boolean]
      def has_value?; end

      # @param kwargs [Hash]
      # @option kwargs [String] :key ("")
      # @option kwargs [BasicTestT::TestMessage2, nil] :value (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [MapMessageWireEquiv_entry2]
      def self.decode(data); end
      # @param msg [MapMessageWireEquiv_entry2]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [MapMessageWireEquiv_entry2]
      def self.decode_json(data, options = {}); end
      # @param msg [MapMessageWireEquiv_entry2]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class OneofMessage
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [String, nil]
      attr_accessor :a
      def clear_a; end
      # @return [Boolean]
      def has_a?; end

      # @return [Integer, nil]
      attr_accessor :b
      def clear_b; end
      # @return [Boolean]
      def has_b?; end

      # @return [BasicTestT::TestMessage2, nil]
      attr_accessor :c
      def clear_c; end
      # @return [Boolean]
      def has_c?; end

      # @return [Symbol, Integer, nil]
      attr_accessor :d
      def clear_d; end
      # @return [Boolean]
      def has_d?; end
      # @return [Integer, nil]
      attr_reader :d_const

      # @return [Symbol, nil]
      attr_reader :my_oneof

      # @param kwargs [Hash]
      # @option kwargs [String, nil] :a (nil)
      # @option kwargs [Integer, nil] :b (nil)
      # @option kwargs [BasicTestT::TestMessage2, nil] :c (nil)
      # @option kwargs [Symbol, Integer, nil] :d (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [OneofMessage]
      def self.decode(data); end
      # @param msg [OneofMessage]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [OneofMessage]
      def self.decode_json(data, options = {}); end
      # @param msg [OneofMessage]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Outer
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Hash{Integer=>BasicTestT::Inner, nil}]
      attr_accessor :items
      def clear_items; end
      # @return [Boolean]
      def has_items?; end

      # @param kwargs [Hash]
      # @option kwargs [Hash{Integer=>BasicTestT::Inner, nil}] :items ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Outer]
      def self.decode(data); end
      # @param msg [Outer]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Outer]
      def self.decode_json(data, options = {}); end
      # @param msg [Outer]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Inner
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @param kwargs [Hash]
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Inner]
      def self.decode(data); end
      # @param msg [Inner]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Inner]
      def self.decode_json(data, options = {}); end
      # @param msg [Inner]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Wrapper
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Google::Protobuf::DoubleValue, nil]
      attr_accessor :double
      def clear_double; end
      # @return [Boolean]
      def has_double?; end
      # @return [Float, nil]
      attr_accessor :double_as_value

      # @return [Google::Protobuf::FloatValue, nil]
      attr_accessor :float
      def clear_float; end
      # @return [Boolean]
      def has_float?; end
      # @return [Float, nil]
      attr_accessor :float_as_value

      # @return [Google::Protobuf::Int32Value, nil]
      attr_accessor :int32
      def clear_int32; end
      # @return [Boolean]
      def has_int32?; end
      # @return [Integer, nil]
      attr_accessor :int32_as_value

      # @return [Google::Protobuf::Int64Value, nil]
      attr_accessor :int64
      def clear_int64; end
      # @return [Boolean]
      def has_int64?; end
      # @return [Integer, nil]
      attr_accessor :int64_as_value

      # @return [Google::Protobuf::UInt32Value, nil]
      attr_accessor :uint32
      def clear_uint32; end
      # @return [Boolean]
      def has_uint32?; end
      # @return [Integer, nil]
      attr_accessor :uint32_as_value

      # @return [Google::Protobuf::UInt64Value, nil]
      attr_accessor :uint64
      def clear_uint64; end
      # @return [Boolean]
      def has_uint64?; end
      # @return [Integer, nil]
      attr_accessor :uint64_as_value

      # @return [Google::Protobuf::BoolValue, nil]
      attr_accessor :bool
      def clear_bool; end
      # @return [Boolean]
      def has_bool?; end
      # @return [Boolean, nil]
      attr_accessor :bool_as_value

      # @return [Google::Protobuf::StringValue, nil]
      attr_accessor :string
      def clear_string; end
      # @return [Boolean]
      def has_string?; end
      # @return [String, nil]
      attr_accessor :string_as_value

      # @return [Google::Protobuf::BytesValue, nil]
      attr_accessor :bytes
      def clear_bytes; end
      # @return [Boolean]
      def has_bytes?; end
      # @return [String, nil]
      attr_accessor :bytes_as_value

      # @return [String]
      attr_accessor :real_string
      def clear_real_string; end
      # @return [Boolean]
      def has_real_string?; end

      # @return [String, nil]
      attr_accessor :string_in_oneof
      def clear_string_in_oneof; end
      # @return [Boolean]
      def has_string_in_oneof?; end

      # @return [Array<Google::Protobuf::DoubleValue>]
      attr_accessor :repeated_double
      def clear_repeated_double; end
      # @return [Boolean]
      def has_repeated_double?; end
      # @return [Float, nil]
      attr_accessor :repeated_double_as_value

      # @return [Array<Google::Protobuf::FloatValue>]
      attr_accessor :repeated_float
      def clear_repeated_float; end
      # @return [Boolean]
      def has_repeated_float?; end
      # @return [Float, nil]
      attr_accessor :repeated_float_as_value

      # @return [Array<Google::Protobuf::Int32Value>]
      attr_accessor :repeated_int32
      def clear_repeated_int32; end
      # @return [Boolean]
      def has_repeated_int32?; end
      # @return [Integer, nil]
      attr_accessor :repeated_int32_as_value

      # @return [Array<Google::Protobuf::Int64Value>]
      attr_accessor :repeated_int64
      def clear_repeated_int64; end
      # @return [Boolean]
      def has_repeated_int64?; end
      # @return [Integer, nil]
      attr_accessor :repeated_int64_as_value

      # @return [Array<Google::Protobuf::UInt32Value>]
      attr_accessor :repeated_uint32
      def clear_repeated_uint32; end
      # @return [Boolean]
      def has_repeated_uint32?; end
      # @return [Integer, nil]
      attr_accessor :repeated_uint32_as_value

      # @return [Array<Google::Protobuf::UInt64Value>]
      attr_accessor :repeated_uint64
      def clear_repeated_uint64; end
      # @return [Boolean]
      def has_repeated_uint64?; end
      # @return [Integer, nil]
      attr_accessor :repeated_uint64_as_value

      # @return [Array<Google::Protobuf::BoolValue>]
      attr_accessor :repeated_bool
      def clear_repeated_bool; end
      # @return [Boolean]
      def has_repeated_bool?; end
      # @return [Boolean, nil]
      attr_accessor :repeated_bool_as_value

      # @return [Array<Google::Protobuf::StringValue>]
      attr_accessor :repeated_string
      def clear_repeated_string; end
      # @return [Boolean]
      def has_repeated_string?; end
      # @return [String, nil]
      attr_accessor :repeated_string_as_value

      # @return [Array<Google::Protobuf::BytesValue>]
      attr_accessor :repeated_bytes
      def clear_repeated_bytes; end
      # @return [Boolean]
      def has_repeated_bytes?; end
      # @return [String, nil]
      attr_accessor :repeated_bytes_as_value

      # @return [Hash{Integer=>Google::Protobuf::DoubleValue, nil}]
      attr_accessor :map_double
      def clear_map_double; end
      # @return [Boolean]
      def has_map_double?; end

      # @return [Hash{Integer=>Google::Protobuf::FloatValue, nil}]
      attr_accessor :map_float
      def clear_map_float; end
      # @return [Boolean]
      def has_map_float?; end

      # @return [Hash{Integer=>Google::Protobuf::Int32Value, nil}]
      attr_accessor :map_int32
      def clear_map_int32; end
      # @return [Boolean]
      def has_map_int32?; end

      # @return [Hash{Integer=>Google::Protobuf::Int64Value, nil}]
      attr_accessor :map_int64
      def clear_map_int64; end
      # @return [Boolean]
      def has_map_int64?; end

      # @return [Hash{Integer=>Google::Protobuf::UInt32Value, nil}]
      attr_accessor :map_uint32
      def clear_map_uint32; end
      # @return [Boolean]
      def has_map_uint32?; end

      # @return [Hash{Integer=>Google::Protobuf::UInt64Value, nil}]
      attr_accessor :map_uint64
      def clear_map_uint64; end
      # @return [Boolean]
      def has_map_uint64?; end

      # @return [Hash{Integer=>Google::Protobuf::BoolValue, nil}]
      attr_accessor :map_bool
      def clear_map_bool; end
      # @return [Boolean]
      def has_map_bool?; end

      # @return [Hash{Integer=>Google::Protobuf::StringValue, nil}]
      attr_accessor :map_string
      def clear_map_string; end
      # @return [Boolean]
      def has_map_string?; end

      # @return [Hash{Integer=>Google::Protobuf::BytesValue, nil}]
      attr_accessor :map_bytes
      def clear_map_bytes; end
      # @return [Boolean]
      def has_map_bytes?; end

      # @return [Google::Protobuf::DoubleValue, nil]
      attr_accessor :oneof_double
      def clear_oneof_double; end
      # @return [Boolean]
      def has_oneof_double?; end
      # @return [Float, nil]
      attr_accessor :oneof_double_as_value

      # @return [Google::Protobuf::FloatValue, nil]
      attr_accessor :oneof_float
      def clear_oneof_float; end
      # @return [Boolean]
      def has_oneof_float?; end
      # @return [Float, nil]
      attr_accessor :oneof_float_as_value

      # @return [Google::Protobuf::Int32Value, nil]
      attr_accessor :oneof_int32
      def clear_oneof_int32; end
      # @return [Boolean]
      def has_oneof_int32?; end
      # @return [Integer, nil]
      attr_accessor :oneof_int32_as_value

      # @return [Google::Protobuf::Int64Value, nil]
      attr_accessor :oneof_int64
      def clear_oneof_int64; end
      # @return [Boolean]
      def has_oneof_int64?; end
      # @return [Integer, nil]
      attr_accessor :oneof_int64_as_value

      # @return [Google::Protobuf::UInt32Value, nil]
      attr_accessor :oneof_uint32
      def clear_oneof_uint32; end
      # @return [Boolean]
      def has_oneof_uint32?; end
      # @return [Integer, nil]
      attr_accessor :oneof_uint32_as_value

      # @return [Google::Protobuf::UInt64Value, nil]
      attr_accessor :oneof_uint64
      def clear_oneof_uint64; end
      # @return [Boolean]
      def has_oneof_uint64?; end
      # @return [Integer, nil]
      attr_accessor :oneof_uint64_as_value

      # @return [Google::Protobuf::BoolValue, nil]
      attr_accessor :oneof_bool
      def clear_oneof_bool; end
      # @return [Boolean]
      def has_oneof_bool?; end
      # @return [Boolean, nil]
      attr_accessor :oneof_bool_as_value

      # @return [Google::Protobuf::StringValue, nil]
      attr_accessor :oneof_string
      def clear_oneof_string; end
      # @return [Boolean]
      def has_oneof_string?; end
      # @return [String, nil]
      attr_accessor :oneof_string_as_value

      # @return [Google::Protobuf::BytesValue, nil]
      attr_accessor :oneof_bytes
      def clear_oneof_bytes; end
      # @return [Boolean]
      def has_oneof_bytes?; end
      # @return [String, nil]
      attr_accessor :oneof_bytes_as_value

      # @return [String, nil]
      attr_accessor :oneof_plain_string
      def clear_oneof_plain_string; end
      # @return [Boolean]
      def has_oneof_plain_string?; end

      # @return [Symbol, nil]
      attr_reader :a_oneof

      # @return [Symbol, nil]
      attr_reader :wrapper_oneof

      # @param kwargs [Hash]
      # @option kwargs [Google::Protobuf::DoubleValue, nil] :double (nil)
      # @option kwargs [Google::Protobuf::FloatValue, nil] :float (nil)
      # @option kwargs [Google::Protobuf::Int32Value, nil] :int32 (nil)
      # @option kwargs [Google::Protobuf::Int64Value, nil] :int64 (nil)
      # @option kwargs [Google::Protobuf::UInt32Value, nil] :uint32 (nil)
      # @option kwargs [Google::Protobuf::UInt64Value, nil] :uint64 (nil)
      # @option kwargs [Google::Protobuf::BoolValue, nil] :bool (nil)
      # @option kwargs [Google::Protobuf::StringValue, nil] :string (nil)
      # @option kwargs [Google::Protobuf::BytesValue, nil] :bytes (nil)
      # @option kwargs [String] :real_string ("")
      # @option kwargs [String, nil] :string_in_oneof (nil)
      # @option kwargs [Array<Google::Protobuf::DoubleValue>] :repeated_double ([])
      # @option kwargs [Array<Google::Protobuf::FloatValue>] :repeated_float ([])
      # @option kwargs [Array<Google::Protobuf::Int32Value>] :repeated_int32 ([])
      # @option kwargs [Array<Google::Protobuf::Int64Value>] :repeated_int64 ([])
      # @option kwargs [Array<Google::Protobuf::UInt32Value>] :repeated_uint32 ([])
      # @option kwargs [Array<Google::Protobuf::UInt64Value>] :repeated_uint64 ([])
      # @option kwargs [Array<Google::Protobuf::BoolValue>] :repeated_bool ([])
      # @option kwargs [Array<Google::Protobuf::StringValue>] :repeated_string ([])
      # @option kwargs [Array<Google::Protobuf::BytesValue>] :repeated_bytes ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::DoubleValue, nil}] :map_double ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::FloatValue, nil}] :map_float ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::Int32Value, nil}] :map_int32 ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::Int64Value, nil}] :map_int64 ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::UInt32Value, nil}] :map_uint32 ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::UInt64Value, nil}] :map_uint64 ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::BoolValue, nil}] :map_bool ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::StringValue, nil}] :map_string ([])
      # @option kwargs [Hash{Integer=>Google::Protobuf::BytesValue, nil}] :map_bytes ([])
      # @option kwargs [Google::Protobuf::DoubleValue, nil] :oneof_double (nil)
      # @option kwargs [Google::Protobuf::FloatValue, nil] :oneof_float (nil)
      # @option kwargs [Google::Protobuf::Int32Value, nil] :oneof_int32 (nil)
      # @option kwargs [Google::Protobuf::Int64Value, nil] :oneof_int64 (nil)
      # @option kwargs [Google::Protobuf::UInt32Value, nil] :oneof_uint32 (nil)
      # @option kwargs [Google::Protobuf::UInt64Value, nil] :oneof_uint64 (nil)
      # @option kwargs [Google::Protobuf::BoolValue, nil] :oneof_bool (nil)
      # @option kwargs [Google::Protobuf::StringValue, nil] :oneof_string (nil)
      # @option kwargs [Google::Protobuf::BytesValue, nil] :oneof_bytes (nil)
      # @option kwargs [String, nil] :oneof_plain_string (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Wrapper]
      def self.decode(data); end
      # @param msg [Wrapper]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Wrapper]
      def self.decode_json(data, options = {}); end
      # @param msg [Wrapper]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class TimeMessage
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Google::Protobuf::Timestamp, nil]
      attr_accessor :timestamp
      def clear_timestamp; end
      # @return [Boolean]
      def has_timestamp?; end

      # @return [Google::Protobuf::Duration, nil]
      attr_accessor :duration
      def clear_duration; end
      # @return [Boolean]
      def has_duration?; end

      # @param kwargs [Hash]
      # @option kwargs [Google::Protobuf::Timestamp, nil] :timestamp (nil)
      # @option kwargs [Google::Protobuf::Duration, nil] :duration (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [TimeMessage]
      def self.decode(data); end
      # @param msg [TimeMessage]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [TimeMessage]
      def self.decode_json(data, options = {}); end
      # @param msg [TimeMessage]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class Enumer
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Symbol, Integer]
      attr_accessor :optional_enum
      def clear_optional_enum; end
      # @return [Boolean]
      def has_optional_enum?; end
      # @return [Integer]
      attr_reader :optional_enum_const

      # @return [Array<Symbol, Integer>]
      attr_accessor :repeated_enum
      def clear_repeated_enum; end
      # @return [Boolean]
      def has_repeated_enum?; end
      # @return [Integer]
      attr_reader :repeated_enum_const

      # @return [String]
      attr_accessor :a_const
      def clear_a_const; end
      # @return [Boolean]
      def has_a_const?; end

      # @return [String, nil]
      attr_accessor :str
      def clear_str; end
      # @return [Boolean]
      def has_str?; end

      # @return [Symbol, Integer, nil]
      attr_accessor :const
      def clear_const; end
      # @return [Boolean]
      def has_const?; end
      # @return [Integer, nil]
      attr_reader :const_const

      # @return [Symbol, nil]
      attr_reader :a_oneof

      # @param kwargs [Hash]
      # @option kwargs [Symbol, Integer] :optional_enum (0)
      # @option kwargs [Array<Symbol, Integer>] :repeated_enum ([])
      # @option kwargs [String] :a_const ("")
      # @option kwargs [String, nil] :str (nil)
      # @option kwargs [Symbol, Integer, nil] :const (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [Enumer]
      def self.decode(data); end
      # @param msg [Enumer]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [Enumer]
      def self.decode_json(data, options = {}); end
      # @param msg [Enumer]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class MyRepeatedStruct
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [Array<BasicTestT::MyStruct>]
      attr_accessor :structs
      def clear_structs; end
      # @return [Boolean]
      def has_structs?; end

      # @param kwargs [Hash]
      # @option kwargs [Array<BasicTestT::MyStruct>] :structs ([])
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [MyRepeatedStruct]
      def self.decode(data); end
      # @param msg [MyRepeatedStruct]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [MyRepeatedStruct]
      def self.decode_json(data, options = {}); end
      # @param msg [MyRepeatedStruct]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    class MyStruct
      include ::Google::Protobuf::MessageExts
      extend ::Google::Protobuf::MessageExts::ClassMethods

      # @return [String]
      attr_accessor :string
      def clear_string; end
      # @return [Boolean]
      def has_string?; end

      # @return [Google::Protobuf::Struct, nil]
      attr_accessor :struct
      def clear_struct; end
      # @return [Boolean]
      def has_struct?; end

      # @param kwargs [Hash]
      # @option kwargs [String] :string ("")
      # @option kwargs [Google::Protobuf::Struct, nil] :struct (nil)
      def initialize(kwargs = {}); end

      # @param index [String]
      # @return [Object]
      def [](index); end
      # @param index [String]
      # @param value [Object]
      def []=(index, value); end

      # @param data [String]
      # @return [MyStruct]
      def self.decode(data); end
      # @param msg [MyStruct]
      # @return [String]
      def self.encode(msg); end
      # @param data [String]
      # @param options [Hash]
      # @return [MyStruct]
      def self.decode_json(data, options = {}); end
      # @param msg [MyStruct]
      # @param options [Hash]
      # @return [String]
      def self.encode_json(msg, options = {}); end
    end

    module TestEnum
      Default = 0
      A = 1
      B = 2
      C = 3

      # @param number [Integer]
      # @return [Symbol, nil]
      def self.lookup(number)
      end
      # @param name [Symbol]
      # @return [Integer, nil]
      def self.resolve(name)
      end
      # @return [Google::Protobuf::EnumDescriptor]
      def self.descriptor
      end
    end
  end
end

@haberman
Copy link
Member

Thanks for the PR. I think we do want to make some changes to the generated code, both to help IDEs and to preserve more of the information from the descriptor.

Your approach is interesting. If everything for IDEs and human readers is inside an if false block, it does give us a lot of leeway to optimize that code for maximum readability.

Have you tested that this works with common IDEs for Ruby?

Another possibility is something like this:

Google::Protobuf::DescriptorPool.generated_pool.add_serialized_descriptor(
  "<serialized_descriptor>"
)

# Google::Protobuf::Message defines #inherited to hook in the correct behaviors.
# This fails if #add_serialized_descriptor has not been called for "Foo."
class Foo < Google::Protobuf::Message
  # The base class overrides attr_accessor to do the right thing (maybe even
  # define it as a no-op if #inherited is handling the hard part.
  attr_accessor :foo
end

This seems a little nicer if we can make it work. Would you agree?

@qnighy
Copy link
Contributor Author

qnighy commented Jun 15, 2020

Have you tested that this works with common IDEs for Ruby?

This works well with RubyMine.

スクリーンショット 2020-06-15 18 00 50

スクリーンショット 2020-06-15 18 01 00

I also tested Solargraph (with VSCode) but it had a lot of restrictions and I couldn't see any clues it makes use of the annotations. However, Solargraph is already able to handle YARD annotations in other places so it should ideally be able to use our annotations.

YARD, of course, understands YARD annotations, but unfortunately, YARD is clever enough to ignore things inside if false.

@qnighy
Copy link
Contributor Author

qnighy commented Jun 15, 2020

Another possibility is something like this:

Google::Protobuf::DescriptorPool.generated_pool.add_serialized_descriptor(
  "<serialized_descriptor>"
)

# Google::Protobuf::Message defines #inherited to hook in the correct behaviors.
# This fails if #add_serialized_descriptor has not been called for "Foo."
class Foo < Google::Protobuf::Message
  # The base class overrides attr_accessor to do the right thing (maybe even
  # define it as a no-op if #inherited is handling the hard part.
  attr_accessor :foo
end

This seems a little nicer if we can make it work. Would you agree?

That looks nice. I'm willing to help implementation if you're ok with that approach.

@acozzette
Copy link

@haberman and I discussed this offline and we think this is an important feature request, but there are many possible solutions and we should try to come up with a plan for how we want to do this. Let me go ahead and close this pull request for a now, but I opened a new issue (#9495) where we can move the discussion and try to come up with a plan.

@acozzette acozzette closed this Feb 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants