Index: third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc |
diff --git a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc |
index cf5d8cfb234555d80cd721d798890460f091cf4c..66cb4a16084a0372687bf75d324faa96dfa35bd1 100644 |
--- a/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc |
+++ b/third_party/protobuf/src/google/protobuf/compiler/objectivec/objectivec_field.cc |
@@ -28,6 +28,8 @@ |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+#include <iostream> |
+ |
#include <google/protobuf/compiler/objectivec/objectivec_field.h> |
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> |
#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h> |
@@ -45,6 +47,7 @@ namespace compiler { |
namespace objectivec { |
namespace { |
+ |
void SetCommonFieldVariables(const FieldDescriptor* descriptor, |
map<string, string>* variables) { |
string camel_case_name = FieldName(descriptor); |
@@ -74,8 +77,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, |
(*variables)["field_number_name"] = |
classname + "_FieldNumber_" + capitalized_name; |
(*variables)["field_number"] = SimpleItoa(descriptor->number()); |
- (*variables)["has_index"] = SimpleItoa(descriptor->index()); |
(*variables)["field_type"] = GetCapitalizedType(descriptor); |
+ (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor); |
std::vector<string> field_flags; |
if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated"); |
if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired"); |
@@ -98,18 +101,9 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, |
(*variables)["dataTypeSpecific_name"] = "className"; |
(*variables)["dataTypeSpecific_value"] = "NULL"; |
- string field_options = descriptor->options().SerializeAsString(); |
- // Must convert to a standard byte order for packing length into |
- // a cstring. |
- uint32 length = ghtonl(field_options.length()); |
- if (length > 0) { |
- string bytes((const char*)&length, sizeof(length)); |
- bytes.append(field_options); |
- string options_str = "\"" + CEscape(bytes) + "\""; |
- (*variables)["fieldoptions"] = "\"" + CEscape(bytes) + "\""; |
- } else { |
- (*variables)["fieldoptions"] = ""; |
- } |
+ (*variables)["storage_offset_value"] = |
+ "(uint32_t)offsetof(" + classname + "__storage_, " + camel_case_name + ")"; |
+ (*variables)["storage_offset_comment"] = ""; |
// Clear some common things so they can be set just when needed. |
(*variables)["storage_attribute"] = ""; |
@@ -117,39 +111,40 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, |
} // namespace |
-FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { |
+FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, |
+ const Options& options) { |
FieldGenerator* result = NULL; |
if (field->is_repeated()) { |
switch (GetObjectiveCType(field)) { |
case OBJECTIVECTYPE_MESSAGE: { |
if (field->is_map()) { |
- result = new MapFieldGenerator(field); |
+ result = new MapFieldGenerator(field, options); |
} else { |
- result = new RepeatedMessageFieldGenerator(field); |
+ result = new RepeatedMessageFieldGenerator(field, options); |
} |
break; |
} |
case OBJECTIVECTYPE_ENUM: |
- result = new RepeatedEnumFieldGenerator(field); |
+ result = new RepeatedEnumFieldGenerator(field, options); |
break; |
default: |
- result = new RepeatedPrimitiveFieldGenerator(field); |
+ result = new RepeatedPrimitiveFieldGenerator(field, options); |
break; |
} |
} else { |
switch (GetObjectiveCType(field)) { |
case OBJECTIVECTYPE_MESSAGE: { |
- result = new MessageFieldGenerator(field); |
+ result = new MessageFieldGenerator(field, options); |
break; |
} |
case OBJECTIVECTYPE_ENUM: |
- result = new EnumFieldGenerator(field); |
+ result = new EnumFieldGenerator(field, options); |
break; |
default: |
if (IsReferenceType(field)) { |
- result = new PrimitiveObjFieldGenerator(field); |
+ result = new PrimitiveObjFieldGenerator(field, options); |
} else { |
- result = new PrimitiveFieldGenerator(field); |
+ result = new PrimitiveFieldGenerator(field, options); |
} |
break; |
} |
@@ -158,8 +153,8 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { |
return result; |
} |
- |
-FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) |
+FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, |
+ const Options& options) |
: descriptor_(descriptor) { |
SetCommonFieldVariables(descriptor, &variables_); |
} |
@@ -188,52 +183,54 @@ void FieldGenerator::DetermineForwardDeclarations( |
} |
void FieldGenerator::GenerateFieldDescription( |
- io::Printer* printer) const { |
- printer->Print( |
- variables_, |
- "{\n" |
- " .name = \"$name$\",\n" |
- " .number = $field_number_name$,\n" |
- " .hasIndex = $has_index$,\n" |
- " .flags = $fieldflags$,\n" |
- " .dataType = GPBDataType$field_type$,\n" |
- " .offset = offsetof($classname$__storage_, $name$),\n" |
- " .defaultValue.$default_name$ = $default$,\n"); |
- |
- // TODO(thomasvl): It might be useful to add a CPP wrapper to support |
- // compiling away the EnumDescriptors. To do that, we'd need a #if here |
- // to control setting the descriptor vs. the validator, and above in |
- // SetCommonFieldVariables() we'd want to wrap how we add |
- // GPBFieldHasDefaultValue to the flags. |
- |
- // " .dataTypeSpecific.value* = [something]," |
- GenerateFieldDescriptionTypeSpecific(printer); |
- |
- const string& field_options(variables_.find("fieldoptions")->second); |
- if (field_options.empty()) { |
- printer->Print(" .fieldOptions = NULL,\n"); |
+ io::Printer* printer, bool include_default) const { |
+ // Printed in the same order as the structure decl. |
+ if (include_default) { |
+ printer->Print( |
+ variables_, |
+ "{\n" |
+ " .defaultValue.$default_name$ = $default$,\n" |
+ " .core.name = \"$name$\",\n" |
+ " .core.dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n" |
+ " .core.number = $field_number_name$,\n" |
+ " .core.hasIndex = $has_index$,\n" |
+ " .core.offset = $storage_offset_value$,$storage_offset_comment$\n" |
+ " .core.flags = $fieldflags$,\n" |
+ " .core.dataType = GPBDataType$field_type$,\n" |
+ "},\n"); |
} else { |
- // Can't use PrintRaw() here to get the #if/#else/#endif lines completely |
- // outdented because the need for indent captured on the previous |
- // printing of a \n and there is no way to get the current indent level |
- // to call the right number of Outdent()/Indents() to maintain state. |
printer->Print( |
variables_, |
- "#if GPBOBJC_INCLUDE_FIELD_OPTIONS\n" |
- " .fieldOptions = $fieldoptions$,\n" |
- "#else\n" |
- " .fieldOptions = NULL,\n" |
- "#endif // GPBOBJC_INCLUDE_FIELD_OPTIONS\n"); |
+ "{\n" |
+ " .name = \"$name$\",\n" |
+ " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n" |
+ " .number = $field_number_name$,\n" |
+ " .hasIndex = $has_index$,\n" |
+ " .offset = $storage_offset_value$,$storage_offset_comment$\n" |
+ " .flags = $fieldflags$,\n" |
+ " .dataType = GPBDataType$field_type$,\n" |
+ "},\n"); |
} |
+} |
- printer->Print("},\n"); |
+void FieldGenerator::SetRuntimeHasBit(int has_index) { |
+ variables_["has_index"] = SimpleItoa(has_index); |
} |
-void FieldGenerator::GenerateFieldDescriptionTypeSpecific( |
- io::Printer* printer) const { |
- printer->Print( |
- variables_, |
- " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"); |
+void FieldGenerator::SetNoHasBit(void) { |
+ variables_["has_index"] = "GPBNoHasBit"; |
+} |
+ |
+int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { |
+ return 0; |
+} |
+ |
+void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) { |
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some |
+ // error cases, so it seems to be ok to use as a back door for errors. |
+ cerr << "Error: should have overriden SetExtraRuntimeHasBitsBase()." << endl; |
+ cerr.flush(); |
+ abort(); |
} |
void FieldGenerator::SetOneofIndexBase(int index_base) { |
@@ -252,9 +249,9 @@ void FieldGenerator::FinishInitialization(void) { |
} |
} |
-SingleFieldGenerator::SingleFieldGenerator( |
- const FieldDescriptor* descriptor) |
- : FieldGenerator(descriptor) { |
+SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor, |
+ const Options& options) |
+ : FieldGenerator(descriptor, options) { |
// Nothing |
} |
@@ -268,15 +265,15 @@ void SingleFieldGenerator::GenerateFieldStorageDeclaration( |
void SingleFieldGenerator::GeneratePropertyDeclaration( |
io::Printer* printer) const { |
printer->Print(variables_, "$comments$"); |
+ printer->Print( |
+ variables_, |
+ "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n" |
+ "\n"); |
if (WantsHasProperty()) { |
printer->Print( |
variables_, |
- "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n"); |
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n"); |
} |
- printer->Print( |
- variables_, |
- "@property(nonatomic, readwrite) $property_type$ $name$;\n" |
- "\n"); |
} |
void SingleFieldGenerator::GeneratePropertyImplementation( |
@@ -300,9 +297,17 @@ bool SingleFieldGenerator::WantsHasProperty(void) const { |
return false; |
} |
-ObjCObjFieldGenerator::ObjCObjFieldGenerator( |
- const FieldDescriptor* descriptor) |
- : SingleFieldGenerator(descriptor) { |
+bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { |
+ if (descriptor_->containing_oneof() != NULL) { |
+ // The oneof tracks what is set instead. |
+ return false; |
+ } |
+ return true; |
+} |
+ |
+ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, |
+ const Options& options) |
+ : SingleFieldGenerator(descriptor, options) { |
variables_["property_storage_attribute"] = "strong"; |
if (IsRetainedName(variables_["name"])) { |
variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; |
@@ -324,36 +329,38 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration( |
// conventions (init*, new*, etc.) |
printer->Print(variables_, "$comments$"); |
+ printer->Print( |
+ variables_, |
+ "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"); |
if (WantsHasProperty()) { |
printer->Print( |
variables_, |
- "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n"); |
+ "/// Test to see if @c $name$ has been set.\n" |
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n"); |
} |
- printer->Print( |
- variables_, |
- "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$;\n"); |
if (IsInitName(variables_.find("name")->second)) { |
// If property name starts with init we need to annotate it to get past ARC. |
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227 |
printer->Print(variables_, |
- "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n"); |
+ "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n"); |
} |
printer->Print("\n"); |
} |
RepeatedFieldGenerator::RepeatedFieldGenerator( |
- const FieldDescriptor* descriptor) |
- : ObjCObjFieldGenerator(descriptor) { |
- // Repeated fields don't use the has index. |
- variables_["has_index"] = "GPBNoHasBit"; |
+ const FieldDescriptor* descriptor, const Options& options) |
+ : ObjCObjFieldGenerator(descriptor, options) { |
+ // Default to no comment and let the cases needing it fill it in. |
+ variables_["array_comment"] = ""; |
} |
RepeatedFieldGenerator::~RepeatedFieldGenerator() {} |
void RepeatedFieldGenerator::FinishInitialization(void) { |
FieldGenerator::FinishInitialization(); |
- variables_["array_comment"] = |
- "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n"; |
+ if (variables_.find("array_property_type") == variables_.end()) { |
+ variables_["array_property_type"] = variable("array_storage_type"); |
+ } |
} |
void RepeatedFieldGenerator::GenerateFieldStorageDeclaration( |
@@ -379,13 +386,14 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration( |
variables_, |
"$comments$" |
"$array_comment$" |
- "@property(nonatomic, readwrite, strong, null_resettable) $array_storage_type$ *$name$$storage_attribute$;\n" |
- "@property(nonatomic, readonly) NSUInteger $name$_Count;\n"); |
+ "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n" |
+ "/// The number of items in @c $name$ without causing the array to be created.\n" |
+ "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n"); |
if (IsInitName(variables_.find("name")->second)) { |
// If property name starts with init we need to annotate it to get past ARC. |
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227 |
printer->Print(variables_, |
- "- ($array_storage_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n"); |
+ "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n"); |
} |
printer->Print("\n"); |
} |
@@ -395,7 +403,12 @@ bool RepeatedFieldGenerator::WantsHasProperty(void) const { |
return false; |
} |
-FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) |
+bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { |
+ return false; // The array having anything is what is used. |
+} |
+ |
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, |
+ const Options& options) |
: descriptor_(descriptor), |
field_generators_( |
new scoped_ptr<FieldGenerator>[descriptor->field_count()]), |
@@ -403,10 +416,12 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) |
new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) { |
// Construct all the FieldGenerators. |
for (int i = 0; i < descriptor->field_count(); i++) { |
- field_generators_[i].reset(FieldGenerator::Make(descriptor->field(i))); |
+ field_generators_[i].reset( |
+ FieldGenerator::Make(descriptor->field(i), options)); |
} |
for (int i = 0; i < descriptor->extension_count(); i++) { |
- extension_generators_[i].reset(FieldGenerator::Make(descriptor->extension(i))); |
+ extension_generators_[i].reset( |
+ FieldGenerator::Make(descriptor->extension(i), options)); |
} |
} |
@@ -422,12 +437,40 @@ const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { |
return *extension_generators_[index]; |
} |
+int FieldGeneratorMap::CalculateHasBits(void) { |
+ int total_bits = 0; |
+ for (int i = 0; i < descriptor_->field_count(); i++) { |
+ if (field_generators_[i]->RuntimeUsesHasBit()) { |
+ field_generators_[i]->SetRuntimeHasBit(total_bits); |
+ ++total_bits; |
+ } else { |
+ field_generators_[i]->SetNoHasBit(); |
+ } |
+ int extra_bits = field_generators_[i]->ExtraRuntimeHasBitsNeeded(); |
+ if (extra_bits) { |
+ field_generators_[i]->SetExtraRuntimeHasBitsBase(total_bits); |
+ total_bits += extra_bits; |
+ } |
+ } |
+ return total_bits; |
+} |
+ |
void FieldGeneratorMap::SetOneofIndexBase(int index_base) { |
for (int i = 0; i < descriptor_->field_count(); i++) { |
field_generators_[i]->SetOneofIndexBase(index_base); |
} |
} |
+bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const { |
+ for (int i = 0; i < descriptor_->field_count(); i++) { |
+ if (HasNonZeroDefaultValue(descriptor_->field(i))) { |
+ return true; |
+ } |
+ } |
+ |
+ return false; |
+} |
+ |
} // namespace objectivec |
} // namespace compiler |
} // namespace protobuf |