Merge branch 'master' into rubybuilder
diff --git a/.gitignore b/.gitignore
index d38133b..4e52414 100644
--- a/.gitignore
+++ b/.gitignore
@@ -183,7 +183,6 @@
/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
diff --git a/ruby/ext/google/protobuf_c/defs.c b/ruby/ext/google/protobuf_c/defs.c
index 992f54b..88da610 100644
--- a/ruby/ext/google/protobuf_c/defs.c
+++ b/ruby/ext/google/protobuf_c/defs.c
@@ -320,6 +320,29 @@
/*
* 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
*
* Finds a Descriptor or EnumDescriptor by name and returns it, or nil if none
@@ -1460,6 +1483,11 @@
return Qnil;
}
+<<<<<<< HEAD
+static VALUE make_mapentry(VALUE _message_builder, VALUE types, int argc,
+ const VALUE* argv) {
+ DEFINE_SELF(MessageBuilderContext, message_builder, _message_builder);
+=======
static void MessageBuilderContext_add_synthetic_oneofs(VALUE _self);
/*
@@ -1793,6 +1821,7 @@
#endif
MessageBuilderContext* message_builder =
ruby_to_MessageBuilderContext(_message_builder);
+>>>>>>> master
VALUE type_class = rb_ary_entry(types, 2);
FileBuilderContext* file_context =
ruby_to_FileBuilderContext(message_builder->file_builder);
diff --git a/ruby/lib/google/protobuf/descriptor_builder.rb b/ruby/lib/google/protobuf/descriptor_builder.rb
new file mode 100644
index 0000000..af485bd
--- /dev/null
+++ b/ruby/lib/google/protobuf/descriptor_builder.rb
@@ -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