aboutsummaryrefslogtreecommitdiffstats
path: root/src/google/protobuf/compiler/javamicro
diff options
context:
space:
mode:
Diffstat (limited to 'src/google/protobuf/compiler/javamicro')
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_file.cc94
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_generator.cc22
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_helpers.cc127
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_helpers.h26
-rw-r--r--src/google/protobuf/compiler/javamicro/javamicro_message.cc18
5 files changed, 107 insertions, 180 deletions
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_file.cc b/src/google/protobuf/compiler/javamicro/javamicro_file.cc
index 9513aec..43bf012 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_file.cc
+++ b/src/google/protobuf/compiler/javamicro/javamicro_file.cc
@@ -32,6 +32,8 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#include <iostream>
+
#include <google/protobuf/compiler/javamicro/javamicro_file.h>
#include <google/protobuf/compiler/javamicro/javamicro_enum.h>
#include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
@@ -101,56 +103,48 @@ bool FileGenerator::Validate(string* error) {
return false;
}
- // If there is no outer class name then there must be only
- // message and no enums defined in the file scope.
- if (!params_.has_java_outer_classname(file_->name())) {
- if (file_->message_type_count() != 1) {
- error->assign(file_->name());
- error->append(
- ": Java MICRO_RUNTIME may only have 1 message if there is no 'option java_outer_classname'\"");
- return false;
- }
+ if (file_->service_count() != 0) {
+ error->assign(file_->name());
+ error->append(
+ ": Java MICRO_RUNTIME does not support services\"");
+ return false;
+ }
- if (file_->enum_type_count() != 0) {
- error->assign(file_->name());
- error->append(
- ": Java MICRO_RUNTIME must have an 'option java_outer_classname' if file scope enums are present\"");
- return false;
- }
+ if (!IsOuterClassNeeded(params_, file_)) {
+ return true;
+ }
+
+ // Check whether legacy javamicro generator would omit the outer class.
+ if (!params_.has_java_outer_classname(file_->name())
+ && file_->message_type_count() == 1
+ && file_->enum_type_count() == 0 && file_->extension_count() == 0) {
+ cout << "INFO: " << file_->name() << ":" << endl;
+ cout << "Javamicro generator has changed to align with java generator. "
+ "An outer class will be created for this file and the single message "
+ "in the file will become a nested class. Use java_multiple_files to "
+ "skip generating the outer class, or set an explicit "
+ "java_outer_classname to suppress this message." << endl;
}
// Check that no class name matches the file's class name. This is a common
// problem that leads to Java compile errors that can be hard to understand.
// It's especially bad when using the java_multiple_files, since we would
// end up overwriting the outer class with one of the inner ones.
- int found_fileName = 0;
- for (int i = 0; i < file_->enum_type_count(); i++) {
- if (file_->enum_type(i)->name() == classname_) {
- found_fileName += 1;
- }
- }
- for (int i = 0; i < file_->message_type_count(); i++) {
+ bool found_conflict = false;
+ for (int i = 0; !found_conflict && i < file_->message_type_count(); i++) {
if (file_->message_type(i)->name() == classname_) {
- found_fileName += 1;
+ found_conflict = true;
}
}
- if (file_->service_count() != 0) {
+ if (found_conflict) {
error->assign(file_->name());
error->append(
- ": Java MICRO_RUNTIME does not support services\"");
- return false;
- }
-
- if (found_fileName > 1) {
- error->assign(file_->name());
- error->append(
- ": Cannot generate Java output because there is more than one class name, \"");
+ ": Cannot generate Java output because the file's outer class name, \"");
error->append(classname_);
error->append(
"\", matches the name of one of the types declared inside it. "
"Please either rename the type or use the java_outer_classname "
- "option to specify a different outer class name for the .proto file."
- " -- FIX THIS MESSAGE");
+ "option to specify a different outer class name for the .proto file.");
return false;
}
return true;
@@ -169,20 +163,19 @@ void FileGenerator::Generate(io::Printer* printer) {
"package", java_package_);
}
- if (params_.has_java_outer_classname(file_->name())) {
- printer->Print(
- "public final class $classname$ {\n"
- " private $classname$() {}\n",
- "classname", classname_);
- printer->Indent();
- }
+ printer->Print(
+ "public final class $classname$ {\n"
+ " private $classname$() {}\n",
+ "classname", classname_);
+ printer->Indent();
// -----------------------------------------------------------------
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ EnumGenerator(file_->enum_type(i), params_).Generate(printer);
+ }
+
if (!params_.java_multiple_files(file_->name())) {
- for (int i = 0; i < file_->enum_type_count(); i++) {
- EnumGenerator(file_->enum_type(i), params_).Generate(printer);
- }
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator(file_->message_type(i), params_).Generate(printer);
}
@@ -194,11 +187,9 @@ void FileGenerator::Generate(io::Printer* printer) {
MessageGenerator(file_->message_type(i), params_).GenerateStaticVariables(printer);
}
- if (params_.has_java_outer_classname(file_->name())) {
- printer->Outdent();
- printer->Print(
- "}\n");
- }
+ printer->Outdent();
+ printer->Print(
+ "}\n");
}
template<typename GeneratorClass, typename DescriptorClass>
@@ -232,11 +223,6 @@ void FileGenerator::GenerateSiblings(const string& package_dir,
OutputDirectory* output_directory,
vector<string>* file_list) {
if (params_.java_multiple_files(file_->name())) {
- for (int i = 0; i < file_->enum_type_count(); i++) {
- GenerateSibling<EnumGenerator>(package_dir, java_package_,
- file_->enum_type(i),
- output_directory, file_list, params_);
- }
for (int i = 0; i < file_->message_type_count(); i++) {
GenerateSibling<MessageGenerator>(package_dir, java_package_,
file_->message_type(i),
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_generator.cc b/src/google/protobuf/compiler/javamicro/javamicro_generator.cc
index 4643899..1b74509 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_generator.cc
+++ b/src/google/protobuf/compiler/javamicro/javamicro_generator.cc
@@ -173,16 +173,18 @@ bool JavaMicroGenerator::Generate(const FileDescriptor* file,
vector<string> all_files;
- string java_filename = package_dir;
- java_filename += file_generator.classname();
- java_filename += ".java";
- all_files.push_back(java_filename);
-
- // Generate main java file.
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(java_filename));
- io::Printer printer(output.get(), '$');
- file_generator.Generate(&printer);
+ if (IsOuterClassNeeded(params, file)) {
+ string java_filename = package_dir;
+ java_filename += file_generator.classname();
+ java_filename += ".java";
+ all_files.push_back(java_filename);
+
+ // Generate main java file.
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ output_directory->Open(java_filename));
+ io::Printer printer(output.get(), '$');
+ file_generator.Generate(&printer);
+ }
// Generate sibling files.
file_generator.GenerateSiblings(package_dir, output_directory, &all_files);
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
index 3647ec3..f6ce653 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
+++ b/src/google/protobuf/compiler/javamicro/javamicro_helpers.cc
@@ -120,31 +120,20 @@ string StripProto(const string& filename) {
}
string FileClassName(const Params& params, const FileDescriptor* file) {
- string name;
-
if (params.has_java_outer_classname(file->name())) {
- name = params.java_outer_classname(file->name());
+ return params.java_outer_classname(file->name());
} else {
- if ((file->message_type_count() == 1)
- || (file->enum_type_count() == 0)) {
- // If no outer calls and only one message then
- // use the message name as the file name
- name = file->message_type(0)->name();
+ // Use the filename itself with underscores removed
+ // and a CamelCase style name.
+ string basename;
+ string::size_type last_slash = file->name().find_last_of('/');
+ if (last_slash == string::npos) {
+ basename = file->name();
} else {
- // Use the filename it self with underscores removed
- // and a CamelCase style name.
- string basename;
- string::size_type last_slash = file->name().find_last_of('/');
- if (last_slash == string::npos) {
- basename = file->name();
- } else {
- basename = file->name().substr(last_slash + 1);
- }
- name = UnderscoresToCamelCaseImpl(StripProto(basename), true);
+ basename = file->name().substr(last_slash + 1);
}
+ return UnderscoresToCamelCaseImpl(StripProto(basename), true);
}
-
- return name;
}
string FileJavaPackage(const Params& params, const FileDescriptor* file) {
@@ -160,38 +149,27 @@ string FileJavaPackage(const Params& params, const FileDescriptor* file) {
}
}
-string ToJavaName(const Params& params, const string& full_name,
- const FileDescriptor* file) {
- string result;
- if (params.java_multiple_files(file->name())) {
- result = FileJavaPackage(params, file);
- } else {
- result = ClassName(params, file);
+bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file) {
+ // Enums and extensions need the outer class as the scope.
+ if (file->enum_type_count() != 0 || file->extension_count() != 0) {
+ return true;
}
- if (file->package().empty()) {
- result += '.';
- result += full_name;
+ // Messages need the outer class only if java_multiple_files is false.
+ return !params.java_multiple_files(file->name());
+}
+
+string ToJavaName(const Params& params, const string& name, bool is_class,
+ const Descriptor* parent, const FileDescriptor* file) {
+ string result;
+ if (parent != NULL) {
+ result.append(ClassName(params, parent));
+ } else if (is_class && params.java_multiple_files(file->name())) {
+ result.append(FileJavaPackage(params, file));
} else {
- // Strip the proto package from full_name since we've replaced it with
- // the Java package. If there isn't an outer classname then strip it too.
- int sizeToSkipPackageName = file->package().size();
- int sizeToSkipOutClassName;
- if (params.has_java_outer_classname(file->name())) {
- sizeToSkipOutClassName = 0;
- } else {
- sizeToSkipOutClassName =
- full_name.find_first_of('.', sizeToSkipPackageName + 1);
- }
- int sizeToSkip = sizeToSkipOutClassName > 0 ?
- sizeToSkipOutClassName : sizeToSkipPackageName;
- string class_name = full_name.substr(sizeToSkip + 1);
- if (class_name == FileClassName(params, file)) {
- // Done class_name is already present.
- } else {
- result += '.';
- result += class_name;
- }
+ result.append(ClassName(params, file));
}
+ if (!result.empty()) result.append(1, '.');
+ result.append(name); // TODO(maxtroy): add '_' if name is a Java keyword.
return result;
}
@@ -203,51 +181,14 @@ string ClassName(const Params& params, const FileDescriptor* descriptor) {
}
string ClassName(const Params& params, const EnumDescriptor* descriptor) {
- string result;
- const FileDescriptor* file = descriptor->file();
- const string file_name = file->name();
- const string full_name = descriptor->full_name();
-
- // Remove enum class name as we use int's for enums
- string base_name = full_name.substr(0, full_name.find_last_of('.'));
-
- if (!file->package().empty()) {
- if (file->package() == base_name.substr(0, file->package().size())) {
- // Remove package name leaving just the parent class of the enum
- int offset = file->package().size();
- if (base_name.size() > offset) {
- // Remove period between package and class name if there is a classname
- offset += 1;
- }
- base_name = base_name.substr(offset);
- } else {
- GOOGLE_LOG(FATAL) << "Expected package name to start an enum";
- }
- }
-
- // Construct the path name from the package and outer class
-
- // Add the java package name if it exsits
- if (params.has_java_package(file_name)) {
- result += params.java_package(file_name);
- }
-
- // Add the outer classname if it exists
- if (params.has_java_outer_classname(file_name)) {
- if (!result.empty()) {
- result += ".";
- }
- result += params.java_outer_classname(file_name);
- }
-
- // Create the full class name from the base and path
- if (!base_name.empty()) {
- if (!result.empty()) {
- result += ".";
- }
- result += base_name;
+ // An enum's class name is the enclosing message's class name or the outer
+ // class name.
+ const Descriptor* parent = descriptor->containing_type();
+ if (parent != NULL) {
+ return ClassName(params, parent);
+ } else {
+ return ClassName(params, descriptor->file());
}
- return result;
}
string FieldConstantName(const FieldDescriptor *field) {
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_helpers.h b/src/google/protobuf/compiler/javamicro/javamicro_helpers.h
index eeddbf9..6131c15 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_helpers.h
+++ b/src/google/protobuf/compiler/javamicro/javamicro_helpers.h
@@ -69,25 +69,35 @@ string FileClassName(const Params& params, const FileDescriptor* file);
// Returns the file's Java package name.
string FileJavaPackage(const Params& params, const FileDescriptor* file);
-// Converts the given fully-qualified name in the proto namespace to its
-// fully-qualified name in the Java namespace, given that it is in the given
-// file.
-string ToJavaName(const Params& params, const string& full_name,
- const FileDescriptor* file);
+// Returns whether the Java outer class is needed, i.e. whether the option
+// java_multiple_files is false, or the proto file contains any file-scope
+// enums/extensions.
+bool IsOuterClassNeeded(const Params& params, const FileDescriptor* file);
+
+// Converts the given simple name of a proto entity to its fully-qualified name
+// in the Java namespace, given that it is in the given file enclosed in the
+// given parent message (or NULL for file-scope entities). Whether the file's
+// outer class name should be included in the return value depends on factors
+// inferrable from the given arguments, including is_class which indicates
+// whether the entity translates to a Java class.
+string ToJavaName(const Params& params, const string& name, bool is_class,
+ const Descriptor* parent, const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
inline string ClassName(const Params& params, const Descriptor* descriptor) {
- return ToJavaName(params, descriptor->full_name(), descriptor->file());
+ return ToJavaName(params, descriptor->name(), true,
+ descriptor->containing_type(), descriptor->file());
}
string ClassName(const Params& params, const EnumDescriptor* descriptor);
inline string ClassName(const Params& params,
const ServiceDescriptor* descriptor) {
- return ToJavaName(params, descriptor->full_name(), descriptor->file());
+ return ToJavaName(params, descriptor->name(), true, NULL, descriptor->file());
}
inline string ExtensionIdentifierName(const Params& params,
const FieldDescriptor* descriptor) {
- return ToJavaName(params, descriptor->full_name(), descriptor->file());
+ return ToJavaName(params, descriptor->name(), false,
+ descriptor->extension_scope(), descriptor->file());
}
string ClassName(const Params& params, const FileDescriptor* descriptor);
diff --git a/src/google/protobuf/compiler/javamicro/javamicro_message.cc b/src/google/protobuf/compiler/javamicro/javamicro_message.cc
index 6f67e74..cf48b3c 100644
--- a/src/google/protobuf/compiler/javamicro/javamicro_message.cc
+++ b/src/google/protobuf/compiler/javamicro/javamicro_message.cc
@@ -173,15 +173,7 @@ void MessageGenerator::Generate(io::Printer* printer) {
const string& file_name = descriptor_->file()->name();
bool is_own_file =
params_.java_multiple_files(file_name)
- || ((descriptor_->containing_type() == NULL)
- && !params_.has_java_outer_classname(file_name));
-
-#if 0
- GOOGLE_LOG(INFO) << "is_own_file=" << is_own_file;
- GOOGLE_LOG(INFO) << "containing_type()=" << ((descriptor_->containing_type() == NULL) ? "NULL" : "not null");
- GOOGLE_LOG(INFO) << "java_multiple_files()=" << params_.java_multiple_files();
- GOOGLE_LOG(INFO) << "has_java_outer_classname()=" << params_.has_java_outer_classname(file_->name());
-#endif
+ && descriptor_->containing_type() == NULL;
if ((descriptor_->extension_count() != 0)
|| (descriptor_->extension_range_count() != 0)) {
@@ -362,25 +354,21 @@ void MessageGenerator::GenerateMergeFromMethods(io::Printer* printer) {
void MessageGenerator::
GenerateParseFromMethods(io::Printer* printer) {
- bool is_own_file =
- descriptor_->containing_type() == NULL;
-
// Note: These are separate from GenerateMessageSerializationMethods()
// because they need to be generated even for messages that are optimized
// for code size.
printer->Print(
- "public $static$ $classname$ parseFrom(byte[] data)\n"
+ "public static $classname$ parseFrom(byte[] data)\n"
" throws com.google.protobuf.micro.InvalidProtocolBufferMicroException {\n"
" return ($classname$) (new $classname$().mergeFrom(data));\n"
"}\n"
"\n"
- "public $static$ $classname$ parseFrom(\n"
+ "public static $classname$ parseFrom(\n"
" com.google.protobuf.micro.CodedInputStreamMicro input)\n"
" throws java.io.IOException {\n"
" return new $classname$().mergeFrom(input);\n"
"}\n"
"\n",
- "static", (is_own_file ? "static" : ""),
"classname", descriptor_->name());
}