63 "abstract",
"boolean",
"break",
"byte",
"case",
64 "catch",
"char",
"class",
"const",
"continue",
65 "debugger",
"default",
"delete",
"do",
"double",
66 "else",
"enum",
"export",
"extends",
"false",
67 "final",
"finally",
"float",
"for",
"function",
68 "goto",
"if",
"implements",
"import",
"in",
69 "instanceof",
"int",
"interface",
"long",
"native",
70 "new",
"null",
"package",
"private",
"protected",
71 "public",
"return",
"short",
"static",
"super",
72 "switch",
"synchronized",
"this",
"throw",
"throws",
73 "transient",
"try",
"typeof",
"var",
"void",
74 "volatile",
"while",
"with",
109 StrEndsWith(filename,
".protodevel") ?
".protodevel" :
".proto";
128 string GetRootPath(
const std::string& from_filename,
130 if (to_filename.find(
"google/protobuf") == 0) {
135 return "google-protobuf/";
138 size_t slashes =
std::count(from_filename.begin(), from_filename.end(),
'/');
143 for (
size_t i = 0;
i < slashes;
i++) {
163 return basename +
"_pb";
170 if (!
options.namespace_prefix.empty()) {
171 return options.namespace_prefix;
172 }
else if (!file->
package().empty()) {
173 return "proto." + file->
package();
190 if (!result.empty() && result[0] !=
'.') {
191 result =
"." + result;
202 GetNestedMessageName(containing_type);
243 from_file != to_message->
file()) {
246 return ModuleAlias(to_message->
file()->
name()) +
251 return GetMessagePath(
options, to_message);
270 char ToLowerASCII(
char c) {
271 if (c >=
'A' && c <=
'Z') {
272 return (c -
'A') +
'a';
279 std::vector<std::string>
words;
281 for (
int i = 0;
i <
input.size();
i++) {
298 std::vector<std::string>
words;
300 for (
int i = 0;
i <
input.size();
i++) {
315 for (
int i = 0;
i <
words.size();
i++) {
317 if (
i == 0 && (word[0] >=
'A' && word[0] <=
'Z')) {
318 word[0] = (word[0] -
'A') +
'a';
319 }
else if (
i != 0 && (word[0] >=
'a' && word[0] <=
'z')) {
320 word[0] = (word[0] -
'a') +
'A';
329 for (
int i = 0;
i <
words.size();
i++) {
331 if (word[0] >=
'a' && word[0] <=
'z') {
332 word[0] = (word[0] -
'a') +
'A';
344 result.reserve(
input.size());
346 for (
int i = 0;
i <
input.size();
i++) {
348 result.push_back(
input[
i] -
'a' +
'A');
350 result.push_back(
input[
i]);
359 result.reserve(
input.size());
361 for (
int i = 0;
i <
input.size();
i++) {
363 result.push_back(
input[
i] -
'A' +
'a');
365 result.push_back(
input[
i]);
383 bool with_filename) {
386 (with_filename ? (
"_" + snake_name +
"_extensions") :
"") +
387 options.GetFileNameExtension();
397 static std::map<const Descriptor*, std::string>* long_name_dict =
398 new std::map<const Descriptor*, std::string>();
405 std::vector<std::string> all_message_names;
407 if (one_desc->containing_type() ==
nullptr) {
408 all_message_names.push_back(
ToLower(one_desc->name()));
411 sort(all_message_names.begin(), all_message_names.end());
412 for (
auto one_message : all_message_names) {
413 if (!filename_base.empty()) {
414 filename_base +=
"_";
416 filename_base += one_message;
418 if (filename_base.size() + package_base.size() > 200) {
420 (*long_name_dict).end()) {
424 StrCat(snake_name,
"_long_sccs_",
425 static_cast<uint64>((*long_name_dict).size()));
429 return options.output_dir +
"/" + package_base + filename_base +
430 options.GetFileNameExtension();
438 return options.output_dir +
"/" +
452 if (!
field->is_extension())
return false;
454 return file->
name() ==
"net/proto2/proto/descriptor.proto" ||
455 file->
name() ==
"google/protobuf/descriptor.proto";
463 return IgnoreExtensionField(
field);
468 bool IgnoreMessage(
const Descriptor*
d) {
return d->options().map_entry(); }
473 if (!IgnoreField(oneof->
field(
i))) {
482 bool is_map,
bool drop_list) {
485 result = is_upper_camel
486 ? ToUpperCamel(ParseUpperCamel(
field->message_type()->name()))
487 : ToLowerCamel(ParseUpperCamel(
field->message_type()->name()));
489 result = is_upper_camel ? ToUpperCamel(ParseLowerUnderscore(
field->name()))
490 : ToLowerCamel(ParseLowerUnderscore(
field->name()));
492 if (is_map ||
field->is_map()) {
495 }
else if (!drop_list &&
field->is_repeated()) {
508 if (IsReserved(
name)) {
514 std::string JSByteGetterSuffix(BytesMode bytes_mode) {
515 switch (bytes_mode) {
532 BytesMode bytes_mode = BYTES_DEFAULT,
533 bool drop_list =
false) {
538 std::string suffix = JSByteGetterSuffix(bytes_mode);
539 if (!suffix.empty()) {
540 name +=
"_as" + suffix;
543 if (
name ==
"Extension" ||
name ==
"JsPbMessageId") {
552 return ToUpperCamel(ParseLowerUnderscore(oneof->
name()));
566 if (parent_type !=
NULL) {
584 if (!IgnoreField(
f)) {
602 if ((*
bytes & 0x80) == 0) {
604 }
else if ((*
bytes & 0xe0) == 0xc0) {
606 }
else if ((*
bytes & 0xf0) == 0xe0) {
625 return ((
bytes[0] & 0x1F) << 6) | ((
bytes[1] & 0x3F) << 0);
627 return ((
bytes[0] & 0x0F) << 12) | ((
bytes[1] & 0x3F) << 6) |
628 ((
bytes[2] & 0x3F) << 0);
641 for (
size_t i = 0;
i < in.size();
i += decoded) {
644 size_t have_bytes = in.size() -
i;
646 static_cast<uint8>(in[
i]),
647 static_cast<uint8>(((
i + 1) < in.size()) ? in[
i + 1] : 0),
648 static_cast<uint8>(((
i + 2) < in.size()) ? in[
i + 2] : 0),
650 codepoint = DecodeUTF8Codepoint(
bytes, &have_bytes);
651 if (have_bytes == 0) {
654 decoded = have_bytes;
698 if (codepoint >= 0x20 && codepoint <= 0x7e) {
699 *out +=
static_cast<char>(codepoint);
700 }
else if (codepoint >= 0x100) {
712 static const char* kAlphabet =
713 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
716 for (
size_t i = 0;
i < in.size();
i += 3) {
717 int value = (in[
i] << 16) | (((
i + 1) < in.size()) ? (in[
i + 1] << 8) : 0) |
718 (((
i + 2) < in.size()) ? (in[
i + 2] << 0) : 0);
719 result += kAlphabet[(
value >> 18) & 0x3f];
720 result += kAlphabet[(
value >> 12) & 0x3f];
721 if ((
i + 1) < in.size()) {
722 result += kAlphabet[(
value >> 6) & 0x3f];
726 if ((
i + 2) < in.size()) {
727 result += kAlphabet[(
value >> 0) & 0x3f];
741 if (result ==
"inf") {
743 }
else if (result ==
"-inf") {
745 }
else if (result ==
"nan") {
753 std::string::size_type exp_pos = result.find(
'e');
754 if (exp_pos != std::string::npos) {
759 if (mantissa.find(
'.') == std::string::npos) {
764 bool exp_neg =
false;
765 if (!exponent.empty() && exponent[0] ==
'+') {
766 exponent = exponent.substr(1);
767 }
else if (!exponent.empty() && exponent[0] ==
'-') {
769 exponent = exponent.substr(1);
773 while (exponent.size() > 1 && exponent[0] ==
'0') {
774 exponent = exponent.substr(1);
777 return mantissa +
"E" +
string(exp_neg ?
"-" :
"") + exponent;
782 if (result.find(
'.') == std::string::npos) {
791 return PostProcessFloat(result);
796 return PostProcessFloat(result);
802 switch (
field->cpp_type()) {
815 return IsIntegralFieldWithStringJSType(
field) ? (
"\"" + orig +
"\"") : orig;
819 if (
field->is_repeated()) {
823 switch (
field->cpp_type()) {
825 return MaybeNumberString(
field,
831 return MaybeNumberString(
835 return MaybeNumberString(
field,
839 return MaybeNumberString(
843 return StrCat(
field->default_value_enum()->number());
845 return field->default_value_bool() ?
"true" :
"false";
847 return FloatToString(
field->default_value_float());
849 return DoubleToString(
field->default_value_double());
853 bool is_valid = EscapeJSString(
field->default_value_string(), &out);
857 <<
" was truncated since it contained invalid UTF-8 or"
858 " codepoints outside the basic multilingual plane.";
860 return "\"" + out +
"\"";
862 return "\"" + EscapeBase64(
field->default_value_string()) +
"\"";
873 switch (
field->type()) {
916 return IsIntegralFieldWithStringJSType(
field) ?
"string" :
"number";
921 BytesMode bytes_mode) {
923 switch (bytes_mode) {
925 return "(string|Uint8Array)";
939 switch (
field->cpp_type()) {
943 return JSIntegerTypeName(
field);
945 return JSIntegerTypeName(
field);
947 return JSIntegerTypeName(
field);
949 return JSIntegerTypeName(
field);
978 field->is_optional()) {
984 !
field->has_default_value();
1027 field->has_default_value();
1033 return type ==
"undefined" ||
type ==
"string" ||
type ==
"number" ||
1039 bool is_setter_argument,
bool force_present,
1040 bool singular_if_not_packed,
1041 BytesMode bytes_mode = BYTES_DEFAULT,
1042 bool force_singular =
false) {
1045 if (!force_singular &&
field->is_repeated() &&
1046 (
field->is_packed() || !singular_if_not_packed)) {
1048 bytes_mode == BYTES_DEFAULT) {
1049 jstype =
"(Array<!Uint8Array>|Array<string>)";
1051 if (!IsPrimitive(jstype)) {
1052 jstype =
"!" + jstype;
1054 jstype =
"Array<" + jstype +
">";
1058 bool is_null_or_undefined =
false;
1060 if (is_setter_argument) {
1062 jstype =
"?" + jstype;
1063 is_null_or_undefined =
true;
1067 jstype +=
"|undefined";
1068 is_null_or_undefined =
true;
1070 }
else if (force_present) {
1074 jstype =
"?" + jstype;
1075 is_null_or_undefined =
true;
1079 if (!is_null_or_undefined && !IsPrimitive(jstype)) {
1080 jstype =
"!" + jstype;
1088 if (
name[0] >=
'a' &&
name[0] <=
'z') {
1091 return IsIntegralFieldWithStringJSType(
field) ? (
name +
"String") :
name;
1097 if (
field->is_packed()) {
1099 }
else if (is_writer &&
field->is_repeated()) {
1107 return "jspb.BinaryReader.prototype.read" +
1108 JSBinaryReadWriteMethodName(
field,
false);
1113 if (
field->containing_type() &&
1114 field->containing_type()->options().message_set_wire_format()) {
1115 return "jspb.BinaryWriter.prototype.writeMessageSet";
1117 return "jspb.BinaryWriter.prototype.write" +
1118 JSBinaryReadWriteMethodName(
field,
true);
1126 switch (
desc->type()) {
1140 if (IsIntegralFieldWithStringJSType(
desc)) {
1166 for (
int i = 0;
i <
desc->field_count();
i++) {
1167 if (
desc->field(
i)->is_repeated() && !
desc->field(
i)->is_map()) {
1174 static const char* kRepeatedFieldArrayName =
".repeatedFields_";
1179 ? (GetMessagePath(
options,
desc) + kRepeatedFieldArrayName)
1184 for (
int i = 0;
i <
desc->field_count();
i++) {
1185 if (
desc->field(
i)->containing_oneof()) {
1192 static const char* kOneofGroupArrayName =
".oneofGroups_";
1196 return HasOneofFields(
desc)
1197 ? (GetMessagePath(
options,
desc) + kOneofGroupArrayName)
1203 std::vector<std::string> numbers;
1204 for (
int i = 0;
i <
desc->field_count();
i++) {
1205 if (
desc->field(
i)->is_repeated() && !
desc->field(
i)->is_map()) {
1206 numbers.push_back(JSFieldIndex(
desc->field(
i)));
1209 return "[" +
Join(numbers,
",") +
"]";
1214 std::vector<std::string> oneof_entries;
1215 for (
int i = 0;
i <
desc->oneof_decl_count();
i++) {
1217 if (IgnoreOneof(oneof)) {
1221 std::vector<std::string> oneof_fields;
1223 if (IgnoreField(oneof->
field(j))) {
1226 oneof_fields.push_back(JSFieldIndex(oneof->
field(j)));
1228 oneof_entries.push_back(
"[" +
Join(oneof_fields,
",") +
"]");
1230 return "[" +
Join(oneof_entries,
",") +
"]";
1235 return OneofFieldsArrayName(
options,
field->containing_type()) +
"[" +
1236 JSOneofIndex(
field->containing_oneof()) +
"]";
1247 ?
field->enum_type()->full_name()
1248 :
field->message_type()->full_name();
1254 for (
int i = 0;
i <
type.size() &&
i < containing_type.size();
i++) {
1255 if (
type[
i] != containing_type[
i]) {
1269 if (
desc->full_name() ==
"google.protobuf.bridge.MessageSet") {
1271 return "jspb.Message.messageSetExtensions";
1273 return MaybeCrossFileRef(
options, from_file,
desc) +
".extensions";
1277 static const int kMapKeyField = 1;
1278 static const int kMapValueField = 2;
1281 assert(
field->is_map());
1282 return field->message_type()->FindFieldByNumber(kMapKeyField);
1286 assert(
field->is_map());
1287 return field->message_type()->FindFieldByNumber(kMapValueField);
1292 if (
field->is_map()) {
1308 field->is_repeated() ?
"repeated"
1309 : (
field->is_optional() ?
"optional" :
"required");
1331 " * Note that Uint8Array is not supported on all browsers.\n"
1332 " * @see http://caniuse.com/Uint8Array\n";
1338 return field->is_extension() && !IgnoreField(
field);
1342 for (
int i = 0;
i <
desc->extension_count();
i++) {
1343 if (ShouldGenerateExtension(
desc->extension(
i))) {
1347 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
1348 if (HasExtensions(
desc->nested_type(
i))) {
1357 if (ShouldGenerateExtension(file->
extension(
i))) {
1370 for (
int i = 0;
i <
desc->field_count();
i++) {
1371 if (
desc->field(
i)->is_map()) {
1375 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
1384 for (
int i = 0;
i <
desc->message_type_count();
i++) {
1393 return desc->extension_range_count() > 0;
1399 static const int kDefaultPivot = 500;
1402 int max_field_number = 0;
1403 for (
int i = 0;
i <
desc->field_count();
i++) {
1404 if (!IgnoreField(
desc->field(
i)) &&
1405 desc->field(
i)->number() > max_field_number) {
1406 max_field_number =
desc->field(
i)->number();
1412 pivot = ((max_field_number + 1) < kDefaultPivot) ? (max_field_number + 1)
1423 if (
field->is_repeated() ||
field->is_map()) {
1446 class FileDeduplicator {
1457 bool AddFile(
const std::pair<std::string, std::string> filenames,
1462 *
error =
"Name conflict: file name " + filenames.first +
1463 " would be generated by two descriptors";
1478 void GetAllowedMap(std::map<const void*, std::string>* allowed_set) {
1493 std::vector<const FileDescriptor*>* list,
1494 std::set<const FileDescriptor*>* seen) {
1495 if (!seen->insert(file).second) {
1500 for (
int i = 0;
i < file->dependency_count();
i++) {
1501 DepthFirstSearch(file->dependency(
i), list, seen);
1505 list->push_back(file);
1512 explicit NotInSet(
const std::set<const FileDescriptor*>& file_set)
1527 void GenerateJspbFileOrder(
const std::vector<const FileDescriptor*>&
input,
1528 std::vector<const FileDescriptor*>* ordered) {
1533 std::set<const FileDescriptor*> seen;
1534 std::set<const FileDescriptor*> input_set;
1535 for (
int i = 0;
i <
input.size();
i++) {
1536 DepthFirstSearch(
input[
i], ordered, &seen);
1537 input_set.insert(
input[
i]);
1542 std::remove_if(ordered->begin(), ordered->end(), NotInSet(input_set)),
1550 struct DepsGenerator {
1551 std::vector<const Descriptor*> operator()(
const Descriptor*
desc)
const {
1552 std::vector<const Descriptor*> deps;
1554 if (d) deps.push_back(d);
1556 for (
int i = 0;
i <
desc->field_count();
i++) {
1557 if (!IgnoreField(
desc->field(
i))) {
1558 maybe_add(
desc->field(
i)->message_type());
1561 for (
int i = 0;
i <
desc->extension_count();
i++) {
1562 maybe_add(
desc->extension(
i)->message_type());
1563 maybe_add(
desc->extension(
i)->containing_type());
1565 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
1566 maybe_add(
desc->nested_type(
i));
1568 maybe_add(
desc->containing_type());
1574 bool GenerateJspbAllowedMap(
const GeneratorOptions&
options,
1575 const std::vector<const FileDescriptor*>& files,
1576 std::map<const void*, std::string>* allowed_set,
1577 SCCAnalyzer<DepsGenerator>* analyzer,
1579 std::vector<const FileDescriptor*> files_ordered;
1580 GenerateJspbFileOrder(files, &files_ordered);
1583 FileDeduplicator dedup(
options);
1584 std::set<const SCC*> added;
1585 for (
int i = 0;
i < files_ordered.size();
i++) {
1586 for (
int j = 0; j < files_ordered[
i]->message_type_count(); j++) {
1588 if (added.insert(analyzer->GetSCC(
desc)).second &&
1591 GetMessagesFileName(
options, analyzer->GetSCC(
desc),
false),
1592 GetMessagesFileName(
options, analyzer->GetSCC(
desc),
true)),
1597 for (
int j = 0; j < files_ordered[
i]->enum_type_count(); j++) {
1599 if (!dedup.AddFile(std::make_pair(GetEnumFileName(
options,
desc,
false),
1607 bool has_extension =
false;
1609 for (
int j = 0; j < files_ordered[
i]->extension_count(); j++) {
1610 if (ShouldGenerateExtension(files_ordered[
i]->
extension(j))) {
1611 has_extension =
true;
1615 if (has_extension) {
1618 GetExtensionFileName(
options, files_ordered[
i],
false),
1619 GetExtensionFileName(
options, files_ordered[
i],
true)),
1620 files_ordered[
i],
error)) {
1626 dedup.GetAllowedMap(allowed_set);
1634 io::Printer* printer) {
1637 annotations.SerializeToString(&meta_content);
1643 printer->Print(
"\n// Below is base64 encoded GeneratedCodeInfo proto");
1644 printer->Print(
"\n// $encoded_proto$\n",
"encoded_proto", meta_64);
1656 if (file !=
nullptr) {
1657 printer->
Print(
"// source: $filename$\n",
"filename", file->
name());
1661 " * @fileoverview\n"
1663 " * @suppress {messageConventions} JS Compiler reports an "
1664 "error if a variable or\n"
1665 " * field starts with 'MSG_' and isn't a translatable "
1669 "// GENERATED CODE -- DO NOT EDIT!\n"
1676 std::set<std::string>* provided)
const {
1687 const std::vector<const FileDescriptor*>& files,
1688 std::set<std::string>* provided)
const {
1689 for (
int i = 0;
i < files.size();
i++) {
1693 printer->
Print(
"\n");
1698 std::set<std::string>* provided) {
1700 JSOneofName(oneof) +
"Case";
1701 provided->insert(
name);
1706 std::set<std::string>* provided) {
1707 if (HasOneofFields(
desc)) {
1708 for (
int i = 0;
i <
desc->oneof_decl_count();
i++) {
1709 if (IgnoreOneof(
desc->oneof_decl(
i))) {
1720 std::set<std::string>* provided)
const {
1721 if (IgnoreMessage(
desc)) {
1726 provided->insert(
name);
1728 for (
int i = 0;
i <
desc->enum_type_count();
i++) {
1734 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
1741 std::set<std::string>* provided)
const {
1743 provided->insert(
name);
1748 const std::vector<const FieldDescriptor*>&
fields,
1749 std::set<std::string>* provided)
const {
1750 for (
int i = 0;
i <
fields.size();
i++) {
1753 if (IgnoreField(
field)) {
1759 provided->insert(
name);
1765 std::set<std::string>* provided)
const {
1766 for (std::set<std::string>::iterator
it = provided->begin();
1767 it != provided->end(); ++
it) {
1769 printer->
Print(
"goog.provide('$name$');\n",
"name", *
it);
1784 namespaceObject.erase(0, 6);
1785 printer->
Print(
"goog.exportSymbol('$name$', null, proto);\n",
"name",
1788 printer->
Print(
"goog.exportSymbol('$name$', null, global);\n",
"name",
1797 std::set<std::string>* provided)
const {
1798 std::set<std::string> required;
1799 std::set<std::string> forwards;
1800 bool have_message =
false;
1801 bool has_extension =
false;
1802 bool has_map =
false;
1804 if (
desc->containing_type() ==
nullptr) {
1807 has_extension = (has_extension || HasExtensions(
desc));
1820 const std::vector<const FileDescriptor*>& files,
1821 std::set<std::string>* provided)
const {
1824 std::set<std::string> required;
1825 std::set<std::string> forwards;
1826 bool have_extensions =
false;
1827 bool have_map =
false;
1828 bool have_message =
false;
1830 for (
int i = 0;
i < files.size();
i++) {
1831 for (
int j = 0; j < files[
i]->message_type_count(); j++) {
1833 if (!IgnoreMessage(
desc)) {
1839 if (!have_extensions && HasExtensions(files[
i])) {
1840 have_extensions =
true;
1843 if (!have_map && FileHasMap(
options, files[
i])) {
1847 for (
int j = 0; j < files[
i]->extension_count(); j++) {
1853 "google.protobuf.bridge.MessageSet") {
1857 have_extensions =
true;
1869 const std::vector<const FieldDescriptor*>&
fields,
1870 std::set<std::string>* provided)
const {
1871 std::set<std::string> required;
1872 std::set<std::string> forwards;
1873 for (
int i = 0;
i <
fields.size();
i++) {
1875 if (IgnoreField(
field)) {
1889 std::set<std::string>* required,
1890 std::set<std::string>* forwards,
1891 std::set<std::string>* provided,
1892 bool require_jspb,
bool require_extension,
1893 bool require_map)
const {
1895 required->insert(
"jspb.Message");
1896 required->insert(
"jspb.BinaryReader");
1897 required->insert(
"jspb.BinaryWriter");
1899 if (require_extension) {
1900 required->insert(
"jspb.ExtensionFieldBinaryInfo");
1901 required->insert(
"jspb.ExtensionFieldInfo");
1904 required->insert(
"jspb.Map");
1907 std::set<std::string>::iterator
it;
1908 for (
it = required->begin();
it != required->end(); ++
it) {
1909 if (provided->find(*
it) != provided->end()) {
1912 printer->
Print(
"goog.require('$name$');\n",
"name", *
it);
1915 printer->
Print(
"\n");
1917 for (
it = forwards->begin();
it != forwards->end(); ++
it) {
1918 if (provided->find(*
it) != provided->end()) {
1921 printer->
Print(
"goog.forwardDeclare('$name$');\n",
"name", *
it);
1931 std::set<std::string>* required,
1932 std::set<std::string>* forwards,
1933 bool* have_message)
const {
1936 *have_message =
true;
1937 for (
int i = 0;
i <
desc->field_count();
i++) {
1939 if (IgnoreField(
field)) {
1946 for (
int i = 0;
i <
desc->extension_count();
i++) {
1948 if (IgnoreField(
field)) {
1954 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
1962 std::set<std::string>* required,
1963 std::set<std::string>* forwards)
const {
1967 !(
field->is_extension() &&
field->extension_scope() ==
nullptr)) {
1968 if (
options.add_require_for_enums) {
1969 required->insert(GetEnumPath(
options,
field->enum_type()));
1971 forwards->insert(GetEnumPath(
options,
field->enum_type()));
1974 if (!IgnoreMessage(
field->message_type())) {
1975 required->insert(GetMessagePath(
options,
field->message_type()));
1982 std::set<std::string>* required, std::set<std::string>* forwards)
const {
1983 if (
field->containing_type()->full_name() !=
"google.protobuf.bridge.MessageSet") {
1984 required->insert(GetMessagePath(
options,
field->containing_type()));
1992 printer->
Print(
"goog.setTestOnly();\n\n");
1994 printer->
Print(
"\n");
2015 if (IgnoreMessage(
desc)) {
2020 printer->
Print(
"\n");
2036 for (
int i = 0;
i <
desc->enum_type_count();
i++) {
2039 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
2048 for (
int i = 0;
i <
desc->extension_count();
i++) {
2060 " * Generated by JsPbCodeGenerator.\n"
2061 " * @param {Array=} opt_data Optional initial data array, typically "
2063 " * server response, or constructed directly in Javascript. The array "
2065 " * in place and becomes part of the constructed object. It is not "
2067 " * If no data is provided, the constructed object will be empty, but "
2070 " * @extends {jspb.Message}\n"
2073 "$classprefix$$classname$ = function(opt_data) {\n",
2074 "classprefix", GetMessagePathPrefix(
options,
desc),
"classname",
2079 " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, "
2080 "$rptfields$, $oneoffields$);\n",
2082 !message_id.empty() ? (
"'" + message_id +
"'")
2083 : (IsResponse(
desc) ?
"''" :
"0"),
2084 "pivot", GetPivot(
desc),
"rptfields",
2085 RepeatedFieldsArrayName(
options,
desc),
"oneoffields",
2089 "goog.inherits($classname$, jspb.Message);\n"
2090 "if (goog.DEBUG && !COMPILED) {\n"
2097 " $classname$.displayName = '$classname$';\n"
2111 for (
int i = 0;
i <
desc->nested_type_count();
i++) {
2112 if (!IgnoreMessage(
desc->nested_type(
i))) {
2125 " * List of repeated fields within this message type.\n"
2126 " * @private {!Array<number>}\n"
2129 "$classname$$rptfieldarray$ = $rptfields$;\n"
2131 "classname", GetMessagePath(
options,
desc),
"rptfieldarray",
2132 kRepeatedFieldArrayName,
"rptfields",
2136 if (HasOneofFields(
desc)) {
2139 " * Oneof group definitions for this message. Each group defines the "
2141 " * numbers belonging to that group. When of these fields' value is "
2143 " * other fields in the group are cleared. During deserialization, if "
2145 " * fields are encountered for a group, only the last value seen will "
2147 " * @private {!Array<!Array<number>>}\n"
2150 "$classname$$oneofgrouparray$ = $oneofgroups$;\n"
2152 "classname", GetMessagePath(
options,
desc),
"oneofgrouparray",
2153 kOneofGroupArrayName,
"oneofgroups", OneofGroupList(
desc));
2155 for (
int i = 0;
i <
desc->oneof_decl_count();
i++) {
2156 if (IgnoreOneof(
desc->oneof_decl(
i))) {
2170 "$class$.prototype.messageXid = xid('$class$');\n",
2179 " * @enum {number}\n"
2181 "$classname$.$oneof$Case = {\n"
2182 " $upcase$_NOT_SET: 0",
2184 JSOneofName(oneof),
"upcase", ToEnumCase(oneof->
name()));
2187 if (IgnoreField(oneof->
field(
i))) {
2193 " $upcase$: $number$",
2194 "upcase", ToEnumCase(oneof->
field(
i)->
name()),
"number",
2195 JSFieldIndex(oneof->
field(
i)));
2204 " * @return {$class$.$oneof$Case}\n"
2206 "$class$.prototype.get$oneof$Case = function() {\n"
2207 " return /** @type {$class$.$oneof$Case} */(jspb.Message."
2208 "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n"
2212 JSOneofName(oneof),
"oneofindex", JSOneofIndex(oneof));
2221 "if (jspb.Message.GENERATE_TO_OBJECT) {\n"
2223 " * Creates an object representation of this proto.\n"
2224 " * Field names that are reserved in JavaScript and will be renamed to "
2226 " * Optional fields that are not set will be set to undefined.\n"
2227 " * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.\n"
2228 " * For the list of reserved names please see:\n"
2229 " * net/proto2/compiler/js/internal/generator.cc#kKeyword.\n"
2230 " * @param {boolean=} opt_includeInstance Deprecated. whether to include "
2232 " * JSPB instance for transitional soy proto support:\n"
2233 " * http://goto/soy-param-migration\n"
2234 " * @return {!Object}\n"
2236 "$classname$.prototype.toObject = function(opt_includeInstance) {\n"
2237 " return $classname$.toObject(opt_includeInstance, this);\n"
2242 " * Static version of the {@see toObject} method.\n"
2243 " * @param {boolean|undefined} includeInstance Deprecated. Whether to "
2245 " * the JSPB instance for transitional soy proto support:\n"
2246 " * http://goto/soy-param-migration\n"
2247 " * @param {!$classname$} msg The msg instance to transform.\n"
2248 " * @return {!Object}\n"
2249 " * @suppress {unusedLocalVariables} f is only used for nested messages\n"
2251 "$classname$.toObject = function(includeInstance, msg) {\n"
2256 for (
int i = 0;
i <
desc->field_count();
i++) {
2258 if (IgnoreField(
field)) {
2263 printer->
Print(
",\n ");
2265 printer->
Print(
"\n ");
2273 printer->
Print(
"\n };\n\n");
2275 printer->
Print(
"\n\n };\n\n");
2280 " jspb.Message.toObjectExtension(/** @type {!jspb.Message} */ (msg), "
2282 " $extObject$, $class$.prototype.getExtension,\n"
2283 " includeInstance);\n",
2289 " if (includeInstance) {\n"
2290 " obj.$$jspbMessageInstance = msg;\n"
2301 const char* obj_reference,
2303 bool use_default)
const {
2304 const bool is_float_or_double =
2309 const string with_default = use_default ?
"WithDefault" :
"";
2310 const string default_arg =
2311 use_default ?
StrCat(
", ", JSFieldDefault(
field)) :
"";
2312 const string cardinality =
field->is_repeated() ?
"Repeated" :
"";
2314 if (is_float_or_double) {
2315 type =
"FloatingPoint";
2332 if (is_float_or_double && !
field->is_repeated() && !use_default) {
2334 "jspb.Message.getOptionalFloatingPointField($obj$, "
2335 "$index$$default$)",
2336 "obj", obj_reference,
"index", JSFieldIndex(
field),
"default",
2340 "jspb.Message.get$cardinality$$type$Field$with_default$($obj$, "
2341 "$index$$default$)",
2342 "cardinality", cardinality,
"type",
type,
"with_default", with_default,
2343 "obj", obj_reference,
"index", JSFieldIndex(
field),
"default",
2351 printer->
Print(
"$fieldname$: ",
"fieldname",
2354 if (
field->is_map()) {
2363 value_to_object =
"undefined";
2366 "(f = msg.get$name$()) ? f.toObject(includeInstance, $valuetoobject$) "
2368 "name", JSGetterName(
options,
field),
"valuetoobject", value_to_object);
2371 if (
field->is_repeated()) {
2374 "jspb.Message.toObjectList(msg.get$getter$(),\n"
2375 " $type$.toObject, includeInstance)",
2381 "(f = msg.get$getter$()) && "
2382 "$type$.toObject(includeInstance, f)",
2388 printer->
Print(
"msg.get$getter$()",
"getter",
2391 bool use_default =
field->has_default_value();
2411 printer->
Print(
"(f = ");
2415 printer->
Print(
") == null ? undefined : f");
2429 " * The raw object form of $messageName$ as accepted by the `fromObject` "
2433 "$typeName$ = function() {\n",
2434 "messageName",
desc->name(),
"typeName", type_name);
2436 for (
int i = 0;
i <
desc->field_count();
i++) {
2438 printer->
Print(
"\n");
2441 " /** @type {$fieldType$|undefined} */\n"
2442 " this.$fieldName$;\n",
2443 "fieldName", JSObjectFieldName(
options,
desc->field(
i)),
2448 printer->
Print(
"};\n\n");
2454 printer->
Print(
"if (jspb.Message.GENERATE_FROM_OBJECT) {\n\n");
2460 " * Loads data from an object into a new instance of this proto.\n"
2461 " * @param {!$classname$.ObjectFormat} obj\n"
2462 " * The object representation of this proto to load the data from.\n"
2463 " * @return {!$classname$}\n"
2465 "$classname$.fromObject = function(obj) {\n"
2466 " var msg = new $classname$();\n",
2469 for (
int i = 0;
i <
desc->field_count();
i++) {
2471 if (!IgnoreField(
field)) {
2485 if (
field->is_map()) {
2491 " obj.$name$ && jspb.Message.setWrapperField(\n"
2492 " msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, "
2493 "$fieldclass$.fromObject));\n",
2495 JSFieldIndex(
field),
"fieldclass",
2503 "jspb.Message.setField(msg, $index$, obj.$name$);\n",
2505 JSFieldIndex(
field));
2509 if (
field->is_repeated()) {
2513 "jspb.Message.setRepeatedWrapperField(\n"
2514 " msg, $index$, obj.$name$.map(\n"
2515 " $fieldclass$.fromObject));\n",
2517 JSFieldIndex(
field),
"fieldclass",
2522 " obj.$name$ && jspb.Message.setWrapperField(\n"
2523 " msg, $index$, $fieldclass$.fromObject(obj.$name$));\n",
2530 " obj.$name$ != null && jspb.Message.setField(msg, $index$, "
2533 JSFieldIndex(
field));
2541 for (
int i = 0;
i <
desc->extension_count();
i++) {
2543 if (ShouldGenerateExtension(
extension)) {
2553 for (
int i = 0;
i <
desc->field_count();
i++) {
2554 if (!IgnoreField(
desc->field(
i))) {
2571 " * This is a type-conversion wrapper around `get$defname$()`\n"
2572 " * @return {$type$}\n"
2574 "$class$.prototype.get$name$ = function() {\n"
2575 " return /** @type {$type$} */ (jspb.Message.bytes$list$As$suffix$(\n"
2576 " this.get$defname$()));\n"
2580 "fielddef", FieldDefinition(
options,
field),
"comment",
2581 FieldComments(
field, bytes_mode),
"type",
type,
"class",
2582 GetMessagePath(
options,
field->containing_type()),
"name",
2584 field->is_repeated() ?
"List" :
"",
"suffix",
2585 JSByteGetterSuffix(bytes_mode),
"defname",
2592 if (
field->is_map()) {
2597 JSFieldTypeAnnotation(
options, key_field,
2602 JSFieldTypeAnnotation(
options, value_field,
2610 " * @param {boolean=} opt_noLazyCreate Do not create the map if\n"
2611 " * empty, instead returning `undefined`\n"
2612 " * @return {!jspb.Map<$keytype$,$valuetype$>}\n"
2617 "$class$.prototype.$gettername$ = function(opt_noLazyCreate) {\n"
2618 " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n",
2619 "class", GetMessagePath(
options,
field->containing_type()),
2624 " jspb.Message.getMapField(this, $index$, opt_noLazyCreate",
2625 "index", JSFieldIndex(
field));
2638 printer->
Print(
"));\n");
2652 " * @return {$type$}\n"
2654 "fielddef", FieldDefinition(
options,
field),
"comment",
2655 FieldComments(
field, BYTES_DEFAULT),
"type",
2661 "$class$.prototype.$gettername$ = function() {\n"
2662 " return /** @type{$type$} */ (\n"
2663 " jspb.Message.get$rpt$WrapperField(this, $wrapperclass$, "
2664 "$index$$required$));\n"
2668 "class", GetMessagePath(
options,
field->containing_type()),
2669 "gettername",
"get" + JSGetterName(
options,
field),
"type",
2674 "rpt", (
field->is_repeated() ?
"Repeated" :
""),
"index",
2680 "/** @param {$optionaltype$} value$returndoc$ */\n"
2681 "$class$.prototype.$settername$ = function(value) {\n"
2682 " jspb.Message.set$oneoftag$$repeatedtag$WrapperField(",
2689 GetMessagePath(
options,
field->containing_type()),
"settername",
2691 (
field->containing_oneof() ?
"Oneof" :
""),
"repeatedtag",
2692 (
field->is_repeated() ?
"Repeated" :
""));
2696 "this, $index$$oneofgroup$, value);$returnvalue$\n"
2700 "index", JSFieldIndex(
field),
"oneofgroup",
2703 "returnvalue", JSReturnClause(
field));
2705 if (
field->is_repeated()) {
2718 BytesMode bytes_mode =
2731 " * @return {?} Raw field, untyped.\n"
2738 " * @return {$type$}\n"
2740 "fielddef", FieldDefinition(
options,
field),
"comment",
2741 FieldComments(
field, bytes_mode),
"type", typed_annotation);
2744 printer->
Print(
"$class$.prototype.$gettername$ = function() {\n",
"class",
2750 printer->
Print(
" return ");
2752 printer->
Print(
" return /** @type {$type$} */ (",
"type",
2756 bool use_default = !ReturnsNullWhenUnset(
options,
field);
2759 if (untyped && !
field->has_default_value()) {
2760 use_default =
false;
2765 if (
field->is_repeated()) {
2766 use_default =
false;
2793 " * @param {*} value$returndoc$\n"
2798 "/** @param {$optionaltype$} value$returndoc$ */\n",
"optionaltype",
2812 "$class$.prototype.$settername$ = function(value) {\n"
2813 " jspb.Message.setProto3$typetag$Field(this, $index$, "
2814 "value);$returnvalue$\n"
2818 "class", GetMessagePath(
options,
field->containing_type()),
2819 "settername",
"set" + JSGetterName(
options,
field),
"typetag",
2820 JSTypeTag(
field),
"index", JSFieldIndex(
field),
"returnvalue",
2821 JSReturnClause(
field));
2826 "$class$.prototype.$settername$ = function(value) {\n"
2827 " jspb.Message.set$oneoftag$Field(this, $index$",
2828 "class", GetMessagePath(
options,
field->containing_type()),
2829 "settername",
"set" + JSGetterName(
options,
field),
"oneoftag",
2830 (
field->containing_oneof() ?
"Oneof" :
""),
"index",
2831 JSFieldIndex(
field));
2834 "$oneofgroup$, $type$value$rptvalueinit$$typeclose$);$returnvalue$\n"
2839 untyped ?
"/** @type{string|number|boolean|Array|undefined} */(" :
"",
2840 "typeclose", untyped ?
")" :
"",
"oneofgroup",
2843 "returnvalue", JSReturnClause(
field),
"rptvalueinit",
2844 (
field->is_repeated() ?
" || []" :
""));
2850 " * Clears the value.$returndoc$\n"
2855 if (
field->is_repeated()) {
2862 if (
field->is_map()) {
2866 " * Clears values from the map. The map will be non-null."
2869 "$class$.prototype.$clearername$ = function() {\n"
2870 " this.$gettername$().clear();$returnvalue$\n"
2875 "class", GetMessagePath(
options,
field->containing_type()),
2878 "returnvalue", JSReturnClause(
field));
2881 }
else if (
field->is_repeated() ||
2883 !
field->is_required())) {
2888 " * $jsdoc$$returndoc$\n"
2890 "$class$.prototype.$clearername$ = function() {\n"
2891 " this.$settername$($clearedvalue$);$returnvalue$\n"
2895 "jsdoc",
field->is_repeated()
2896 ?
"Clears the list making it empty but non-null."
2897 :
"Clears the message field making it undefined.",
2899 "class", GetMessagePath(
options,
field->containing_type()),
2902 "clearedvalue", (
field->is_repeated() ?
"[]" :
"undefined"),
2903 "returnvalue", JSReturnClause(
field));
2912 " * Clears the field making it undefined.$returndoc$\n"
2914 "$class$.prototype.$clearername$ = function() {\n"
2915 " jspb.Message.set$maybeoneof$Field(this, "
2916 "$index$$maybeoneofgroup$, ",
2918 "class", GetMessagePath(
options,
field->containing_type()),
2920 "maybeoneof", (
field->containing_oneof() ?
"Oneof" :
""),
2921 "maybeoneofgroup", (
field->containing_oneof()
2924 "index", JSFieldIndex(
field));
2928 "$clearedvalue$);$returnvalue$\n"
2932 "clearedvalue", (
field->is_repeated() ?
"[]" :
"undefined"),
2933 "returnvalue", JSReturnClause(
field));
2939 " * Returns whether this field is set.\n"
2940 " * @return {boolean}\n"
2942 "$class$.prototype.$hasername$ = function() {\n"
2943 " return jspb.Message.getField(this, $index$) != null;\n"
2947 "class", GetMessagePath(
options,
field->containing_type()),
"hasername",
2959 " * @param {$optionaltype$} value\n"
2960 " * @param {number=} opt_index$returndoc$\n"
2962 "$class$.prototype.$addername$ = function(value, opt_index) {\n"
2963 " jspb.Message.addToRepeatedField(this, $index$",
2964 "class", GetMessagePath(
options,
field->containing_type()),
"addername",
2968 JSFieldTypeAnnotation(
2975 "index", JSFieldIndex(
field),
2979 "$oneofgroup$, $type$value$rptvalueinit$$typeclose$, "
2980 "opt_index);$returnvalue$\n"
2984 "type", untyped ?
"/** @type{string|number|boolean|!Uint8Array} */(" :
"",
2985 "typeclose", untyped ?
")" :
"",
"oneofgroup",
2988 "returnvalue", JSReturnClause(
field));
2997 " * @param {!$optionaltype$=} opt_value\n"
2998 " * @param {number=} opt_index\n"
2999 " * @return {!$optionaltype$}\n"
3001 "$class$.prototype.$addername$ = function(opt_value, opt_index) {\n"
3002 " return jspb.Message.addTo$repeatedtag$WrapperField(",
3003 "optionaltype", JSTypeName(
options,
field, BYTES_DEFAULT),
"class",
3004 GetMessagePath(
options,
field->containing_type()),
"addername",
3007 "repeatedtag", (
field->is_repeated() ?
"Repeated" :
""));
3011 "this, $index$$oneofgroup$, opt_value, $ctor$, opt_index);\n"
3015 "index", JSFieldIndex(
field),
"oneofgroup",
3017 "ctor", GetMessagePath(
options,
field->message_type()));
3027 " * The extensions registered with this message class. This is a "
3029 " * extension field number to fieldInfo object.\n"
3032 " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
3033 "ctor: proto.example.MyMessage} }\n"
3035 " * fieldName contains the JsCompiler renamed field name property "
3037 " * works in OPTIMIZED mode.\n"
3039 " * @type {!Object<number, jspb.ExtensionFieldInfo>}\n"
3041 "$class$.extensions = {};\n"
3048 " * The extensions registered with this message class. This is a "
3050 " * extension field number to fieldInfo object.\n"
3053 " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
3054 "ctor: proto.example.MyMessage} }\n"
3056 " * fieldName contains the JsCompiler renamed field name property "
3058 " * works in OPTIMIZED mode.\n"
3060 " * @type {!Object<number, jspb.ExtensionFieldBinaryInfo>}\n"
3062 "$class$.extensionsBinary = {};\n"
3077 " * Deserializes binary data (in protobuf wire format).\n"
3078 " * @param {jspb.ByteSource} bytes The bytes to deserialize.\n"
3079 " * @return {!$class$}\n"
3081 "$class$.deserializeBinary = function(bytes) {\n"
3082 " var reader = new jspb.BinaryReader(bytes);\n"
3083 " var msg = new $class$;\n"
3084 " return $class$.deserializeBinaryFromReader(msg, reader);\n"
3089 " * Deserializes binary data (in protobuf wire format) from the\n"
3090 " * given reader into the given message object.\n"
3091 " * @param {!$class$} msg The message object to deserialize into.\n"
3092 " * @param {!jspb.BinaryReader} reader The BinaryReader to use.\n"
3093 " * @return {!$class$}\n"
3095 "$class$.deserializeBinaryFromReader = function(msg, reader) {\n"
3096 " while (reader.nextField()) {\n",
3099 " if (reader.isEndGroup()) {\n"
3102 " var field = reader.getFieldNumber();\n"
3103 " switch (field) {\n");
3105 for (
int i = 0;
i <
desc->field_count();
i++) {
3106 if (!IgnoreField(
desc->field(
i))) {
3111 printer->
Print(
" default:\n");
3114 " jspb.Message.readBinaryExtension(msg, reader,\n"
3115 " $extobj$Binary,\n"
3116 " $class$.prototype.getExtension,\n"
3117 " $class$.prototype.setExtension);\n"
3124 " reader.skipField();\n"
3142 if (
field->is_map()) {
3146 " var value = msg.get$name$();\n"
3147 " reader.readMessage(value, function(message, reader) {\n",
3151 " jspb.Map.deserializeBinary(message, reader, "
3152 "$keyReaderFn$, $valueReaderFn$",
3153 "keyReaderFn", JSBinaryReaderMethodName(
options, key_field),
3154 "valueReaderFn", JSBinaryReaderMethodName(
options, value_field));
3157 printer->
Print(
", $messageType$.deserializeBinaryFromReader",
3161 printer->
Print(
", null");
3163 printer->
Print(
", $defaultKey$",
"defaultKey", JSFieldDefault(key_field));
3164 printer->
Print(
");\n");
3165 printer->
Print(
" });\n");
3169 " var value = new $fieldclass$;\n"
3170 " reader.read$msgOrGroup$($grpfield$value,"
3171 "$fieldclass$.deserializeBinaryFromReader);\n",
3172 "fieldclass", SubmessageTypeRef(
options,
field),
"msgOrGroup",
3180 " var value = /** @type {$fieldtype$} */ "
3181 "(reader.read$reader$());\n",
3186 JSBinaryReadWriteMethodName(
field,
false));
3189 if (
field->is_repeated() && !
field->is_packed()) {
3191 " msg.add$name$(value);\n",
"name",
3197 printer->
Print(
" msg.set$name$(value);\n",
"name",
3202 printer->
Print(
" break;\n");
3210 " * Serializes the message to binary data (in protobuf wire format).\n"
3211 " * @return {!Uint8Array}\n"
3213 "$class$.prototype.serializeBinary = function() {\n"
3214 " var writer = new jspb.BinaryWriter();\n"
3215 " $class$.serializeBinaryToWriter(this, writer);\n"
3216 " return writer.getResultBuffer();\n"
3221 " * Serializes the given message to binary data (in protobuf wire\n"
3222 " * format), writing to the given BinaryWriter.\n"
3223 " * @param {!$class$} message\n"
3224 " * @param {!jspb.BinaryWriter} writer\n"
3225 " * @suppress {unusedLocalVariables} f is only used for nested messages\n"
3227 "$class$.serializeBinaryToWriter = function(message, "
3229 " var f = undefined;\n",
3232 for (
int i = 0;
i <
desc->field_count();
i++) {
3233 if (!IgnoreField(
desc->field(
i))) {
3240 " jspb.Message.serializeBinaryExtensions(message, writer,\n"
3241 " $extobj$Binary, $class$.prototype.getExtension);\n",
3242 "extobj", JSExtensionsObjectName(
options,
desc->file(),
desc),
"class",
3264 " f = /** @type {$type$} */ "
3265 "(jspb.Message.getField(message, $index$));\n",
3266 "index", JSFieldIndex(
field),
"type", typed_annotation);
3269 " f = message.get$name$($nolazy$);\n",
"name",
3272 "nolazy",
field->is_map() ?
"true" :
"");
3277 if (
field->is_map()) {
3278 printer->
Print(
" if (f && f.getLength() > 0) {\n");
3279 }
else if (
field->is_repeated()) {
3280 printer->
Print(
" if (f.length > 0) {\n");
3283 printer->
Print(
" if (f != null) {\n");
3288 switch (
field->cpp_type()) {
3293 if (IsIntegralFieldWithStringJSType(
field)) {
3298 printer->
Print(
" if (parseInt(f, 10) !== 0) {\n");
3300 printer->
Print(
" if (f !== 0) {\n");
3308 printer->
Print(
" if (f !== 0.0) {\n");
3311 printer->
Print(
" if (f) {\n");
3314 printer->
Print(
" if (f.length > 0) {\n");
3324 if (
field->is_map()) {
3328 " f.serializeBinary($index$, writer, "
3329 "$keyWriterFn$, $valueWriterFn$",
3331 JSBinaryWriterMethodName(
options, key_field),
"valueWriterFn",
3332 JSBinaryWriterMethodName(
options, value_field));
3335 printer->
Print(
", $messageType$.serializeBinaryToWriter",
"messageType",
3339 printer->
Print(
");\n");
3342 " writer.write$method$(\n"
3345 "method", JSBinaryReadWriteMethodName(
field,
true),
3352 " $submsg$.serializeBinaryToWriter\n",
3355 printer->
Print(
"\n");
3358 printer->
Print(
" );\n");
3362 printer->
Print(
" }\n");
3370 " * @enum {number}\n"
3372 "$enumprefix$$name$ = {\n",
3373 "enumprefix", GetEnumPathPrefix(
options, enumdesc),
"name",
3375 printer->
Annotate(
"name", enumdesc);
3379 printer->
Print(
" $name$: $value$$comma$\n",
"name",
3380 ToEnumCase(
value->name()),
"value",
3395 (
field->extension_scope()
3403 " * A tuple of {field number, class constructor} for the extension\n"
3404 " * field named `$nameInComment$`.\n"
3405 " * @type {!jspb.ExtensionFieldInfo<$extensionType$>}\n"
3407 "$class$.$name$ = new jspb.ExtensionFieldInfo(\n",
3408 "nameInComment", extension_object_name,
"name", extension_object_name,
3409 "class", extension_scope,
"extensionType",
3419 " /** @type {?function((boolean|undefined),!jspb.Message=): "
3423 "index",
StrCat(
field->number()),
"name", extension_object_name,
3432 "repeated", (
field->is_repeated() ?
"1" :
"0"));
3436 "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
3437 " $class$.$name$,\n"
3438 " $binaryReaderFn$,\n"
3439 " $binaryWriterFn$,\n"
3440 " $binaryMessageSerializeFn$,\n"
3441 " $binaryMessageDeserializeFn$,\n",
3444 "index",
StrCat(
field->number()),
"class", extension_scope,
"name",
3445 extension_object_name,
"binaryReaderFn",
3446 JSBinaryReaderMethodName(
options,
field),
"binaryWriterFn",
3447 JSBinaryWriterMethodName(
options,
field),
"binaryMessageSerializeFn",
3449 ? (SubmessageTypeRef(
options,
field) +
".serializeBinaryToWriter")
3451 "binaryMessageDeserializeFn",
3453 ? (SubmessageTypeRef(
options,
field) +
".deserializeBinaryFromReader")
3456 printer->
Print(
" $isPacked$);\n",
"isPacked",
3457 (
field->is_packed() ?
"true" :
"false"));
3460 "// This registers the extension field with the extended class, so that\n"
3461 "// toObject() will function correctly.\n"
3462 "$extendName$[$index$] = $class$.$name$;\n"
3466 "index",
StrCat(
field->number()),
"class", extension_scope,
"name",
3467 extension_object_name);
3471 const std::vector<std::pair<std::string, std::string> >&
options,
3476 *
error =
"Unexpected option value for add_require_for_enums";
3482 *
error =
"Unexpected option value for binary";
3488 *
error =
"Unexpected option value for testonly";
3494 *
error =
"Unexpected option value for error_on_name_conflict";
3505 if (
options[
i].second ==
"closure") {
3507 }
else if (
options[
i].second ==
"commonjs") {
3509 }
else if (
options[
i].second ==
"commonjs_strict") {
3511 }
else if (
options[
i].second ==
"browser") {
3513 }
else if (
options[
i].second ==
"es6") {
3516 *
error =
"Unknown import style " +
options[
i].second +
", expected " +
3517 "one of: closure, commonjs, browser, es6.";
3521 }
else if (
options[
i].
first ==
"one_output_file_per_input_file") {
3523 *
error =
"Unexpected option value for one_output_file_per_input_file";
3529 *
error =
"Unexpected option value for annotate_code";
3549 "The add_require_for_enums, testonly, library, error_on_name_conflict, "
3550 "extension, and one_output_file_per_input_file options should only be "
3551 "used for import_style=closure";
3576 const std::vector<const FileDescriptor*>& files)
const {
3579 std::set<const FileDescriptor*> all_files(files.begin(), files.end());
3581 std::set<const FileDescriptor*> generated;
3582 for (
int i = 0;
i < files.size();
i++) {
3590 std::set<const FileDescriptor*>* generated)
const {
3592 if (generated->find(
root) != generated->end()) {
3595 generated->insert(
root);
3598 for (
int i = 0;
i <
root->dependency_count();
i++) {
3606 if (all_files->find(
root) != all_files->end()) {
3614 bool use_short_name)
const {
3617 GetJSFilename(
options, use_short_name
3618 ? file->
name().substr(file->
name().rfind(
'/'))
3620 std::unique_ptr<io::ZeroCopyOutputStream>
output(context->
Open(filename));
3626 options.annotate_code ? &annotation_collector :
nullptr);
3635 EmbedCodeAnnotations(annotations, &printer);
3649 printer->
Print(
"var jspb = require('google-protobuf');\n");
3650 printer->
Print(
"var goog = jspb;\n");
3654 printer->
Print(
"var proto = {};\n\n");
3656 printer->
Print(
"var global = Function('return this')();\n\n");
3662 "var $alias$ = require('$file$');\n"
3663 "goog.object.extend(proto, $alias$);\n",
3664 "alias", ModuleAlias(
name),
"file",
3669 std::set<std::string> provided;
3670 std::set<const FieldDescriptor*> extensions;
3679 provided.insert(GetNamespace(
options, file) +
"." +
3686 std::vector<const FileDescriptor*> files;
3687 files.push_back(file);
3696 for (std::set<const FieldDescriptor*>::const_iterator
it = extensions.begin();
3697 it != extensions.end(); ++
it) {
3703 !provided.empty()) {
3704 printer->
Print(
"goog.object.extend(exports, $package$);\n",
"package",
3707 printer->
Print(
"goog.object.extend(exports, proto);\n",
"package",
3715 printer->
Print(toc->data);
3724 std::vector<std::pair<std::string, std::string> > option_pairs;
3735 options.GetFileNameExtension();
3736 std::unique_ptr<io::ZeroCopyOutputStream>
output(context->
Open(filename));
3743 options.annotate_code ? &annotation_collector :
nullptr);
3747 std::vector<const FieldDescriptor*> extensions;
3748 for (
int i = 0;
i < files.size();
i++) {
3749 for (
int j = 0; j < files[
i]->extension_count(); j++) {
3755 if (files.size() == 1) {
3761 std::set<std::string> provided;
3770 for (
int i = 0;
i < extensions.size();
i++) {
3771 if (ShouldGenerateExtension(extensions[
i])) {
3780 EmbedCodeAnnotations(annotations, &printer);
3783 std::set<const Descriptor*> have_printed;
3785 std::map<const void*, std::string> allowed_map;
3786 if (!GenerateJspbAllowedMap(
options, files, &allowed_map, &analyzer,
3791 bool generated =
false;
3792 for (
int i = 0;
i < files.size();
i++) {
3795 if (IsWellKnownTypeFile(file)) {
3804 if (have_printed.count(
desc) ||
3805 allowed_map.count(analyzer.
GetSCC(
desc)) == 0) {
3812 std::unique_ptr<io::ZeroCopyOutputStream>
output(
3813 context->
Open(filename));
3820 options.annotate_code ? &annotation_collector :
nullptr);
3824 std::set<std::string> provided;
3826 if (one_desc->containing_type() ==
nullptr) {
3835 if (one_desc->containing_type() ==
nullptr) {
3841 if (one_desc->containing_type() ==
nullptr) {
3847 have_printed.insert(one_desc);
3854 EmbedCodeAnnotations(annotations, &printer);
3859 if (allowed_map.count(enumdesc) == 0) {
3864 const std::string& filename = allowed_map[enumdesc];
3865 std::unique_ptr<io::ZeroCopyOutputStream>
output(
3866 context->
Open(filename));
3873 options.annotate_code ? &annotation_collector :
nullptr);
3877 std::set<std::string> provided;
3888 EmbedCodeAnnotations(annotations, &printer);
3893 if (allowed_map.count(file) == 1) {
3897 std::unique_ptr<io::ZeroCopyOutputStream>
output(
3898 context->
Open(filename));
3905 options.annotate_code ? &annotation_collector :
nullptr);
3909 std::set<std::string> provided;
3910 std::vector<const FieldDescriptor*>
fields;
3912 for (
int j = 0; j < files[
i]->extension_count(); j++) {
3913 if (ShouldGenerateExtension(files[
i]->
extension(j))) {
3923 for (
int j = 0; j < files[
i]->extension_count(); j++) {
3924 if (ShouldGenerateExtension(files[
i]->
extension(j))) {
3929 EmbedCodeAnnotations(annotations, &printer);
3935 "empty_no_content_void_file" +
3936 options.GetFileNameExtension();
3937 std::unique_ptr<io::ZeroCopyOutputStream>
output(context->
Open(filename));
3942 for (
int i = 0;
i < files.size();
i++) {