Module: Magicprotorb::Registrar
- Defined in:
- lib/magicprotorb/registrar.rb
Overview
Takes a compiled FileDescriptorSet and registers it through the stock protobuf machinery — DescriptorPool.generated_pool#add_serialized_file plus the same constant assignments a generated ‘*_pb.rb` performs. The resulting message classes are therefore indistinguishable from generated ones.
Constant Summary collapse
- WELL_KNOWN_PREFIX =
The protobuf runtime already owns google/protobuf/*; never re-register or assign constants for those (it would clobber Google::Protobuf::Timestamp and friends, and add_serialized_file would reject the duplicate).
"google/protobuf/"
Class Method Summary collapse
-
.assign_constants(pool, file) ⇒ Object
— constant assignment (mirrors protoc’s Ruby generator) —————-.
- .assign_enum(pool, parent, scope_fullname, enum_name) ⇒ Object
- .assign_message(pool, parent, scope_fullname, msg) ⇒ Object
-
.ensure_module(segments) ⇒ Object
Walk/create a chain of modules (e.g. %w[MyCo SubPkg V1]) under Object, returning the innermost.
-
.qualify(scope, name) ⇒ Object
— helpers ————————————————————–.
-
.register(file_descriptor_set) ⇒ Object
Register every file in the set (dependency-ordered by the compiler), then assign Ruby constants for each non-well-known file.
- .register_file(pool, file) ⇒ Object
- .set_const(parent, name, value) ⇒ Object
Class Method Details
.assign_constants(pool, file) ⇒ Object
— constant assignment (mirrors protoc’s Ruby generator) —————-
46 47 48 49 50 51 |
# File 'lib/magicprotorb/registrar.rb', line 46 def assign_constants(pool, file) package = file.package scope = ensure_module(Naming.package_modules(package)) file..each { |msg| (pool, scope, package, msg) } file.enum_type.each { |enum| assign_enum(pool, scope, package, enum.name) } end |
.assign_enum(pool, parent, scope_fullname, enum_name) ⇒ Object
67 68 69 70 |
# File 'lib/magicprotorb/registrar.rb', line 67 def assign_enum(pool, parent, scope_fullname, enum_name) full_name = qualify(scope_fullname, enum_name) set_const(parent, Naming.constant_name(enum_name), pool.lookup(full_name).enummodule) end |
.assign_message(pool, parent, scope_fullname, msg) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/magicprotorb/registrar.rb', line 53 def (pool, parent, scope_fullname, msg) full_name = qualify(scope_fullname, msg.name) klass = pool.lookup(full_name).msgclass set_const(parent, Naming.constant_name(msg.name), klass) # Synthetic map-entry messages get no constant (protoc skips them too). msg.nested_type.each do |nested| next if nested.&.map_entry (pool, klass, full_name, nested) end msg.enum_type.each { |enum| assign_enum(pool, klass, full_name, enum.name) } end |
.ensure_module(segments) ⇒ Object
Walk/create a chain of modules (e.g. %w[MyCo SubPkg V1]) under Object, returning the innermost. An empty list returns Object (no-package case).
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/magicprotorb/registrar.rb', line 80 def ensure_module(segments) segments.reduce(Object) do |parent, segment| if parent.const_defined?(segment, false) parent.const_get(segment, false) else mod = Module.new parent.const_set(segment, mod) mod end end end |
.qualify(scope, name) ⇒ Object
— helpers ————————————————————–
74 75 76 |
# File 'lib/magicprotorb/registrar.rb', line 74 def qualify(scope, name) scope.nil? || scope.empty? ? name : "#{scope}.#{name}" end |
.register(file_descriptor_set) ⇒ Object
Register every file in the set (dependency-ordered by the compiler), then assign Ruby constants for each non-well-known file. Idempotent.
23 24 25 26 |
# File 'lib/magicprotorb/registrar.rb', line 23 def register(file_descriptor_set) pool = Google::Protobuf::DescriptorPool.generated_pool file_descriptor_set.file.each { |file| register_file(pool, file) } end |
.register_file(pool, file) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/magicprotorb/registrar.rb', line 28 def register_file(pool, file) name = file.name return if @loaded_files[name] begin pool.add_serialized_file(file.to_proto) rescue Google::Protobuf::TypeError => e # Already present (a well-known type, or a shared import registered by a # previously imported proto). Anything else is a real error. raise unless e..include?("duplicate file name") end @loaded_files[name] = true assign_constants(pool, file) unless name.start_with?(WELL_KNOWN_PREFIX) end |
.set_const(parent, name, value) ⇒ Object
92 93 94 |
# File 'lib/magicprotorb/registrar.rb', line 92 def set_const(parent, name, value) parent.const_set(name, value) unless parent.const_defined?(name, false) end |