|
@@ -37,6 +37,16 @@
|
|
#include <google/protobuf/io/printer.h>
|
|
#include <google/protobuf/io/printer.h>
|
|
#include <google/protobuf/io/zero_copy_stream.h>
|
|
#include <google/protobuf/io/zero_copy_stream.h>
|
|
#include <google/protobuf/stubs/strutil.h>
|
|
#include <google/protobuf/stubs/strutil.h>
|
|
|
|
+#include <google/protobuf/any.pb.h>
|
|
|
|
+#include <google/protobuf/api.pb.h>
|
|
|
|
+#include <google/protobuf/duration.pb.h>
|
|
|
|
+#include <google/protobuf/empty.pb.h>
|
|
|
|
+#include <google/protobuf/field_mask.pb.h>
|
|
|
|
+#include <google/protobuf/source_context.pb.h>
|
|
|
|
+#include <google/protobuf/struct.pb.h>
|
|
|
|
+#include <google/protobuf/timestamp.pb.h>
|
|
|
|
+#include <google/protobuf/type.pb.h>
|
|
|
|
+#include <google/protobuf/wrappers.pb.h>
|
|
|
|
|
|
#include <sstream>
|
|
#include <sstream>
|
|
|
|
|
|
@@ -91,6 +101,9 @@ std::string UnderscoresToCamelCase(const string& name, bool cap_first_letter);
|
|
std::string BinaryToHex(const string& binary);
|
|
std::string BinaryToHex(const string& binary);
|
|
void Indent(io::Printer* printer);
|
|
void Indent(io::Printer* printer);
|
|
void Outdent(io::Printer* printer);
|
|
void Outdent(io::Printer* printer);
|
|
|
|
+void GenerateAddFilesToPool(const FileDescriptor* file,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes,
|
|
|
|
+ io::Printer* printer);
|
|
void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
|
|
void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
|
|
int is_descriptor);
|
|
int is_descriptor);
|
|
void GenerateMessageConstructorDocComment(io::Printer* printer,
|
|
void GenerateMessageConstructorDocComment(io::Printer* printer,
|
|
@@ -111,7 +124,6 @@ void GenerateServiceDocComment(io::Printer* printer,
|
|
void GenerateServiceMethodDocComment(io::Printer* printer,
|
|
void GenerateServiceMethodDocComment(io::Printer* printer,
|
|
const MethodDescriptor* method);
|
|
const MethodDescriptor* method);
|
|
|
|
|
|
-
|
|
|
|
std::string ReservedNamePrefix(const string& classname,
|
|
std::string ReservedNamePrefix(const string& classname,
|
|
const FileDescriptor* file) {
|
|
const FileDescriptor* file) {
|
|
bool is_reserved = false;
|
|
bool is_reserved = false;
|
|
@@ -924,13 +936,20 @@ void GenerateMessageToPool(const string& name_prefix, const Descriptor* message,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor,
|
|
|
|
- io::Printer* printer) {
|
|
|
|
- printer->Print(
|
|
|
|
- "public static $is_initialized = false;\n\n"
|
|
|
|
- "public static function initOnce() {\n");
|
|
|
|
- Indent(printer);
|
|
|
|
|
|
+void GenerateAddFileToPool(
|
|
|
|
+ const FileDescriptor* file,
|
|
|
|
+ bool is_descriptor,
|
|
|
|
+ bool aggregate_metadata,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes,
|
|
|
|
+ io::Printer* printer) {
|
|
|
|
+ printer->Print(
|
|
|
|
+ "public static $is_initialized = false;\n\n"
|
|
|
|
+ "public static function initOnce() {\n");
|
|
|
|
+ Indent(printer);
|
|
|
|
|
|
|
|
+ if (aggregate_metadata) {
|
|
|
|
+ GenerateAddFilesToPool(file, aggregate_metadata_prefixes, printer);
|
|
|
|
+ } else {
|
|
printer->Print(
|
|
printer->Print(
|
|
"$pool = \\Google\\Protobuf\\Internal\\"
|
|
"$pool = \\Google\\Protobuf\\Internal\\"
|
|
"DescriptorPool::getGeneratedPool();\n\n"
|
|
"DescriptorPool::getGeneratedPool();\n\n"
|
|
@@ -938,79 +957,210 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor,
|
|
" return;\n"
|
|
" return;\n"
|
|
"}\n");
|
|
"}\n");
|
|
|
|
|
|
- if (is_descriptor) {
|
|
|
|
- for (int i = 0; i < file->message_type_count(); i++) {
|
|
|
|
- GenerateMessageToPool("", file->message_type(i), printer);
|
|
|
|
- }
|
|
|
|
- for (int i = 0; i < file->enum_type_count(); i++) {
|
|
|
|
- GenerateEnumToPool(file->enum_type(i), printer);
|
|
|
|
- }
|
|
|
|
|
|
+ if (is_descriptor) {
|
|
|
|
+ for (int i = 0; i < file->message_type_count(); i++) {
|
|
|
|
+ GenerateMessageToPool("", file->message_type(i), printer);
|
|
|
|
+ }
|
|
|
|
+ for (int i = 0; i < file->enum_type_count(); i++) {
|
|
|
|
+ GenerateEnumToPool(file->enum_type(i), printer);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ printer->Print(
|
|
|
|
+ "$pool->finish();\n");
|
|
|
|
+ } else {
|
|
|
|
+ for (int i = 0; i < file->dependency_count(); i++) {
|
|
|
|
+ const std::string& name = file->dependency(i)->name();
|
|
|
|
+ // Currently, descriptor.proto is not ready for external usage. Skip to
|
|
|
|
+ // import it for now, so that its dependencies can still work as long as
|
|
|
|
+ // they don't use protos defined in descriptor.proto.
|
|
|
|
+ if (name == kDescriptorFile) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ std::string dependency_filename =
|
|
|
|
+ GeneratedMetadataFileName(file->dependency(i), is_descriptor);
|
|
|
|
+ printer->Print(
|
|
|
|
+ "\\^name^::initOnce();\n",
|
|
|
|
+ "name", FilenameToClassname(dependency_filename));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Add messages and enums to descriptor pool.
|
|
|
|
+ FileDescriptorSet files;
|
|
|
|
+ FileDescriptorProto* file_proto = files.add_file();
|
|
|
|
+ file->CopyTo(file_proto);
|
|
|
|
+
|
|
|
|
+ // Filter out descriptor.proto as it cannot be depended on for now.
|
|
|
|
+ RepeatedPtrField<string>* dependency = file_proto->mutable_dependency();
|
|
|
|
+ for (RepeatedPtrField<string>::iterator it = dependency->begin();
|
|
|
|
+ it != dependency->end(); ++it) {
|
|
|
|
+ if (*it != kDescriptorFile) {
|
|
|
|
+ dependency->erase(it);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Filter out all extensions, since we do not support extension yet.
|
|
|
|
+ file_proto->clear_extension();
|
|
|
|
+ RepeatedPtrField<DescriptorProto>* message_type =
|
|
|
|
+ file_proto->mutable_message_type();
|
|
|
|
+ for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
|
|
|
|
+ it != message_type->end(); ++it) {
|
|
|
|
+ it->clear_extension();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ string files_data;
|
|
|
|
+ files.SerializeToString(&files_data);
|
|
|
|
|
|
|
|
+ printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n");
|
|
|
|
+ Indent(printer);
|
|
|
|
+
|
|
|
|
+ printer->Print(
|
|
|
|
+ "\"^data^\"\n",
|
|
|
|
+ "data", BinaryToHex(files_data));
|
|
|
|
+
|
|
|
|
+ Outdent(printer);
|
|
|
|
+ printer->Print(
|
|
|
|
+ "), true);\n\n");
|
|
|
|
+ }
|
|
printer->Print(
|
|
printer->Print(
|
|
- "$pool->finish();\n");
|
|
|
|
|
|
+ "static::$is_initialized = true;\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Outdent(printer);
|
|
|
|
+ printer->Print("}\n");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void AnalyzeDependencyForFile(
|
|
|
|
+ const FileDescriptor* file,
|
|
|
|
+ std::set<const FileDescriptor*>* nodes_without_dependency,
|
|
|
|
+ std::map<const FileDescriptor*, std::set<const FileDescriptor*>>* deps,
|
|
|
|
+ std::map<const FileDescriptor*, int>* dependency_count) {
|
|
|
|
+ int count = file->dependency_count();
|
|
|
|
+ for (int i = 0; i < file->dependency_count(); i++) {
|
|
|
|
+ const FileDescriptor* dependency = file->dependency(i);
|
|
|
|
+ if (dependency->name() == kDescriptorFile) {
|
|
|
|
+ count--;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (count == 0) {
|
|
|
|
+ nodes_without_dependency->insert(file);
|
|
} else {
|
|
} else {
|
|
|
|
+ (*dependency_count)[file] = count;
|
|
for (int i = 0; i < file->dependency_count(); i++) {
|
|
for (int i = 0; i < file->dependency_count(); i++) {
|
|
- const std::string& name = file->dependency(i)->name();
|
|
|
|
- // Currently, descriptor.proto is not ready for external usage. Skip to
|
|
|
|
- // import it for now, so that its dependencies can still work as long as
|
|
|
|
- // they don't use protos defined in descriptor.proto.
|
|
|
|
- if (name == kDescriptorFile) {
|
|
|
|
|
|
+ const FileDescriptor* dependency = file->dependency(i);
|
|
|
|
+ if (dependency->name() == kDescriptorFile) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- std::string dependency_filename =
|
|
|
|
- GeneratedMetadataFileName(file->dependency(i), is_descriptor);
|
|
|
|
- printer->Print(
|
|
|
|
- "\\^name^::initOnce();\n",
|
|
|
|
- "name", FilenameToClassname(dependency_filename));
|
|
|
|
|
|
+ if (deps->find(dependency) == deps->end()) {
|
|
|
|
+ (*deps)[dependency] = std::set<const FileDescriptor*>();
|
|
|
|
+ }
|
|
|
|
+ (*deps)[dependency].insert(file);
|
|
|
|
+ AnalyzeDependencyForFile(
|
|
|
|
+ dependency, nodes_without_dependency, deps, dependency_count);
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- // Add messages and enums to descriptor pool.
|
|
|
|
- FileDescriptorSet files;
|
|
|
|
- FileDescriptorProto* file_proto = files.add_file();
|
|
|
|
- file->CopyTo(file_proto);
|
|
|
|
-
|
|
|
|
- // Filter out descriptor.proto as it cannot be depended on for now.
|
|
|
|
- RepeatedPtrField<string>* dependency = file_proto->mutable_dependency();
|
|
|
|
- for (RepeatedPtrField<string>::iterator it = dependency->begin();
|
|
|
|
- it != dependency->end(); ++it) {
|
|
|
|
- if (*it != kDescriptorFile) {
|
|
|
|
- dependency->erase(it);
|
|
|
|
|
|
+static bool NeedsUnwrapping(
|
|
|
|
+ const FileDescriptor* file,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes) {
|
|
|
|
+ bool has_aggregate_metadata_prefix = false;
|
|
|
|
+ if (aggregate_metadata_prefixes.empty()) {
|
|
|
|
+ has_aggregate_metadata_prefix = true;
|
|
|
|
+ } else {
|
|
|
|
+ for (const auto& prefix : aggregate_metadata_prefixes) {
|
|
|
|
+ if (HasPrefixString(file->package(), prefix)) {
|
|
|
|
+ has_aggregate_metadata_prefix = true;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return has_aggregate_metadata_prefix;
|
|
|
|
+}
|
|
|
|
|
|
- // Filter out all extensions, since we do not support extension yet.
|
|
|
|
- file_proto->clear_extension();
|
|
|
|
- RepeatedPtrField<DescriptorProto>* message_type =
|
|
|
|
- file_proto->mutable_message_type();
|
|
|
|
- for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
|
|
|
|
- it != message_type->end(); ++it) {
|
|
|
|
- it->clear_extension();
|
|
|
|
|
|
+void GenerateAddFilesToPool(
|
|
|
|
+ const FileDescriptor* file,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes,
|
|
|
|
+ io::Printer* printer) {
|
|
|
|
+ printer->Print(
|
|
|
|
+ "$pool = \\Google\\Protobuf\\Internal\\"
|
|
|
|
+ "DescriptorPool::getGeneratedPool();\n"
|
|
|
|
+ "if (static::$is_initialized == true) {\n"
|
|
|
|
+ " return;\n"
|
|
|
|
+ "}\n");
|
|
|
|
+
|
|
|
|
+ // Sort files according to dependency
|
|
|
|
+ std::map<const FileDescriptor*, std::set<const FileDescriptor*>> deps;
|
|
|
|
+ std::map<const FileDescriptor*, int> dependency_count;
|
|
|
|
+ std::set<const FileDescriptor*> nodes_without_dependency;
|
|
|
|
+ FileDescriptorSet sorted_file_set;
|
|
|
|
+
|
|
|
|
+ AnalyzeDependencyForFile(
|
|
|
|
+ file, &nodes_without_dependency, &deps, &dependency_count);
|
|
|
|
+
|
|
|
|
+ while (!nodes_without_dependency.empty()) {
|
|
|
|
+ auto file = *nodes_without_dependency.begin();
|
|
|
|
+ nodes_without_dependency.erase(file);
|
|
|
|
+ for (auto dependent : deps[file]) {
|
|
|
|
+ if (dependency_count[dependent] == 1) {
|
|
|
|
+ dependency_count.erase(dependent);
|
|
|
|
+ nodes_without_dependency.insert(dependent);
|
|
|
|
+ } else {
|
|
|
|
+ dependency_count[dependent] -= 1;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- string files_data;
|
|
|
|
- files.SerializeToString(&files_data);
|
|
|
|
|
|
+ bool needs_aggregate = NeedsUnwrapping(file, aggregate_metadata_prefixes);
|
|
|
|
|
|
- printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n");
|
|
|
|
- Indent(printer);
|
|
|
|
|
|
+ if (needs_aggregate) {
|
|
|
|
+ auto file_proto = sorted_file_set.add_file();
|
|
|
|
+ file->CopyTo(file_proto);
|
|
|
|
+
|
|
|
|
+ // Filter out descriptor.proto as it cannot be depended on for now.
|
|
|
|
+ RepeatedPtrField<string>* dependency = file_proto->mutable_dependency();
|
|
|
|
+ for (RepeatedPtrField<string>::iterator it = dependency->begin();
|
|
|
|
+ it != dependency->end(); ++it) {
|
|
|
|
+ if (*it != kDescriptorFile) {
|
|
|
|
+ dependency->erase(it);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- // Only write 30 bytes per line.
|
|
|
|
- static const int kBytesPerLine = 30;
|
|
|
|
- for (int i = 0; i < files_data.size(); i += kBytesPerLine) {
|
|
|
|
|
|
+ // Filter out all extensions, since we do not support extension yet.
|
|
|
|
+ file_proto->clear_extension();
|
|
|
|
+ RepeatedPtrField<DescriptorProto>* message_type =
|
|
|
|
+ file_proto->mutable_message_type();
|
|
|
|
+ for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
|
|
|
|
+ it != message_type->end(); ++it) {
|
|
|
|
+ it->clear_extension();
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ std::string dependency_filename =
|
|
|
|
+ GeneratedMetadataFileName(file, false);
|
|
printer->Print(
|
|
printer->Print(
|
|
- "\"^data^\"^dot^\n",
|
|
|
|
- "data", BinaryToHex(files_data.substr(i, kBytesPerLine)),
|
|
|
|
- "dot", i + kBytesPerLine < files_data.size() ? " ." : "");
|
|
|
|
|
|
+ "\\^name^::initOnce();\n",
|
|
|
|
+ "name", FilenameToClassname(dependency_filename));
|
|
}
|
|
}
|
|
-
|
|
|
|
- Outdent(printer);
|
|
|
|
- printer->Print(
|
|
|
|
- "), true);\n\n");
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ string files_data;
|
|
|
|
+ sorted_file_set.SerializeToString(&files_data);
|
|
|
|
+
|
|
|
|
+ printer->Print("$pool->internalAddGeneratedFile(hex2bin(\n");
|
|
|
|
+ Indent(printer);
|
|
|
|
+
|
|
printer->Print(
|
|
printer->Print(
|
|
- "static::$is_initialized = true;\n");
|
|
|
|
|
|
+ "\"^data^\"\n",
|
|
|
|
+ "data", BinaryToHex(files_data));
|
|
|
|
+
|
|
Outdent(printer);
|
|
Outdent(printer);
|
|
- printer->Print("}\n");
|
|
|
|
|
|
+ printer->Print(
|
|
|
|
+ "), true);\n");
|
|
|
|
+
|
|
|
|
+ printer->Print(
|
|
|
|
+ "static::$is_initialized = true;\n");
|
|
}
|
|
}
|
|
|
|
|
|
void GenerateUseDeclaration(bool is_descriptor, io::Printer* printer) {
|
|
void GenerateUseDeclaration(bool is_descriptor, io::Printer* printer) {
|
|
@@ -1051,6 +1201,8 @@ std::string FilenameToClassname(const string& filename) {
|
|
|
|
|
|
void GenerateMetadataFile(const FileDescriptor* file,
|
|
void GenerateMetadataFile(const FileDescriptor* file,
|
|
bool is_descriptor,
|
|
bool is_descriptor,
|
|
|
|
+ bool aggregate_metadata,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes,
|
|
GeneratorContext* generator_context) {
|
|
GeneratorContext* generator_context) {
|
|
std::string filename = GeneratedMetadataFileName(file, is_descriptor);
|
|
std::string filename = GeneratedMetadataFileName(file, is_descriptor);
|
|
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
|
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
|
@@ -1079,7 +1231,8 @@ void GenerateMetadataFile(const FileDescriptor* file,
|
|
}
|
|
}
|
|
Indent(&printer);
|
|
Indent(&printer);
|
|
|
|
|
|
- GenerateAddFileToPool(file, is_descriptor, &printer);
|
|
|
|
|
|
+ GenerateAddFileToPool(file, is_descriptor, aggregate_metadata,
|
|
|
|
+ aggregate_metadata_prefixes, &printer);
|
|
|
|
|
|
Outdent(&printer);
|
|
Outdent(&printer);
|
|
printer.Print("}\n\n");
|
|
printer.Print("}\n\n");
|
|
@@ -1229,6 +1382,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
|
|
|
|
|
|
void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
|
|
void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
|
|
bool is_descriptor,
|
|
bool is_descriptor,
|
|
|
|
+ bool aggregate_metadata,
|
|
GeneratorContext* generator_context) {
|
|
GeneratorContext* generator_context) {
|
|
// Don't generate MapEntry messages -- we use the PHP extension's native
|
|
// Don't generate MapEntry messages -- we use the PHP extension's native
|
|
// support for map fields instead.
|
|
// support for map fields instead.
|
|
@@ -1285,10 +1439,12 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
|
|
GeneratedMetadataFileName(file, is_descriptor);
|
|
GeneratedMetadataFileName(file, is_descriptor);
|
|
std::string metadata_fullname = FilenameToClassname(metadata_filename);
|
|
std::string metadata_fullname = FilenameToClassname(metadata_filename);
|
|
printer.Print(
|
|
printer.Print(
|
|
- "\\^fullname^::initOnce();\n"
|
|
|
|
- "parent::__construct($data);\n",
|
|
|
|
|
|
+ "\\^fullname^::initOnce();\n",
|
|
"fullname", metadata_fullname);
|
|
"fullname", metadata_fullname);
|
|
|
|
|
|
|
|
+ printer.Print(
|
|
|
|
+ "parent::__construct($data);\n");
|
|
|
|
+
|
|
Outdent(&printer);
|
|
Outdent(&printer);
|
|
printer.Print("}\n\n");
|
|
printer.Print("}\n\n");
|
|
|
|
|
|
@@ -1328,6 +1484,7 @@ void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
|
|
// Nested messages and enums.
|
|
// Nested messages and enums.
|
|
for (int i = 0; i < message->nested_type_count(); i++) {
|
|
for (int i = 0; i < message->nested_type_count(); i++) {
|
|
GenerateMessageFile(file, message->nested_type(i), is_descriptor,
|
|
GenerateMessageFile(file, message->nested_type(i), is_descriptor,
|
|
|
|
+ aggregate_metadata,
|
|
generator_context);
|
|
generator_context);
|
|
}
|
|
}
|
|
for (int i = 0; i < message->enum_type_count(); i++) {
|
|
for (int i = 0; i < message->enum_type_count(); i++) {
|
|
@@ -1384,10 +1541,15 @@ void GenerateServiceFile(const FileDescriptor* file,
|
|
}
|
|
}
|
|
|
|
|
|
void GenerateFile(const FileDescriptor* file, bool is_descriptor,
|
|
void GenerateFile(const FileDescriptor* file, bool is_descriptor,
|
|
|
|
+ bool aggregate_metadata,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes,
|
|
GeneratorContext* generator_context) {
|
|
GeneratorContext* generator_context) {
|
|
- GenerateMetadataFile(file, is_descriptor, generator_context);
|
|
|
|
|
|
+ GenerateMetadataFile(file, is_descriptor, aggregate_metadata,
|
|
|
|
+ aggregate_metadata_prefixes, generator_context);
|
|
|
|
+
|
|
for (int i = 0; i < file->message_type_count(); i++) {
|
|
for (int i = 0; i < file->message_type_count(); i++) {
|
|
GenerateMessageFile(file, file->message_type(i), is_descriptor,
|
|
GenerateMessageFile(file, file->message_type(i), is_descriptor,
|
|
|
|
+ aggregate_metadata,
|
|
generator_context);
|
|
generator_context);
|
|
}
|
|
}
|
|
for (int i = 0; i < file->enum_type_count(); i++) {
|
|
for (int i = 0; i < file->enum_type_count(); i++) {
|
|
@@ -1397,7 +1559,7 @@ void GenerateFile(const FileDescriptor* file, bool is_descriptor,
|
|
if (file->options().php_generic_services()) {
|
|
if (file->options().php_generic_services()) {
|
|
for (int i = 0; i < file->service_count(); i++) {
|
|
for (int i = 0; i < file->service_count(); i++) {
|
|
GenerateServiceFile(file, file->service(i), is_descriptor,
|
|
GenerateServiceFile(file, file->service(i), is_descriptor,
|
|
- generator_context);
|
|
|
|
|
|
+ generator_context);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1653,8 +1815,17 @@ void GenerateServiceMethodDocComment(io::Printer* printer,
|
|
bool Generator::Generate(const FileDescriptor* file, const string& parameter,
|
|
bool Generator::Generate(const FileDescriptor* file, const string& parameter,
|
|
GeneratorContext* generator_context,
|
|
GeneratorContext* generator_context,
|
|
string* error) const {
|
|
string* error) const {
|
|
- bool is_descriptor = parameter == "internal";
|
|
|
|
|
|
+ return Generate(file, false, false, std::set<string>(),
|
|
|
|
+ generator_context, error);
|
|
|
|
+}
|
|
|
|
|
|
|
|
+bool Generator::Generate(
|
|
|
|
+ const FileDescriptor* file,
|
|
|
|
+ bool is_descriptor,
|
|
|
|
+ bool aggregate_metadata,
|
|
|
|
+ const std::set<string>& aggregate_metadata_prefixes,
|
|
|
|
+ GeneratorContext* generator_context,
|
|
|
|
+ string* error) const {
|
|
if (is_descriptor && file->name() != kDescriptorFile) {
|
|
if (is_descriptor && file->name() != kDescriptorFile) {
|
|
*error =
|
|
*error =
|
|
"Can only generate PHP code for google/protobuf/descriptor.proto.\n";
|
|
"Can only generate PHP code for google/protobuf/descriptor.proto.\n";
|
|
@@ -1668,8 +1839,44 @@ bool Generator::Generate(const FileDescriptor* file, const string& parameter,
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- GenerateFile(file, is_descriptor, generator_context);
|
|
|
|
|
|
+ GenerateFile(file, is_descriptor, aggregate_metadata,
|
|
|
|
+ aggregate_metadata_prefixes, generator_context);
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
|
|
|
|
+bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
|
|
|
|
+ const std::string& parameter,
|
|
|
|
+ GeneratorContext* generator_context,
|
|
|
|
+ std::string* error) const {
|
|
|
|
+ bool is_descriptor = false;
|
|
|
|
+ bool aggregate_metadata = false;
|
|
|
|
+ std::set<string> aggregate_metadata_prefixes;
|
|
|
|
+
|
|
|
|
+ for (const auto& option : Split(parameter, ",")) {
|
|
|
|
+ const auto option_pair = Split(option, "=");
|
|
|
|
+ if (HasPrefixString(option_pair[0], "aggregate_metadata")) {
|
|
|
|
+ string options_string = option_pair[1];
|
|
|
|
+ const auto options = Split(options_string, "#", false);
|
|
|
|
+ aggregate_metadata = true;
|
|
|
|
+ for (int i = 0; i < options.size(); i++) {
|
|
|
|
+ aggregate_metadata_prefixes.insert(options[i]);
|
|
|
|
+ GOOGLE_LOG(INFO) << options[i];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (option_pair[0] == "internal") {
|
|
|
|
+ is_descriptor = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (auto file : files) {
|
|
|
|
+ if (!Generate(
|
|
|
|
+ file, is_descriptor, aggregate_metadata,
|
|
|
|
+ aggregate_metadata_prefixes,
|
|
|
|
+ generator_context, error)) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|