aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-04-18 00:02:12 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-04-18 00:02:12 +0000
commitcfa2d8aa87cc0b22b5092a5fb3bf7e394f85cbf1 (patch)
tree77ee2f4d02dfb43187511f3eb5a37a00c2f6f5de /src/google/protobuf/compiler
parenteb26a1efdef3f1f5e77807d456a08f3c76cc5207 (diff)
Generate field number constants. Patch from Michael Poole.
Diffstat (limited to 'src/google/protobuf/compiler')
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_extension.cc28
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc30
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc17
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc4
-rw-r--r--src/google/protobuf/compiler/java/java_extension.cc4
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.cc6
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h4
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc3
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc5
10 files changed, 94 insertions, 11 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc
index 0dd8420d..3f212b93 100644
--- a/src/google/protobuf/compiler/cpp/cpp_extension.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc
@@ -77,9 +77,11 @@ ExtensionGenerator::~ExtensionGenerator() {}
void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
map<string, string> vars;
- vars["extendee" ] = ClassName(descriptor_->containing_type(), true);
- vars["type_traits"] = type_traits_;
- vars["name" ] = descriptor_->name();
+ vars["extendee" ] = ClassName(descriptor_->containing_type(), true);
+ vars["number" ] = SimpleItoa(descriptor_->number());
+ vars["type_traits" ] = type_traits_;
+ vars["name" ] = descriptor_->name();
+ vars["constant_name"] = FieldConstantName(descriptor_);
// If this is a class member, it needs to be declared "static". Otherwise,
// it needs to be "extern".
@@ -91,24 +93,34 @@ void ExtensionGenerator::GenerateDeclaration(io::Printer* printer) {
}
printer->Print(vars,
+ "static const int $constant_name$ = $number$;\n"
"$qualifier$ ::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
" ::google::protobuf::internal::$type_traits$ > $name$;\n");
}
void ExtensionGenerator::GenerateDefinition(io::Printer* printer) {
map<string, string> vars;
- vars["extendee" ] = ClassName(descriptor_->containing_type(), true);
- vars["number" ] = SimpleItoa(descriptor_->number());
- vars["type_traits"] = type_traits_;
- vars["name" ] = descriptor_->name();
+ vars["extendee" ] = ClassName(descriptor_->containing_type(), true);
+ vars["type_traits" ] = type_traits_;
+ vars["name" ] = descriptor_->name();
+ vars["constant_name"] = FieldConstantName(descriptor_);
// If this is a class member, it needs to be declared in its class scope.
vars["scope"] = (descriptor_->extension_scope() == NULL) ? "" :
ClassName(descriptor_->extension_scope(), false) + "::";
+ // Likewise, class members need to declare the field constant variable.
+ if (descriptor_->extension_scope() != NULL) {
+ printer->Print(vars,
+ "#ifndef _MSC_VER\n"
+ "const int $scope$$constant_name$;\n"
+ "#endif\n");
+ }
+
printer->Print(vars,
"::google::protobuf::internal::ExtensionIdentifier< $extendee$,\n"
- " ::google::protobuf::internal::$type_traits$ > $scope$$name$($number$);\n");
+ " ::google::protobuf::internal::$type_traits$ > $scope$$name$("
+ "$constant_name$);\n");
}
} // namespace cpp
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 11122883..d536bea4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -77,6 +77,31 @@ hash_set<string> MakeKeywordsMap() {
hash_set<string> kKeywords = MakeKeywordsMap();
+string UnderscoresToCamelCase(const string& input, bool cap_next_letter) {
+ string result;
+ // Note: I distrust ctype.h due to locales.
+ for (int i = 0; i < input.size(); i++) {
+ if ('a' <= input[i] && input[i] <= 'z') {
+ if (cap_next_letter) {
+ result += input[i] + ('A' - 'a');
+ } else {
+ result += input[i];
+ }
+ cap_next_letter = false;
+ } else if ('A' <= input[i] && input[i] <= 'Z') {
+ // Capital letters are left as-is.
+ result += input[i];
+ cap_next_letter = false;
+ } else if ('0' <= input[i] && input[i] <= '9') {
+ result += input[i];
+ cap_next_letter = true;
+ } else {
+ cap_next_letter = true;
+ }
+ }
+ return result;
+}
+
} // namespace
const char kThickSeparator[] =
@@ -124,6 +149,11 @@ string FieldName(const FieldDescriptor* field) {
return result;
}
+string FieldConstantName(const FieldDescriptor *field) {
+ string field_name = UnderscoresToCamelCase(field->name(), true);
+ return "k" + field_name + "FieldNumber";
+}
+
string StripProto(const string& filename) {
if (HasSuffixString(filename, ".protodevel")) {
return StripSuffixString(filename, ".protodevel");
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 80c2f2ee..30c6e7d0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -65,6 +65,10 @@ string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
// anyway, so normally this just returns field->name().
string FieldName(const FieldDescriptor* field);
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
// Returns the scope where the field was defined (for extensions, this is
// different from the message type to which the field applies).
inline const Descriptor* FieldScope(const FieldDescriptor* field) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index d2f76803..2ec49234 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -204,6 +204,8 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
map<string, string> vars;
vars["name"] = FieldName(field);
+ vars["constant_name"] = FieldConstantName(field);
+ vars["number"] = SimpleItoa(field->number());
if (field->is_repeated()) {
printer->Print(vars, "inline int $name$_size() const;\n");
@@ -212,6 +214,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
}
printer->Print(vars, "inline void clear_$name$();\n");
+ printer->Print(vars, "static const int $constant_name$ = $number$;\n");
// Generate type-specific accessor declarations.
field_generators_.get(field).GenerateAccessorDeclarations(printer);
@@ -665,9 +668,21 @@ GenerateClassMethods(io::Printer* printer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
.GenerateNonInlineAccessorDefinitions(printer);
- printer->Print("\n");
}
+ // Generate field number constants.
+ printer->Print("#ifndef _MSC_VER\n");
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor *field = descriptor_->field(i);
+ printer->Print(
+ "const int $classname$::$constant_name$;\n",
+ "classname", ClassName(FieldScope(field), false),
+ "constant_name", FieldConstantName(field));
+ }
+ printer->Print(
+ "#endif // !_MSC_VER\n"
+ "\n");
+
// Define extension identifiers.
for (int i = 0; i < descriptor_->extension_count(); i++) {
extension_generators_[i]->GenerateDefinition(printer);
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 51c5c6f5..8e10e9b0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -180,10 +180,10 @@ void StringFieldGenerator::
GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
if (descriptor_->default_value_string().empty()) {
printer->Print(variables_,
- "const ::std::string $classname$::_default_$name$_;");
+ "const ::std::string $classname$::_default_$name$_;\n");
} else {
printer->Print(variables_,
- "const ::std::string $classname$::_default_$name$_($default$);");
+ "const ::std::string $classname$::_default_$name$_($default$);\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_extension.cc b/src/google/protobuf/compiler/java/java_extension.cc
index 8f6500b5..302dcea4 100644
--- a/src/google/protobuf/compiler/java/java_extension.cc
+++ b/src/google/protobuf/compiler/java/java_extension.cc
@@ -57,6 +57,8 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
map<string, string> vars;
vars["name"] = UnderscoresToCamelCase(descriptor_);
vars["containing_type"] = ClassName(descriptor_->containing_type());
+ vars["number"] = SimpleItoa(descriptor_->number());
+ vars["constant_name"] = FieldConstantName(descriptor_);
JavaType java_type = GetJavaType(descriptor_);
string singular_type;
@@ -72,6 +74,8 @@ void ExtensionGenerator::Generate(io::Printer* printer) {
break;
}
+ printer->Print(vars,
+ "public static final int $constant_name$ = $number$;\n");
if (descriptor_->is_repeated()) {
printer->Print(vars,
"public static\n"
diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc
index c1994352..6a107650 100644
--- a/src/google/protobuf/compiler/java/java_helpers.cc
+++ b/src/google/protobuf/compiler/java/java_helpers.cc
@@ -171,6 +171,12 @@ string ClassName(const FileDescriptor* descriptor) {
return result;
}
+string FieldConstantName(const FieldDescriptor *field) {
+ string name = field->name() + "_FIELD_NUMBER";
+ UpperString(&name);
+ return name;
+}
+
JavaType GetJavaType(FieldDescriptor::Type field_type) {
switch (field_type) {
case FieldDescriptor::TYPE_INT32:
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index 43f2add0..de3f883b 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -88,6 +88,10 @@ inline string ExtensionIdentifierName(const FieldDescriptor* descriptor) {
}
string ClassName(const FileDescriptor* descriptor);
+// Get the unqualified name that should be used for a field's field
+// number constant.
+string FieldConstantName(const FieldDescriptor *field);
+
enum JavaType {
JAVATYPE_INT,
JAVATYPE_LONG,
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 9a4b2f79..c2e0c115 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -311,6 +311,9 @@ void MessageGenerator::Generate(io::Printer* printer) {
// Fields
for (int i = 0; i < descriptor_->field_count(); i++) {
PrintFieldComment(printer, descriptor_->field(i));
+ printer->Print("public static final int $constant_name$ = $number$;\n",
+ "constant_name", FieldConstantName(descriptor_->field(i)),
+ "number", SimpleItoa(descriptor_->field(i)->number()));
field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
printer->Print("\n");
}
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index ca69fd4c..d301f015 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -319,6 +319,11 @@ void Generator::PrintTopLevelExtensions() const {
const bool is_extension = true;
for (int i = 0; i < file_->extension_count(); ++i) {
const FieldDescriptor& extension_field = *file_->extension(i);
+ string constant_name = extension_field.name() + "_FIELD_NUMBER";
+ UpperString(&constant_name);
+ printer_->Print("$constant_name$ = $number$\n",
+ "constant_name", constant_name,
+ "number", SimpleItoa(extension_field.number()));
printer_->Print("$name$ = ", "name", extension_field.name());
PrintFieldDescriptor(extension_field, is_extension);
printer_->Print("\n");