|
|
|
@ -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 { |
|
|
|
|