Some preliminary work towards a ruby builder.

pull/8850/head
Joshua Haberman 5 years ago
parent f15ac4091f
commit 2adea4c64a
  1. 1
      .gitignore
  2. 25
      ruby/ext/google/protobuf_c/defs.c
  3. 110
      ruby/lib/google/protobuf/descriptor_builder.rb

1
.gitignore vendored

@ -178,7 +178,6 @@ js/testproto_libs2.js
/bazel-*
# ruby test output
ruby/lib/
ruby/tests/basic_test_pb.rb
ruby/tests/basic_test_proto2_pb.rb
ruby/tests/generated_code_pb.rb

@ -438,6 +438,29 @@ VALUE DescriptorPool_build(int argc, VALUE* argv, VALUE _self) {
return Qnil;
}
/*
* call-seq:
* DescriptorPool.build_file(serialized_file_proto)
*
* Adds the given serialized FileDescriptorProto to the pool.
*/
VALUE DescriptorPool_build(value _self, VALUE serialized_file_proto) {
DEFINE_SELF(DescriptorPool, self, _self);
Check_Type(serialized_file_proto, T_STRING);
upb_arena *arena = upb_arena_new();
google_protobuf_FileDescriptorProto* file_proto =
google_protobuf_FileDescriptorProto_parse(
RSTRING_PTR(serialized_file_proto),
RSTRING_LEN(serialized_file_proto), arena);
upb_status status;
upb_status_clear(&status);
if (!upb_symtab_addfile(self->symtab, file_proto, &status)) {
rb_raise(cTypeError, "Unable to build file to DescriptorPool: %s",
upb_status_errmsg(&status));
}
return Qnil;
}
/*
* call-seq:
* DescriptorPool.lookup(name) => descriptor
@ -1522,7 +1545,7 @@ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
}
static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
VALUE* argv) {
const VALUE* argv) {
DEFINE_SELF(MessageBuilderContext, message_builder, _message_builder);
VALUE type_class = rb_ary_entry(types, 2);
FileBuilderContext* file_context =

@ -0,0 +1,110 @@
#!/usr/bin/ruby
#
# Summary description of library or script.
#
# This doc string should contain an overall description of the module/script
# and can optionally briefly describe exported classes and functions.
#
# ClassFoo: One line summary.
# function_foo: One line summary.
#
# $Id$
module Google
module Protobuf
module Internal
class FileBuilder
def initialize(pool, name, options=nil)
@pool = pool
@file_proto = Google::Protobuf::FileDescriptorProto.new
@file_proto.name = name
@file_proto.syntax = "proto3" # Default syntax for Ruby is proto3.
if options
if options.key?(:syntax)
@file_proto.syntax = options[:key].to_s
end
end
end
def add_message(name, &block)
MessageBuilder.new(name, @file_proto).instance_eval &block
end
def add_enum(name, &block)
enum_proto = Google::Protobuf::
EnumBuilder.new(name, @file_proto).instance_eval &block
end
end
class MessageBuilder
def initialize(name, file_proto)
@msg_proto = Google::Protobuf::DescriptorProto.new
@msg_proto.name = name
file_proto.message_type << @msg_proto
end
def optional(name, type, number, type_class=nil, options=nil)
# Allow passing either:
# - (name, type, number, options) or
# - (name, type, number, type_class, options)
if options.nil? and type_class.instance_of?(Hash)
options = type_class;
type_class = Qnil;
end
add_field(:LABEL_OPTIONAL, name, type, number, type_class, options)
end
def required(name, type, number, type_class=nil, options=nil)
# Allow passing either:
# - (name, type, number, options) or
# - (name, type, number, type_class, options)
if options.nil? and type_class.instance_of?(Hash)
options = type_class;
type_class = Qnil;
end
add_field(:LABEL_REQUIRED, name, type, number, type_class, options)
end
def repeated(name, type, number, type_class = nil)
add_field(:LABEL_REPEATED, name, type, number, type_class, nil)
end
def map(name, key_type, value_type, number, value_type_class = nil)
entry_name = "MapEntry_#{name}"
add_message
end
private def add_field(label, name, type, number, type_class, options,
oneof_index)
field_proto = Google::Protobuf::FieldDescriptorProto.new(
:label => label,
:name => name,
:type => type,
:number => number
)
if type_class
# Make it an absolute type name by prepending a dot.
field_proto.type_name = "." + type_class
end
if oneof_index
field_proto.oneof_index = oneof_index
end
if options
if options.key?(:default)
# Call #to_s since all defaults are strings in the descriptor.
field_proto.default_value = options[:default].to_s
end
end
@msg_proto.field << field_proto
end
end
end
end
end
Loading…
Cancel
Save