Merge pull request #1239 from jskeet/call_generate_protos

Generate C# code whenever descriptor.proto changes
diff --git a/.travis.yml b/.travis.yml
index e368826..c0309fa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,8 +7,8 @@
 os:
   - linux
   - osx
-# The Objective C build needs Xcode 6.4 or later.
-osx_image: xcode7.1
+# The Objective C build needs Xcode 7.0 or later.
+osx_image: xcode7.2
 script:
   - ./travis.sh $CONFIG
 env:
@@ -67,5 +67,8 @@
       env: CONFIG=ruby22
     - os: osx
       env: CONFIG=jruby
+    # Currently showing flake randomly, doesn't trace back to a single commit.
+    - os: osx
+      env: CONFIG=objectivec_ios
 notifications:
   email: false
diff --git a/BUILD b/BUILD
index 3cac4a8..c4de1c4 100644
--- a/BUILD
+++ b/BUILD
@@ -462,11 +462,11 @@
     name = "gen_well_known_protos_java",
     srcs = WELL_KNOWN_PROTOS,
     outs = [
-        "wellknown.srcjar"
+        "wellknown.srcjar",
     ],
     cmd = "$(location :protoc) --java_out=$(@D)/wellknown.jar" +
-        " -Isrc $(SRCS) " +
-        " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar",
+          " -Isrc $(SRCS) " +
+          " && mv $(@D)/wellknown.jar $(@D)/wellknown.srcjar",
     tools = [":protoc"],
 )
 
@@ -539,7 +539,10 @@
     ]),
     copts = COPTS + [
         "-DGOOGLE_PROTOBUF_HAS_ONEOF=1",
-    ],
+    ] + select({
+        "//conditions:default": [],
+        ":allow_oversize_protos": ["-DPROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS=1"],
+    }),
     includes = [
         "python/",
         "src/",
@@ -561,6 +564,13 @@
     },
 )
 
+config_setting(
+    name = "allow_oversize_protos",
+    values = {
+        "define": "allow_oversize_protos=true",
+    },
+)
+
 py_proto_library(
     name = "protobuf_python",
     srcs = WELL_KNOWN_PROTOS,
diff --git a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
index a2c833f..5b7185d 100644
--- a/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
+++ b/csharp/src/Google.Protobuf.Test/WellKnownTypes/WrappersTest.cs
@@ -319,9 +319,10 @@
 
         // Merging is odd with wrapper types, due to the way that default values aren't emitted in
         // the binary stream. In fact we cheat a little bit - a message with an explicitly present default
-        // value will have that default value ignored.
+        // value will have that default value ignored. See issue 615. Fixing this would require significant upheaval to
+        // the FieldCodec side of things.
         [Test]
-        public void MergingCornerCase()
+        public void MergingStreamExplicitValue()
         {
             var message = new TestWellKnownTypes { Int32Field = 5 };
 
@@ -343,10 +344,48 @@
 
             message.MergeFrom(bytes);
             // A normal implementation would have 0 now, as the explicit default would have been overwritten the 5.
+            // With the FieldCodec for Nullable<int>, we can't tell the difference between an implicit 0 and an explicit 0.
             Assert.AreEqual(5, message.Int32Field);
         }
 
         [Test]
+        public void MergingStreamNoValue()
+        {
+            var message = new TestWellKnownTypes { Int32Field = 5 };
+
+            // Create a byte array which an Int32 field, but with no value.
+            var bytes = new TestWellKnownTypes { Int32Field = 0 }.ToByteArray();
+            Assert.AreEqual(2, bytes.Length); // The tag for Int32Field is a single byte, then a byte indicating a 0-length message.
+            message.MergeFrom(bytes);
+
+            // The "implicit" 0 did *not* overwrite the value.
+            // (This is the correct behaviour.)
+            Assert.AreEqual(5, message.Int32Field);
+        }
+
+        // All permutations of origin/merging value being null, zero (default) or non-default.
+        // As this is the in-memory version, we don't need to worry about the difference between implicit and explicit 0.
+        [Test]
+        [TestCase(null, null, null)]
+        [TestCase(null, 0, 0)]
+        [TestCase(null, 5, 5)]
+        [TestCase(0, null, 0)]
+        [TestCase(0, 0, 0)]
+        [TestCase(0, 5, 5)]
+        [TestCase(5, null, 5)]
+        [TestCase(5, 0, 5)]
+        [TestCase(5, 10, 10)]
+        public void MergingMessageWithZero(int? originValue, int? mergingValue, int? expectedResult)
+        {
+            // This differs from the MergingStreamCornerCase because when we merge message *objects*,
+            // we ignore default values from the "source".
+            var message1 = new TestWellKnownTypes { Int32Field = originValue };
+            var message2 = new TestWellKnownTypes { Int32Field = mergingValue };
+            message1.MergeFrom(message2);
+            Assert.AreEqual(expectedResult, message1.Int32Field);
+        }
+
+        [Test]
         public void UnknownFieldInWrapper()
         {
             var stream = new MemoryStream();
diff --git a/objectivec/DevTools/full_mac_build.sh b/objectivec/DevTools/full_mac_build.sh
index 709aae0..c8681e2 100755
--- a/objectivec/DevTools/full_mac_build.sh
+++ b/objectivec/DevTools/full_mac_build.sh
@@ -234,7 +234,7 @@
       echo "ERROR: Xcode 6.3/6.4 no longer supported for building, please use 7.0 or higher." 1>&2
       exit 10
       ;;
-    7.* )
+    7.1* )
       XCODEBUILD_TEST_BASE_IOS+=(
           -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
           -destination "platform=iOS Simulator,name=iPhone 6,OS=9.0" # 64bit
@@ -242,6 +242,14 @@
           -destination "platform=iOS Simulator,name=iPad Air,OS=9.0" # 64bit
       )
       ;;
+    7.* )
+      XCODEBUILD_TEST_BASE_IOS+=(
+          -destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
+          -destination "platform=iOS Simulator,name=iPhone 6,OS=9.2" # 64bit
+          -destination "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
+          -destination "platform=iOS Simulator,name=iPad Air,OS=9.2" # 64bit
+      )
+      ;;
     * )
       echo "Time to update the simulator targets for Xcode ${XCODE_VERSION}"
       exit 2
diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc
index 863cde0..60ec9c1 100644
--- a/python/google/protobuf/pyext/message.cc
+++ b/python/google/protobuf/pyext/message.cc
@@ -1921,6 +1921,15 @@
   AssureWritable(self);
   io::CodedInputStream input(
       reinterpret_cast<const uint8*>(data), data_length);
+#if PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS
+  // Protobuf has a 64MB limit built in, this code will override this. Please do
+  // not enable this unless you fully understand the implications: protobufs
+  // must all be kept in memory at the same time, so if they grow too big you
+  // may get OOM errors. The protobuf APIs do not provide any tools for
+  // processing protobufs in chunks.  If you have protos this big you should
+  // break them up if it is at all convenient to do so.
+  input.SetTotalBytesLimit(INT_MAX, INT_MAX);
+#endif  // PROTOBUF_PYTHON_ALLOW_OVERSIZE_PROTOS
   PyDescriptorPool* pool = GetDescriptorPoolForMessage(self);
   input.SetExtensionRegistry(pool->pool, pool->message_factory);
   bool success = self->message->MergePartialFromCodedStream(&input);
diff --git a/ruby/src/main/sentinel.proto b/ruby/src/main/sentinel.proto
index 89a1ae1..722041b 100644
--- a/ruby/src/main/sentinel.proto
+++ b/ruby/src/main/sentinel.proto
@@ -3,13 +3,13 @@
 option optimize_for = CODE_SIZE;
 
 message Sentinel {
-  optional int32 default_int32 = 1;
-  optional int64 default_int64 = 2;
-  optional uint32 default_unit32 = 3;
-  optional uint64 default_uint64 = 4;
-  optional string default_string = 5;
-  optional bool default_bool = 6;
-  optional float default_float = 7;
-  optional double default_double = 8;
-  optional bytes default_bytes = 9;
+  int32 default_int32 = 1;
+  int64 default_int64 = 2;
+  uint32 default_unit32 = 3;
+  uint64 default_uint64 = 4;
+  string default_string = 5;
+  bool default_bool = 6;
+  float default_float = 7;
+  double default_double = 8;
+  bytes default_bytes = 9;
 }
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index c3e9fe7..47729e1 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -107,7 +107,7 @@
 
   virtual io::ZeroCopyOutputStream* Open(const string& filename) {
     string** map_slot = &files_[filename];
-    if (*map_slot != NULL) delete *map_slot;
+    delete *map_slot;
     *map_slot = new string;
 
     return new io::StringOutputStream(*map_slot);
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index 1be6c86..9c621b6 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -241,9 +241,7 @@
 
 GzipOutputStream::~GzipOutputStream() {
   Close();
-  if (input_buffer_ != NULL) {
-    operator delete(input_buffer_);
-  }
+  operator delete(input_buffer_);
 }
 
 // private
diff --git a/travis.sh b/travis.sh
index 5a77a2a..c973ec6 100755
--- a/travis.sh
+++ b/travis.sh
@@ -179,8 +179,10 @@
 }
 
 internal_xctool_debug_and_release() {
-  xctool -configuration Debug "$@"
-  xctool -configuration Release "$@"
+  # Always use -reporter plain to avoid escape codes in output (makes travis
+  # logs easier to read).
+  xctool -reporter plain -configuration Debug "$@"
+  xctool -reporter plain -configuration Release "$@"
 }
 
 build_objectivec_ios() {
@@ -195,17 +197,20 @@
     build-tests
   IOS_DESTINATIONS=(
     "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
-    "platform=iOS Simulator,name=iPhone 6,OS=9.1" # 64bit
+    "platform=iOS Simulator,name=iPhone 6,OS=9.2" # 64bit
     "platform=iOS Simulator,name=iPad 2,OS=8.1" # 32bit
-    "platform=iOS Simulator,name=iPad Air,OS=9.1" # 64bit
+    "platform=iOS Simulator,name=iPad Air,OS=9.2" # 64bit
   )
   for i in "${IOS_DESTINATIONS[@]}" ; do
+    # Throw -newSimulatorInstance in incase it helps with the flake that
+    # started happening after xctool 0.2.8 got released.
     internal_xctool_debug_and_release \
       -project objectivec/ProtocolBuffers_iOS.xcodeproj \
       -scheme ProtocolBuffers \
       -sdk iphonesimulator \
       -destination "${i}" \
-      run-tests
+      run-tests \
+      -newSimulatorInstance
   done
 }