aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/js/js_generator.cc
diff options
context:
space:
mode:
authorGravatar Adam Cozzette <acozzette@google.com>2016-11-17 16:48:38 -0800
committerGravatar Adam Cozzette <acozzette@google.com>2016-11-17 16:59:59 -0800
commit5a76e633ea9b5adb215e93fdc11e1c0c08b3fc74 (patch)
tree0276f81f8848a05d84cd7e287b43d665e30f04e3 /src/google/protobuf/compiler/js/js_generator.cc
parente28286fa05d8327fd6c5aa70cfb3be558f0932b8 (diff)
Integrated internal changes from Google
Diffstat (limited to 'src/google/protobuf/compiler/js/js_generator.cc')
-rwxr-xr-xsrc/google/protobuf/compiler/js/js_generator.cc393
1 files changed, 213 insertions, 180 deletions
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 58597b4c..e6571f6f 100755
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -28,7 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "google/protobuf/compiler/js/js_generator.h"
+#include <google/protobuf/compiler/js/js_generator.h>
#include <assert.h>
#include <algorithm>
@@ -45,6 +45,7 @@
#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/compiler/js/well_known_types_embed.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
@@ -216,8 +217,13 @@ string GetNestedMessageName(const Descriptor* descriptor) {
if (descriptor == NULL) {
return "";
}
- return StripPrefixString(descriptor->full_name(),
- descriptor->file()->package());
+ string result =
+ StripPrefixString(descriptor->full_name(), descriptor->file()->package());
+ // Add a leading dot if one is not already present.
+ if (!result.empty() && result[0] != '.') {
+ result = "." + result;
+ }
+ return result;
}
// Returns the path prefix for a message or enumeration that
@@ -225,8 +231,8 @@ string GetNestedMessageName(const Descriptor* descriptor) {
string GetPrefix(const GeneratorOptions& options,
const FileDescriptor* file_descriptor,
const Descriptor* containing_type) {
- string prefix = GetPath(options, file_descriptor) +
- GetNestedMessageName(containing_type);
+ string prefix =
+ GetPath(options, file_descriptor) + GetNestedMessageName(containing_type);
if (!prefix.empty()) {
prefix += ".";
}
@@ -278,8 +284,8 @@ string MaybeCrossFileRef(const GeneratorOptions& options,
// Cross-file ref in CommonJS needs to use the module alias instead of
// the global name.
return ModuleAlias(to_message->file()->name()) +
- GetNestedMessageName(to_message->containing_type()) +
- "." + to_message->name();
+ GetNestedMessageName(to_message->containing_type()) + "." +
+ to_message->name();
} else {
// Within a single file we use a full name.
return GetPath(options, to_message);
@@ -309,8 +315,8 @@ char ToLowerASCII(char c) {
}
}
-vector<string> ParseLowerUnderscore(const string& input) {
- vector<string> words;
+std::vector<string> ParseLowerUnderscore(const string& input) {
+ std::vector<string> words;
string running = "";
for (int i = 0; i < input.size(); i++) {
if (input[i] == '_') {
@@ -328,8 +334,8 @@ vector<string> ParseLowerUnderscore(const string& input) {
return words;
}
-vector<string> ParseUpperCamel(const string& input) {
- vector<string> words;
+std::vector<string> ParseUpperCamel(const string& input) {
+ std::vector<string> words;
string running = "";
for (int i = 0; i < input.size(); i++) {
if (input[i] >= 'A' && input[i] <= 'Z' && !running.empty()) {
@@ -344,7 +350,7 @@ vector<string> ParseUpperCamel(const string& input) {
return words;
}
-string ToLowerCamel(const vector<string>& words) {
+string ToLowerCamel(const std::vector<string>& words) {
string result;
for (int i = 0; i < words.size(); i++) {
string word = words[i];
@@ -358,7 +364,7 @@ string ToLowerCamel(const vector<string>& words) {
return result;
}
-string ToUpperCamel(const vector<string>& words) {
+string ToUpperCamel(const std::vector<string>& words) {
string result;
for (int i = 0; i < words.size(); i++) {
string word = words[i];
@@ -927,16 +933,10 @@ string JSTypeName(const GeneratorOptions& options,
}
}
+// Used inside Google only -- do not remove.
bool UseBrokenPresenceSemantics(const GeneratorOptions& options,
const FieldDescriptor* field) {
- if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
- return options.broken_proto3_semantics;
- } else if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO2) {
- return false;
- } else {
- GOOGLE_LOG(FATAL) << "We can only handle syntax=proto2 and syntax=proto3.";
- return false;
- }
+ return false;
}
// Returns true for fields that return "null" from accessors when they are
@@ -1077,22 +1077,14 @@ string JSBinaryReadWriteMethodName(const FieldDescriptor* field,
string JSBinaryReaderMethodName(const GeneratorOptions& options,
const FieldDescriptor* field) {
- if (options.binary) {
- return "jspb.BinaryReader.prototype.read" +
- JSBinaryReadWriteMethodName(field, /* is_writer = */ false);
- } else {
- return "null";
- }
+ return "jspb.BinaryReader.prototype.read" +
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ false);
}
string JSBinaryWriterMethodName(const GeneratorOptions& options,
const FieldDescriptor* field) {
- if (options.binary) {
- return "jspb.BinaryWriter.prototype.write" +
- JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
- } else {
- return "null";
- }
+ return "jspb.BinaryWriter.prototype.write" +
+ JSBinaryReadWriteMethodName(field, /* is_writer = */ true);
}
string JSReturnClause(const FieldDescriptor* desc) {
@@ -1327,6 +1319,29 @@ bool HasExtensions(const FileDescriptor* file) {
return false;
}
+bool HasMap(const GeneratorOptions& options, const Descriptor* desc) {
+ for (int i = 0; i < desc->field_count(); i++) {
+ if (IsMap(options, desc->field(i))) {
+ return true;
+ }
+ }
+ for (int i = 0; i < desc->nested_type_count(); i++) {
+ if (HasMap(options, desc->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool FileHasMap(const GeneratorOptions& options, const FileDescriptor* desc) {
+ for (int i = 0; i < desc->message_type_count(); i++) {
+ if (HasMap(options, desc->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool IsExtendable(const Descriptor* desc) {
return desc->extension_range_count() > 0;
}
@@ -1398,19 +1413,19 @@ class FileDeduplicator {
return true;
}
- void GetAllowedSet(set<const void*>* allowed_set) {
+ void GetAllowedSet(std::set<const void*>* allowed_set) {
*allowed_set = allowed_descs_;
}
private:
bool error_on_conflict_;
- map<string, const void*> descs_by_filename_;
- set<const void*> allowed_descs_;
+ std::map<string, const void*> descs_by_filename_;
+ std::set<const void*> allowed_descs_;
};
void DepthFirstSearch(const FileDescriptor* file,
- vector<const FileDescriptor*>* list,
- set<const FileDescriptor*>* seen) {
+ std::vector<const FileDescriptor*>* list,
+ std::set<const FileDescriptor*>* seen) {
if (!seen->insert(file).second) {
return;
}
@@ -1428,7 +1443,7 @@ void DepthFirstSearch(const FileDescriptor* file,
// FileDescriptor is not in the given set.
class NotInSet {
public:
- explicit NotInSet(const set<const FileDescriptor*>& file_set)
+ explicit NotInSet(const std::set<const FileDescriptor*>& file_set)
: file_set_(file_set) {}
bool operator()(const FileDescriptor* file) {
@@ -1436,21 +1451,21 @@ class NotInSet {
}
private:
- const set<const FileDescriptor*>& file_set_;
+ const std::set<const FileDescriptor*>& file_set_;
};
// This function generates an ordering of the input FileDescriptors that matches
// the logic of the old code generator. The order is significant because two
// different input files can generate the same output file, and the last one
// needs to win.
-void GenerateJspbFileOrder(const vector<const FileDescriptor*>& input,
- vector<const FileDescriptor*>* ordered) {
+void GenerateJspbFileOrder(const std::vector<const FileDescriptor*>& input,
+ std::vector<const FileDescriptor*>* ordered) {
// First generate an ordering of all reachable files (including dependencies)
// with depth-first search. This mimics the behavior of --include_imports,
// which is what the old codegen used.
ordered->clear();
- set<const FileDescriptor*> seen;
- set<const FileDescriptor*> input_set;
+ std::set<const FileDescriptor*> seen;
+ std::set<const FileDescriptor*> input_set;
for (int i = 0; i < input.size(); i++) {
DepthFirstSearch(input[i], ordered, &seen);
input_set.insert(input[i]);
@@ -1467,10 +1482,10 @@ void GenerateJspbFileOrder(const vector<const FileDescriptor*>& input,
// only those to generate code.
bool GenerateJspbAllowedSet(const GeneratorOptions& options,
- const vector<const FileDescriptor*>& files,
- set<const void*>* allowed_set,
+ const std::vector<const FileDescriptor*>& files,
+ std::set<const void*>* allowed_set,
string* error) {
- vector<const FileDescriptor*> files_ordered;
+ std::vector<const FileDescriptor*> files_ordered;
GenerateJspbFileOrder(files, &files_ordered);
// Choose the last descriptor for each filename.
@@ -1538,7 +1553,7 @@ void Generator::FindProvidesForFile(const GeneratorOptions& options,
void Generator::FindProvides(const GeneratorOptions& options,
io::Printer* printer,
- const vector<const FileDescriptor*>& files,
+ const std::vector<const FileDescriptor*>& files,
std::set<string>* provided) const {
for (int i = 0; i < files.size(); i++) {
FindProvidesForFile(options, printer, files[i], provided);
@@ -1580,7 +1595,7 @@ void Generator::FindProvidesForEnum(const GeneratorOptions& options,
void Generator::FindProvidesForFields(
const GeneratorOptions& options,
io::Printer* printer,
- const vector<const FieldDescriptor*>& fields,
+ const std::vector<const FieldDescriptor*>& fields,
std::set<string>* provided) const {
for (int i = 0; i < fields.size(); i++) {
const FieldDescriptor* field = fields[i];
@@ -1629,18 +1644,20 @@ void Generator::GenerateRequiresForMessage(const GeneratorOptions& options,
GenerateRequiresImpl(options, printer, &required, &forwards, provided,
/* require_jspb = */ have_message,
- /* require_extension = */ HasExtensions(desc));
+ /* require_extension = */ HasExtensions(desc),
+ /* require_map = */ HasMap(options, desc));
}
void Generator::GenerateRequiresForLibrary(
const GeneratorOptions& options, io::Printer* printer,
- const vector<const FileDescriptor*>& files,
+ const std::vector<const FileDescriptor*>& files,
std::set<string>* provided) const {
GOOGLE_CHECK_EQ(options.import_style, GeneratorOptions::kImportClosure);
// For Closure imports we need to import every message type individually.
std::set<string> required;
std::set<string> forwards;
bool have_extensions = false;
+ bool have_map = false;
bool have_message = false;
for (int i = 0; i < files.size(); i++) {
@@ -1656,6 +1673,10 @@ void Generator::GenerateRequiresForLibrary(
have_extensions = true;
}
+ if (!have_map && FileHasMap(options, files[i])) {
+ have_map = true;
+ }
+
for (int j = 0; j < files[i]->extension_count(); j++) {
const FieldDescriptor* extension = files[i]->extension(j);
if (IgnoreField(extension)) {
@@ -1672,12 +1693,13 @@ void Generator::GenerateRequiresForLibrary(
GenerateRequiresImpl(options, printer, &required, &forwards, provided,
/* require_jspb = */ have_message,
- /* require_extension = */ have_extensions);
+ /* require_extension = */ have_extensions,
+ /* require_map = */ have_map);
}
void Generator::GenerateRequiresForExtensions(
const GeneratorOptions& options, io::Printer* printer,
- const vector<const FieldDescriptor*>& fields,
+ const std::vector<const FieldDescriptor*>& fields,
std::set<string>* provided) const {
std::set<string> required;
std::set<string> forwards;
@@ -1691,7 +1713,8 @@ void Generator::GenerateRequiresForExtensions(
GenerateRequiresImpl(options, printer, &required, &forwards, provided,
/* require_jspb = */ false,
- /* require_extension = */ fields.size() > 0);
+ /* require_extension = */ fields.size() > 0,
+ /* require_map = */ false);
}
void Generator::GenerateRequiresImpl(const GeneratorOptions& options,
@@ -1699,25 +1722,22 @@ void Generator::GenerateRequiresImpl(const GeneratorOptions& options,
std::set<string>* required,
std::set<string>* forwards,
std::set<string>* provided,
- bool require_jspb,
- bool require_extension) const {
+ bool require_jspb, bool require_extension,
+ bool require_map) const {
if (require_jspb) {
printer->Print(
- "goog.require('jspb.Message');\n");
- if (options.binary) {
- printer->Print(
- "goog.require('jspb.BinaryReader');\n"
- "goog.require('jspb.BinaryWriter');\n");
- }
+ "goog.require('jspb.Message');\n"
+ "goog.require('jspb.BinaryReader');\n"
+ "goog.require('jspb.BinaryWriter');\n");
}
if (require_extension) {
- if (options.binary) {
- printer->Print(
- "goog.require('jspb.ExtensionFieldBinaryInfo');\n");
- }
+ printer->Print("goog.require('jspb.ExtensionFieldBinaryInfo');\n");
printer->Print(
"goog.require('jspb.ExtensionFieldInfo');\n");
}
+ if (require_map) {
+ printer->Print("goog.require('jspb.Map');\n");
+ }
std::set<string>::iterator it;
for (it = required->begin(); it != required->end(); ++it) {
@@ -1839,14 +1859,13 @@ void Generator::GenerateClass(const GeneratorOptions& options,
GenerateClassToObject(options, printer, desc);
- if (options.binary) {
- // These must come *before* the extension-field info generation in
- // GenerateClassRegistration so that references to the binary
- // serialization/deserialization functions may be placed in the extension
- // objects.
- GenerateClassDeserializeBinary(options, printer, desc);
- GenerateClassSerializeBinary(options, printer, desc);
- }
+ // These must come *before* the extension-field info generation in
+ // GenerateClassRegistration so that references to the binary
+ // serialization/deserialization functions may be placed in the extension
+ // objects.
+ GenerateClassDeserializeBinary(options, printer, desc);
+ GenerateClassSerializeBinary(options, printer, desc);
+
GenerateClassRegistration(options, printer, desc);
GenerateClassFields(options, printer, desc);
if (IsExtendable(desc) && desc->full_name() != "google.protobuf.bridge.MessageSet") {
@@ -2143,8 +2162,20 @@ void Generator::GenerateClassFieldToObject(const GeneratorOptions& options,
"fieldname", JSObjectFieldName(options, field));
if (IsMap(options, field)) {
- printer->Print("(f = msg.get$name$()) ? f.toArray() : []",
- "name", JSGetterName(options, field));
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ // If the map values are of a message type, we must provide their static
+ // toObject() method; otherwise we pass undefined for that argument.
+ string value_to_object;
+ if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ value_to_object =
+ GetPath(options, value_field->message_type()) + ".toObject";
+ } else {
+ value_to_object = "undefined";
+ }
+ printer->Print(
+ "(f = msg.get$name$()) ? f.toObject(includeInstance, $valuetoobject$) "
+ ": []",
+ "name", JSGetterName(options, field), "valuetoobject", value_to_object);
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
// Message field.
if (field->is_repeated()) {
@@ -2217,14 +2248,27 @@ void Generator::GenerateClassFieldFromObject(
io::Printer* printer,
const FieldDescriptor* field) const {
if (IsMap(options, field)) {
- // `msg` is a newly-constructed message object that has not yet built any
- // map containers wrapping underlying arrays, so we can simply directly set
- // the array here without fear of a stale wrapper.
- printer->Print(
- " goog.isDef(obj.$name$) && "
- "jspb.Message.setField(msg, $index$, obj.$name$);\n",
- "name", JSObjectFieldName(options, field),
- "index", JSFieldIndex(field));
+ const FieldDescriptor* value_field = MapFieldValue(field);
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ // Since the map values are of message type, we have to do some extra work
+ // to recursively call fromObject() on them before setting the map field.
+ printer->Print(
+ " goog.isDef(obj.$name$) && jspb.Message.setWrapperField(\n"
+ " msg, $index$, jspb.Map.fromObject(obj.$name$, $fieldclass$, "
+ "$fieldclass$.fromObject));\n",
+ "name", JSObjectFieldName(options, field),
+ "index", JSFieldIndex(field),
+ "fieldclass", GetPath(options, value_field->message_type()));
+ } else {
+ // `msg` is a newly-constructed message object that has not yet built any
+ // map containers wrapping underlying arrays, so we can simply directly
+ // set the array here without fear of a stale wrapper.
+ printer->Print(
+ " goog.isDef(obj.$name$) && "
+ "jspb.Message.setField(msg, $index$, obj.$name$);\n",
+ "name", JSObjectFieldName(options, field),
+ "index", JSFieldIndex(field));
+ }
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
// Message field (singular or repeated)
if (field->is_repeated()) {
@@ -2358,7 +2402,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
printer->Print(",\n"
" $messageType$",
"messageType", GetPath(options, value_field->message_type()));
- } else if (options.binary) {
+ } else {
printer->Print(",\n"
" null");
}
@@ -2711,28 +2755,26 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
"\n",
"class", GetPath(options, desc));
- if (options.binary) {
- printer->Print(
- "\n"
- "/**\n"
- " * The extensions registered with this message class. This is a "
- "map of\n"
- " * extension field number to fieldInfo object.\n"
- " *\n"
- " * For example:\n"
- " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
- "ctor: proto.example.MyMessage} }\n"
- " *\n"
- " * fieldName contains the JsCompiler renamed field name property "
- "so that it\n"
- " * works in OPTIMIZED mode.\n"
- " *\n"
- " * @type {!Object.<number, jspb.ExtensionFieldBinaryInfo>}\n"
- " */\n"
- "$class$.extensionsBinary = {};\n"
- "\n",
- "class", GetPath(options, desc));
- }
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * The extensions registered with this message class. This is a "
+ "map of\n"
+ " * extension field number to fieldInfo object.\n"
+ " *\n"
+ " * For example:\n"
+ " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
+ "ctor: proto.example.MyMessage} }\n"
+ " *\n"
+ " * fieldName contains the JsCompiler renamed field name property "
+ "so that it\n"
+ " * works in OPTIMIZED mode.\n"
+ " *\n"
+ " * @type {!Object.<number, jspb.ExtensionFieldBinaryInfo>}\n"
+ " */\n"
+ "$class$.extensionsBinary = {};\n"
+ "\n",
+ "class", GetPath(options, desc));
}
}
@@ -2773,7 +2815,9 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
"class", GetPath(options, desc));
for (int i = 0; i < desc->field_count(); i++) {
- GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
+ if (!IgnoreField(desc->field(i))) {
+ GenerateClassDeserializeBinaryField(options, printer, desc->field(i));
+ }
}
printer->Print(
@@ -2873,44 +2917,36 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options,
const Descriptor* desc) const {
printer->Print(
"/**\n"
- " * Class method variant: serializes the given message to binary data\n"
- " * (in protobuf wire format), writing to the given BinaryWriter.\n"
- " * @param {!$class$} message\n"
- " * @param {!jspb.BinaryWriter} writer\n"
- " */\n"
- "$class$.serializeBinaryToWriter = function(message, "
- "writer) {\n"
- " message.serializeBinaryToWriter(writer);\n"
- "};\n"
- "\n"
- "\n"
- "/**\n"
" * Serializes the message to binary data (in protobuf wire format).\n"
" * @return {!Uint8Array}\n"
" */\n"
"$class$.prototype.serializeBinary = function() {\n"
" var writer = new jspb.BinaryWriter();\n"
- " this.serializeBinaryToWriter(writer);\n"
+ " $class$.serializeBinaryToWriter(this, writer);\n"
" return writer.getResultBuffer();\n"
"};\n"
"\n"
"\n"
"/**\n"
- " * Serializes the message to binary data (in protobuf wire format),\n"
- " * writing to the given BinaryWriter.\n"
+ " * Serializes the given message to binary data (in protobuf wire\n"
+ " * format), writing to the given BinaryWriter.\n"
+ " * @param {!$class$} message\n"
" * @param {!jspb.BinaryWriter} writer\n"
" */\n"
- "$class$.prototype.serializeBinaryToWriter = function (writer) {\n"
+ "$class$.serializeBinaryToWriter = function(message, "
+ "writer) {\n"
" var f = undefined;\n",
"class", GetPath(options, desc));
for (int i = 0; i < desc->field_count(); i++) {
- GenerateClassSerializeBinaryField(options, printer, desc->field(i));
+ if (!IgnoreField(desc->field(i))) {
+ GenerateClassSerializeBinaryField(options, printer, desc->field(i));
+ }
}
if (IsExtendable(desc)) {
printer->Print(
- " jspb.Message.serializeBinaryExtensions(this, writer,\n"
+ " jspb.Message.serializeBinaryExtensions(message, writer,\n"
" $extobj$Binary, $class$.prototype.getExtension);\n",
"extobj", JSExtensionsObjectName(options, desc->file(), desc),
"class", GetPath(options, desc));
@@ -2935,15 +2971,16 @@ void Generator::GenerateClassSerializeBinaryField(
/* singular_if_not_packed = */ false,
/* bytes_mode = */ BYTES_DEFAULT);
printer->Print(
- " f = /** @type {$type$} */ (jspb.Message.getField(this, $index$));\n",
+ " f = /** @type {$type$} */ "
+ "(jspb.Message.getField(message, $index$));\n",
"index", JSFieldIndex(field),
"type", typed_annotation);
} else {
printer->Print(
- " f = this.get$name$($nolazy$);\n",
+ " f = message.get$name$($nolazy$);\n",
"name", JSGetterName(options, field, BYTES_U8),
// No lazy creation for maps containers -- fastpath the empty case.
- "nolazy", (field->is_map()) ? "true" : "");
+ "nolazy", IsMap(options, field) ? "true" : "");
}
// Print an `if (condition)` statement that evaluates to true if the field
@@ -3102,35 +3139,30 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
string("null")),
"repeated", (field->is_repeated() ? "1" : "0"));
- if (options.binary) {
- printer->Print(
- "\n"
- "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
- " $class$.$name$,\n"
- " $binaryReaderFn$,\n"
- " $binaryWriterFn$,\n"
- " $binaryMessageSerializeFn$,\n"
- " $binaryMessageDeserializeFn$,\n",
- "extendName", JSExtensionsObjectName(options, field->file(),
- field->containing_type()),
- "index", SimpleItoa(field->number()),
- "class", extension_scope,
- "name", JSObjectFieldName(options, field),
- "binaryReaderFn", JSBinaryReaderMethodName(options, field),
- "binaryWriterFn", JSBinaryWriterMethodName(options, field),
- "binaryMessageSerializeFn",
- (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
- (SubmessageTypeRef(options, field) +
- ".serializeBinaryToWriter") : "undefined",
- "binaryMessageDeserializeFn",
- (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
- (SubmessageTypeRef(options, field) +
- ".deserializeBinaryFromReader") : "undefined");
-
- printer->Print(
- " $isPacked$);\n",
- "isPacked", (field->is_packed() ? "true" : "false"));
- }
+ printer->Print(
+ "\n"
+ "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
+ " $class$.$name$,\n"
+ " $binaryReaderFn$,\n"
+ " $binaryWriterFn$,\n"
+ " $binaryMessageSerializeFn$,\n"
+ " $binaryMessageDeserializeFn$,\n",
+ "extendName",
+ JSExtensionsObjectName(options, field->file(), field->containing_type()),
+ "index", SimpleItoa(field->number()), "class", extension_scope, "name",
+ JSObjectFieldName(options, field), "binaryReaderFn",
+ JSBinaryReaderMethodName(options, field), "binaryWriterFn",
+ JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
+ ? (SubmessageTypeRef(options, field) + ".serializeBinaryToWriter")
+ : "undefined",
+ "binaryMessageDeserializeFn",
+ (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
+ ? (SubmessageTypeRef(options, field) + ".deserializeBinaryFromReader")
+ : "undefined");
+
+ printer->Print(" $isPacked$);\n", "isPacked",
+ (field->is_packed() ? "true" : "false"));
printer->Print(
"// This registers the extension field with the extended class, so that\n"
@@ -3145,7 +3177,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
}
bool GeneratorOptions::ParseFromOptions(
- const vector< pair< string, string > >& options,
+ const std::vector< std::pair< string, string > >& options,
string* error) {
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "add_require_for_enums") {
@@ -3199,12 +3231,6 @@ bool GeneratorOptions::ParseFromOptions(
return false;
}
one_output_file_per_input_file = true;
- } else if (options[i].first == "broken_proto3_semantics") {
- if (!options[i].second.empty()) {
- *error = "Unexpected option value for broken_proto3_semantics";
- return false;
- }
- broken_proto3_semantics = true;
} else {
// Assume any other option is an output directory, as long as it is a bare
// `key` rather than a `key=value` option.
@@ -3218,13 +3244,12 @@ bool GeneratorOptions::ParseFromOptions(
if (import_style != kImportClosure &&
(add_require_for_enums || testonly || !library.empty() ||
- error_on_name_conflict || broken_proto3_semantics ||
- extension != ".js" || one_output_file_per_input_file)) {
+ error_on_name_conflict || extension != ".js" ||
+ one_output_file_per_input_file)) {
*error =
"The add_require_for_enums, testonly, library, error_on_name_conflict, "
- "broken_proto3_semantics, extension, and "
- "one_output_file_per_input_file options should only be used for "
- "import_style=closure";
+ "extension, and one_output_file_per_input_file options should only be "
+ "used for import_style=closure";
return false;
}
@@ -3250,7 +3275,7 @@ GeneratorOptions::OutputMode GeneratorOptions::output_mode() const {
void Generator::GenerateFilesInDepOrder(
const GeneratorOptions& options,
io::Printer* printer,
- const vector<const FileDescriptor*>& files) const {
+ const std::vector<const FileDescriptor*>& files) const {
// Build a std::set over all files so that the DFS can detect when it recurses
// into a dep not specified in the user's command line.
std::set<const FileDescriptor*> all_files(files.begin(), files.end());
@@ -3307,8 +3332,8 @@ void Generator::GenerateFile(const GeneratorOptions& options,
}
}
- set<string> provided;
- set<const FieldDescriptor*> extensions;
+ std::set<string> provided;
+ std::set<const FieldDescriptor*> extensions;
for (int i = 0; i < file->extension_count(); i++) {
// We honor the jspb::ignore option here only when working with
// Closure-style imports. Use of this option is discouraged and so we want
@@ -3324,7 +3349,7 @@ void Generator::GenerateFile(const GeneratorOptions& options,
FindProvidesForFile(options, printer, file, &provided);
GenerateProvides(options, printer, &provided);
- vector<const FileDescriptor*> files;
+ std::vector<const FileDescriptor*> files;
files.push_back(file);
if (options.import_style == GeneratorOptions::kImportClosure) {
GenerateRequiresForLibrary(options, printer, files, &provided);
@@ -3334,7 +3359,7 @@ void Generator::GenerateFile(const GeneratorOptions& options,
// Generate code for top-level extensions. Extensions nested inside messages
// are emitted inside GenerateClassesAndEnums().
- for (set<const FieldDescriptor*>::const_iterator it = extensions.begin();
+ for (std::set<const FieldDescriptor*>::const_iterator it = extensions.begin();
it != extensions.end(); ++it) {
GenerateExtension(options, printer, *it);
}
@@ -3343,13 +3368,21 @@ void Generator::GenerateFile(const GeneratorOptions& options,
printer->Print("goog.object.extend(exports, $package$);\n",
"package", GetPath(options, file));
}
+
+ // Emit well-known type methods.
+ for (FileToc* toc = well_known_types_js; toc->name != NULL; toc++) {
+ string name = string("google/protobuf/") + toc->name;
+ if (name == StripProto(file->name()) + ".js") {
+ printer->Print(toc->data);
+ }
+ }
}
-bool Generator::GenerateAll(const vector<const FileDescriptor*>& files,
+bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
const string& parameter,
GeneratorContext* context,
string* error) const {
- vector< pair< string, string > > option_pairs;
+ std::vector< std::pair< string, string > > option_pairs;
ParseGeneratorParameter(parameter, &option_pairs);
GeneratorOptions options;
if (!options.ParseFromOptions(option_pairs, error)) {
@@ -3367,7 +3400,7 @@ bool Generator::GenerateAll(const vector<const FileDescriptor*>& files,
// Pull out all extensions -- we need these to generate all
// provides/requires.
- vector<const FieldDescriptor*> extensions;
+ std::vector<const FieldDescriptor*> extensions;
for (int i = 0; i < files.size(); i++) {
for (int j = 0; j < files[i]->extension_count(); j++) {
const FieldDescriptor* extension = files[i]->extension(j);
@@ -3396,7 +3429,7 @@ bool Generator::GenerateAll(const vector<const FileDescriptor*>& files,
return false;
}
} else if (options.output_mode() == GeneratorOptions::kOneOutputFilePerType) {
- set<const void*> allowed_set;
+ std::set<const void*> allowed_set;
if (!GenerateJspbAllowedSet(options, files, &allowed_set, error)) {
return false;
}
@@ -3467,7 +3500,7 @@ bool Generator::GenerateAll(const vector<const FileDescriptor*>& files,
GenerateHeader(options, &printer);
std::set<string> provided;
- vector<const FieldDescriptor*> fields;
+ std::vector<const FieldDescriptor*> fields;
for (int j = 0; j < files[i]->extension_count(); j++) {
if (ShouldGenerateExtension(files[i]->extension(j))) {