Media CAS Proxy SDK release: 16.5.0
This commit is contained in:
179
ubuntu/google/protobuf/compiler/objectivec/method_dump.sh
Normal file
179
ubuntu/google/protobuf/compiler/objectivec/method_dump.sh
Normal file
@@ -0,0 +1,179 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Updates objectivec_nsobject_methods.h by generating a list of all of the properties
|
||||
# and methods on NSObject that Protobufs should not overload from iOS and macOS combined.
|
||||
#
|
||||
# The rules:
|
||||
# - No property should ever be overloaded.
|
||||
# - Do not overload any methods that have 0 args such as "autorelease".
|
||||
# - Do not overload any methods that start with "set[A-Z]" and have 1 arg such as
|
||||
# "setValuesForKeysWithDictionary:". Note that these will end up in the list as just
|
||||
# the "proto field" name, so "setValuesForKeysWithDictionary:" will become
|
||||
# "valuesForKeysWithDictionary".
|
||||
|
||||
set -eu
|
||||
|
||||
trim() {
|
||||
local var="$*"
|
||||
# remove leading whitespace characters
|
||||
var="${var#"${var%%[![:space:]]*}"}"
|
||||
# remove trailing whitespace characters
|
||||
var="${var%"${var##*[![:space:]]}"}"
|
||||
echo -n "$var"
|
||||
}
|
||||
|
||||
objc_code=$(cat <<'END_CODE'
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <objc/runtime.h>
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
Class cls = [NSObject class];
|
||||
|
||||
// List out the protocols on NSObject just so we are aware if they change.
|
||||
unsigned int protocolCount;
|
||||
__unsafe_unretained Protocol **protocols =
|
||||
class_copyProtocolList(cls, &protocolCount);
|
||||
for (unsigned int i = 0; i < protocolCount; i++) {
|
||||
printf("// Protocol: %s\n", protocol_getName(protocols[i]));
|
||||
}
|
||||
free(protocols);
|
||||
|
||||
// Grab all the properties.
|
||||
unsigned int propCount;
|
||||
objc_property_t *props = class_copyPropertyList(cls, &propCount);
|
||||
NSMutableSet *reservedNames = [[NSMutableSet alloc] init];
|
||||
for (unsigned int i = 0; i < propCount; ++i) {
|
||||
NSString *propertyName = [NSString stringWithUTF8String:property_getName(props[i])];
|
||||
[reservedNames addObject:propertyName];
|
||||
}
|
||||
free(props);
|
||||
|
||||
// Note that methods have 2 defaults args (_cmd and SEL) so a method "0 arg method"
|
||||
// actually has 2.
|
||||
unsigned int methodCount;
|
||||
Method *methods = class_copyMethodList(cls, &methodCount);
|
||||
for (unsigned int i = 0; i < methodCount; ++i) {
|
||||
int argCount = method_getNumberOfArguments(methods[i]);
|
||||
NSString *methodName =
|
||||
[NSString stringWithUTF8String:sel_getName(method_getName(methods[i]))];
|
||||
if (argCount == 2) {
|
||||
[reservedNames addObject:methodName];
|
||||
}
|
||||
if (argCount == 3 && [methodName hasPrefix:@"set"] && methodName.length > 4) {
|
||||
NSString *firstLetter = [methodName substringWithRange:NSMakeRange(3,1)];
|
||||
NSString *lowerFirstLetter = [firstLetter lowercaseString];
|
||||
if ([lowerFirstLetter isEqual:firstLetter]) {
|
||||
// Make sure the next letter is a capital letter so we do not take things like
|
||||
// settingSomething:
|
||||
continue;
|
||||
}
|
||||
// -5 because 3 for set, 1 for the firstLetter and 1 for the colon on the end.
|
||||
NSString *restOfString =
|
||||
[methodName substringWithRange:NSMakeRange(4, methodName.length - 5)];
|
||||
methodName = [lowerFirstLetter stringByAppendingString:restOfString];
|
||||
[reservedNames addObject:methodName];
|
||||
}
|
||||
}
|
||||
free(methods);
|
||||
|
||||
SEL sortSelector = @selector(caseInsensitiveCompare:);
|
||||
NSArray *array = [reservedNames.allObjects sortedArrayUsingSelector:sortSelector];
|
||||
for (NSString *item in array) {
|
||||
// Some items with _ in them get returned in quotes, so do not add more.
|
||||
if ([item hasPrefix:@"\""]) {
|
||||
printf("\t%s,\n", item.UTF8String);
|
||||
} else {
|
||||
printf("\t\"%s\",\n", item.UTF8String);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
END_CODE
|
||||
)
|
||||
|
||||
file_header=$(cat <<'END_HEADER'
|
||||
// NSObject methods
|
||||
// Autogenerated by method_dump.sh. Do not edit by hand.
|
||||
// Date: %DATE%
|
||||
// macOS: %MACOS%
|
||||
// iOS: %IOS%
|
||||
|
||||
const char* const kNSObjectMethodsList[] = {
|
||||
END_HEADER
|
||||
)
|
||||
|
||||
file_footer=$(cat <<'END_FOOTER'
|
||||
};
|
||||
END_FOOTER
|
||||
)
|
||||
|
||||
# Check to make sure we are updating the correct file.
|
||||
if [[ ! -e "objectivec_nsobject_methods.h" ]]; then
|
||||
echo "error: Must be run in the src/google/protobuf/compiler/objectivec directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
temp_dir=$(mktemp -d)
|
||||
|
||||
echo "$objc_code" >> "$temp_dir"/method_dump.m
|
||||
|
||||
# Compile up iphonesimulator and macos version of cmd line app.
|
||||
iphone_simulator_sdk=$(xcrun --sdk iphonesimulator --show-sdk-path)
|
||||
clang -isysroot "$iphone_simulator_sdk" -o "$temp_dir"/method_dump_ios \
|
||||
-framework Foundation -framework UIKit "$temp_dir"/method_dump.m
|
||||
macos_sdk=$(xcrun --sdk macosx --show-sdk-path)
|
||||
clang -isysroot "$macos_sdk" -o "$temp_dir"/method_dump_macos -framework Foundation \
|
||||
-framework Cocoa "$temp_dir"/method_dump.m
|
||||
|
||||
# Create a device of the latest phone and iphonesimulator SDK and run our iOS cmd line.
|
||||
device_type=$(xcrun simctl list devicetypes | grep \.iPhone- | tail -1 | sed 's/.*(\(.*\))/\1/')
|
||||
# runtimes come with a space at the end (for Xcode 10) so let's trim all of our input to
|
||||
# be safe.
|
||||
device_type=$(trim "$device_type")
|
||||
runtime=$(xcrun simctl list runtimes | grep \.iOS- | tail -1 | \
|
||||
sed 's/.*\(com\.apple.\CoreSimulator\.SimRuntime\.iOS.*\)/\1/')
|
||||
runtime=$(trim "$runtime")
|
||||
uuid=$(uuidgen)
|
||||
device_name="method_dump_device_$uuid"
|
||||
device=$(xcrun simctl create "$device_name" "$device_type" "$runtime")
|
||||
xcrun simctl spawn "$device" "$temp_dir"/method_dump_ios > "$temp_dir"/methods_unsorted_ios.txt
|
||||
xcrun simctl delete "$device"
|
||||
|
||||
# Run the Mac version
|
||||
"$temp_dir"/method_dump_macos >> "$temp_dir"/methods_unsorted_macos.txt
|
||||
|
||||
# Generate sorted output
|
||||
echo "$file_header" | sed -e "s|%DATE%|$(date)|" -e "s|%MACOS%|$(basename $macos_sdk)|" \
|
||||
-e "s|%IOS%|$(basename $iphone_simulator_sdk)|" > "$temp_dir"/methods_sorted.txt
|
||||
sort -u "$temp_dir"/methods_unsorted_ios.txt \
|
||||
"$temp_dir"/methods_unsorted_macos.txt >> "$temp_dir"/methods_sorted.txt
|
||||
echo $"$file_footer" >> "$temp_dir"/methods_sorted.txt
|
||||
|
||||
# Check for differences. Turn off error checking because we expect diff to fail when
|
||||
# there are no differences.
|
||||
set +e
|
||||
diff_out=$(diff -I "^//.*$" "$temp_dir"/methods_sorted.txt objectivec_nsobject_methods.h)
|
||||
removed_methods=$(echo "$diff_out" | grep '^>.*$')
|
||||
set -e
|
||||
if [[ -n "$removed_methods" ]]; then
|
||||
echo "error: Methods removed from NSObject"
|
||||
echo "It appears that some methods may have been removed from NSObject."
|
||||
echo "This could mean that there may be some backwards compatibility issues."
|
||||
echo "You could potentially build apps that may not work on earlier systems than:"
|
||||
echo "$iphone_simulator_sdk"
|
||||
echo "$macos_sdk"
|
||||
echo "If they declare protobuf types that use any of the following as names:"
|
||||
echo "$removed_methods"
|
||||
echo ""
|
||||
echo "New Version: $temp_dir/methods_sorted.txt"
|
||||
echo "Old Version: objectivec_nsobject_methods.h"
|
||||
exit 1
|
||||
fi
|
||||
if [[ -n "$diff_out" ]]; then
|
||||
echo "Added Methods:"
|
||||
echo "$(echo "$diff_out" | grep '^<.*$' | sed -e 's/^< "\(.*\)",$/ \1/')"
|
||||
fi;
|
||||
cp "$temp_dir"/methods_sorted.txt objectivec_nsobject_methods.h
|
||||
rm -rf "$temp_dir"
|
||||
261
ubuntu/google/protobuf/compiler/objectivec/objectivec_enum.cc
Normal file
261
ubuntu/google/protobuf/compiler/objectivec/objectivec_enum.cc
Normal file
@@ -0,0 +1,261 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_enum.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <algorithm> // std::find()
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
|
||||
: descriptor_(descriptor),
|
||||
name_(EnumName(descriptor_)) {
|
||||
// Track the names for the enum values, and if an alias overlaps a base
|
||||
// value, skip making a name for it. Likewise if two alias overlap, the
|
||||
// first one wins.
|
||||
// The one gap in this logic is if two base values overlap, but for that
|
||||
// to happen you have to have "Foo" and "FOO" or "FOO_BAR" and "FooBar",
|
||||
// and if an enum has that, it is already going to be confusing and a
|
||||
// compile error is just fine.
|
||||
// The values are still tracked to support the reflection apis and
|
||||
// TextFormat handing since they are different there.
|
||||
std::set<std::string> value_names;
|
||||
|
||||
for (int i = 0; i < descriptor_->value_count(); i++) {
|
||||
const EnumValueDescriptor* value = descriptor_->value(i);
|
||||
const EnumValueDescriptor* canonical_value =
|
||||
descriptor_->FindValueByNumber(value->number());
|
||||
|
||||
if (value == canonical_value) {
|
||||
base_values_.push_back(value);
|
||||
value_names.insert(EnumValueName(value));
|
||||
} else {
|
||||
std::string value_name(EnumValueName(value));
|
||||
if (value_names.find(value_name) != value_names.end()) {
|
||||
alias_values_to_skip_.insert(value);
|
||||
} else {
|
||||
value_names.insert(value_name);
|
||||
}
|
||||
}
|
||||
all_values_.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
EnumGenerator::~EnumGenerator() {}
|
||||
|
||||
void EnumGenerator::GenerateHeader(io::Printer* printer) {
|
||||
std::string enum_comments;
|
||||
SourceLocation location;
|
||||
if (descriptor_->GetSourceLocation(&location)) {
|
||||
enum_comments = BuildCommentsString(location, true);
|
||||
} else {
|
||||
enum_comments = "";
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"#pragma mark - Enum $name$\n"
|
||||
"\n",
|
||||
"name", name_);
|
||||
|
||||
// Swift 5 included SE0192 "Handling Future Enum Cases"
|
||||
// https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
|
||||
// Since a .proto file can get new values added to an enum at any time, they
|
||||
// are effectively "non-frozen". Even in a proto3 syntax file where there is
|
||||
// support for the unknown value, an edit to the file can always add a new
|
||||
// value moving something from unknown to known. Since Swift is now ABI
|
||||
// stable, it also means a binary could contain Swift compiled against one
|
||||
// version of the .pbobjc.h file, but finally linked against an enum with
|
||||
// more cases. So the Swift code will always have to treat ObjC Proto Enums
|
||||
// as "non-frozen". The default behavior in SE0192 is for all objc enums to
|
||||
// be "non-frozen" unless marked as otherwise, so this means this generation
|
||||
// doesn't have to bother with the `enum_extensibility` attribute, as the
|
||||
// default will be what is needed.
|
||||
|
||||
printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
|
||||
"comments", enum_comments,
|
||||
"deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()),
|
||||
"name", name_);
|
||||
printer->Indent();
|
||||
|
||||
if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
|
||||
// Include the unknown value.
|
||||
printer->Print(
|
||||
"/**\n"
|
||||
" * Value used if any message's field encounters a value that is not defined\n"
|
||||
" * by this enum. The message will also have C functions to get/set the rawValue\n"
|
||||
" * of the field.\n"
|
||||
" **/\n"
|
||||
"$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
|
||||
"name", name_);
|
||||
}
|
||||
for (int i = 0; i < all_values_.size(); i++) {
|
||||
if (alias_values_to_skip_.find(all_values_[i]) != alias_values_to_skip_.end()) {
|
||||
continue;
|
||||
}
|
||||
SourceLocation location;
|
||||
if (all_values_[i]->GetSourceLocation(&location)) {
|
||||
std::string comments = BuildCommentsString(location, true).c_str();
|
||||
if (comments.length() > 0) {
|
||||
if (i > 0) {
|
||||
printer->Print("\n");
|
||||
}
|
||||
printer->Print(comments.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"$name$$deprecated_attribute$ = $value$,\n",
|
||||
"name", EnumValueName(all_values_[i]),
|
||||
"deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]),
|
||||
"value", StrCat(all_values_[i]->number()));
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n"
|
||||
"\n"
|
||||
"GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
|
||||
"\n"
|
||||
"/**\n"
|
||||
" * Checks to see if the given value is defined by the enum or was not known at\n"
|
||||
" * the time this source was generated.\n"
|
||||
" **/\n"
|
||||
"BOOL $name$_IsValidValue(int32_t value);\n"
|
||||
"\n",
|
||||
"name", name_);
|
||||
}
|
||||
|
||||
void EnumGenerator::GenerateSource(io::Printer* printer) {
|
||||
printer->Print(
|
||||
"#pragma mark - Enum $name$\n"
|
||||
"\n",
|
||||
"name", name_);
|
||||
|
||||
// Note: For the TextFormat decode info, we can't use the enum value as
|
||||
// the key because protocol buffer enums have 'allow_alias', which lets
|
||||
// a value be used more than once. Instead, the index into the list of
|
||||
// enum value descriptions is used. Note: start with -1 so the first one
|
||||
// will be zero.
|
||||
TextFormatDecodeData text_format_decode_data;
|
||||
int enum_value_description_key = -1;
|
||||
std::string text_blob;
|
||||
|
||||
for (int i = 0; i < all_values_.size(); i++) {
|
||||
++enum_value_description_key;
|
||||
std::string short_name(EnumValueShortName(all_values_[i]));
|
||||
text_blob += short_name + '\0';
|
||||
if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) {
|
||||
text_format_decode_data.AddString(enum_value_description_key, short_name,
|
||||
all_values_[i]->name());
|
||||
}
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
|
||||
" static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n"
|
||||
" if (!descriptor) {\n",
|
||||
"name", name_);
|
||||
|
||||
static const int kBytesPerLine = 40; // allow for escaping
|
||||
printer->Print(
|
||||
" static const char *valueNames =");
|
||||
for (int i = 0; i < text_blob.size(); i += kBytesPerLine) {
|
||||
printer->Print(
|
||||
"\n \"$data$\"",
|
||||
"data", EscapeTrigraphs(CEscape(text_blob.substr(i, kBytesPerLine))));
|
||||
}
|
||||
printer->Print(
|
||||
";\n"
|
||||
" static const int32_t values[] = {\n");
|
||||
for (int i = 0; i < all_values_.size(); i++) {
|
||||
printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
|
||||
}
|
||||
printer->Print(" };\n");
|
||||
|
||||
if (text_format_decode_data.num_entries() == 0) {
|
||||
printer->Print(
|
||||
" GPBEnumDescriptor *worker =\n"
|
||||
" [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
|
||||
" valueNames:valueNames\n"
|
||||
" values:values\n"
|
||||
" count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
|
||||
" enumVerifier:$name$_IsValidValue];\n",
|
||||
"name", name_);
|
||||
} else {
|
||||
printer->Print(
|
||||
" static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
|
||||
" GPBEnumDescriptor *worker =\n"
|
||||
" [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
|
||||
" valueNames:valueNames\n"
|
||||
" values:values\n"
|
||||
" count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
|
||||
" enumVerifier:$name$_IsValidValue\n"
|
||||
" extraTextFormatInfo:extraTextFormatInfo];\n",
|
||||
"name", name_,
|
||||
"extraTextFormatInfo", CEscape(text_format_decode_data.Data()));
|
||||
}
|
||||
printer->Print(
|
||||
" GPBEnumDescriptor *expected = nil;\n"
|
||||
" if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n"
|
||||
" [worker release];\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" return descriptor;\n"
|
||||
"}\n\n");
|
||||
|
||||
printer->Print(
|
||||
"BOOL $name$_IsValidValue(int32_t value__) {\n"
|
||||
" switch (value__) {\n",
|
||||
"name", name_);
|
||||
|
||||
for (int i = 0; i < base_values_.size(); i++) {
|
||||
printer->Print(
|
||||
" case $name$:\n",
|
||||
"name", EnumValueName(base_values_[i]));
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
" return YES;\n"
|
||||
" default:\n"
|
||||
" return NO;\n"
|
||||
" }\n"
|
||||
"}\n\n");
|
||||
}
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
71
ubuntu/google/protobuf/compiler/objectivec/objectivec_enum.h
Normal file
71
ubuntu/google/protobuf/compiler/objectivec/objectivec_enum.h
Normal file
@@ -0,0 +1,71 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class EnumGenerator {
|
||||
public:
|
||||
explicit EnumGenerator(const EnumDescriptor* descriptor);
|
||||
~EnumGenerator();
|
||||
|
||||
EnumGenerator(const EnumGenerator&) = delete;
|
||||
EnumGenerator& operator=(const EnumGenerator&) = delete;
|
||||
|
||||
void GenerateHeader(io::Printer* printer);
|
||||
void GenerateSource(io::Printer* printer);
|
||||
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
private:
|
||||
const EnumDescriptor* descriptor_;
|
||||
std::vector<const EnumValueDescriptor*> base_values_;
|
||||
std::vector<const EnumValueDescriptor*> all_values_;
|
||||
std::set<const EnumValueDescriptor*> alias_values_to_skip_;
|
||||
const std::string name_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
|
||||
@@ -0,0 +1,149 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetEnumVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables) {
|
||||
std::string type = EnumName(descriptor->enum_type());
|
||||
(*variables)["storage_type"] = type;
|
||||
// For non repeated fields, if it was defined in a different file, the
|
||||
// property decls need to use "enum NAME" rather than just "NAME" to support
|
||||
// the forward declaration of the enums.
|
||||
if (!descriptor->is_repeated() &&
|
||||
(descriptor->file() != descriptor->enum_type()->file())) {
|
||||
(*variables)["property_type"] = "enum " + type;
|
||||
}
|
||||
(*variables)["enum_verifier"] = type + "_IsValidValue";
|
||||
(*variables)["enum_desc_func"] = type + "_EnumDescriptor";
|
||||
|
||||
(*variables)["dataTypeSpecific_name"] = "enumDescFunc";
|
||||
(*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"];
|
||||
|
||||
const Descriptor* msg_descriptor = descriptor->containing_type();
|
||||
(*variables)["owning_message_class"] = ClassName(msg_descriptor);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: SingleFieldGenerator(descriptor, options) {
|
||||
SetEnumVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
EnumFieldGenerator::~EnumFieldGenerator() {}
|
||||
|
||||
void EnumFieldGenerator::GenerateCFunctionDeclarations(
|
||||
io::Printer* printer) const {
|
||||
if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
|
||||
return;
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
variables_,
|
||||
"/**\n"
|
||||
" * Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
|
||||
" * if the value was not defined by the enum at the time the code was generated.\n"
|
||||
" **/\n"
|
||||
"int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n"
|
||||
"/**\n"
|
||||
" * Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
|
||||
" * it to be set to a value that was not defined by the enum at the time the code\n"
|
||||
" * was generated.\n"
|
||||
" **/\n"
|
||||
"void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::GenerateCFunctionImplementations(
|
||||
io::Printer* printer) const {
|
||||
if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return;
|
||||
|
||||
printer->Print(
|
||||
variables_,
|
||||
"int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n"
|
||||
" GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
|
||||
" GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
|
||||
" return GPBGetMessageRawEnumField(message, field);\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n"
|
||||
" GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
|
||||
" GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
|
||||
" GPBSetMessageRawEnumField(message, field, value);\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void EnumFieldGenerator::DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls);
|
||||
// If it is an enum defined in a different file, then we'll need a forward
|
||||
// declaration for it. When it is in our file, all the enums are output
|
||||
// before the message, so it will be declared before it is needed.
|
||||
if (descriptor_->file() != descriptor_->enum_type()->file()) {
|
||||
// Enum name is already in "storage_type".
|
||||
const std::string& name = variable("storage_type");
|
||||
fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")");
|
||||
}
|
||||
}
|
||||
|
||||
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: RepeatedFieldGenerator(descriptor, options) {
|
||||
SetEnumVariables(descriptor, &variables_);
|
||||
variables_["array_storage_type"] = "GPBEnumArray";
|
||||
}
|
||||
|
||||
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
|
||||
|
||||
void RepeatedEnumFieldGenerator::FinishInitialization(void) {
|
||||
RepeatedFieldGenerator::FinishInitialization();
|
||||
variables_["array_comment"] =
|
||||
"// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,78 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_field.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class EnumFieldGenerator : public SingleFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
EnumFieldGenerator(const EnumFieldGenerator&) = delete;
|
||||
EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete;
|
||||
|
||||
public:
|
||||
virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
|
||||
virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
|
||||
virtual void DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
|
||||
protected:
|
||||
EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
|
||||
virtual ~EnumFieldGenerator();
|
||||
};
|
||||
|
||||
class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
public:
|
||||
virtual void FinishInitialization();
|
||||
|
||||
protected:
|
||||
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
virtual ~RepeatedEnumFieldGenerator();
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
|
||||
@@ -0,0 +1,156 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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_extension.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name,
|
||||
const FieldDescriptor* descriptor)
|
||||
: method_name_(ExtensionMethodName(descriptor)),
|
||||
root_class_and_method_name_(root_class_name + "_" + method_name_),
|
||||
descriptor_(descriptor) {
|
||||
if (descriptor->is_map()) {
|
||||
// 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.
|
||||
std::cerr << "error: Extension is a map<>!"
|
||||
<< " That used to be blocked by the compiler." << std::endl;
|
||||
std::cerr.flush();
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionGenerator::~ExtensionGenerator() {}
|
||||
|
||||
void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
|
||||
std::map<std::string, std::string> vars;
|
||||
vars["method_name"] = method_name_;
|
||||
if (IsRetainedName(method_name_)) {
|
||||
vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
|
||||
} else {
|
||||
vars["storage_attribute"] = "";
|
||||
}
|
||||
SourceLocation location;
|
||||
if (descriptor_->GetSourceLocation(&location)) {
|
||||
vars["comments"] = BuildCommentsString(location, true);
|
||||
} else {
|
||||
vars["comments"] = "";
|
||||
}
|
||||
// Unlike normal message fields, check if the file for the extension was
|
||||
// deprecated.
|
||||
vars["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file());
|
||||
printer->Print(vars,
|
||||
"$comments$"
|
||||
"+ (GPBExtensionDescriptor *)$method_name$$storage_attribute$$deprecated_attribute$;\n");
|
||||
}
|
||||
|
||||
void ExtensionGenerator::GenerateStaticVariablesInitialization(
|
||||
io::Printer* printer) {
|
||||
std::map<std::string, std::string> vars;
|
||||
vars["root_class_and_method_name"] = root_class_and_method_name_;
|
||||
const std::string containing_type = ClassName(descriptor_->containing_type());
|
||||
vars["extended_type"] = ObjCClass(containing_type);
|
||||
vars["number"] = StrCat(descriptor_->number());
|
||||
|
||||
std::vector<std::string> options;
|
||||
if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
|
||||
if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked");
|
||||
if (descriptor_->containing_type()->options().message_set_wire_format()) {
|
||||
options.push_back("GPBExtensionSetWireFormat");
|
||||
}
|
||||
vars["options"] = BuildFlagsString(FLAGTYPE_EXTENSION, options);
|
||||
|
||||
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
|
||||
if (objc_type == OBJECTIVECTYPE_MESSAGE) {
|
||||
std::string message_type = ClassName(descriptor_->message_type());
|
||||
vars["type"] = ObjCClass(message_type);
|
||||
} else {
|
||||
vars["type"] = "Nil";
|
||||
}
|
||||
|
||||
vars["default_name"] = GPBGenericValueFieldName(descriptor_);
|
||||
if (descriptor_->is_repeated()) {
|
||||
vars["default"] = "nil";
|
||||
} else {
|
||||
vars["default"] = DefaultValue(descriptor_);
|
||||
}
|
||||
std::string type = GetCapitalizedType(descriptor_);
|
||||
vars["extension_type"] = std::string("GPBDataType") + type;
|
||||
|
||||
if (objc_type == OBJECTIVECTYPE_ENUM) {
|
||||
vars["enum_desc_func_name"] =
|
||||
EnumName(descriptor_->enum_type()) + "_EnumDescriptor";
|
||||
} else {
|
||||
vars["enum_desc_func_name"] = "NULL";
|
||||
}
|
||||
|
||||
printer->Print(vars,
|
||||
"{\n"
|
||||
" .defaultValue.$default_name$ = $default$,\n"
|
||||
" .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n"
|
||||
" .extendedClass.clazz = $extended_type$,\n"
|
||||
" .messageOrGroupClass.clazz = $type$,\n"
|
||||
" .enumDescriptorFunc = $enum_desc_func_name$,\n"
|
||||
" .fieldNumber = $number$,\n"
|
||||
" .dataType = $extension_type$,\n"
|
||||
" .options = $options$,\n"
|
||||
"},\n");
|
||||
}
|
||||
|
||||
void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) {
|
||||
std::string extended_type = ClassName(descriptor_->containing_type());
|
||||
fwd_decls->insert(ObjCClassDeclaration(extended_type));
|
||||
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
|
||||
if (objc_type == OBJECTIVECTYPE_MESSAGE) {
|
||||
std::string message_type = ClassName(descriptor_->message_type());
|
||||
fwd_decls->insert(ObjCClassDeclaration(message_type));
|
||||
}
|
||||
}
|
||||
|
||||
void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) {
|
||||
printer->Print(
|
||||
"[registry addExtension:$root_class_and_method_name$];\n",
|
||||
"root_class_and_method_name", root_class_and_method_name_);
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,67 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class ExtensionGenerator {
|
||||
public:
|
||||
ExtensionGenerator(const std::string& root_class_name,
|
||||
const FieldDescriptor* descriptor);
|
||||
~ExtensionGenerator();
|
||||
|
||||
ExtensionGenerator(const ExtensionGenerator&) = delete;
|
||||
ExtensionGenerator& operator=(const ExtensionGenerator&) = delete;
|
||||
|
||||
void GenerateMembersHeader(io::Printer* printer);
|
||||
void GenerateStaticVariablesInitialization(io::Printer* printer);
|
||||
void GenerateRegistrationSource(io::Printer* printer);
|
||||
void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
|
||||
|
||||
private:
|
||||
std::string method_name_;
|
||||
std::string root_class_and_method_name_;
|
||||
const FieldDescriptor* descriptor_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
|
||||
475
ubuntu/google/protobuf/compiler/objectivec/objectivec_field.cc
Normal file
475
ubuntu/google/protobuf/compiler/objectivec/objectivec_field.cc
Normal file
@@ -0,0 +1,475 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_map_field.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_message_field.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetCommonFieldVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables) {
|
||||
std::string camel_case_name = FieldName(descriptor);
|
||||
std::string raw_field_name;
|
||||
if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
|
||||
raw_field_name = descriptor->message_type()->name();
|
||||
} else {
|
||||
raw_field_name = descriptor->name();
|
||||
}
|
||||
// The logic here has to match -[GGPBFieldDescriptor textFormatName].
|
||||
const std::string un_camel_case_name(
|
||||
UnCamelCaseFieldName(camel_case_name, descriptor));
|
||||
const bool needs_custom_name = (raw_field_name != un_camel_case_name);
|
||||
|
||||
SourceLocation location;
|
||||
if (descriptor->GetSourceLocation(&location)) {
|
||||
(*variables)["comments"] = BuildCommentsString(location, true);
|
||||
} else {
|
||||
(*variables)["comments"] = "\n";
|
||||
}
|
||||
const std::string& classname = ClassName(descriptor->containing_type());
|
||||
(*variables)["classname"] = classname;
|
||||
(*variables)["name"] = camel_case_name;
|
||||
const std::string& capitalized_name = FieldNameCapitalized(descriptor);
|
||||
(*variables)["capitalized_name"] = capitalized_name;
|
||||
(*variables)["raw_field_name"] = raw_field_name;
|
||||
(*variables)["field_number_name"] =
|
||||
classname + "_FieldNumber_" + capitalized_name;
|
||||
(*variables)["field_number"] = StrCat(descriptor->number());
|
||||
(*variables)["field_type"] = GetCapitalizedType(descriptor);
|
||||
(*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
|
||||
std::vector<std::string> field_flags;
|
||||
if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
|
||||
if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
|
||||
if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
|
||||
if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked");
|
||||
|
||||
// ObjC custom flags.
|
||||
if (descriptor->has_default_value())
|
||||
field_flags.push_back("GPBFieldHasDefaultValue");
|
||||
if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
|
||||
if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
|
||||
field_flags.push_back("GPBFieldHasEnumDescriptor");
|
||||
}
|
||||
// It will clear on a zero value if...
|
||||
// - not repeated/map
|
||||
// - doesn't have presence
|
||||
bool clear_on_zero =
|
||||
(!descriptor->is_repeated() && !descriptor->has_presence());
|
||||
if (clear_on_zero) {
|
||||
field_flags.push_back("GPBFieldClearHasIvarOnZero");
|
||||
}
|
||||
|
||||
(*variables)["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
|
||||
|
||||
(*variables)["default"] = DefaultValue(descriptor);
|
||||
(*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
|
||||
|
||||
(*variables)["dataTypeSpecific_name"] = "clazz";
|
||||
(*variables)["dataTypeSpecific_value"] = "Nil";
|
||||
|
||||
(*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"] = "";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
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, options);
|
||||
} else {
|
||||
result = new RepeatedMessageFieldGenerator(field, options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OBJECTIVECTYPE_ENUM:
|
||||
result = new RepeatedEnumFieldGenerator(field, options);
|
||||
break;
|
||||
default:
|
||||
result = new RepeatedPrimitiveFieldGenerator(field, options);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (GetObjectiveCType(field)) {
|
||||
case OBJECTIVECTYPE_MESSAGE: {
|
||||
result = new MessageFieldGenerator(field, options);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVECTYPE_ENUM:
|
||||
result = new EnumFieldGenerator(field, options);
|
||||
break;
|
||||
default:
|
||||
if (IsReferenceType(field)) {
|
||||
result = new PrimitiveObjFieldGenerator(field, options);
|
||||
} else {
|
||||
result = new PrimitiveFieldGenerator(field, options);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
result->FinishInitialization();
|
||||
return result;
|
||||
}
|
||||
|
||||
FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: descriptor_(descriptor) {
|
||||
SetCommonFieldVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
FieldGenerator::~FieldGenerator() {}
|
||||
|
||||
void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"$field_number_name$ = $field_number$,\n");
|
||||
}
|
||||
|
||||
void FieldGenerator::GenerateCFunctionDeclarations(
|
||||
io::Printer* printer) const {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
void FieldGenerator::GenerateCFunctionImplementations(
|
||||
io::Printer* printer) const {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
void FieldGenerator::DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
void FieldGenerator::DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
void FieldGenerator::GenerateFieldDescription(
|
||||
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 {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"{\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");
|
||||
}
|
||||
}
|
||||
|
||||
void FieldGenerator::SetRuntimeHasBit(int has_index) {
|
||||
variables_["has_index"] = StrCat(has_index);
|
||||
}
|
||||
|
||||
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.
|
||||
std::cerr << "Error: should have overridden SetExtraRuntimeHasBitsBase()." << std::endl;
|
||||
std::cerr.flush();
|
||||
abort();
|
||||
}
|
||||
|
||||
void FieldGenerator::SetOneofIndexBase(int index_base) {
|
||||
const OneofDescriptor *oneof = descriptor_->real_containing_oneof();
|
||||
if (oneof != NULL) {
|
||||
int index = oneof->index() + index_base;
|
||||
// Flip the sign to mark it as a oneof.
|
||||
variables_["has_index"] = StrCat(-index);
|
||||
}
|
||||
}
|
||||
|
||||
bool FieldGenerator::WantsHasProperty(void) const {
|
||||
return descriptor_->has_presence() && !descriptor_->real_containing_oneof();
|
||||
}
|
||||
|
||||
void FieldGenerator::FinishInitialization(void) {
|
||||
// If "property_type" wasn't set, make it "storage_type".
|
||||
if ((variables_.find("property_type") == variables_.end()) &&
|
||||
(variables_.find("storage_type") != variables_.end())) {
|
||||
variables_["property_type"] = variable("storage_type");
|
||||
}
|
||||
}
|
||||
|
||||
SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: FieldGenerator(descriptor, options) {
|
||||
// Nothing
|
||||
}
|
||||
|
||||
SingleFieldGenerator::~SingleFieldGenerator() {}
|
||||
|
||||
void SingleFieldGenerator::GenerateFieldStorageDeclaration(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(variables_, "$storage_type$ $name$;\n");
|
||||
}
|
||||
|
||||
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$$deprecated_attribute$;\n");
|
||||
}
|
||||
}
|
||||
|
||||
void SingleFieldGenerator::GeneratePropertyImplementation(
|
||||
io::Printer* printer) const {
|
||||
if (WantsHasProperty()) {
|
||||
printer->Print(variables_, "@dynamic has$capitalized_name$, $name$;\n");
|
||||
} else {
|
||||
printer->Print(variables_, "@dynamic $name$;\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
|
||||
if (descriptor_->real_containing_oneof()) {
|
||||
// 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";
|
||||
}
|
||||
}
|
||||
|
||||
ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
|
||||
|
||||
void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(variables_, "$storage_type$ *$name$;\n");
|
||||
}
|
||||
|
||||
void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
|
||||
io::Printer* printer) const {
|
||||
|
||||
// Differs from SingleFieldGenerator::GeneratePropertyDeclaration() in that
|
||||
// it uses pointers and deals with Objective C's rules around storage name
|
||||
// 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_,
|
||||
"/** Test to see if @c $name$ has been set. */\n"
|
||||
"@property(nonatomic, readwrite) BOOL has$capitalized_name$$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_,
|
||||
"- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
|
||||
}
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
RepeatedFieldGenerator::RepeatedFieldGenerator(
|
||||
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();
|
||||
if (variables_.find("array_property_type") == variables_.end()) {
|
||||
variables_["array_property_type"] = variable("array_storage_type");
|
||||
}
|
||||
}
|
||||
|
||||
void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(variables_, "$array_storage_type$ *$name$;\n");
|
||||
}
|
||||
|
||||
void RepeatedFieldGenerator::GeneratePropertyImplementation(
|
||||
io::Printer* printer) const {
|
||||
printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
|
||||
}
|
||||
|
||||
void RepeatedFieldGenerator::GeneratePropertyDeclaration(
|
||||
io::Printer* printer) const {
|
||||
|
||||
// Repeated fields don't need the has* properties, but they do expose a
|
||||
// *Count (to check without autocreation). So for the field property we need
|
||||
// the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for
|
||||
// dealing with needing Objective C's rules around storage name conventions
|
||||
// (init*, new*, etc.)
|
||||
|
||||
printer->Print(
|
||||
variables_,
|
||||
"$comments$"
|
||||
"$array_comment$"
|
||||
"@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_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
|
||||
}
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
|
||||
return false; // The array (or map/dict) having anything is what is used.
|
||||
}
|
||||
|
||||
FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
|
||||
const Options& options)
|
||||
: descriptor_(descriptor),
|
||||
field_generators_(descriptor->field_count()),
|
||||
extension_generators_(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), options));
|
||||
}
|
||||
for (int i = 0; i < descriptor->extension_count(); i++) {
|
||||
extension_generators_[i].reset(
|
||||
FieldGenerator::Make(descriptor->extension(i), options));
|
||||
}
|
||||
}
|
||||
|
||||
FieldGeneratorMap::~FieldGeneratorMap() {}
|
||||
|
||||
const FieldGenerator& FieldGeneratorMap::get(
|
||||
const FieldDescriptor* field) const {
|
||||
GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
|
||||
return *field_generators_[field->index()];
|
||||
}
|
||||
|
||||
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
|
||||
} // namespace google
|
||||
194
ubuntu/google/protobuf/compiler/objectivec/objectivec_field.h
Normal file
194
ubuntu/google/protobuf/compiler/objectivec/objectivec_field.h
Normal file
@@ -0,0 +1,194 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class FieldGenerator {
|
||||
public:
|
||||
static FieldGenerator* Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
virtual ~FieldGenerator();
|
||||
|
||||
FieldGenerator(const FieldGenerator&) = delete;
|
||||
FieldGenerator& operator=(const FieldGenerator&) = delete;
|
||||
|
||||
// Exposed for subclasses to fill in.
|
||||
virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0;
|
||||
virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0;
|
||||
virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0;
|
||||
|
||||
// Called by GenerateFieldDescription, exposed for classes that need custom
|
||||
// generation.
|
||||
|
||||
// Exposed for subclasses to extend, base does nothing.
|
||||
virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
|
||||
virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
|
||||
|
||||
// Exposed for subclasses, should always call it on the parent class also.
|
||||
virtual void DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
virtual void DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
|
||||
// Used during generation, not intended to be extended by subclasses.
|
||||
void GenerateFieldDescription(
|
||||
io::Printer* printer, bool include_default) const;
|
||||
void GenerateFieldNumberConstant(io::Printer* printer) const;
|
||||
|
||||
// Exposed to get and set the has bits information.
|
||||
virtual bool RuntimeUsesHasBit(void) const = 0;
|
||||
void SetRuntimeHasBit(int has_index);
|
||||
void SetNoHasBit(void);
|
||||
virtual int ExtraRuntimeHasBitsNeeded(void) const;
|
||||
virtual void SetExtraRuntimeHasBitsBase(int index_base);
|
||||
void SetOneofIndexBase(int index_base);
|
||||
|
||||
std::string variable(const char* key) const {
|
||||
return variables_.find(key)->second;
|
||||
}
|
||||
|
||||
bool needs_textformat_name_support() const {
|
||||
const std::string& field_flags = variable("fieldflags");
|
||||
return field_flags.find("GPBFieldTextFormatNameCustom") !=
|
||||
std::string::npos;
|
||||
}
|
||||
std::string generated_objc_name() const { return variable("name"); }
|
||||
std::string raw_field_name() const { return variable("raw_field_name"); }
|
||||
|
||||
protected:
|
||||
FieldGenerator(const FieldDescriptor* descriptor, const Options& options);
|
||||
|
||||
virtual void FinishInitialization(void);
|
||||
bool WantsHasProperty(void) const;
|
||||
|
||||
const FieldDescriptor* descriptor_;
|
||||
std::map<std::string, std::string> variables_;
|
||||
};
|
||||
|
||||
class SingleFieldGenerator : public FieldGenerator {
|
||||
public:
|
||||
virtual ~SingleFieldGenerator();
|
||||
|
||||
SingleFieldGenerator(const SingleFieldGenerator&) = delete;
|
||||
SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete;
|
||||
|
||||
virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const;
|
||||
virtual void GeneratePropertyDeclaration(io::Printer* printer) const;
|
||||
|
||||
virtual void GeneratePropertyImplementation(io::Printer* printer) const;
|
||||
|
||||
virtual bool RuntimeUsesHasBit(void) const;
|
||||
|
||||
protected:
|
||||
SingleFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
};
|
||||
|
||||
// Subclass with common support for when the field ends up as an ObjC Object.
|
||||
class ObjCObjFieldGenerator : public SingleFieldGenerator {
|
||||
public:
|
||||
virtual ~ObjCObjFieldGenerator();
|
||||
|
||||
ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete;
|
||||
ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete;
|
||||
|
||||
virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const;
|
||||
virtual void GeneratePropertyDeclaration(io::Printer* printer) const;
|
||||
|
||||
protected:
|
||||
ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
};
|
||||
|
||||
class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
|
||||
public:
|
||||
virtual ~RepeatedFieldGenerator();
|
||||
|
||||
RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete;
|
||||
RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete;
|
||||
|
||||
virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const;
|
||||
virtual void GeneratePropertyDeclaration(io::Printer* printer) const;
|
||||
|
||||
virtual void GeneratePropertyImplementation(io::Printer* printer) const;
|
||||
|
||||
virtual bool RuntimeUsesHasBit(void) const;
|
||||
|
||||
protected:
|
||||
RepeatedFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
virtual void FinishInitialization(void);
|
||||
};
|
||||
|
||||
// Convenience class which constructs FieldGenerators for a Descriptor.
|
||||
class FieldGeneratorMap {
|
||||
public:
|
||||
FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
|
||||
~FieldGeneratorMap();
|
||||
|
||||
FieldGeneratorMap(const FieldGeneratorMap&) = delete;
|
||||
FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete;
|
||||
|
||||
const FieldGenerator& get(const FieldDescriptor* field) const;
|
||||
const FieldGenerator& get_extension(int index) const;
|
||||
|
||||
// Assigns the has bits and returns the number of bits needed.
|
||||
int CalculateHasBits(void);
|
||||
|
||||
void SetOneofIndexBase(int index_base);
|
||||
|
||||
// Check if any field of this message has a non zero default.
|
||||
bool DoesAnyFieldHaveNonZeroDefault(void) const;
|
||||
|
||||
private:
|
||||
const Descriptor* descriptor_;
|
||||
std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
|
||||
std::vector<std::unique_ptr<FieldGenerator>> extension_generators_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
|
||||
610
ubuntu/google/protobuf/compiler/objectivec/objectivec_file.cc
Normal file
610
ubuntu/google/protobuf/compiler/objectivec/objectivec_file.cc
Normal file
@@ -0,0 +1,610 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <google/protobuf/compiler/objectivec/objectivec_file.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_enum.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_extension.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_message.h>
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
#include <google/protobuf/stubs/stl_util.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <algorithm> // std::find()
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
// 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.
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
namespace {
|
||||
|
||||
// This is also found in GPBBootstrap.h, and needs to be kept in sync.
|
||||
const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004;
|
||||
|
||||
const char* kHeaderExtension = ".pbobjc.h";
|
||||
|
||||
// Checks if a message contains any enums definitions (on the message or
|
||||
// a nested message under it).
|
||||
bool MessageContainsEnums(const Descriptor* message) {
|
||||
if (message->enum_type_count() > 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < message->nested_type_count(); i++) {
|
||||
if (MessageContainsEnums(message->nested_type(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if a message contains any extension definitions (on the message or
|
||||
// a nested message under it).
|
||||
bool MessageContainsExtensions(const Descriptor* message) {
|
||||
if (message->extension_count() > 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < message->nested_type_count(); i++) {
|
||||
if (MessageContainsExtensions(message->nested_type(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if the file contains any enum definitions (at the root or
|
||||
// nested under a message).
|
||||
bool FileContainsEnums(const FileDescriptor* file) {
|
||||
if (file->enum_type_count() > 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < file->message_type_count(); i++) {
|
||||
if (MessageContainsEnums(file->message_type(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Checks if the file contains any extensions definitions (at the root or
|
||||
// nested under a message).
|
||||
bool FileContainsExtensions(const FileDescriptor* file) {
|
||||
if (file->extension_count() > 0) {
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < file->message_type_count(); i++) {
|
||||
if (MessageContainsExtensions(file->message_type(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all
|
||||
// deps as visited and prunes them from the needed files list.
|
||||
void PruneFileAndDepsMarkingAsVisited(
|
||||
const FileDescriptor* file,
|
||||
std::vector<const FileDescriptor*>* files,
|
||||
std::set<const FileDescriptor*>* files_visited) {
|
||||
std::vector<const FileDescriptor*>::iterator iter =
|
||||
std::find(files->begin(), files->end(), file);
|
||||
if (iter != files->end()) {
|
||||
files->erase(iter);
|
||||
}
|
||||
files_visited->insert(file);
|
||||
for (int i = 0; i < file->dependency_count(); i++) {
|
||||
PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper for CollectMinimalFileDepsContainingExtensions.
|
||||
void CollectMinimalFileDepsContainingExtensionsWorker(
|
||||
const FileDescriptor* file,
|
||||
std::vector<const FileDescriptor*>* files,
|
||||
std::set<const FileDescriptor*>* files_visited) {
|
||||
if (files_visited->find(file) != files_visited->end()) {
|
||||
return;
|
||||
}
|
||||
files_visited->insert(file);
|
||||
|
||||
if (FileContainsExtensions(file)) {
|
||||
files->push_back(file);
|
||||
for (int i = 0; i < file->dependency_count(); i++) {
|
||||
const FileDescriptor* dep = file->dependency(i);
|
||||
PruneFileAndDepsMarkingAsVisited(dep, files, files_visited);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < file->dependency_count(); i++) {
|
||||
const FileDescriptor* dep = file->dependency(i);
|
||||
CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
|
||||
files_visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect the deps of the given file that contain extensions. This can be used to
|
||||
// create the chain of roots that need to be wired together.
|
||||
//
|
||||
// NOTE: If any changes are made to this and the supporting functions, you will
|
||||
// need to manually validate what the generated code is for the test files:
|
||||
// objectivec/Tests/unittest_extension_chain_*.proto
|
||||
// There are comments about what the expected code should be line and limited
|
||||
// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports
|
||||
// specifically).
|
||||
void CollectMinimalFileDepsContainingExtensions(
|
||||
const FileDescriptor* file,
|
||||
std::vector<const FileDescriptor*>* files) {
|
||||
std::set<const FileDescriptor*> files_visited;
|
||||
for (int i = 0; i < file->dependency_count(); i++) {
|
||||
const FileDescriptor* dep = file->dependency(i);
|
||||
CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
|
||||
&files_visited);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
|
||||
for (int i = 0; i < file->dependency_count(); i++) {
|
||||
if (dep == file->dependency(i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
|
||||
: file_(file),
|
||||
root_class_name_(FileClassName(file)),
|
||||
is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)),
|
||||
options_(options) {
|
||||
for (int i = 0; i < file_->enum_type_count(); i++) {
|
||||
EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
|
||||
enum_generators_.emplace_back(generator);
|
||||
}
|
||||
for (int i = 0; i < file_->message_type_count(); i++) {
|
||||
MessageGenerator *generator =
|
||||
new MessageGenerator(root_class_name_, file_->message_type(i), options_);
|
||||
message_generators_.emplace_back(generator);
|
||||
}
|
||||
for (int i = 0; i < file_->extension_count(); i++) {
|
||||
ExtensionGenerator *generator =
|
||||
new ExtensionGenerator(root_class_name_, file_->extension(i));
|
||||
extension_generators_.emplace_back(generator);
|
||||
}
|
||||
}
|
||||
|
||||
FileGenerator::~FileGenerator() {}
|
||||
|
||||
void FileGenerator::GenerateHeader(io::Printer *printer) {
|
||||
std::vector<std::string> headers;
|
||||
// Generated files bundled with the library get minimal imports, everything
|
||||
// else gets the wrapper so everything is usable.
|
||||
if (is_bundled_proto_) {
|
||||
headers.push_back("GPBDescriptor.h");
|
||||
headers.push_back("GPBMessage.h");
|
||||
headers.push_back("GPBRootObject.h");
|
||||
} else {
|
||||
headers.push_back("GPBProtocolBuffers.h");
|
||||
}
|
||||
PrintFileRuntimePreamble(printer, headers);
|
||||
|
||||
// Add some verification that the generated code matches the source the
|
||||
// code is being compiled with.
|
||||
// NOTE: This captures the raw numeric values at the time the generator was
|
||||
// compiled, since that will be the versions for the ObjC runtime at that
|
||||
// time. The constants in the generated code will then get their values at
|
||||
// at compile time (so checking against the headers being used to compile).
|
||||
printer->Print(
|
||||
"#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n"
|
||||
"#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.\n"
|
||||
"#endif\n"
|
||||
"#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION\n"
|
||||
"#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.\n"
|
||||
"#endif\n"
|
||||
"\n",
|
||||
"google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION));
|
||||
|
||||
// #import any headers for "public imports" in the proto file.
|
||||
{
|
||||
ImportWriter import_writer(
|
||||
options_.generate_for_named_framework,
|
||||
options_.named_framework_to_proto_path_mappings_path,
|
||||
options_.runtime_import_prefix,
|
||||
is_bundled_proto_);
|
||||
const std::string header_extension(kHeaderExtension);
|
||||
for (int i = 0; i < file_->public_dependency_count(); i++) {
|
||||
import_writer.AddFile(file_->public_dependency(i), header_extension);
|
||||
}
|
||||
import_writer.Print(printer);
|
||||
}
|
||||
|
||||
// Note:
|
||||
// deprecated-declarations suppression is only needed if some place in this
|
||||
// proto file is something deprecated or if it references something from
|
||||
// another file that is deprecated.
|
||||
printer->Print(
|
||||
"// @@protoc_insertion_point(imports)\n"
|
||||
"\n"
|
||||
"#pragma clang diagnostic push\n"
|
||||
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
|
||||
"\n"
|
||||
"CF_EXTERN_C_BEGIN\n"
|
||||
"\n");
|
||||
|
||||
std::set<std::string> fwd_decls;
|
||||
for (const auto& generator : message_generators_) {
|
||||
generator->DetermineForwardDeclarations(&fwd_decls);
|
||||
}
|
||||
for (std::set<std::string>::const_iterator i(fwd_decls.begin());
|
||||
i != fwd_decls.end(); ++i) {
|
||||
printer->Print("$value$;\n", "value", *i);
|
||||
}
|
||||
if (fwd_decls.begin() != fwd_decls.end()) {
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"NS_ASSUME_NONNULL_BEGIN\n"
|
||||
"\n");
|
||||
|
||||
// need to write out all enums first
|
||||
for (const auto& generator : enum_generators_) {
|
||||
generator->GenerateHeader(printer);
|
||||
}
|
||||
|
||||
for (const auto& generator : message_generators_) {
|
||||
generator->GenerateEnumHeader(printer);
|
||||
}
|
||||
|
||||
// For extensions to chain together, the Root gets created even if there
|
||||
// are no extensions.
|
||||
printer->Print(
|
||||
"#pragma mark - $root_class_name$\n"
|
||||
"\n"
|
||||
"/**\n"
|
||||
" * Exposes the extension registry for this file.\n"
|
||||
" *\n"
|
||||
" * The base class provides:\n"
|
||||
" * @code\n"
|
||||
" * + (GPBExtensionRegistry *)extensionRegistry;\n"
|
||||
" * @endcode\n"
|
||||
" * which is a @c GPBExtensionRegistry that includes all the extensions defined by\n"
|
||||
" * this file and all files that it depends on.\n"
|
||||
" **/\n"
|
||||
"GPB_FINAL @interface $root_class_name$ : GPBRootObject\n"
|
||||
"@end\n"
|
||||
"\n",
|
||||
"root_class_name", root_class_name_);
|
||||
|
||||
if (!extension_generators_.empty()) {
|
||||
// The dynamic methods block is only needed if there are extensions.
|
||||
printer->Print(
|
||||
"@interface $root_class_name$ (DynamicMethods)\n",
|
||||
"root_class_name", root_class_name_);
|
||||
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->GenerateMembersHeader(printer);
|
||||
}
|
||||
|
||||
printer->Print("@end\n\n");
|
||||
} // !extension_generators_.empty()
|
||||
|
||||
for (const auto& generator : message_generators_) {
|
||||
generator->GenerateMessageHeader(printer);
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"NS_ASSUME_NONNULL_END\n"
|
||||
"\n"
|
||||
"CF_EXTERN_C_END\n"
|
||||
"\n"
|
||||
"#pragma clang diagnostic pop\n"
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(global_scope)\n");
|
||||
}
|
||||
|
||||
void FileGenerator::GenerateSource(io::Printer *printer) {
|
||||
// #import the runtime support.
|
||||
std::vector<std::string> headers;
|
||||
headers.push_back("GPBProtocolBuffers_RuntimeSupport.h");
|
||||
PrintFileRuntimePreamble(printer, headers);
|
||||
|
||||
// Enums use atomic in the generated code, so add the system import as needed.
|
||||
if (FileContainsEnums(file_)) {
|
||||
printer->Print(
|
||||
"#import <stdatomic.h>\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
std::vector<const FileDescriptor*> deps_with_extensions;
|
||||
CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions);
|
||||
|
||||
{
|
||||
ImportWriter import_writer(
|
||||
options_.generate_for_named_framework,
|
||||
options_.named_framework_to_proto_path_mappings_path,
|
||||
options_.runtime_import_prefix,
|
||||
is_bundled_proto_);
|
||||
const std::string header_extension(kHeaderExtension);
|
||||
|
||||
// #import the header for this proto file.
|
||||
import_writer.AddFile(file_, header_extension);
|
||||
|
||||
// #import the headers for anything that a plain dependency of this proto
|
||||
// file (that means they were just an include, not a "public" include).
|
||||
std::set<std::string> public_import_names;
|
||||
for (int i = 0; i < file_->public_dependency_count(); i++) {
|
||||
public_import_names.insert(file_->public_dependency(i)->name());
|
||||
}
|
||||
for (int i = 0; i < file_->dependency_count(); i++) {
|
||||
const FileDescriptor *dep = file_->dependency(i);
|
||||
bool public_import = (public_import_names.count(dep->name()) != 0);
|
||||
if (!public_import) {
|
||||
import_writer.AddFile(dep, header_extension);
|
||||
}
|
||||
}
|
||||
|
||||
// If any indirect dependency provided extensions, it needs to be directly
|
||||
// imported so it can get merged into the root's extensions registry.
|
||||
// See the Note by CollectMinimalFileDepsContainingExtensions before
|
||||
// changing this.
|
||||
for (std::vector<const FileDescriptor *>::iterator iter =
|
||||
deps_with_extensions.begin();
|
||||
iter != deps_with_extensions.end(); ++iter) {
|
||||
if (!IsDirectDependency(*iter, file_)) {
|
||||
import_writer.AddFile(*iter, header_extension);
|
||||
}
|
||||
}
|
||||
|
||||
import_writer.Print(printer);
|
||||
}
|
||||
|
||||
bool includes_oneof = false;
|
||||
for (const auto& generator : message_generators_) {
|
||||
if (generator->IncludesOneOfDefinition()) {
|
||||
includes_oneof = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> fwd_decls;
|
||||
for (const auto& generator : message_generators_) {
|
||||
generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
|
||||
}
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
|
||||
}
|
||||
|
||||
// Note:
|
||||
// deprecated-declarations suppression is only needed if some place in this
|
||||
// proto file is something deprecated or if it references something from
|
||||
// another file that is deprecated.
|
||||
// dollar-in-identifier-extension is needed because we use references to
|
||||
// objc class names that have $ in identifiers.
|
||||
printer->Print(
|
||||
"// @@protoc_insertion_point(imports)\n"
|
||||
"\n"
|
||||
"#pragma clang diagnostic push\n"
|
||||
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
|
||||
if (includes_oneof) {
|
||||
// The generated code for oneof's uses direct ivar access, suppress the
|
||||
// warning in case developer turn that on in the context they compile the
|
||||
// generated code.
|
||||
printer->Print(
|
||||
"#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n");
|
||||
}
|
||||
if (!fwd_decls.empty()) {
|
||||
printer->Print(
|
||||
"#pragma clang diagnostic ignored \"-Wdollar-in-identifier-extension\"\n");
|
||||
}
|
||||
printer->Print(
|
||||
"\n");
|
||||
if (!fwd_decls.empty()) {
|
||||
printer->Print(
|
||||
"#pragma mark - Objective C Class declarations\n"
|
||||
"// Forward declarations of Objective C classes that we can use as\n"
|
||||
"// static values in struct initializers.\n"
|
||||
"// We don't use [Foo class] because it is not a static value.\n");
|
||||
}
|
||||
for (const auto& i : fwd_decls) {
|
||||
printer->Print("$value$\n", "value", i);
|
||||
}
|
||||
if (!fwd_decls.empty()) {
|
||||
printer->Print("\n");
|
||||
}
|
||||
printer->Print(
|
||||
"#pragma mark - $root_class_name$\n"
|
||||
"\n"
|
||||
"@implementation $root_class_name$\n\n",
|
||||
"root_class_name", root_class_name_);
|
||||
|
||||
const bool file_contains_extensions = FileContainsExtensions(file_);
|
||||
|
||||
// If there were any extensions or this file has any dependencies, output
|
||||
// a registry to override to create the file specific registry.
|
||||
if (file_contains_extensions || !deps_with_extensions.empty()) {
|
||||
printer->Print(
|
||||
"+ (GPBExtensionRegistry*)extensionRegistry {\n"
|
||||
" // This is called by +initialize so there is no need to worry\n"
|
||||
" // about thread safety and initialization of registry.\n"
|
||||
" static GPBExtensionRegistry* registry = nil;\n"
|
||||
" if (!registry) {\n"
|
||||
" GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n"
|
||||
" registry = [[GPBExtensionRegistry alloc] init];\n");
|
||||
|
||||
printer->Indent();
|
||||
printer->Indent();
|
||||
|
||||
if (file_contains_extensions) {
|
||||
printer->Print(
|
||||
"static GPBExtensionDescription descriptions[] = {\n");
|
||||
printer->Indent();
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->GenerateStaticVariablesInitialization(printer);
|
||||
}
|
||||
for (const auto& generator : message_generators_) {
|
||||
generator->GenerateStaticVariablesInitialization(printer);
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n"
|
||||
"for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
|
||||
" GPBExtensionDescriptor *extension =\n"
|
||||
" [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]\n"
|
||||
" usesClassRefs:YES];\n"
|
||||
" [registry addExtension:extension];\n"
|
||||
" [self globallyRegisterExtension:extension];\n"
|
||||
" [extension release];\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
if (deps_with_extensions.empty()) {
|
||||
printer->Print(
|
||||
"// None of the imports (direct or indirect) defined extensions, so no need to add\n"
|
||||
"// them to this registry.\n");
|
||||
} else {
|
||||
printer->Print(
|
||||
"// Merge in the imports (direct or indirect) that defined extensions.\n");
|
||||
for (std::vector<const FileDescriptor *>::iterator iter =
|
||||
deps_with_extensions.begin();
|
||||
iter != deps_with_extensions.end(); ++iter) {
|
||||
const std::string root_class_name(FileClassName((*iter)));
|
||||
printer->Print(
|
||||
"[registry addExtensions:[$dependency$ extensionRegistry]];\n",
|
||||
"dependency", root_class_name);
|
||||
}
|
||||
}
|
||||
|
||||
printer->Outdent();
|
||||
printer->Outdent();
|
||||
|
||||
printer->Print(
|
||||
" }\n"
|
||||
" return registry;\n"
|
||||
"}\n");
|
||||
} else {
|
||||
if (file_->dependency_count() > 0) {
|
||||
printer->Print(
|
||||
"// No extensions in the file and none of the imports (direct or indirect)\n"
|
||||
"// defined extensions, so no need to generate +extensionRegistry.\n");
|
||||
} else {
|
||||
printer->Print(
|
||||
"// No extensions in the file and no imports, so no need to generate\n"
|
||||
"// +extensionRegistry.\n");
|
||||
}
|
||||
}
|
||||
|
||||
printer->Print("\n@end\n\n");
|
||||
|
||||
// File descriptor only needed if there are messages to use it.
|
||||
if (!message_generators_.empty()) {
|
||||
std::map<std::string, std::string> vars;
|
||||
vars["root_class_name"] = root_class_name_;
|
||||
vars["package"] = file_->package();
|
||||
vars["objc_prefix"] = FileClassPrefix(file_);
|
||||
switch (file_->syntax()) {
|
||||
case FileDescriptor::SYNTAX_UNKNOWN:
|
||||
vars["syntax"] = "GPBFileSyntaxUnknown";
|
||||
break;
|
||||
case FileDescriptor::SYNTAX_PROTO2:
|
||||
vars["syntax"] = "GPBFileSyntaxProto2";
|
||||
break;
|
||||
case FileDescriptor::SYNTAX_PROTO3:
|
||||
vars["syntax"] = "GPBFileSyntaxProto3";
|
||||
break;
|
||||
}
|
||||
printer->Print(vars,
|
||||
"#pragma mark - $root_class_name$_FileDescriptor\n"
|
||||
"\n"
|
||||
"static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
|
||||
" // This is called by +initialize so there is no need to worry\n"
|
||||
" // about thread safety of the singleton.\n"
|
||||
" static GPBFileDescriptor *descriptor = NULL;\n"
|
||||
" if (!descriptor) {\n"
|
||||
" GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n");
|
||||
if (!vars["objc_prefix"].empty()) {
|
||||
printer->Print(
|
||||
vars,
|
||||
" descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
|
||||
" objcPrefix:@\"$objc_prefix$\"\n"
|
||||
" syntax:$syntax$];\n");
|
||||
} else {
|
||||
printer->Print(
|
||||
vars,
|
||||
" descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
|
||||
" syntax:$syntax$];\n");
|
||||
}
|
||||
printer->Print(
|
||||
" }\n"
|
||||
" return descriptor;\n"
|
||||
"}\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
for (const auto& generator : enum_generators_) {
|
||||
generator->GenerateSource(printer);
|
||||
}
|
||||
for (const auto& generator : message_generators_) {
|
||||
generator->GenerateSource(printer);
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"\n"
|
||||
"#pragma clang diagnostic pop\n"
|
||||
"\n"
|
||||
"// @@protoc_insertion_point(global_scope)\n");
|
||||
}
|
||||
|
||||
// Helper to print the import of the runtime support at the top of generated
|
||||
// files. This currently only supports the runtime coming from a framework
|
||||
// as defined by the official CocoaPod.
|
||||
void FileGenerator::PrintFileRuntimePreamble(
|
||||
io::Printer* printer,
|
||||
const std::vector<std::string>& headers_to_import) const {
|
||||
printer->Print(
|
||||
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
|
||||
"// source: $filename$\n"
|
||||
"\n",
|
||||
"filename", file_->name());
|
||||
ImportWriter::PrintRuntimeImports(
|
||||
printer, headers_to_import, options_.runtime_import_prefix, true);
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
84
ubuntu/google/protobuf/compiler/objectivec/objectivec_file.h
Normal file
84
ubuntu/google/protobuf/compiler/objectivec/objectivec_file.h
Normal file
@@ -0,0 +1,84 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class EnumGenerator;
|
||||
class ExtensionGenerator;
|
||||
class MessageGenerator;
|
||||
|
||||
class FileGenerator {
|
||||
public:
|
||||
FileGenerator(const FileDescriptor* file, const Options& options);
|
||||
~FileGenerator();
|
||||
|
||||
FileGenerator(const FileGenerator&) = delete;
|
||||
FileGenerator& operator=(const FileGenerator&) = delete;
|
||||
|
||||
void GenerateSource(io::Printer* printer);
|
||||
void GenerateHeader(io::Printer* printer);
|
||||
|
||||
const std::string& RootClassName() const { return root_class_name_; }
|
||||
|
||||
private:
|
||||
const FileDescriptor* file_;
|
||||
std::string root_class_name_;
|
||||
bool is_bundled_proto_;
|
||||
|
||||
std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
|
||||
std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
|
||||
std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
|
||||
|
||||
const Options options_;
|
||||
|
||||
void PrintFileRuntimePreamble(
|
||||
io::Printer* printer,
|
||||
const std::vector<std::string>& headers_to_import) const;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
|
||||
@@ -0,0 +1,182 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <string>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_generator.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_file.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/zero_copy_stream.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
ObjectiveCGenerator::ObjectiveCGenerator() {}
|
||||
|
||||
ObjectiveCGenerator::~ObjectiveCGenerator() {}
|
||||
|
||||
bool ObjectiveCGenerator::HasGenerateAll() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
|
||||
const std::string& parameter,
|
||||
GeneratorContext* context,
|
||||
std::string* error) const {
|
||||
*error = "Unimplemented Generate() method. Call GenerateAll() instead.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectiveCGenerator::GenerateAll(
|
||||
const std::vector<const FileDescriptor*>& files,
|
||||
const std::string& parameter, GeneratorContext* context,
|
||||
std::string* error) const {
|
||||
// -----------------------------------------------------------------
|
||||
// Parse generator options. These options are passed to the compiler using the
|
||||
// --objc_opt flag. The options are passed as a comma separated list of
|
||||
// options along with their values. If the option appears multiple times, only
|
||||
// the last value will be considered.
|
||||
//
|
||||
// e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
|
||||
|
||||
Options generation_options;
|
||||
|
||||
std::vector<std::pair<std::string, std::string> > options;
|
||||
ParseGeneratorParameter(parameter, &options);
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
if (options[i].first == "expected_prefixes_path") {
|
||||
// Path to find a file containing the expected prefixes
|
||||
// (objc_class_prefix "PREFIX") for proto packages (package NAME). The
|
||||
// generator will then issue warnings/errors if in the proto files being
|
||||
// generated the option is not listed/wrong/etc in the file.
|
||||
//
|
||||
// The format of the file is:
|
||||
// - An entry is a line of "package=prefix".
|
||||
// - Comments start with "#".
|
||||
// - A comment can go on a line after a expected package/prefix pair.
|
||||
// (i.e. - "package=prefix # comment")
|
||||
//
|
||||
// There is no validation that the prefixes are good prefixes, it is
|
||||
// assumed that they are when you create the file.
|
||||
generation_options.expected_prefixes_path = options[i].second;
|
||||
} else if (options[i].first == "expected_prefixes_suppressions") {
|
||||
// A semicolon delimited string that lists the paths of .proto files to
|
||||
// exclude from the package prefix validations (expected_prefixes_path).
|
||||
// This is provided as an "out", to skip some files being checked.
|
||||
for (StringPiece split_piece : Split(
|
||||
options[i].second, ";", true)) {
|
||||
generation_options.expected_prefixes_suppressions.push_back(
|
||||
std::string(split_piece));
|
||||
}
|
||||
} else if (options[i].first == "generate_for_named_framework") {
|
||||
// The name of the framework that protos are being generated for. This
|
||||
// will cause the #import statements to be framework based using this
|
||||
// name (i.e. - "#import <NAME/proto.pbobjc.h>).
|
||||
//
|
||||
// NOTE: If this option is used with
|
||||
// named_framework_to_proto_path_mappings_path, then this is effectively
|
||||
// the "default" framework name used for everything that wasn't mapped by
|
||||
// the mapping file.
|
||||
generation_options.generate_for_named_framework = options[i].second;
|
||||
} else if (options[i].first == "named_framework_to_proto_path_mappings_path") {
|
||||
// Path to find a file containing the list of framework names and proto
|
||||
// files. The generator uses this to decide if a proto file
|
||||
// referenced should use a framework style import vs. a user level import
|
||||
// (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h").
|
||||
//
|
||||
// The format of the file is:
|
||||
// - An entry is a line of "frameworkName: file.proto, dir/file2.proto".
|
||||
// - Comments start with "#".
|
||||
// - A comment can go on a line after a expected package/prefix pair.
|
||||
// (i.e. - "frameworkName: file.proto # comment")
|
||||
//
|
||||
// Any number of files can be listed for a framework, just separate them
|
||||
// with commas.
|
||||
//
|
||||
// There can be multiple lines listing the same frameworkName in case it
|
||||
// has a lot of proto files included in it; having multiple lines makes
|
||||
// things easier to read. If a proto file is not configured in the
|
||||
// mappings file, it will use the default framework name if one was passed
|
||||
// with generate_for_named_framework, or the relative path to it's include
|
||||
// path otherwise.
|
||||
generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
|
||||
} else if (options[i].first == "runtime_import_prefix") {
|
||||
// Path to use as a prefix on #imports of runtime provided headers in the
|
||||
// generated files. When integrating ObjC protos into a build system,
|
||||
// this can be used to avoid having to add the runtime directory to the
|
||||
// header search path since the generate #import will be more complete.
|
||||
generation_options.runtime_import_prefix =
|
||||
StripSuffixString(options[i].second, "/");
|
||||
} else {
|
||||
*error = "error: Unknown generator option: " + options[i].first;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
// Validate the objc prefix/package pairings.
|
||||
if (!ValidateObjCClassPrefixes(files, generation_options, error)) {
|
||||
// *error will have been filled in.
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
const FileDescriptor* file = files[i];
|
||||
FileGenerator file_generator(file, generation_options);
|
||||
std::string filepath = FilePath(file);
|
||||
|
||||
// Generate header.
|
||||
{
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
context->Open(filepath + ".pbobjc.h"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
file_generator.GenerateHeader(&printer);
|
||||
}
|
||||
|
||||
// Generate m file.
|
||||
{
|
||||
std::unique_ptr<io::ZeroCopyOutputStream> output(
|
||||
context->Open(filepath + ".pbobjc.m"));
|
||||
io::Printer printer(output.get(), '$');
|
||||
file_generator.GenerateSource(&printer);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,79 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Generates ObjectiveC code for a given .proto file.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
|
||||
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/code_generator.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
// CodeGenerator implementation which generates a ObjectiveC source file and
|
||||
// header. If you create your own protocol compiler binary and you want it to
|
||||
// support ObjectiveC output, you can do so by registering an instance of this
|
||||
// CodeGenerator with the CommandLineInterface in your main() function.
|
||||
class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
|
||||
public:
|
||||
ObjectiveCGenerator();
|
||||
~ObjectiveCGenerator();
|
||||
|
||||
ObjectiveCGenerator(const ObjectiveCGenerator&) = delete;
|
||||
ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete;
|
||||
|
||||
// implements CodeGenerator ----------------------------------------
|
||||
bool HasGenerateAll() const override;
|
||||
bool Generate(const FileDescriptor* file, const std::string& parameter,
|
||||
GeneratorContext* context, std::string* error) const override;
|
||||
bool GenerateAll(const std::vector<const FileDescriptor*>& files,
|
||||
const std::string& parameter, GeneratorContext* context,
|
||||
std::string* error) const override;
|
||||
|
||||
uint64_t GetSupportedFeatures() const override {
|
||||
return FEATURE_PROTO3_OPTIONAL;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
|
||||
1779
ubuntu/google/protobuf/compiler/objectivec/objectivec_helpers.cc
Normal file
1779
ubuntu/google/protobuf/compiler/objectivec/objectivec_helpers.cc
Normal file
File diff suppressed because it is too large
Load Diff
329
ubuntu/google/protobuf/compiler/objectivec/objectivec_helpers.h
Normal file
329
ubuntu/google/protobuf/compiler/objectivec/objectivec_helpers.h
Normal file
@@ -0,0 +1,329 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Helper functions for generating ObjectiveC code.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
// Generator options (see objectivec_generator.cc for a description of each):
|
||||
struct Options {
|
||||
Options();
|
||||
std::string expected_prefixes_path;
|
||||
std::vector<std::string> expected_prefixes_suppressions;
|
||||
std::string generate_for_named_framework;
|
||||
std::string named_framework_to_proto_path_mappings_path;
|
||||
std::string runtime_import_prefix;
|
||||
};
|
||||
|
||||
// Escape C++ trigraphs by escaping question marks to "\?".
|
||||
std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& to_escape);
|
||||
|
||||
// Strips ".proto" or ".protodevel" from the end of a filename.
|
||||
std::string PROTOC_EXPORT StripProto(const std::string& filename);
|
||||
|
||||
// Remove white space from either end of a StringPiece.
|
||||
void PROTOC_EXPORT TrimWhitespace(StringPiece* input);
|
||||
|
||||
// Returns true if the name requires a ns_returns_not_retained attribute applied
|
||||
// to it.
|
||||
bool PROTOC_EXPORT IsRetainedName(const std::string& name);
|
||||
|
||||
// Returns true if the name starts with "init" and will need to have special
|
||||
// handling under ARC.
|
||||
bool PROTOC_EXPORT IsInitName(const std::string& name);
|
||||
|
||||
// Gets the objc_class_prefix.
|
||||
std::string PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file);
|
||||
|
||||
// Gets the path of the file we're going to generate (sans the .pb.h
|
||||
// extension). The path will be dependent on the objectivec package
|
||||
// declared in the proto package.
|
||||
std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
|
||||
|
||||
// Just like FilePath(), but without the directory part.
|
||||
std::string PROTOC_EXPORT FilePathBasename(const FileDescriptor* file);
|
||||
|
||||
// Gets the name of the root class we'll generate in the file. This class
|
||||
// is not meant for external consumption, but instead contains helpers that
|
||||
// the rest of the classes need
|
||||
std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
|
||||
|
||||
// These return the fully-qualified class name corresponding to the given
|
||||
// descriptor.
|
||||
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
|
||||
std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
|
||||
std::string* out_suffix_added);
|
||||
std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
|
||||
|
||||
// Returns the fully-qualified name of the enum value corresponding to the
|
||||
// the descriptor.
|
||||
std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
|
||||
|
||||
// Returns the name of the enum value corresponding to the descriptor.
|
||||
std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
|
||||
|
||||
// Reverse what an enum does.
|
||||
std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
|
||||
|
||||
// Returns the name to use for the extension (used as the method off the file's
|
||||
// Root class).
|
||||
std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
|
||||
|
||||
// Returns the transformed field name.
|
||||
std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
|
||||
std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
|
||||
|
||||
// Returns the transformed oneof name.
|
||||
std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
|
||||
std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
|
||||
std::string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
|
||||
|
||||
// Returns a symbol that can be used in C code to refer to an Objective C
|
||||
// class without initializing the class.
|
||||
std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
|
||||
|
||||
// Declares an Objective C class without initializing the class so that it can
|
||||
// be refrerred to by ObjCClass.
|
||||
std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& class_name);
|
||||
|
||||
inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) {
|
||||
return file->syntax() == FileDescriptor::SYNTAX_PROTO3;
|
||||
}
|
||||
|
||||
inline bool IsMapEntryMessage(const Descriptor* descriptor) {
|
||||
return descriptor->options().map_entry();
|
||||
}
|
||||
|
||||
// Reverse of the above.
|
||||
std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& name,
|
||||
const FieldDescriptor* field);
|
||||
|
||||
enum ObjectiveCType {
|
||||
OBJECTIVECTYPE_INT32,
|
||||
OBJECTIVECTYPE_UINT32,
|
||||
OBJECTIVECTYPE_INT64,
|
||||
OBJECTIVECTYPE_UINT64,
|
||||
OBJECTIVECTYPE_FLOAT,
|
||||
OBJECTIVECTYPE_DOUBLE,
|
||||
OBJECTIVECTYPE_BOOLEAN,
|
||||
OBJECTIVECTYPE_STRING,
|
||||
OBJECTIVECTYPE_DATA,
|
||||
OBJECTIVECTYPE_ENUM,
|
||||
OBJECTIVECTYPE_MESSAGE
|
||||
};
|
||||
|
||||
enum FlagType {
|
||||
FLAGTYPE_DESCRIPTOR_INITIALIZATION,
|
||||
FLAGTYPE_EXTENSION,
|
||||
FLAGTYPE_FIELD
|
||||
};
|
||||
|
||||
template <class TDescriptor>
|
||||
std::string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
|
||||
const FileDescriptor* file = NULL,
|
||||
bool preSpace = true,
|
||||
bool postNewline = false) {
|
||||
bool isDeprecated = descriptor->options().deprecated();
|
||||
// The file is only passed when checking Messages & Enums, so those types
|
||||
// get tagged. At the moment, it doesn't seem to make sense to tag every
|
||||
// field or enum value with when the file is deprecated.
|
||||
bool isFileLevelDeprecation = false;
|
||||
if (!isDeprecated && file) {
|
||||
isFileLevelDeprecation = file->options().deprecated();
|
||||
isDeprecated = isFileLevelDeprecation;
|
||||
}
|
||||
if (isDeprecated) {
|
||||
std::string message;
|
||||
const FileDescriptor* sourceFile = descriptor->file();
|
||||
if (isFileLevelDeprecation) {
|
||||
message = sourceFile->name() + " is deprecated.";
|
||||
} else {
|
||||
message = descriptor->full_name() + " is deprecated (see " +
|
||||
sourceFile->name() + ").";
|
||||
}
|
||||
|
||||
std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
|
||||
if (preSpace) {
|
||||
result.insert(0, " ");
|
||||
}
|
||||
if (postNewline) {
|
||||
result.append("\n");
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field);
|
||||
|
||||
ObjectiveCType PROTOC_EXPORT
|
||||
GetObjectiveCType(FieldDescriptor::Type field_type);
|
||||
|
||||
inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
|
||||
return GetObjectiveCType(field->type());
|
||||
}
|
||||
|
||||
bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field);
|
||||
bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field);
|
||||
|
||||
std::string PROTOC_EXPORT
|
||||
GPBGenericValueFieldName(const FieldDescriptor* field);
|
||||
std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
|
||||
bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
|
||||
|
||||
std::string PROTOC_EXPORT
|
||||
BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
|
||||
|
||||
// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
|
||||
// file.
|
||||
std::string PROTOC_EXPORT BuildCommentsString(const SourceLocation& location,
|
||||
bool prefer_single_line);
|
||||
|
||||
// The name the commonly used by the library when built as a framework.
|
||||
// This lines up to the name used in the CocoaPod.
|
||||
extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName;
|
||||
// Returns the CPP symbol name to use as the gate for framework style imports
|
||||
// for the given framework name to use.
|
||||
std::string PROTOC_EXPORT
|
||||
ProtobufFrameworkImportSymbol(const std::string& framework_name);
|
||||
|
||||
// Checks if the file is one of the proto's bundled with the library.
|
||||
bool PROTOC_EXPORT
|
||||
IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
|
||||
|
||||
// Checks the prefix for the given files and outputs any warnings as needed. If
|
||||
// there are flat out errors, then out_error is filled in with the first error
|
||||
// and the result is false.
|
||||
bool PROTOC_EXPORT ValidateObjCClassPrefixes(
|
||||
const std::vector<const FileDescriptor*>& files,
|
||||
const Options& generation_options, std::string* out_error);
|
||||
|
||||
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
|
||||
// the input into the expected output.
|
||||
class PROTOC_EXPORT TextFormatDecodeData {
|
||||
public:
|
||||
TextFormatDecodeData();
|
||||
~TextFormatDecodeData();
|
||||
|
||||
TextFormatDecodeData(const TextFormatDecodeData&) = delete;
|
||||
TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
|
||||
|
||||
void AddString(int32 key, const std::string& input_for_decode,
|
||||
const std::string& desired_output);
|
||||
size_t num_entries() const { return entries_.size(); }
|
||||
std::string Data() const;
|
||||
|
||||
static std::string DecodeDataForString(const std::string& input_for_decode,
|
||||
const std::string& desired_output);
|
||||
|
||||
private:
|
||||
typedef std::pair<int32, std::string> DataEntry;
|
||||
std::vector<DataEntry> entries_;
|
||||
};
|
||||
|
||||
// Helper for parsing simple files.
|
||||
class PROTOC_EXPORT LineConsumer {
|
||||
public:
|
||||
LineConsumer();
|
||||
virtual ~LineConsumer();
|
||||
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0;
|
||||
};
|
||||
|
||||
bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
|
||||
LineConsumer* line_consumer,
|
||||
std::string* out_error);
|
||||
|
||||
// Helper class for parsing framework import mappings and generating
|
||||
// import statements.
|
||||
class PROTOC_EXPORT ImportWriter {
|
||||
public:
|
||||
ImportWriter(const std::string& generate_for_named_framework,
|
||||
const std::string& named_framework_to_proto_path_mappings_path,
|
||||
const std::string& runtime_import_prefix,
|
||||
bool include_wkt_imports);
|
||||
~ImportWriter();
|
||||
|
||||
void AddFile(const FileDescriptor* file, const std::string& header_extension);
|
||||
void Print(io::Printer *printer) const;
|
||||
|
||||
static void PrintRuntimeImports(io::Printer *printer,
|
||||
const std::vector<std::string>& header_to_import,
|
||||
const std::string& runtime_import_prefix,
|
||||
bool default_cpp_symbol = false);
|
||||
|
||||
private:
|
||||
class ProtoFrameworkCollector : public LineConsumer {
|
||||
public:
|
||||
ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
|
||||
: map_(inout_proto_file_to_framework_name) {}
|
||||
|
||||
virtual bool ConsumeLine(const StringPiece& line, std::string* out_error);
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string>* map_;
|
||||
};
|
||||
|
||||
void ParseFrameworkMappings();
|
||||
|
||||
const std::string generate_for_named_framework_;
|
||||
const std::string named_framework_to_proto_path_mappings_path_;
|
||||
const std::string runtime_import_prefix_;
|
||||
const bool include_wkt_imports_;
|
||||
std::map<std::string, std::string> proto_file_to_framework_name_;
|
||||
bool need_to_parse_mapping_file_;
|
||||
|
||||
std::vector<std::string> protobuf_imports_;
|
||||
std::vector<std::string> other_framework_imports_;
|
||||
std::vector<std::string> other_imports_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#include <google/protobuf/port_undef.inc>
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
|
||||
@@ -0,0 +1,257 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2014 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/testing/googletest.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
namespace {
|
||||
|
||||
TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
|
||||
std::string input_for_decode("abcdefghIJ");
|
||||
std::string desired_output_for_decode;
|
||||
std::string expected;
|
||||
std::string result;
|
||||
|
||||
// Different data, can't transform.
|
||||
|
||||
desired_output_for_decode = "zbcdefghIJ";
|
||||
expected = std::string("\0zbcdefghIJ\0", 12);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
desired_output_for_decode = "abcdezghIJ";
|
||||
expected = std::string("\0abcdezghIJ\0", 12);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
// Shortened data, can't transform.
|
||||
|
||||
desired_output_for_decode = "abcdefghI";
|
||||
expected = std::string("\0abcdefghI\0", 11);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
// Extra data, can't transform.
|
||||
|
||||
desired_output_for_decode = "abcdefghIJz";
|
||||
expected = std::string("\0abcdefghIJz\0", 13);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
}
|
||||
|
||||
TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
|
||||
std::string input_for_decode("abcdefghIJ");
|
||||
std::string desired_output_for_decode;
|
||||
std::string expected;
|
||||
std::string result;
|
||||
|
||||
desired_output_for_decode = "abcdefghIJ";
|
||||
expected = std::string("\x0A\x0", 2);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
desired_output_for_decode = "_AbcdefghIJ";
|
||||
expected = std::string("\xCA\x0", 2);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
desired_output_for_decode = "ABCD__EfghI_j";
|
||||
expected = std::string("\x64\x80\xC5\xA1\x0", 5);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
|
||||
// Long name so multiple decode ops are needed.
|
||||
|
||||
input_for_decode =
|
||||
"longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000";
|
||||
desired_output_for_decode =
|
||||
"long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000";
|
||||
expected = std::string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
|
||||
result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
|
||||
desired_output_for_decode);
|
||||
EXPECT_EQ(expected, result);
|
||||
}
|
||||
|
||||
// Death tests do not work on Windows as of yet.
|
||||
#ifdef PROTOBUF_HAS_DEATH_TEST
|
||||
TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) {
|
||||
// Empty inputs.
|
||||
|
||||
EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", ""),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got empty string for making TextFormat data, input:");
|
||||
EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("a", ""),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got empty string for making TextFormat data, input:");
|
||||
EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", "a"),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got empty string for making TextFormat data, input:");
|
||||
|
||||
// Null char in the string.
|
||||
|
||||
std::string str_with_null_char("ab\0c", 4);
|
||||
EXPECT_EXIT(
|
||||
TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got a null char in a string for making TextFormat data, input:");
|
||||
EXPECT_EXIT(
|
||||
TextFormatDecodeData::DecodeDataForString("def", str_with_null_char),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got a null char in a string for making TextFormat data, input:");
|
||||
}
|
||||
#endif // PROTOBUF_HAS_DEATH_TEST
|
||||
|
||||
TEST(ObjCHelper, TextFormatDecodeData_RawStrings) {
|
||||
TextFormatDecodeData decode_data;
|
||||
|
||||
// Different data, can't transform.
|
||||
decode_data.AddString(1, "abcdefghIJ", "zbcdefghIJ");
|
||||
decode_data.AddString(3, "abcdefghIJ", "abcdezghIJ");
|
||||
// Shortened data, can't transform.
|
||||
decode_data.AddString(2, "abcdefghIJ", "abcdefghI");
|
||||
// Extra data, can't transform.
|
||||
decode_data.AddString(4, "abcdefghIJ", "abcdefghIJz");
|
||||
|
||||
EXPECT_EQ(4, decode_data.num_entries());
|
||||
|
||||
uint8 expected_data[] = {
|
||||
0x4,
|
||||
0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0,
|
||||
0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0,
|
||||
0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0,
|
||||
0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0,
|
||||
};
|
||||
std::string expected((const char*)expected_data, sizeof(expected_data));
|
||||
|
||||
EXPECT_EQ(expected, decode_data.Data());
|
||||
}
|
||||
|
||||
TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) {
|
||||
TextFormatDecodeData decode_data;
|
||||
|
||||
decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
|
||||
decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
|
||||
decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
|
||||
decode_data.AddString(4, "abcdefghIJ", "ABCD__EfghI_j");
|
||||
decode_data.AddString(1000,
|
||||
"longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000",
|
||||
"long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000");
|
||||
|
||||
EXPECT_EQ(5, decode_data.num_entries());
|
||||
|
||||
uint8 expected_data[] = {
|
||||
0x5,
|
||||
// All as is (00 op)
|
||||
0x1, 0x0A, 0x0,
|
||||
// Underscore, upper + 9 (10 op)
|
||||
0x3, 0xCA, 0x0,
|
||||
// Upper + 3 (10 op), underscore, upper + 5 (10 op)
|
||||
0x2, 0x44, 0xC6, 0x0,
|
||||
// All Upper for 4 (11 op), underscore, underscore, upper + 5 (10 op),
|
||||
// underscore, lower + 0 (01 op)
|
||||
0x4, 0x64, 0x80, 0xC5, 0xA1, 0x0,
|
||||
// 2 byte key: as is + 3 (00 op), underscore, lower + 4 (01 op),
|
||||
// underscore, lower + 3 (01 op), underscore, lower + 1 (01 op),
|
||||
// underscore, lower + 30 (01 op), as is + 30 (00 op), as is + 13 (00
|
||||
// op),
|
||||
// underscore, as is + 3 (00 op)
|
||||
0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0,
|
||||
};
|
||||
std::string expected((const char*)expected_data, sizeof(expected_data));
|
||||
|
||||
EXPECT_EQ(expected, decode_data.Data());
|
||||
}
|
||||
|
||||
|
||||
// Death tests do not work on Windows as of yet.
|
||||
#ifdef PROTOBUF_HAS_DEATH_TEST
|
||||
TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
|
||||
TextFormatDecodeData decode_data;
|
||||
|
||||
// Empty inputs.
|
||||
|
||||
EXPECT_EXIT(decode_data.AddString(1, "", ""),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got empty string for making TextFormat data, input:");
|
||||
EXPECT_EXIT(decode_data.AddString(1, "a", ""),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got empty string for making TextFormat data, input:");
|
||||
EXPECT_EXIT(decode_data.AddString(1, "", "a"),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got empty string for making TextFormat data, input:");
|
||||
|
||||
// Null char in the string.
|
||||
|
||||
std::string str_with_null_char("ab\0c", 4);
|
||||
EXPECT_EXIT(
|
||||
decode_data.AddString(1, str_with_null_char, "def"),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got a null char in a string for making TextFormat data, input:");
|
||||
EXPECT_EXIT(
|
||||
decode_data.AddString(1, "def", str_with_null_char),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: got a null char in a string for making TextFormat data, input:");
|
||||
|
||||
// Duplicate keys
|
||||
|
||||
decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
|
||||
decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
|
||||
decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
|
||||
EXPECT_EXIT(decode_data.AddString(2, "xyz", "x_yz"),
|
||||
::testing::KilledBySignal(SIGABRT),
|
||||
"error: duplicate key \\(2\\) making TextFormat data, input:");
|
||||
}
|
||||
#endif // PROTOBUF_HAS_DEATH_TEST
|
||||
|
||||
// TODO(thomasvl): Should probably add some unittests for all the special cases
|
||||
// of name mangling (class name, field name, enum names). Rather than doing
|
||||
// this with an ObjC test in the objectivec directory, we should be able to
|
||||
// use src/google/protobuf/compiler/importer* (like other tests) to support a
|
||||
// virtual file system to feed in protos, once we have the Descriptor tree, the
|
||||
// tests could use the helper methods for generating names and validate the
|
||||
// right things are happening.
|
||||
|
||||
} // namespace
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,189 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_map_field.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
// MapFieldGenerator uses RepeatedFieldGenerator as the parent because it
|
||||
// provides a bunch of things (no has* methods, comments for contained type,
|
||||
// etc.).
|
||||
|
||||
namespace {
|
||||
|
||||
const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
|
||||
ObjectiveCType type = GetObjectiveCType(descriptor);
|
||||
switch (type) {
|
||||
case OBJECTIVECTYPE_INT32:
|
||||
return "Int32";
|
||||
case OBJECTIVECTYPE_UINT32:
|
||||
return "UInt32";
|
||||
case OBJECTIVECTYPE_INT64:
|
||||
return "Int64";
|
||||
case OBJECTIVECTYPE_UINT64:
|
||||
return "UInt64";
|
||||
case OBJECTIVECTYPE_FLOAT:
|
||||
return "Float";
|
||||
case OBJECTIVECTYPE_DOUBLE:
|
||||
return "Double";
|
||||
case OBJECTIVECTYPE_BOOLEAN:
|
||||
return "Bool";
|
||||
case OBJECTIVECTYPE_STRING:
|
||||
return (isKey ? "String" : "Object");
|
||||
case OBJECTIVECTYPE_DATA:
|
||||
return "Object";
|
||||
case OBJECTIVECTYPE_ENUM:
|
||||
return "Enum";
|
||||
case OBJECTIVECTYPE_MESSAGE:
|
||||
return "Object";
|
||||
}
|
||||
|
||||
// Some compilers report reaching end of function even though all cases of
|
||||
// the enum are handed in the switch.
|
||||
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: RepeatedFieldGenerator(descriptor, options) {
|
||||
const FieldDescriptor* key_descriptor =
|
||||
descriptor->message_type()->map_key();
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor->message_type()->map_value();
|
||||
value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options));
|
||||
|
||||
// Pull over some variables_ from the value.
|
||||
variables_["field_type"] = value_field_generator_->variable("field_type");
|
||||
variables_["default"] = value_field_generator_->variable("default");
|
||||
variables_["default_name"] = value_field_generator_->variable("default_name");
|
||||
|
||||
// Build custom field flags.
|
||||
std::vector<std::string> field_flags;
|
||||
field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor));
|
||||
// Pull over the current text format custom name values that was calculated.
|
||||
if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") !=
|
||||
std::string::npos) {
|
||||
field_flags.push_back("GPBFieldTextFormatNameCustom");
|
||||
}
|
||||
// Pull over some info from the value's flags.
|
||||
const std::string& value_field_flags =
|
||||
value_field_generator_->variable("fieldflags");
|
||||
if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) {
|
||||
field_flags.push_back("GPBFieldHasDefaultValue");
|
||||
}
|
||||
if (value_field_flags.find("GPBFieldHasEnumDescriptor") !=
|
||||
std::string::npos) {
|
||||
field_flags.push_back("GPBFieldHasEnumDescriptor");
|
||||
}
|
||||
|
||||
variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
|
||||
|
||||
ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor);
|
||||
const bool value_is_object_type =
|
||||
((value_objc_type == OBJECTIVECTYPE_STRING) ||
|
||||
(value_objc_type == OBJECTIVECTYPE_DATA) ||
|
||||
(value_objc_type == OBJECTIVECTYPE_MESSAGE));
|
||||
if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) &&
|
||||
value_is_object_type) {
|
||||
variables_["array_storage_type"] = "NSMutableDictionary";
|
||||
variables_["array_property_type"] =
|
||||
"NSMutableDictionary<NSString*, " +
|
||||
value_field_generator_->variable("storage_type") + "*>";
|
||||
} else {
|
||||
std::string class_name("GPB");
|
||||
class_name += MapEntryTypeName(key_descriptor, true);
|
||||
class_name += MapEntryTypeName(value_descriptor, false);
|
||||
class_name += "Dictionary";
|
||||
variables_["array_storage_type"] = class_name;
|
||||
if (value_is_object_type) {
|
||||
variables_["array_property_type"] =
|
||||
class_name + "<" +
|
||||
value_field_generator_->variable("storage_type") + "*>";
|
||||
}
|
||||
}
|
||||
|
||||
variables_["dataTypeSpecific_name"] =
|
||||
value_field_generator_->variable("dataTypeSpecific_name");
|
||||
variables_["dataTypeSpecific_value"] =
|
||||
value_field_generator_->variable("dataTypeSpecific_value");
|
||||
}
|
||||
|
||||
MapFieldGenerator::~MapFieldGenerator() {}
|
||||
|
||||
void MapFieldGenerator::FinishInitialization(void) {
|
||||
RepeatedFieldGenerator::FinishInitialization();
|
||||
// Use the array_comment support in RepeatedFieldGenerator to output what the
|
||||
// values in the map are.
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor_->message_type()->FindFieldByName("value");
|
||||
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) {
|
||||
variables_["array_comment"] =
|
||||
"// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n";
|
||||
}
|
||||
}
|
||||
|
||||
void MapFieldGenerator::DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor_->message_type()->FindFieldByName("value");
|
||||
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
|
||||
const std::string& value_storage_type =
|
||||
value_field_generator_->variable("storage_type");
|
||||
fwd_decls->insert("@class " + value_storage_type);
|
||||
}
|
||||
}
|
||||
|
||||
void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
// Class name is already in "storage_type".
|
||||
const FieldDescriptor* value_descriptor =
|
||||
descriptor_->message_type()->FindFieldByName("value");
|
||||
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
|
||||
fwd_decls->insert(ObjCClassDeclaration(
|
||||
value_field_generator_->variable("storage_type")));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,71 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2015 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_field.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class MapFieldGenerator : public RepeatedFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
public:
|
||||
virtual void FinishInitialization(void);
|
||||
|
||||
MapFieldGenerator(const MapFieldGenerator&) = delete;
|
||||
MapFieldGenerator& operator=(const MapFieldGenerator&) = delete;
|
||||
|
||||
protected:
|
||||
MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
|
||||
virtual ~MapFieldGenerator();
|
||||
|
||||
virtual void DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
virtual void DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<FieldGenerator> value_field_generator_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
|
||||
636
ubuntu/google/protobuf/compiler/objectivec/objectivec_message.cc
Normal file
636
ubuntu/google/protobuf/compiler/objectivec/objectivec_message.cc
Normal file
@@ -0,0 +1,636 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_message.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_enum.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_extension.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/stubs/stl_util.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
#include <google/protobuf/wire_format_lite.h>
|
||||
#include <google/protobuf/descriptor.pb.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
namespace {
|
||||
struct FieldOrderingByNumber {
|
||||
inline bool operator()(const FieldDescriptor* a,
|
||||
const FieldDescriptor* b) const {
|
||||
return a->number() < b->number();
|
||||
}
|
||||
};
|
||||
|
||||
int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) {
|
||||
// The first item in the object structure is our uint32[] for has bits.
|
||||
// We then want to order things to make the instances as small as
|
||||
// possible. So we follow the has bits with:
|
||||
// 1. Anything always 4 bytes - float, *32, enums
|
||||
// 2. Anything that is always a pointer (they will be 8 bytes on 64 bit
|
||||
// builds and 4 bytes on 32bit builds.
|
||||
// 3. Anything always 8 bytes - double, *64
|
||||
//
|
||||
// NOTE: Bools aren't listed, they were stored in the has bits.
|
||||
//
|
||||
// Why? Using 64bit builds as an example, this means worse case, we have
|
||||
// enough bools that we overflow 1 byte from 4 byte alignment, so 3 bytes
|
||||
// are wasted before the 4 byte values. Then if we have an odd number of
|
||||
// those 4 byte values, the 8 byte values will be pushed down by 32bits to
|
||||
// keep them aligned. But the structure will end 8 byte aligned, so no
|
||||
// waste on the end. If you did the reverse order, you could waste 4 bytes
|
||||
// before the first 8 byte value (after the has array), then a single
|
||||
// bool on the end would need 7 bytes of padding to make the overall
|
||||
// structure 8 byte aligned; so 11 bytes, wasted total.
|
||||
|
||||
// Anything repeated is a GPB*Array/NSArray, so pointer.
|
||||
if (descriptor->is_repeated()) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
switch (descriptor->type()) {
|
||||
// All always 8 bytes.
|
||||
case FieldDescriptor::TYPE_DOUBLE:
|
||||
case FieldDescriptor::TYPE_INT64:
|
||||
case FieldDescriptor::TYPE_SINT64:
|
||||
case FieldDescriptor::TYPE_UINT64:
|
||||
case FieldDescriptor::TYPE_SFIXED64:
|
||||
case FieldDescriptor::TYPE_FIXED64:
|
||||
return 4;
|
||||
|
||||
// Pointers (string and bytes are NSString and NSData); 8 or 4 bytes
|
||||
// depending on the build architecture.
|
||||
case FieldDescriptor::TYPE_GROUP:
|
||||
case FieldDescriptor::TYPE_MESSAGE:
|
||||
case FieldDescriptor::TYPE_STRING:
|
||||
case FieldDescriptor::TYPE_BYTES:
|
||||
return 3;
|
||||
|
||||
// All always 4 bytes (enums are int32s).
|
||||
case FieldDescriptor::TYPE_FLOAT:
|
||||
case FieldDescriptor::TYPE_INT32:
|
||||
case FieldDescriptor::TYPE_SINT32:
|
||||
case FieldDescriptor::TYPE_UINT32:
|
||||
case FieldDescriptor::TYPE_SFIXED32:
|
||||
case FieldDescriptor::TYPE_FIXED32:
|
||||
case FieldDescriptor::TYPE_ENUM:
|
||||
return 2;
|
||||
|
||||
// 0 bytes. Stored in the has bits.
|
||||
case FieldDescriptor::TYPE_BOOL:
|
||||
return 99; // End of the list (doesn't really matter).
|
||||
}
|
||||
|
||||
// Some compilers report reaching end of function even though all cases of
|
||||
// the enum are handed in the switch.
|
||||
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct FieldOrderingByStorageSize {
|
||||
inline bool operator()(const FieldDescriptor* a,
|
||||
const FieldDescriptor* b) const {
|
||||
// Order by grouping.
|
||||
const int order_group_a = OrderGroupForFieldDescriptor(a);
|
||||
const int order_group_b = OrderGroupForFieldDescriptor(b);
|
||||
if (order_group_a != order_group_b) {
|
||||
return order_group_a < order_group_b;
|
||||
}
|
||||
// Within the group, order by field number (provides stable ordering).
|
||||
return a->number() < b->number();
|
||||
}
|
||||
};
|
||||
|
||||
struct ExtensionRangeOrdering {
|
||||
bool operator()(const Descriptor::ExtensionRange* a,
|
||||
const Descriptor::ExtensionRange* b) const {
|
||||
return a->start < b->start;
|
||||
}
|
||||
};
|
||||
|
||||
// Sort the fields of the given Descriptor by number into a new[]'d array
|
||||
// and return it.
|
||||
const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
|
||||
const FieldDescriptor** fields =
|
||||
new const FieldDescriptor* [descriptor->field_count()];
|
||||
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||
fields[i] = descriptor->field(i);
|
||||
}
|
||||
std::sort(fields, fields + descriptor->field_count(), FieldOrderingByNumber());
|
||||
return fields;
|
||||
}
|
||||
|
||||
// Sort the fields of the given Descriptor by storage size into a new[]'d
|
||||
// array and return it.
|
||||
const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) {
|
||||
const FieldDescriptor** fields =
|
||||
new const FieldDescriptor* [descriptor->field_count()];
|
||||
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||
fields[i] = descriptor->field(i);
|
||||
}
|
||||
std::sort(fields, fields + descriptor->field_count(),
|
||||
FieldOrderingByStorageSize());
|
||||
return fields;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
MessageGenerator::MessageGenerator(const std::string& root_classname,
|
||||
const Descriptor* descriptor,
|
||||
const Options& options)
|
||||
: root_classname_(root_classname),
|
||||
descriptor_(descriptor),
|
||||
field_generators_(descriptor, options),
|
||||
class_name_(ClassName(descriptor_)),
|
||||
deprecated_attribute_(GetOptionalDeprecatedAttribute(
|
||||
descriptor, descriptor->file(), false, true)) {
|
||||
for (int i = 0; i < descriptor_->extension_count(); i++) {
|
||||
extension_generators_.emplace_back(
|
||||
new ExtensionGenerator(class_name_, descriptor_->extension(i)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
|
||||
OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
|
||||
oneof_generators_.emplace_back(generator);
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
|
||||
EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i));
|
||||
enum_generators_.emplace_back(generator);
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
|
||||
MessageGenerator* generator =
|
||||
new MessageGenerator(root_classname_,
|
||||
descriptor_->nested_type(i),
|
||||
options);
|
||||
nested_message_generators_.emplace_back(generator);
|
||||
}
|
||||
}
|
||||
|
||||
MessageGenerator::~MessageGenerator() {}
|
||||
|
||||
void MessageGenerator::GenerateStaticVariablesInitialization(
|
||||
io::Printer* printer) {
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->GenerateStaticVariablesInitialization(printer);
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->GenerateStaticVariablesInitialization(printer);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageGenerator::DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) {
|
||||
if (!IsMapEntryMessage(descriptor_)) {
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
|
||||
field_generators_.get(fieldDescriptor)
|
||||
.DetermineForwardDeclarations(fwd_decls);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->DetermineForwardDeclarations(fwd_decls);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageGenerator::DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) {
|
||||
if (!IsMapEntryMessage(descriptor_)) {
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
|
||||
field_generators_.get(fieldDescriptor)
|
||||
.DetermineObjectiveCClassDefinitions(fwd_decls);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->DetermineObjectiveCClassDefinitions(fwd_decls);
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->DetermineObjectiveCClassDefinitions(fwd_decls);
|
||||
}
|
||||
|
||||
const Descriptor* containing_descriptor = descriptor_->containing_type();
|
||||
if (containing_descriptor != NULL) {
|
||||
std::string containing_class = ClassName(containing_descriptor);
|
||||
fwd_decls->insert(ObjCClassDeclaration(containing_class));
|
||||
}
|
||||
}
|
||||
|
||||
bool MessageGenerator::IncludesOneOfDefinition() const {
|
||||
if (!oneof_generators_.empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
if (generator->IncludesOneOfDefinition()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
|
||||
for (const auto& generator : enum_generators_) {
|
||||
generator->GenerateHeader(printer);
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->GenerateEnumHeader(printer);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageGenerator::GenerateExtensionRegistrationSource(
|
||||
io::Printer* printer) {
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->GenerateRegistrationSource(printer);
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->GenerateExtensionRegistrationSource(printer);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
|
||||
// This a a map entry message, just recurse and do nothing directly.
|
||||
if (IsMapEntryMessage(descriptor_)) {
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->GenerateMessageHeader(printer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"#pragma mark - $classname$\n"
|
||||
"\n",
|
||||
"classname", class_name_);
|
||||
|
||||
if (descriptor_->field_count()) {
|
||||
std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
|
||||
SortFieldsByNumber(descriptor_));
|
||||
|
||||
printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
|
||||
"classname", class_name_);
|
||||
printer->Indent();
|
||||
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
field_generators_.get(sorted_fields[i])
|
||||
.GenerateFieldNumberConstant(printer);
|
||||
}
|
||||
|
||||
printer->Outdent();
|
||||
printer->Print("};\n\n");
|
||||
}
|
||||
|
||||
for (const auto& generator : oneof_generators_) {
|
||||
generator->GenerateCaseEnum(printer);
|
||||
}
|
||||
|
||||
std::string message_comments;
|
||||
SourceLocation location;
|
||||
if (descriptor_->GetSourceLocation(&location)) {
|
||||
message_comments = BuildCommentsString(location, false);
|
||||
} else {
|
||||
message_comments = "";
|
||||
}
|
||||
|
||||
printer->Print(
|
||||
"$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n",
|
||||
"classname", class_name_,
|
||||
"deprecated_attribute", deprecated_attribute_,
|
||||
"comments", message_comments);
|
||||
|
||||
std::vector<char> seen_oneofs(oneof_generators_.size(), 0);
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
const FieldDescriptor* field = descriptor_->field(i);
|
||||
const OneofDescriptor *oneof = field->real_containing_oneof();
|
||||
if (oneof) {
|
||||
const int oneof_index = oneof->index();
|
||||
if (!seen_oneofs[oneof_index]) {
|
||||
seen_oneofs[oneof_index] = 1;
|
||||
oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
|
||||
printer);
|
||||
}
|
||||
}
|
||||
field_generators_.get(field).GeneratePropertyDeclaration(printer);
|
||||
}
|
||||
|
||||
printer->Print("@end\n\n");
|
||||
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
field_generators_.get(descriptor_->field(i))
|
||||
.GenerateCFunctionDeclarations(printer);
|
||||
}
|
||||
|
||||
if (!oneof_generators_.empty()) {
|
||||
for (const auto& generator : oneof_generators_) {
|
||||
generator->GenerateClearFunctionDeclaration(printer);
|
||||
}
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
if (descriptor_->extension_count() > 0) {
|
||||
printer->Print("@interface $classname$ (DynamicMethods)\n\n",
|
||||
"classname", class_name_);
|
||||
for (const auto& generator : extension_generators_) {
|
||||
generator->GenerateMembersHeader(printer);
|
||||
}
|
||||
printer->Print("@end\n\n");
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->GenerateMessageHeader(printer);
|
||||
}
|
||||
}
|
||||
|
||||
void MessageGenerator::GenerateSource(io::Printer* printer) {
|
||||
if (!IsMapEntryMessage(descriptor_)) {
|
||||
printer->Print(
|
||||
"#pragma mark - $classname$\n"
|
||||
"\n",
|
||||
"classname", class_name_);
|
||||
|
||||
if (!deprecated_attribute_.empty()) {
|
||||
// No warnings when compiling the impl of this deprecated class.
|
||||
printer->Print(
|
||||
"#pragma clang diagnostic push\n"
|
||||
"#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
printer->Print("@implementation $classname$\n\n",
|
||||
"classname", class_name_);
|
||||
|
||||
for (const auto& generator : oneof_generators_) {
|
||||
generator->GeneratePropertyImplementation(printer);
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
field_generators_.get(descriptor_->field(i))
|
||||
.GeneratePropertyImplementation(printer);
|
||||
}
|
||||
|
||||
std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
|
||||
SortFieldsByNumber(descriptor_));
|
||||
std::unique_ptr<const FieldDescriptor*[]> size_order_fields(
|
||||
SortFieldsByStorageSize(descriptor_));
|
||||
|
||||
std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
|
||||
sorted_extensions.reserve(descriptor_->extension_range_count());
|
||||
for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
|
||||
sorted_extensions.push_back(descriptor_->extension_range(i));
|
||||
}
|
||||
|
||||
std::sort(sorted_extensions.begin(), sorted_extensions.end(),
|
||||
ExtensionRangeOrdering());
|
||||
|
||||
// Assign has bits:
|
||||
// 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
|
||||
// who needs has bits and assigning them.
|
||||
// 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
|
||||
// index that groups all the elements in the oneof.
|
||||
size_t num_has_bits = field_generators_.CalculateHasBits();
|
||||
size_t sizeof_has_storage = (num_has_bits + 31) / 32;
|
||||
if (sizeof_has_storage == 0) {
|
||||
// In the case where no field needs has bits, don't let the _has_storage_
|
||||
// end up as zero length (zero length arrays are sort of a grey area
|
||||
// since it has to be at the start of the struct). This also ensures a
|
||||
// field with only oneofs keeps the required negative indices they need.
|
||||
sizeof_has_storage = 1;
|
||||
}
|
||||
// Tell all the fields the oneof base.
|
||||
for (const auto& generator : oneof_generators_) {
|
||||
generator->SetOneofIndexBase(sizeof_has_storage);
|
||||
}
|
||||
field_generators_.SetOneofIndexBase(sizeof_has_storage);
|
||||
// sizeof_has_storage needs enough bits for the single fields that aren't in
|
||||
// any oneof, and then one int32 for each oneof (to store the field number).
|
||||
sizeof_has_storage += oneof_generators_.size();
|
||||
|
||||
printer->Print(
|
||||
"\n"
|
||||
"typedef struct $classname$__storage_ {\n"
|
||||
" uint32_t _has_storage_[$sizeof_has_storage$];\n",
|
||||
"classname", class_name_,
|
||||
"sizeof_has_storage", StrCat(sizeof_has_storage));
|
||||
printer->Indent();
|
||||
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
field_generators_.get(size_order_fields[i])
|
||||
.GenerateFieldStorageDeclaration(printer);
|
||||
}
|
||||
printer->Outdent();
|
||||
|
||||
printer->Print("} $classname$__storage_;\n\n", "classname", class_name_);
|
||||
|
||||
|
||||
printer->Print(
|
||||
"// This method is threadsafe because it is initially called\n"
|
||||
"// in +initialize for each subclass.\n"
|
||||
"+ (GPBDescriptor *)descriptor {\n"
|
||||
" static GPBDescriptor *descriptor = nil;\n"
|
||||
" if (!descriptor) {\n");
|
||||
|
||||
TextFormatDecodeData text_format_decode_data;
|
||||
bool has_fields = descriptor_->field_count() > 0;
|
||||
bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault();
|
||||
std::string field_description_type;
|
||||
if (need_defaults) {
|
||||
field_description_type = "GPBMessageFieldDescriptionWithDefault";
|
||||
} else {
|
||||
field_description_type = "GPBMessageFieldDescription";
|
||||
}
|
||||
if (has_fields) {
|
||||
printer->Indent();
|
||||
printer->Indent();
|
||||
printer->Print(
|
||||
"static $field_description_type$ fields[] = {\n",
|
||||
"field_description_type", field_description_type);
|
||||
printer->Indent();
|
||||
for (int i = 0; i < descriptor_->field_count(); ++i) {
|
||||
const FieldGenerator& field_generator =
|
||||
field_generators_.get(sorted_fields[i]);
|
||||
field_generator.GenerateFieldDescription(printer, need_defaults);
|
||||
if (field_generator.needs_textformat_name_support()) {
|
||||
text_format_decode_data.AddString(sorted_fields[i]->number(),
|
||||
field_generator.generated_objc_name(),
|
||||
field_generator.raw_field_name());
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n");
|
||||
printer->Outdent();
|
||||
printer->Outdent();
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> vars;
|
||||
vars["classname"] = class_name_;
|
||||
vars["rootclassname"] = root_classname_;
|
||||
vars["fields"] = has_fields ? "fields" : "NULL";
|
||||
if (has_fields) {
|
||||
vars["fields_count"] =
|
||||
"(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))";
|
||||
} else {
|
||||
vars["fields_count"] = "0";
|
||||
}
|
||||
|
||||
std::vector<std::string> init_flags;
|
||||
init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs");
|
||||
init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown");
|
||||
if (need_defaults) {
|
||||
init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault");
|
||||
}
|
||||
if (descriptor_->options().message_set_wire_format()) {
|
||||
init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat");
|
||||
}
|
||||
vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION,
|
||||
init_flags);
|
||||
|
||||
printer->Print(
|
||||
vars,
|
||||
" GPBDescriptor *localDescriptor =\n"
|
||||
" [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
|
||||
" rootClass:[$rootclassname$ class]\n"
|
||||
" file:$rootclassname$_FileDescriptor()\n"
|
||||
" fields:$fields$\n"
|
||||
" fieldCount:$fields_count$\n"
|
||||
" storageSize:sizeof($classname$__storage_)\n"
|
||||
" flags:$init_flags$];\n");
|
||||
if (!oneof_generators_.empty()) {
|
||||
printer->Print(
|
||||
" static const char *oneofs[] = {\n");
|
||||
for (const auto& generator : oneof_generators_) {
|
||||
printer->Print(" \"$name$\",\n", "name",
|
||||
generator->DescriptorName());
|
||||
}
|
||||
printer->Print(
|
||||
" };\n"
|
||||
" [localDescriptor setupOneofs:oneofs\n"
|
||||
" count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n"
|
||||
" firstHasIndex:$first_has_index$];\n",
|
||||
"first_has_index", oneof_generators_[0]->HasIndexAsString());
|
||||
}
|
||||
if (text_format_decode_data.num_entries() != 0) {
|
||||
const std::string text_format_data_str(text_format_decode_data.Data());
|
||||
printer->Print(
|
||||
"#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
|
||||
" static const char *extraTextFormatInfo =");
|
||||
static const int kBytesPerLine = 40; // allow for escaping
|
||||
for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) {
|
||||
printer->Print(
|
||||
"\n \"$data$\"",
|
||||
"data", EscapeTrigraphs(
|
||||
CEscape(text_format_data_str.substr(i, kBytesPerLine))));
|
||||
}
|
||||
printer->Print(
|
||||
";\n"
|
||||
" [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n"
|
||||
"#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n");
|
||||
}
|
||||
if (!sorted_extensions.empty()) {
|
||||
printer->Print(
|
||||
" static const GPBExtensionRange ranges[] = {\n");
|
||||
for (int i = 0; i < sorted_extensions.size(); i++) {
|
||||
printer->Print(" { .start = $start$, .end = $end$ },\n",
|
||||
"start", StrCat(sorted_extensions[i]->start),
|
||||
"end", StrCat(sorted_extensions[i]->end));
|
||||
}
|
||||
printer->Print(
|
||||
" };\n"
|
||||
" [localDescriptor setupExtensionRanges:ranges\n"
|
||||
" count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
|
||||
}
|
||||
if (descriptor_->containing_type() != NULL) {
|
||||
std::string containing_class = ClassName(descriptor_->containing_type());
|
||||
std::string parent_class_ref = ObjCClass(containing_class);
|
||||
printer->Print(
|
||||
" [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
|
||||
"parent_class_ref", parent_class_ref);
|
||||
}
|
||||
std::string suffix_added;
|
||||
ClassName(descriptor_, &suffix_added);
|
||||
if (!suffix_added.empty()) {
|
||||
printer->Print(
|
||||
" [localDescriptor setupMessageClassNameSuffix:@\"$suffix$\"];\n",
|
||||
"suffix", suffix_added);
|
||||
}
|
||||
printer->Print(
|
||||
" #if defined(DEBUG) && DEBUG\n"
|
||||
" NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
|
||||
" #endif // DEBUG\n"
|
||||
" descriptor = localDescriptor;\n"
|
||||
" }\n"
|
||||
" return descriptor;\n"
|
||||
"}\n\n"
|
||||
"@end\n\n");
|
||||
|
||||
if (!deprecated_attribute_.empty()) {
|
||||
printer->Print(
|
||||
"#pragma clang diagnostic pop\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) {
|
||||
field_generators_.get(descriptor_->field(i))
|
||||
.GenerateCFunctionImplementations(printer);
|
||||
}
|
||||
|
||||
for (const auto& generator : oneof_generators_) {
|
||||
generator->GenerateClearFunctionImplementation(printer);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& generator : enum_generators_) {
|
||||
generator->GenerateSource(printer);
|
||||
}
|
||||
|
||||
for (const auto& generator : nested_message_generators_) {
|
||||
generator->GenerateSource(printer);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,99 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_field.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_oneof.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class ExtensionGenerator;
|
||||
class EnumGenerator;
|
||||
|
||||
class MessageGenerator {
|
||||
public:
|
||||
MessageGenerator(const std::string& root_classname,
|
||||
const Descriptor* descriptor, const Options& options);
|
||||
~MessageGenerator();
|
||||
|
||||
MessageGenerator(const MessageGenerator&) = delete;
|
||||
MessageGenerator& operator=(const MessageGenerator&) = delete;
|
||||
|
||||
void GenerateStaticVariablesInitialization(io::Printer* printer);
|
||||
void GenerateEnumHeader(io::Printer* printer);
|
||||
void GenerateMessageHeader(io::Printer* printer);
|
||||
void GenerateSource(io::Printer* printer);
|
||||
void GenerateExtensionRegistrationSource(io::Printer* printer);
|
||||
void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
|
||||
void DetermineForwardDeclarations(std::set<std::string>* fwd_decls);
|
||||
|
||||
// Checks if the message or a nested message includes a oneof definition.
|
||||
bool IncludesOneOfDefinition() const;
|
||||
|
||||
private:
|
||||
void GenerateParseFromMethodsHeader(io::Printer* printer);
|
||||
|
||||
void GenerateSerializeOneFieldSource(io::Printer* printer,
|
||||
const FieldDescriptor* field);
|
||||
void GenerateSerializeOneExtensionRangeSource(
|
||||
io::Printer* printer, const Descriptor::ExtensionRange* range);
|
||||
|
||||
void GenerateMessageDescriptionSource(io::Printer* printer);
|
||||
void GenerateDescriptionOneFieldSource(io::Printer* printer,
|
||||
const FieldDescriptor* field);
|
||||
|
||||
const std::string root_classname_;
|
||||
const Descriptor* descriptor_;
|
||||
FieldGeneratorMap field_generators_;
|
||||
const std::string class_name_;
|
||||
const std::string deprecated_attribute_;
|
||||
std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
|
||||
std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
|
||||
std::vector<std::unique_ptr<MessageGenerator>> nested_message_generators_;
|
||||
std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
|
||||
@@ -0,0 +1,107 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_message_field.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
namespace {
|
||||
|
||||
void SetMessageVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables) {
|
||||
const std::string& message_type = ClassName(descriptor->message_type());
|
||||
const std::string& containing_class =
|
||||
ClassName(descriptor->containing_type());
|
||||
(*variables)["type"] = message_type;
|
||||
(*variables)["containing_class"] = containing_class;
|
||||
(*variables)["storage_type"] = message_type;
|
||||
(*variables)["group_or_message"] =
|
||||
(descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
|
||||
(*variables)["dataTypeSpecific_value"] = ObjCClass(message_type);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options)
|
||||
: ObjCObjFieldGenerator(descriptor, options) {
|
||||
SetMessageVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
MessageFieldGenerator::~MessageFieldGenerator() {}
|
||||
|
||||
void MessageFieldGenerator::DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls);
|
||||
// Class name is already in "storage_type".
|
||||
fwd_decls->insert("@class " + variable("storage_type"));
|
||||
}
|
||||
|
||||
void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
|
||||
}
|
||||
|
||||
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: RepeatedFieldGenerator(descriptor, options) {
|
||||
SetMessageVariables(descriptor, &variables_);
|
||||
variables_["array_storage_type"] = "NSMutableArray";
|
||||
variables_["array_property_type"] =
|
||||
"NSMutableArray<" + variables_["storage_type"] + "*>";
|
||||
}
|
||||
|
||||
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
|
||||
|
||||
void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
|
||||
// Class name is already in "storage_type".
|
||||
fwd_decls->insert("@class " + variable("storage_type"));
|
||||
}
|
||||
|
||||
void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const {
|
||||
fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,87 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_field.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class MessageFieldGenerator : public ObjCObjFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
protected:
|
||||
MessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
|
||||
MessageFieldGenerator(const MessageFieldGenerator&) = delete;
|
||||
MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
|
||||
|
||||
virtual ~MessageFieldGenerator();
|
||||
|
||||
public:
|
||||
virtual void DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
virtual void DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
};
|
||||
|
||||
class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
protected:
|
||||
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
virtual ~RepeatedMessageFieldGenerator();
|
||||
|
||||
RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete;
|
||||
RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete;
|
||||
|
||||
public:
|
||||
virtual void DetermineForwardDeclarations(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
virtual void DetermineObjectiveCClassDefinitions(
|
||||
std::set<std::string>* fwd_decls) const;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
|
||||
@@ -0,0 +1,197 @@
|
||||
// NSObject methods
|
||||
// Autogenerated by method_dump.sh. Do not edit by hand.
|
||||
// Date: Thu Nov 1 14:12:16 PDT 2018
|
||||
// macOS: MacOSX10.14.sdk
|
||||
// iOS: iPhoneSimulator12.1.sdk
|
||||
|
||||
const char* const kNSObjectMethodsList[] = {
|
||||
"CAMLType",
|
||||
"CA_copyRenderValue",
|
||||
"CA_prepareRenderValue",
|
||||
"NS_copyCGImage",
|
||||
"NS_tiledLayerVisibleRect",
|
||||
"___tryRetain_OA",
|
||||
"__autorelease_OA",
|
||||
"__dealloc_zombie",
|
||||
"__release_OA",
|
||||
"__retain_OA",
|
||||
"_accessibilityFinalize",
|
||||
"_accessibilityIsTableViewDescendant",
|
||||
"_accessibilityUIElementSpecifier",
|
||||
"_accessibilityUseConvenienceAPI",
|
||||
"_allowsDirectEncoding",
|
||||
"_asScriptTerminologyNameArray",
|
||||
"_asScriptTerminologyNameString",
|
||||
"_bindingAdaptor",
|
||||
"_cfTypeID",
|
||||
"_copyDescription",
|
||||
"_destroyObserverList",
|
||||
"_didEndKeyValueObserving",
|
||||
"_implicitObservationInfo",
|
||||
"_internalAccessibilityAttributedHint",
|
||||
"_internalAccessibilityAttributedLabel",
|
||||
"_internalAccessibilityAttributedValue",
|
||||
"_isAXConnector",
|
||||
"_isAccessibilityContainerSectionCandidate",
|
||||
"_isAccessibilityContentNavigatorSectionCandidate",
|
||||
"_isAccessibilityContentSectionCandidate",
|
||||
"_isAccessibilityTopLevelNavigatorSectionCandidate",
|
||||
"_isDeallocating",
|
||||
"_isKVOA",
|
||||
"_isToManyChangeInformation",
|
||||
"_ivarDescription",
|
||||
"_localClassNameForClass",
|
||||
"_methodDescription",
|
||||
"_observerStorage",
|
||||
"_overrideUseFastBlockObservers",
|
||||
"_propertyDescription",
|
||||
"_releaseBindingAdaptor",
|
||||
"_scriptingCount",
|
||||
"_scriptingCountNonrecursively",
|
||||
"_scriptingDebugDescription",
|
||||
"_scriptingExists",
|
||||
"_scriptingShouldCheckObjectIndexes",
|
||||
"_shortMethodDescription",
|
||||
"_shouldSearchChildrenForSection",
|
||||
"_traitStorageList",
|
||||
"_tryRetain",
|
||||
"_ui_descriptionBuilder",
|
||||
"_uikit_variesByTraitCollections",
|
||||
"_web_description",
|
||||
"_webkit_invokeOnMainThread",
|
||||
"_willBeginKeyValueObserving",
|
||||
"accessibilityActivate",
|
||||
"accessibilityActivationPoint",
|
||||
"accessibilityAllowsOverriddenAttributesWhenIgnored",
|
||||
"accessibilityAssistiveTechnologyFocusedIdentifiers",
|
||||
"accessibilityAttributedHint",
|
||||
"accessibilityAttributedLabel",
|
||||
"accessibilityAttributedValue",
|
||||
"accessibilityContainer",
|
||||
"accessibilityContainerType",
|
||||
"accessibilityCustomActions",
|
||||
"accessibilityCustomRotors",
|
||||
"accessibilityDecrement",
|
||||
"accessibilityDragSourceDescriptors",
|
||||
"accessibilityDropPointDescriptors",
|
||||
"accessibilityElementCount",
|
||||
"accessibilityElementDidBecomeFocused",
|
||||
"accessibilityElementDidLoseFocus",
|
||||
"accessibilityElementIsFocused",
|
||||
"accessibilityElements",
|
||||
"accessibilityElementsHidden",
|
||||
"accessibilityFrame",
|
||||
"accessibilityHeaderElements",
|
||||
"accessibilityHint",
|
||||
"accessibilityIdentification",
|
||||
"accessibilityIdentifier",
|
||||
"accessibilityIncrement",
|
||||
"accessibilityLabel",
|
||||
"accessibilityLanguage",
|
||||
"accessibilityLocalizedStringKey",
|
||||
"accessibilityNavigationStyle",
|
||||
"accessibilityOverriddenAttributes",
|
||||
"accessibilityParameterizedAttributeNames",
|
||||
"accessibilityPath",
|
||||
"accessibilityPerformEscape",
|
||||
"accessibilityPerformMagicTap",
|
||||
"accessibilityPresenterProcessIdentifier",
|
||||
"accessibilityShouldUseUniqueId",
|
||||
"accessibilitySupportsNotifications",
|
||||
"accessibilitySupportsOverriddenAttributes",
|
||||
"accessibilityTemporaryChildren",
|
||||
"accessibilityTraits",
|
||||
"accessibilityValue",
|
||||
"accessibilityViewIsModal",
|
||||
"accessibilityVisibleArea",
|
||||
"allPropertyKeys",
|
||||
"allowsWeakReference",
|
||||
"attributeKeys",
|
||||
"autoContentAccessingProxy",
|
||||
"autorelease",
|
||||
"awakeFromNib",
|
||||
"boolValueSafe",
|
||||
"bs_encoded",
|
||||
"bs_isPlistableType",
|
||||
"bs_secureEncoded",
|
||||
"cl_json_serializeKey",
|
||||
"class",
|
||||
"classCode",
|
||||
"classDescription",
|
||||
"classForArchiver",
|
||||
"classForCoder",
|
||||
"classForKeyedArchiver",
|
||||
"classForPortCoder",
|
||||
"className",
|
||||
"clearProperties",
|
||||
"copy",
|
||||
"dealloc",
|
||||
"debugDescription",
|
||||
"defaultAccessibilityTraits",
|
||||
"description",
|
||||
"doubleValueSafe",
|
||||
"entityName",
|
||||
"exposedBindings",
|
||||
"finalize",
|
||||
"finishObserving",
|
||||
"flushKeyBindings",
|
||||
"hash",
|
||||
"init",
|
||||
"int64ValueSafe",
|
||||
"isAccessibilityElement",
|
||||
"isAccessibilityElementByDefault",
|
||||
"isElementAccessibilityExposedToInterfaceBuilder",
|
||||
"isFault",
|
||||
"isNSArray__",
|
||||
"isNSCFConstantString__",
|
||||
"isNSData__",
|
||||
"isNSDate__",
|
||||
"isNSDictionary__",
|
||||
"isNSNumber__",
|
||||
"isNSObject__",
|
||||
"isNSOrderedSet__",
|
||||
"isNSSet__",
|
||||
"isNSString__",
|
||||
"isNSTimeZone__",
|
||||
"isNSValue__",
|
||||
"isProxy",
|
||||
"mutableCopy",
|
||||
"nilValueForKey",
|
||||
"objectSpecifier",
|
||||
"observationInfo",
|
||||
"pep_onDetachedThread",
|
||||
"pep_onMainThread",
|
||||
"pep_onMainThreadIfNecessary",
|
||||
"prepareForInterfaceBuilder",
|
||||
"release",
|
||||
"releaseOnMainThread",
|
||||
"retain",
|
||||
"retainCount",
|
||||
"retainWeakReference",
|
||||
"scriptingProperties",
|
||||
"self",
|
||||
"shouldGroupAccessibilityChildren",
|
||||
"storedAccessibilityActivationPoint",
|
||||
"storedAccessibilityContainerType",
|
||||
"storedAccessibilityElementsHidden",
|
||||
"storedAccessibilityFrame",
|
||||
"storedAccessibilityNavigationStyle",
|
||||
"storedAccessibilityTraits",
|
||||
"storedAccessibilityViewIsModal",
|
||||
"storedIsAccessibilityElement",
|
||||
"storedShouldGroupAccessibilityChildren",
|
||||
"stringValueSafe",
|
||||
"superclass",
|
||||
"toManyRelationshipKeys",
|
||||
"toOneRelationshipKeys",
|
||||
"traitStorageList",
|
||||
"un_safeBoolValue",
|
||||
"userInterfaceItemIdentifier",
|
||||
"utf8ValueSafe",
|
||||
"valuesForKeysWithDictionary",
|
||||
"zone",
|
||||
// Protocol: CAAnimatableValue
|
||||
// Protocol: CARenderValue
|
||||
// Protocol: NSObject
|
||||
// Protocol: ROCKRemoteInvocationInterface
|
||||
};
|
||||
140
ubuntu/google/protobuf/compiler/objectivec/objectivec_oneof.cc
Normal file
140
ubuntu/google/protobuf/compiler/objectivec/objectivec_oneof.cc
Normal file
@@ -0,0 +1,140 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_oneof.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
|
||||
: descriptor_(descriptor) {
|
||||
variables_["enum_name"] = OneofEnumName(descriptor_);
|
||||
variables_["name"] = OneofName(descriptor_);
|
||||
variables_["capitalized_name"] = OneofNameCapitalized(descriptor_);
|
||||
variables_["raw_index"] = StrCat(descriptor_->index());
|
||||
const Descriptor* msg_descriptor = descriptor_->containing_type();
|
||||
variables_["owning_message_class"] = ClassName(msg_descriptor);
|
||||
|
||||
std::string comments;
|
||||
SourceLocation location;
|
||||
if (descriptor_->GetSourceLocation(&location)) {
|
||||
comments = BuildCommentsString(location, true);
|
||||
} else {
|
||||
comments = "";
|
||||
}
|
||||
variables_["comments"] = comments;
|
||||
}
|
||||
|
||||
OneofGenerator::~OneofGenerator() {}
|
||||
|
||||
void OneofGenerator::SetOneofIndexBase(int index_base) {
|
||||
int index = descriptor_->index() + index_base;
|
||||
// Flip the sign to mark it as a oneof.
|
||||
variables_["index"] = StrCat(-index);
|
||||
}
|
||||
|
||||
void OneofGenerator::GenerateCaseEnum(io::Printer* printer) {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"typedef GPB_ENUM($enum_name$) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(
|
||||
variables_,
|
||||
"$enum_name$_GPBUnsetOneOfCase = 0,\n");
|
||||
std::string enum_name = variables_["enum_name"];
|
||||
for (int j = 0; j < descriptor_->field_count(); j++) {
|
||||
const FieldDescriptor* field = descriptor_->field(j);
|
||||
std::string field_name = FieldNameCapitalized(field);
|
||||
printer->Print(
|
||||
"$enum_name$_$field_name$ = $field_number$,\n",
|
||||
"enum_name", enum_name,
|
||||
"field_name", field_name,
|
||||
"field_number", StrCat(field->number()));
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print(
|
||||
"};\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void OneofGenerator::GeneratePublicCasePropertyDeclaration(
|
||||
io::Printer* printer) {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"$comments$"
|
||||
"@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"/**\n"
|
||||
" * Clears whatever value was set for the oneof '$name$'.\n"
|
||||
" **/\n"
|
||||
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n");
|
||||
}
|
||||
|
||||
void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"@dynamic $name$OneOfCase;\n");
|
||||
}
|
||||
|
||||
void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
|
||||
printer->Print(
|
||||
variables_,
|
||||
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
|
||||
" GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
|
||||
" GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
|
||||
" GPBClearOneof(message, oneof);\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
std::string OneofGenerator::DescriptorName(void) const {
|
||||
return variables_.find("name")->second;
|
||||
}
|
||||
|
||||
std::string OneofGenerator::HasIndexAsString(void) const {
|
||||
return variables_.find("index")->second;
|
||||
}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,76 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class OneofGenerator {
|
||||
public:
|
||||
explicit OneofGenerator(const OneofDescriptor* descriptor);
|
||||
~OneofGenerator();
|
||||
|
||||
OneofGenerator(const OneofGenerator&) = delete;
|
||||
OneofGenerator& operator=(const OneofGenerator&) = delete;
|
||||
|
||||
void SetOneofIndexBase(int index_base);
|
||||
|
||||
void GenerateCaseEnum(io::Printer* printer);
|
||||
|
||||
void GeneratePublicCasePropertyDeclaration(io::Printer* printer);
|
||||
void GenerateClearFunctionDeclaration(io::Printer* printer);
|
||||
|
||||
void GeneratePropertyImplementation(io::Printer* printer);
|
||||
void GenerateClearFunctionImplementation(io::Printer* printer);
|
||||
|
||||
std::string DescriptorName(void) const;
|
||||
std::string HasIndexAsString(void) const;
|
||||
|
||||
private:
|
||||
const OneofDescriptor* descriptor_;
|
||||
std::map<std::string, std::string> variables_;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
|
||||
@@ -0,0 +1,190 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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 <map>
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h>
|
||||
#include <google/protobuf/io/printer.h>
|
||||
#include <google/protobuf/stubs/strutil.h>
|
||||
#include <google/protobuf/wire_format.h>
|
||||
#include <google/protobuf/wire_format_lite.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
using internal::WireFormat;
|
||||
using internal::WireFormatLite;
|
||||
|
||||
namespace {
|
||||
|
||||
const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
|
||||
ObjectiveCType type = GetObjectiveCType(descriptor);
|
||||
switch (type) {
|
||||
case OBJECTIVECTYPE_INT32:
|
||||
return "int32_t";
|
||||
case OBJECTIVECTYPE_UINT32:
|
||||
return "uint32_t";
|
||||
case OBJECTIVECTYPE_INT64:
|
||||
return "int64_t";
|
||||
case OBJECTIVECTYPE_UINT64:
|
||||
return "uint64_t";
|
||||
case OBJECTIVECTYPE_FLOAT:
|
||||
return "float";
|
||||
case OBJECTIVECTYPE_DOUBLE:
|
||||
return "double";
|
||||
case OBJECTIVECTYPE_BOOLEAN:
|
||||
return "BOOL";
|
||||
case OBJECTIVECTYPE_STRING:
|
||||
return "NSString";
|
||||
case OBJECTIVECTYPE_DATA:
|
||||
return "NSData";
|
||||
case OBJECTIVECTYPE_ENUM:
|
||||
return "int32_t";
|
||||
case OBJECTIVECTYPE_MESSAGE:
|
||||
return NULL; // Messages go through objectivec_message_field.cc|h.
|
||||
}
|
||||
|
||||
// Some compilers report reaching end of function even though all cases of
|
||||
// the enum are handed in the switch.
|
||||
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
|
||||
ObjectiveCType type = GetObjectiveCType(descriptor);
|
||||
switch (type) {
|
||||
case OBJECTIVECTYPE_INT32:
|
||||
return "Int32";
|
||||
case OBJECTIVECTYPE_UINT32:
|
||||
return "UInt32";
|
||||
case OBJECTIVECTYPE_INT64:
|
||||
return "Int64";
|
||||
case OBJECTIVECTYPE_UINT64:
|
||||
return "UInt64";
|
||||
case OBJECTIVECTYPE_FLOAT:
|
||||
return "Float";
|
||||
case OBJECTIVECTYPE_DOUBLE:
|
||||
return "Double";
|
||||
case OBJECTIVECTYPE_BOOLEAN:
|
||||
return "Bool";
|
||||
case OBJECTIVECTYPE_STRING:
|
||||
return ""; // Want NSArray
|
||||
case OBJECTIVECTYPE_DATA:
|
||||
return ""; // Want NSArray
|
||||
case OBJECTIVECTYPE_ENUM:
|
||||
return "Enum";
|
||||
case OBJECTIVECTYPE_MESSAGE:
|
||||
// Want NSArray (but goes through objectivec_message_field.cc|h).
|
||||
return "";
|
||||
}
|
||||
|
||||
// Some compilers report reaching end of function even though all cases of
|
||||
// the enum are handed in the switch.
|
||||
GOOGLE_LOG(FATAL) << "Can't get here.";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SetPrimitiveVariables(const FieldDescriptor* descriptor,
|
||||
std::map<std::string, std::string>* variables) {
|
||||
std::string primitive_name = PrimitiveTypeName(descriptor);
|
||||
(*variables)["type"] = primitive_name;
|
||||
(*variables)["storage_type"] = primitive_name;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
PrimitiveFieldGenerator::PrimitiveFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: SingleFieldGenerator(descriptor, options) {
|
||||
SetPrimitiveVariables(descriptor, &variables_);
|
||||
}
|
||||
|
||||
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
|
||||
|
||||
void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
|
||||
io::Printer* printer) const {
|
||||
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
|
||||
// Nothing, BOOLs are stored in the has bits.
|
||||
} else {
|
||||
SingleFieldGenerator::GenerateFieldStorageDeclaration(printer);
|
||||
}
|
||||
}
|
||||
|
||||
int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
|
||||
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
|
||||
// Reserve a bit for the storage of the boolean.
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) {
|
||||
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
|
||||
// Set into the offset the has bit to use for the actual value.
|
||||
variables_["storage_offset_value"] = StrCat(has_base);
|
||||
variables_["storage_offset_comment"] =
|
||||
" // Stored in _has_storage_ to save space.";
|
||||
}
|
||||
}
|
||||
|
||||
PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: ObjCObjFieldGenerator(descriptor, options) {
|
||||
SetPrimitiveVariables(descriptor, &variables_);
|
||||
variables_["property_storage_attribute"] = "copy";
|
||||
}
|
||||
|
||||
PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
|
||||
|
||||
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
|
||||
const FieldDescriptor* descriptor, const Options& options)
|
||||
: RepeatedFieldGenerator(descriptor, options) {
|
||||
SetPrimitiveVariables(descriptor, &variables_);
|
||||
|
||||
std::string base_name = PrimitiveArrayTypeName(descriptor);
|
||||
if (base_name.length()) {
|
||||
variables_["array_storage_type"] = "GPB" + base_name + "Array";
|
||||
} else {
|
||||
variables_["array_storage_type"] = "NSMutableArray";
|
||||
variables_["array_property_type"] =
|
||||
"NSMutableArray<" + variables_["storage_type"] + "*>";
|
||||
}
|
||||
}
|
||||
|
||||
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
@@ -0,0 +1,95 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
|
||||
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <google/protobuf/compiler/objectivec/objectivec_field.h>
|
||||
|
||||
namespace google {
|
||||
namespace protobuf {
|
||||
namespace compiler {
|
||||
namespace objectivec {
|
||||
|
||||
class PrimitiveFieldGenerator : public SingleFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
protected:
|
||||
PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
virtual ~PrimitiveFieldGenerator();
|
||||
|
||||
PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete;
|
||||
PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete;
|
||||
|
||||
virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const;
|
||||
|
||||
virtual int ExtraRuntimeHasBitsNeeded(void) const;
|
||||
virtual void SetExtraRuntimeHasBitsBase(int index_base);
|
||||
};
|
||||
|
||||
class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
protected:
|
||||
PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
virtual ~PrimitiveObjFieldGenerator();
|
||||
|
||||
PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete;
|
||||
PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) =
|
||||
delete;
|
||||
};
|
||||
|
||||
class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
|
||||
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
|
||||
const Options& options);
|
||||
|
||||
protected:
|
||||
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
|
||||
const Options& options);
|
||||
virtual ~RepeatedPrimitiveFieldGenerator();
|
||||
|
||||
RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) =
|
||||
delete;
|
||||
RepeatedPrimitiveFieldGenerator& operator=(
|
||||
const RepeatedPrimitiveFieldGenerator&) = delete;
|
||||
};
|
||||
|
||||
} // namespace objectivec
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
|
||||
Reference in New Issue
Block a user