|
@@ -28,8 +28,6 @@
|
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
-//#PY25 compatible generated code for GAE.
|
|
|
-// Copyright 2007 Google Inc. All Rights Reserved.
|
|
|
// Author: robinson@google.com (Will Robinson)
|
|
|
//
|
|
|
// This module outputs pure-Python protocol message classes that will
|
|
@@ -185,8 +183,6 @@ void PrintTopBoilerplate(io::Printer* printer, const FileDescriptor* file,
|
|
|
"# -*- coding: utf-8 -*-\n"
|
|
|
"# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
|
|
|
"# source: $filename$\n"
|
|
|
- "\nimport sys\n_b=sys.version_info[0]<3 and (lambda x:x) or (lambda "
|
|
|
- "x:x.encode('latin1'))" //##PY25
|
|
|
"\n",
|
|
|
"filename", file->name());
|
|
|
if (HasTopLevelEnums(file)) {
|
|
@@ -272,14 +268,10 @@ std::string StringifyDefaultValue(const FieldDescriptor& field) {
|
|
|
case FieldDescriptor::CPPTYPE_ENUM:
|
|
|
return StrCat(field.default_value_enum()->number());
|
|
|
case FieldDescriptor::CPPTYPE_STRING:
|
|
|
- //##!PY25 return "b\"" + CEscape(field.default_value_string())
|
|
|
- //+
|
|
|
- //##!PY25 (field.type() != FieldDescriptor::TYPE_STRING ? "\""
|
|
|
- //:
|
|
|
- //##!PY25 "\".decode('utf-8')");
|
|
|
- return "_b(\"" + CEscape(field.default_value_string()) + //##PY25
|
|
|
- (field.type() != FieldDescriptor::TYPE_STRING ? "\")" : //##PY25
|
|
|
- "\").decode('utf-8')"); //##PY25
|
|
|
+ return "b\"" + CEscape(field.default_value_string()) +
|
|
|
+ (field.type() != FieldDescriptor::TYPE_STRING
|
|
|
+ ? "\""
|
|
|
+ : "\".decode('utf-8')");
|
|
|
case FieldDescriptor::CPPTYPE_MESSAGE:
|
|
|
return "None";
|
|
|
}
|
|
@@ -305,13 +297,29 @@ std::string StringifySyntax(FileDescriptor::Syntax syntax) {
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
-Generator::Generator() : file_(NULL) {}
|
|
|
+Generator::Generator() : file_(nullptr) {}
|
|
|
|
|
|
Generator::~Generator() {}
|
|
|
|
|
|
bool Generator::Generate(const FileDescriptor* file,
|
|
|
const std::string& parameter,
|
|
|
GeneratorContext* context, std::string* error) const {
|
|
|
+ // -----------------------------------------------------------------
|
|
|
+ // parse generator options
|
|
|
+ bool cpp_generated_lib_linked = false;
|
|
|
+
|
|
|
+ std::vector<std::pair<std::string, std::string> > options;
|
|
|
+ ParseGeneratorParameter(parameter, &options);
|
|
|
+
|
|
|
+ for (int i = 0; i < options.size(); i++) {
|
|
|
+ if (options[i].first == "cpp_generated_lib_linked") {
|
|
|
+ cpp_generated_lib_linked = true;
|
|
|
+ } else {
|
|
|
+ *error = "Unknown generator option: " + options[i].first;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// Completely serialize all Generate() calls on this instance. The
|
|
|
// thread-safety constraints of the CodeGenerator interface aren't clear so
|
|
@@ -327,6 +335,11 @@ bool Generator::Generate(const FileDescriptor* file,
|
|
|
ReplaceCharacters(&filename, ".", '/');
|
|
|
filename += ".py";
|
|
|
|
|
|
+ pure_python_workable_ = !cpp_generated_lib_linked;
|
|
|
+ if (HasPrefixString(file->name(), "google/protobuf/")) {
|
|
|
+ pure_python_workable_ = true;
|
|
|
+ }
|
|
|
+
|
|
|
FileDescriptorProto fdp;
|
|
|
file_->CopyTo(&fdp);
|
|
|
fdp.SerializeToString(&file_descriptor_serialized_);
|
|
@@ -338,25 +351,31 @@ bool Generator::Generate(const FileDescriptor* file,
|
|
|
printer_ = &printer;
|
|
|
|
|
|
PrintTopBoilerplate(printer_, file_, GeneratingDescriptorProto());
|
|
|
- PrintImports();
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ PrintImports();
|
|
|
+ }
|
|
|
PrintFileDescriptor();
|
|
|
PrintTopLevelEnums();
|
|
|
PrintTopLevelExtensions();
|
|
|
- PrintAllNestedEnumsInFile();
|
|
|
- PrintMessageDescriptors();
|
|
|
- FixForeignFieldsInDescriptors();
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ PrintAllNestedEnumsInFile();
|
|
|
+ PrintMessageDescriptors();
|
|
|
+ FixForeignFieldsInDescriptors();
|
|
|
+ }
|
|
|
PrintMessages();
|
|
|
- // We have to fix up the extensions after the message classes themselves,
|
|
|
- // since they need to call static RegisterExtension() methods on these
|
|
|
- // classes.
|
|
|
- FixForeignFieldsInExtensions();
|
|
|
- // Descriptor options may have custom extensions. These custom options
|
|
|
- // can only be successfully parsed after we register corresponding
|
|
|
- // extensions. Therefore we parse all options again here to recognize
|
|
|
- // custom options that may be unknown when we define the descriptors.
|
|
|
- // This does not apply to services because they are not used by extensions.
|
|
|
- FixAllDescriptorOptions();
|
|
|
- PrintServiceDescriptors();
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ // We have to fix up the extensions after the message classes themselves,
|
|
|
+ // since they need to call static RegisterExtension() methods on these
|
|
|
+ // classes.
|
|
|
+ FixForeignFieldsInExtensions();
|
|
|
+ // Descriptor options may have custom extensions. These custom options
|
|
|
+ // can only be successfully parsed after we register corresponding
|
|
|
+ // extensions. Therefore we parse all options again here to recognize
|
|
|
+ // custom options that may be unknown when we define the descriptors.
|
|
|
+ // This does not apply to services because they are not used by extensions.
|
|
|
+ FixAllDescriptorOptions();
|
|
|
+ PrintServiceDescriptors();
|
|
|
+ }
|
|
|
if (HasGenericServices(file)) {
|
|
|
PrintServices();
|
|
|
}
|
|
@@ -425,28 +444,30 @@ void Generator::PrintFileDescriptor() const {
|
|
|
" serialized_options=$options$,\n";
|
|
|
printer_->Print(m, file_descriptor_template);
|
|
|
printer_->Indent();
|
|
|
- printer_->Print(
|
|
|
- //##!PY25 "serialized_pb=b'$value$'\n",
|
|
|
- "serialized_pb=_b('$value$')\n", //##PY25
|
|
|
- "value", strings::CHexEscape(file_descriptor_serialized_));
|
|
|
- if (file_->dependency_count() != 0) {
|
|
|
- printer_->Print(",\ndependencies=[");
|
|
|
- for (int i = 0; i < file_->dependency_count(); ++i) {
|
|
|
- std::string module_alias = ModuleAlias(file_->dependency(i)->name());
|
|
|
- printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
|
|
|
- module_alias);
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ printer_->Print("serialized_pb=b'$value$'\n", "value",
|
|
|
+ strings::CHexEscape(file_descriptor_serialized_));
|
|
|
+ if (file_->dependency_count() != 0) {
|
|
|
+ printer_->Print(",\ndependencies=[");
|
|
|
+ for (int i = 0; i < file_->dependency_count(); ++i) {
|
|
|
+ std::string module_alias = ModuleAlias(file_->dependency(i)->name());
|
|
|
+ printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
|
|
|
+ module_alias);
|
|
|
+ }
|
|
|
+ printer_->Print("]");
|
|
|
}
|
|
|
- printer_->Print("]");
|
|
|
- }
|
|
|
- if (file_->public_dependency_count() > 0) {
|
|
|
- printer_->Print(",\npublic_dependencies=[");
|
|
|
- for (int i = 0; i < file_->public_dependency_count(); ++i) {
|
|
|
- std::string module_alias =
|
|
|
- ModuleAlias(file_->public_dependency(i)->name());
|
|
|
- printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
|
|
|
- module_alias);
|
|
|
+ if (file_->public_dependency_count() > 0) {
|
|
|
+ printer_->Print(",\npublic_dependencies=[");
|
|
|
+ for (int i = 0; i < file_->public_dependency_count(); ++i) {
|
|
|
+ std::string module_alias =
|
|
|
+ ModuleAlias(file_->public_dependency(i)->name());
|
|
|
+ printer_->Print("$module_alias$.DESCRIPTOR,", "module_alias",
|
|
|
+ module_alias);
|
|
|
+ }
|
|
|
+ printer_->Print("]");
|
|
|
}
|
|
|
- printer_->Print("]");
|
|
|
+ } else {
|
|
|
+ printer_->Print("serialized_pb=''\n");
|
|
|
}
|
|
|
|
|
|
// TODO(falk): Also print options and fix the message_type, enum_type,
|
|
@@ -516,10 +537,14 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
|
|
|
printer_->Print(m, enum_descriptor_template);
|
|
|
printer_->Indent();
|
|
|
printer_->Indent();
|
|
|
- for (int i = 0; i < enum_descriptor.value_count(); ++i) {
|
|
|
- PrintEnumValueDescriptor(*enum_descriptor.value(i));
|
|
|
- printer_->Print(",\n");
|
|
|
+
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ for (int i = 0; i < enum_descriptor.value_count(); ++i) {
|
|
|
+ PrintEnumValueDescriptor(*enum_descriptor.value(i));
|
|
|
+ printer_->Print(",\n");
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
printer_->Outdent();
|
|
|
printer_->Print("],\n");
|
|
|
printer_->Print("containing_type=None,\n");
|
|
@@ -529,8 +554,10 @@ void Generator::PrintEnum(const EnumDescriptor& enum_descriptor) const {
|
|
|
PrintSerializedPbInterval(enum_descriptor, edp);
|
|
|
printer_->Outdent();
|
|
|
printer_->Print(")\n");
|
|
|
- printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
|
|
|
- module_level_descriptor_name);
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ printer_->Print("_sym_db.RegisterEnumDescriptor($name$)\n", "name",
|
|
|
+ module_level_descriptor_name);
|
|
|
+ }
|
|
|
printer_->Print("\n");
|
|
|
}
|
|
|
|
|
@@ -650,9 +677,12 @@ void Generator::PrintServiceDescriptor(
|
|
|
|
|
|
void Generator::PrintDescriptorKeyAndModuleName(
|
|
|
const ServiceDescriptor& descriptor) const {
|
|
|
+ std::string name = ModuleLevelServiceDescriptorName(descriptor);
|
|
|
+ if (!pure_python_workable_) {
|
|
|
+ name = "'" + descriptor.full_name() + "'";
|
|
|
+ }
|
|
|
printer_->Print("$descriptor_key$ = $descriptor_name$,\n", "descriptor_key",
|
|
|
- kDescriptorKey, "descriptor_name",
|
|
|
- ModuleLevelServiceDescriptorName(descriptor));
|
|
|
+ kDescriptorKey, "descriptor_name", name);
|
|
|
std::string module_name = ModuleName(file_->name());
|
|
|
printer_->Print("__module__ = '$module_name$'\n", "module_name", module_name);
|
|
|
}
|
|
@@ -841,7 +871,11 @@ void Generator::PrintMessage(const Descriptor& message_descriptor,
|
|
|
PrintNestedMessages(message_descriptor, qualified_name, to_register);
|
|
|
std::map<std::string, std::string> m;
|
|
|
m["descriptor_key"] = kDescriptorKey;
|
|
|
- m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
|
|
|
+ if (pure_python_workable_) {
|
|
|
+ m["descriptor_name"] = ModuleLevelDescriptorName(message_descriptor);
|
|
|
+ } else {
|
|
|
+ m["descriptor_name"] = "'" + message_descriptor.full_name() + "'";
|
|
|
+ }
|
|
|
printer_->Print(m, "'$descriptor_key$' : $descriptor_name$,\n");
|
|
|
std::string module_name = ModuleName(file_->name());
|
|
|
printer_->Print("'__module__' : '$module_name$'\n", "module_name",
|
|
@@ -1012,7 +1046,7 @@ template <typename DescriptorT>
|
|
|
void Generator::FixContainingTypeInDescriptor(
|
|
|
const DescriptorT& descriptor,
|
|
|
const Descriptor* containing_descriptor) const {
|
|
|
- if (containing_descriptor != NULL) {
|
|
|
+ if (containing_descriptor != nullptr) {
|
|
|
const std::string nested_name = ModuleLevelDescriptorName(descriptor);
|
|
|
const std::string parent_name =
|
|
|
ModuleLevelDescriptorName(*containing_descriptor);
|
|
@@ -1027,7 +1061,7 @@ void Generator::FixContainingTypeInDescriptor(
|
|
|
// just set everything in the initial assignment statements).
|
|
|
void Generator::FixForeignFieldsInDescriptors() const {
|
|
|
for (int i = 0; i < file_->message_type_count(); ++i) {
|
|
|
- FixForeignFieldsInDescriptor(*file_->message_type(i), NULL);
|
|
|
+ FixForeignFieldsInDescriptor(*file_->message_type(i), nullptr);
|
|
|
}
|
|
|
for (int i = 0; i < file_->message_type_count(); ++i) {
|
|
|
AddMessageToFileDescriptor(*file_->message_type(i));
|
|
@@ -1038,6 +1072,7 @@ void Generator::FixForeignFieldsInDescriptors() const {
|
|
|
for (int i = 0; i < file_->extension_count(); ++i) {
|
|
|
AddExtensionToFileDescriptor(*file_->extension(i));
|
|
|
}
|
|
|
+
|
|
|
// TODO(jieluo): Move this register to PrintFileDescriptor() when
|
|
|
// FieldDescriptor.file is added in generated file.
|
|
|
printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name",
|
|
@@ -1118,8 +1153,7 @@ std::string Generator::OptionsValue(
|
|
|
if (serialized_options.length() == 0 || GeneratingDescriptorProto()) {
|
|
|
return "None";
|
|
|
} else {
|
|
|
- //##!PY25 return "b'('" + CEscape(serialized_options)+ "')";
|
|
|
- return "_b('" + CEscape(serialized_options) + "')"; //##PY25
|
|
|
+ return "b'" + CEscape(serialized_options) + "'";
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1351,7 +1385,7 @@ void Generator::FixOptionsForField(const FieldDescriptor& field) const {
|
|
|
if (field_options != "None") {
|
|
|
std::string field_name;
|
|
|
if (field.is_extension()) {
|
|
|
- if (field.extension_scope() == NULL) {
|
|
|
+ if (field.extension_scope() == nullptr) {
|
|
|
// Top level extensions.
|
|
|
field_name = field.name();
|
|
|
} else {
|