Skip to content

Commit

Permalink
Ruby: Add support for proto3 json_name in compiler and field definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
lfittl committed Mar 1, 2021
1 parent 8080beb commit 3f6da46
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
48 changes: 42 additions & 6 deletions ruby/ext/google/protobuf_c/defs.c
Expand Up @@ -868,6 +868,22 @@ static VALUE FieldDescriptor_default(VALUE _self) {
return Convert_UpbToRuby(default_val, TypeInfo_get(self->fielddef), Qnil);
}


/*
* call-seq:
* FieldDescriptor.json_name => json_name
*
* Returns this field's json_name, as a Ruby string, or nil if not yet set.
*/
static VALUE FieldDescriptor_json_name(VALUE _self) {
FieldDescriptor* self = ruby_to_FieldDescriptor(_self);
const upb_fielddef *f = self->fielddef;
const char *json_name = upb_fielddef_jsonname(f);
if (json_name != NULL)
return rb_str_new2(json_name);
return Qnil;
}

/*
* call-seq:
* FieldDescriptor.label => label
Expand Down Expand Up @@ -1043,6 +1059,7 @@ static void FieldDescriptor_register(VALUE module) {
rb_define_method(klass, "name", FieldDescriptor_name, 0);
rb_define_method(klass, "type", FieldDescriptor__type, 0);
rb_define_method(klass, "default", FieldDescriptor_default, 0);
rb_define_method(klass, "json_name", FieldDescriptor_json_name, 0);
rb_define_method(klass, "label", FieldDescriptor_label, 0);
rb_define_method(klass, "number", FieldDescriptor_number, 0);
rb_define_method(klass, "submsg_name", FieldDescriptor_submsg_name, 0);
Expand Down Expand Up @@ -1750,6 +1767,19 @@ static void msgdef_add_field(VALUE msgbuilder_rb, upb_label_t label, VALUE name,
field_proto,
FileBuilderContext_strdup(self->file_builder, default_value));
}

if (rb_funcall(options, rb_intern("key?"), 1,
ID2SYM(rb_intern("json_name"))) == Qtrue) {
VALUE json_name =
rb_hash_lookup(options, ID2SYM(rb_intern("json_name")));

/* Call #to_s since json_name is always a string in the descriptor. */
json_name = rb_funcall(json_name, rb_intern("to_s"), 0);

google_protobuf_FieldDescriptorProto_set_json_name(
field_proto,
FileBuilderContext_strdup(self->file_builder, json_name));
}
}

if (oneof_index >= 0) {
Expand Down Expand Up @@ -1899,18 +1929,24 @@ static VALUE MessageBuilderContext_required(int argc, VALUE* argv,
*/
static VALUE MessageBuilderContext_repeated(int argc, VALUE* argv,
VALUE _self) {
VALUE name, type, number, type_class;
VALUE name, type, number;
VALUE type_class, options = Qnil;

rb_scan_args(argc, argv, "32", &name, &type, &number, &type_class, &options);

if (argc < 3) {
rb_raise(rb_eArgError, "Expected at least 3 arguments.");
}
name = argv[0];
type = argv[1];
number = argv[2];
type_class = (argc > 3) ? argv[3] : Qnil;

// Allow passing (name, type, number, options) or
// (name, type, number, type_class, options)
if (argc == 4 && RB_TYPE_P(type_class, T_HASH)) {
options = type_class;
type_class = Qnil;
}

msgdef_add_field(_self, UPB_LABEL_REPEATED, name, type, number, type_class,
Qnil, -1, false);
options, -1, false);

return Qnil;
}
Expand Down
5 changes: 5 additions & 0 deletions src/google/protobuf/compiler/ruby/ruby_generator.cc
Expand Up @@ -220,6 +220,11 @@ void GenerateField(const FieldDescriptor* field, io::Printer* printer) {
DefaultValueForField(field));
}

if (field->has_json_name()) {
printer->Print(", json_name: \"$json_name$\"", "json_name",
field->json_name());
}

printer->Print("\n");
}
}
Expand Down

0 comments on commit 3f6da46

Please sign in to comment.