aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/js/js_generator.cc
diff options
context:
space:
mode:
authorGravatar Jisi Liu <jisi.liu@gmail.com>2017-10-18 12:22:18 -0700
committerGravatar Jisi Liu <jisi.liu@gmail.com>2017-10-18 12:22:18 -0700
commit1a7a7fca804afa1cf67f8be5e71092898ba40334 (patch)
tree04b3da27c71c607510f34a12cf7856a1b94181ae /src/google/protobuf/compiler/js/js_generator.cc
parentc4f59dcc5c13debc572154c8f636b8a9361aacde (diff)
Merge from google internal
Diffstat (limited to 'src/google/protobuf/compiler/js/js_generator.cc')
-rwxr-xr-xsrc/google/protobuf/compiler/js/js_generator.cc131
1 files changed, 90 insertions, 41 deletions
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 812ca9d8..16fe19ad 100755
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -244,22 +244,35 @@ string GetPrefix(const GeneratorOptions& options,
return prefix;
}
+// Returns the fully normalized JavaScript path prefix for the given
+// message descriptor.
+string GetMessagePathPrefix(const GeneratorOptions& options,
+ const Descriptor* descriptor) {
+ return GetPrefix(
+ options, descriptor->file(),
+ descriptor->containing_type());
+}
+
// Returns the fully normalized JavaScript path for the given
// message descriptor.
string GetMessagePath(const GeneratorOptions& options,
const Descriptor* descriptor) {
- return GetPrefix(
- options, descriptor->file(),
- descriptor->containing_type()) + descriptor->name();
+ return GetMessagePathPrefix(options, descriptor) + descriptor->name();
+}
+
+// Returns the fully normalized JavaScript path prefix for the given
+// enumeration descriptor.
+string GetEnumPathPrefix(const GeneratorOptions& options,
+ const EnumDescriptor* enum_descriptor) {
+ return GetPrefix(options, enum_descriptor->file(),
+ enum_descriptor->containing_type());
}
// Returns the fully normalized JavaScript path for the given
// enumeration descriptor.
string GetEnumPath(const GeneratorOptions& options,
const EnumDescriptor* enum_descriptor) {
- return GetPrefix(
- options, enum_descriptor->file(),
- enum_descriptor->containing_type()) + enum_descriptor->name();
+ return GetEnumPathPrefix(options, enum_descriptor) + enum_descriptor->name();
}
string MaybeCrossFileRef(const GeneratorOptions& options,
@@ -1930,8 +1943,10 @@ void Generator::GenerateClassConstructor(const GeneratorOptions& options,
" * @extends {jspb.Message}\n"
" * @constructor\n"
" */\n"
- "$classname$ = function(opt_data) {\n",
- "classname", GetMessagePath(options, desc));
+ "$classprefix$$classname$ = function(opt_data) {\n",
+ "classprefix", GetMessagePathPrefix(options, desc),
+ "classname", desc->name());
+ printer->Annotate("classname", desc);
string message_id = GetMessageId(desc);
printer->Print(
" jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, "
@@ -2413,12 +2428,13 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"keytype", key_type,
"valuetype", value_type);
printer->Print(
- "$class$.prototype.get$name$ = function(opt_noLazyCreate) {\n"
+ "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n"
" return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "gettername", "get" + JSGetterName(options, field),
"keytype", key_type,
"valuetype", value_type);
+ printer->Annotate("gettername", field);
printer->Print(
" jspb.Message.getMapField(this, $index$, opt_noLazyCreate",
"index", JSFieldIndex(field));
@@ -2457,7 +2473,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
/* force_present = */ false,
/* singular_if_not_packed = */ false));
printer->Print(
- "$class$.prototype.get$name$ = function() {\n"
+ "$class$.prototype.$gettername$ = function() {\n"
" return /** @type{$type$} */ (\n"
" jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, "
"$index$$required$));\n"
@@ -2465,7 +2481,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"\n"
"\n",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "gettername", "get" + JSGetterName(options, field),
"type", JSFieldTypeAnnotation(options, field,
/* is_setter_argument = */ false,
/* force_present = */ false,
@@ -2475,9 +2491,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"wrapperclass", SubmessageTypeRef(options, field),
"required", (field->label() == FieldDescriptor::LABEL_REQUIRED ?
", 1" : ""));
+ printer->Annotate("gettername", field);
printer->Print(
"/** @param {$optionaltype$} value$returndoc$ */\n"
- "$class$.prototype.set$name$ = function(value) {\n"
+ "$class$.prototype.$settername$ = function(value) {\n"
" jspb.Message.set$oneoftag$$repeatedtag$WrapperField(",
"optionaltype",
JSFieldTypeAnnotation(options, field,
@@ -2486,9 +2503,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
/* singular_if_not_packed = */ false),
"returndoc", JSReturnDoc(options, field),
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "settername", "set" + JSGetterName(options, field),
"oneoftag", (field->containing_oneof() ? "Oneof" : ""),
"repeatedtag", (field->is_repeated() ? "Repeated" : ""));
+ printer->Annotate("settername", field);
printer->Print(
"this, $index$$oneofgroup$, value);$returnvalue$\n"
@@ -2540,9 +2558,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
}
printer->Print(
- "$class$.prototype.get$name$ = function() {\n",
+ "$class$.prototype.$gettername$ = function() {\n",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field));
+ "gettername", "get" + JSGetterName(options, field));
+ printer->Annotate("gettername", field);
if (untyped) {
printer->Print(
@@ -2610,24 +2629,27 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
// Proto3 non-repeated and non-map fields without presence use the
// setProto3*Field function.
printer->Print(
- "$class$.prototype.set$name$ = function(value) {\n"
+ "$class$.prototype.$settername$ = function(value) {\n"
" jspb.Message.setProto3$typetag$Field(this, $index$, "
"value);$returnvalue$\n"
"};\n"
"\n"
"\n",
- "class", GetMessagePath(options, field->containing_type()), "name",
- JSGetterName(options, field), "typetag", JSTypeTag(field), "index",
- JSFieldIndex(field), "returnvalue", JSReturnClause(field));
+ "class", GetMessagePath(options, field->containing_type()),
+ "settername", "set" + JSGetterName(options, field), "typetag",
+ JSTypeTag(field), "index", JSFieldIndex(field), "returnvalue",
+ JSReturnClause(field));
+ printer->Annotate("settername", field);
} else {
// Otherwise, use the regular setField function.
printer->Print(
- "$class$.prototype.set$name$ = function(value) {\n"
+ "$class$.prototype.$settername$ = function(value) {\n"
" jspb.Message.set$oneoftag$Field(this, $index$",
- "class", GetMessagePath(options, field->containing_type()), "name",
- JSGetterName(options, field), "oneoftag",
+ "class", GetMessagePath(options, field->containing_type()),
+ "settername", "set" + JSGetterName(options, field), "oneoftag",
(field->containing_oneof() ? "Oneof" : ""), "index",
JSFieldIndex(field));
+ printer->Annotate("settername", field);
printer->Print(
"$oneofgroup$, $type$value$rptvalueinit$$typeclose$);$returnvalue$\n"
"};\n"
@@ -2660,41 +2682,46 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
// fields with presence.
if (IsMap(options, field)) {
printer->Print(
- "$class$.prototype.clear$name$ = function() {\n"
- " this.get$name$().clear();$returnvalue$\n"
+ "$class$.prototype.$clearername$ = function() {\n"
+ " this.$gettername$().clear();$returnvalue$\n"
"};\n"
"\n"
"\n",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "clearername", "clear" + JSGetterName(options, field),
+ "gettername", "get" + JSGetterName(options, field),
"returnvalue", JSReturnClause(field));
+ printer->Annotate("clearername", field);
} else if (field->is_repeated() ||
(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
!field->is_required())) {
// Fields where we can delegate to the regular setter.
printer->Print(
- "$class$.prototype.clear$name$ = function() {\n"
- " this.set$name$($clearedvalue$);$returnvalue$\n"
+ "$class$.prototype.$clearername$ = function() {\n"
+ " this.$settername$($clearedvalue$);$returnvalue$\n"
"};\n"
"\n"
"\n",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "clearername", "clear" + JSGetterName(options, field),
+ "settername", "set" + JSGetterName(options, field),
"clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
"returnvalue", JSReturnClause(field));
+ printer->Annotate("clearername", field);
} else if (HasFieldPresence(options, field)) {
// Fields where we can't delegate to the regular setter because it doesn't
// accept "undefined" as an argument.
printer->Print(
- "$class$.prototype.clear$name$ = function() {\n"
+ "$class$.prototype.$clearername$ = function() {\n"
" jspb.Message.set$maybeoneof$Field(this, "
"$index$$maybeoneofgroup$, ",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "clearername", "clear" + JSGetterName(options, field),
"maybeoneof", (field->containing_oneof() ? "Oneof" : ""),
"maybeoneofgroup", (field->containing_oneof() ?
(", " + JSOneofArray(options, field)) : ""),
"index", JSFieldIndex(field));
+ printer->Annotate("clearername", field);
printer->Print(
"$clearedvalue$);$returnvalue$\n"
"};\n"
@@ -2710,14 +2737,15 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
" * Returns whether this field is set.\n"
" * @return {!boolean}\n"
" */\n"
- "$class$.prototype.has$name$ = function() {\n"
+ "$class$.prototype.$hasername$ = function() {\n"
" return jspb.Message.getField(this, $index$) != null;\n"
"};\n"
"\n"
"\n",
"class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field),
+ "hasername", "has" + JSGetterName(options, field),
"index", JSFieldIndex(field));
+ printer->Annotate("hasername", field);
}
}
@@ -2729,13 +2757,14 @@ void Generator::GenerateRepeatedPrimitiveHelperMethods(
" * @param {!$optionaltype$} value\n"
" * @param {number=} opt_index\n"
" */\n"
- "$class$.prototype.add$name$ = function(value, opt_index) {\n"
+ "$class$.prototype.$addername$ = function(value, opt_index) {\n"
" jspb.Message.addToRepeatedField(this, $index$",
- "class", GetMessagePath(options, field->containing_type()),
- "name", JSGetterName(options, field, BYTES_DEFAULT,
- /* drop_list = */ true),
+ "class", GetMessagePath(options, field->containing_type()), "addername",
+ "add" + JSGetterName(options, field, BYTES_DEFAULT,
+ /* drop_list = */ true),
"optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "index",
JSFieldIndex(field));
+ printer->Annotate("addername", field);
printer->Print(
"$oneofgroup$, $type$value$rptvalueinit$$typeclose$, opt_index);\n"
"};\n"
@@ -3133,8 +3162,10 @@ void Generator::GenerateEnum(const GeneratorOptions& options,
"/**\n"
" * @enum {number}\n"
" */\n"
- "$name$ = {\n",
- "name", GetEnumPath(options, enumdesc));
+ "$enumprefix$$name$ = {\n",
+ "enumprefix", GetEnumPathPrefix(options, enumdesc),
+ "name", enumdesc->name());
+ printer->Annotate("name", enumdesc);
for (int i = 0; i < enumdesc->value_count(); i++) {
const EnumValueDescriptor* value = enumdesc->value(i);
@@ -3143,6 +3174,7 @@ void Generator::GenerateEnum(const GeneratorOptions& options,
"name", ToEnumCase(value->name()),
"value", SimpleItoa(value->number()),
"comma", (i == enumdesc->value_count() - 1) ? "" : ",");
+ printer->Annotate("name", value);
}
printer->Print(
@@ -3282,6 +3314,12 @@ bool GeneratorOptions::ParseFromOptions(
return false;
}
one_output_file_per_input_file = true;
+ } else if (options[i].first == "annotate_code") {
+ if (!options[i].second.empty()) {
+ *error = "Unexpected option value for annotate_code";
+ return false;
+ }
+ annotate_code = true;
} else {
// Assume any other option is an output directory, as long as it is a bare
// `key` rather than a `key=value` option.
@@ -3582,16 +3620,27 @@ bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
options.output_dir + "/" + GetJSFilename(options, file->name());
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(context->Open(filename));
GOOGLE_CHECK(output.get());
- io::Printer printer(output.get(), '$');
+ GeneratedCodeInfo annotations;
+ io::AnnotationProtoCollector<GeneratedCodeInfo> annotation_collector(
+ &annotations);
+ io::Printer printer(output.get(), '$',
+ options.annotate_code ? &annotation_collector : NULL);
+
GenerateFile(options, &printer, file);
if (printer.failed()) {
return false;
}
+
+ if (options.annotate_code) {
+ const string meta_file = filename + ".meta";
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> info_output(
+ context->Open(meta_file));
+ annotations.SerializeToZeroCopyStream(info_output.get());
+ }
}
}
-
return true;
}