Merge pull request #2525 from camillol/lite

Eliminate redundant methods in C++ generated code for lite protos
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 2b71acb..2d3d564 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -1661,18 +1661,6 @@
 GenerateClassMethods(io::Printer* printer) {
   if (IsMapEntryMessage(descriptor_)) return;
 
-  // mutable_unknown_fields wrapper function for LazyStringOutputStream
-  // callback.
-  if (PreserveUnknownFields(descriptor_) &&
-      !UseUnknownFieldSet(descriptor_->file(), options_)) {
-    printer->Print(
-        "static ::std::string* MutableUnknownFieldsFor$classname$(\n"
-        "    $classname$* ptr) {\n"
-        "  return ptr->mutable_unknown_fields();\n"
-        "}\n"
-        "\n",
-        "classname", classname_);
-  }
   if (IsAnyMessage(descriptor_)) {
     printer->Print(
       "void $classname$::PackFrom(const ::google::protobuf::Message& message) {\n"
@@ -2936,8 +2924,8 @@
     // on the CodedOutputStream.
     printer->Print(
       "  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
-      "      NewPermanentCallback(\n"
-      "          &MutableUnknownFieldsFor$classname$, this));\n"
+      "      ::google::protobuf::NewPermanentCallback(&_internal_metadata_,\n"
+      "          &::google::protobuf::internal::InternalMetadataWithArenaLite::mutable_unknown_fields));\n"
       "  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
       "      &unknown_fields_string, false);\n",
       "classname", classname_);
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index bbd507a..9ec0497 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -346,6 +346,29 @@
   typedef const base_type& type;
 };
 
+template<typename R, typename T>
+class MethodResultCallback_0_0 : public ResultCallback<R> {
+ public:
+  typedef R (T::*MethodType)();
+  MethodResultCallback_0_0(T* object, MethodType method, bool self_deleting)
+      : object_(object),
+        method_(method),
+        self_deleting_(self_deleting) {}
+  ~MethodResultCallback_0_0() {}
+
+  R Run() {
+    bool needs_delete = self_deleting_;
+    R result = (object_->*method_)();
+    if (needs_delete) delete this;
+    return result;
+  }
+
+ private:
+  T* object_;
+  MethodType method_;
+  bool self_deleting_;
+};
+
 template <typename R, typename T, typename P1, typename P2, typename P3,
           typename P4, typename P5, typename A1, typename A2>
 class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
@@ -520,6 +543,13 @@
       function, false, p1);
 }
 
+// See MethodResultCallback_0_0
+template <typename R, typename T1, typename T2>
+inline ResultCallback<R>* NewPermanentCallback(
+    T1* object, R (T2::*function)()) {
+  return new internal::MethodResultCallback_0_0<R, T1>(object, function, false);
+}
+
 // See MethodResultCallback_5_2
 template <typename R, typename T, typename P1, typename P2, typename P3,
           typename P4, typename P5, typename A1, typename A2>