Make Python package spec indirect

This is part of a change to ease internal usage of GRPC.
diff --git a/Makefile b/Makefile
index 8be6c5f..b50834d 100644
--- a/Makefile
+++ b/Makefile
@@ -3493,6 +3493,44 @@
 $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: 
 
 
+LIBGRPC_PYTHON_PLUGIN_SUPPORT_SRC = \
+    src/compiler/python_generator.cc \
+
+PUBLIC_HEADERS_CXX += \
+    src/compiler/python_generator.h \
+
+LIBGRPC_PYTHON_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PYTHON_PLUGIN_SUPPORT_SRC))))
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC_PYTHON_PLUGIN_SUPPORT_OBJS)
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a
+	$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a $(LIBGRPC_PYTHON_PLUGIN_SUPPORT_OBJS)
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a
+endif
+
+
+
+
+endif
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_PYTHON_PLUGIN_SUPPORT_OBJS:.o=.dep)
+endif
+
+$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: 
+
+
 LIBPUBSUB_CLIENT_LIB_SRC = \
     $(GENDIR)/examples/pubsub/label.pb.cc \
     $(GENDIR)/examples/pubsub/empty.pb.cc \
@@ -8048,7 +8086,6 @@
 
 
 GRPC_PYTHON_PLUGIN_SRC = \
-    src/compiler/python_generator.cc \
     src/compiler/python_plugin.cc \
 
 GRPC_PYTHON_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PYTHON_PLUGIN_SRC))))
@@ -8062,15 +8099,14 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS)
+$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a
 	$(E) "[HOSTLD]  Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin
+	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin
 
 endif
 
-$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: 
-$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o: 
+$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o:  $(LIBDIR)/$(CONFIG)/libgrpc_python_plugin_support.a
 
 deps_grpc_python_plugin: $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep)
 
diff --git a/build.json b/build.json
index 999e140..08b23ec 100644
--- a/build.json
+++ b/build.json
@@ -492,6 +492,19 @@
       "secure": "no"
     },
     {
+      "name": "grpc_python_plugin_support",
+      "build": "protoc",
+      "language": "c++",
+      "public_headers": [
+        "src/compiler/python_generator.h"
+      ],
+      "src": [
+        "src/compiler/python_generator.cc"
+      ],
+      "deps": [],
+      "secure": "no"
+    },
+    {
       "name": "pubsub_client_lib",
       "build": "private",
       "language": "c++",
@@ -1739,14 +1752,12 @@
       "name": "grpc_python_plugin",
       "build": "protoc",
       "language": "c++",
-      "headers": [
-        "src/compiler/python_generator.h"
-      ],
       "src": [
-        "src/compiler/python_generator.cc",
         "src/compiler/python_plugin.cc"
       ],
-      "deps": [],
+      "deps": [
+        "grpc_python_plugin_support"
+      ],
       "secure": "no"
     },
     {
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index e4f8545..1ec3772 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -36,13 +36,18 @@
 #include <cctype>
 #include <cstring>
 #include <map>
+#include <memory>
 #include <ostream>
 #include <sstream>
+#include <string>
+#include <tuple>
 #include <vector>
 
 #include "src/compiler/generator_helpers.h"
 #include "src/compiler/python_generator.h"
+#include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
@@ -53,8 +58,11 @@
 using google::protobuf::FileDescriptor;
 using google::protobuf::MethodDescriptor;
 using google::protobuf::ServiceDescriptor;
+using google::protobuf::compiler::GeneratorContext;
+using google::protobuf::io::CodedOutputStream;
 using google::protobuf::io::Printer;
 using google::protobuf::io::StringOutputStream;
+using google::protobuf::io::ZeroCopyOutputStream;
 using std::initializer_list;
 using std::make_pair;
 using std::map;
@@ -63,6 +71,41 @@
 using std::vector;
 
 namespace grpc_python_generator {
+
+PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config)
+    : config_(config) {}
+
+PythonGrpcGenerator::~PythonGrpcGenerator() {}
+
+bool PythonGrpcGenerator::Generate(
+    const FileDescriptor* file, const std::string& parameter,
+    GeneratorContext* context, std::string* error) const {
+  // Get output file name.
+  std::string file_name;
+  static const int proto_suffix_length = strlen(".proto");
+  if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
+      file->name().find_last_of(".proto") == file->name().size() - 1) {
+    file_name = file->name().substr(
+        0, file->name().size() - proto_suffix_length) + "_pb2.py";
+  } else {
+    *error = "Invalid proto file name. Proto file must end with .proto";
+    return false;
+  }
+
+  std::unique_ptr<ZeroCopyOutputStream> output(
+      context->OpenForInsert(file_name, "module_scope"));
+  CodedOutputStream coded_out(output.get());
+  bool success = false;
+  std::string code = "";
+  tie(success, code) = grpc_python_generator::GetServices(file, config_);
+  if (success) {
+    coded_out.WriteRaw(code.data(), code.size());
+    return true;
+  } else {
+    return false;
+  }
+}
+
 namespace {
 //////////////////////////////////
 // BEGIN FORMATTING BOILERPLATE //
@@ -70,7 +113,8 @@
 
 // Converts an initializer list of the form { key0, value0, key1, value1, ... }
 // into a map of key* to value*. Is merely a readability helper for later code.
-map<std::string, std::string> ListToDict(const initializer_list<std::string>& values) {
+map<std::string, std::string> ListToDict(
+    const initializer_list<std::string>& values) {
   assert(values.size() % 2 == 0);
   map<std::string, std::string> value_map;
   auto value_iter = values.begin();
@@ -237,8 +281,10 @@
   {
     IndentScope raii_create_server_indent(out);
     map<std::string, std::string> method_description_constructors;
-    map<std::string, pair<std::string, std::string>> input_message_modules_and_classes;
-    map<std::string, pair<std::string, std::string>> output_message_modules_and_classes;
+    map<std::string, pair<std::string, std::string>>
+        input_message_modules_and_classes;
+    map<std::string, pair<std::string, std::string>>
+        output_message_modules_and_classes;
     for (int i = 0; i < service->method_count(); ++i) {
       const MethodDescriptor* method = service->method(i);
       const std::string method_description_constructor =
@@ -313,8 +359,10 @@
   {
     IndentScope raii_create_server_indent(out);
     map<std::string, std::string> method_description_constructors;
-    map<std::string, pair<std::string, std::string>> input_message_modules_and_classes;
-    map<std::string, pair<std::string, std::string>> output_message_modules_and_classes;
+    map<std::string, pair<std::string, std::string>>
+        input_message_modules_and_classes;
+    map<std::string, pair<std::string, std::string>>
+        output_message_modules_and_classes;
     for (int i = 0; i < service->method_count(); ++i) {
       const MethodDescriptor* method = service->method(i);
       const std::string method_description_constructor =
@@ -378,22 +426,25 @@
   return true;
 }
 
-bool PrintPreamble(const FileDescriptor* file, Printer* out) {
+bool PrintPreamble(const FileDescriptor* file,
+                   const GeneratorConfiguration& config, Printer* out) {
   out->Print("import abc\n");
-  out->Print("from grpc.early_adopter import implementations\n");
+  out->Print("from $Package$ import implementations\n",
+             "Package", config.implementations_package_root);
   out->Print("from grpc.framework.alpha import utilities\n");
   return true;
 }
 
 }  // namespace
 
-pair<bool, std::string> GetServices(const FileDescriptor* file) {
+pair<bool, std::string> GetServices(const FileDescriptor* file,
+                                    const GeneratorConfiguration& config) {
   std::string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
     StringOutputStream output_stream(&output);
     Printer out(&output_stream, '$');
-    if (!PrintPreamble(file, &out)) {
+    if (!PrintPreamble(file, config, &out)) {
       return make_pair(false, "");
     }
     auto package = file->package();
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index df29ca1..67686db 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -37,6 +37,9 @@
 #include <string>
 #include <utility>
 
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/descriptor.h>
+
 namespace google {
 namespace protobuf {
 class FileDescriptor;
@@ -45,7 +48,28 @@
 
 namespace grpc_python_generator {
 
-std::pair<bool, std::string> GetServices(const google::protobuf::FileDescriptor* file);
+// Data pertaining to configuration of the generator with respect to anything
+// that may be used internally at Google.
+struct GeneratorConfiguration {
+  std::string implementations_package_root;
+};
+
+class PythonGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
+ public:
+  PythonGrpcGenerator(const GeneratorConfiguration& config);
+  ~PythonGrpcGenerator();
+
+  bool Generate(const google::protobuf::FileDescriptor* file,
+                const std::string& parameter,
+                google::protobuf::compiler::GeneratorContext* context,
+                std::string* error) const;
+ private:
+  GeneratorConfiguration config_;
+};
+
+std::pair<bool, std::string> GetServices(
+    const google::protobuf::FileDescriptor* file,
+    const GeneratorConfiguration& config);
 
 }  // namespace grpc_python_generator
 
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
index e7d172f..4f59ec9 100644
--- a/src/compiler/python_plugin.cc
+++ b/src/compiler/python_plugin.cc
@@ -33,60 +33,14 @@
 
 // Generates a Python gRPC service interface out of Protobuf IDL.
 
-#include <cstring>
-#include <memory>
-#include <string>
-#include <tuple>
-
 #include "src/compiler/python_generator.h"
-#include <google/protobuf/compiler/code_generator.h>
 #include <google/protobuf/compiler/plugin.h>
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-#include <google/protobuf/descriptor.h>
 
-using google::protobuf::FileDescriptor;
-using google::protobuf::compiler::CodeGenerator;
-using google::protobuf::compiler::GeneratorContext;
 using google::protobuf::compiler::PluginMain;
-using google::protobuf::io::CodedOutputStream;
-using google::protobuf::io::ZeroCopyOutputStream;
-
-class PythonGrpcGenerator : public CodeGenerator {
- public:
-  PythonGrpcGenerator() {}
-  ~PythonGrpcGenerator() {}
-
-  bool Generate(const FileDescriptor* file, const std::string& parameter,
-                GeneratorContext* context, std::string* error) const {
-    // Get output file name.
-    std::string file_name;
-    static const int proto_suffix_length = strlen(".proto");
-    if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
-        file->name().find_last_of(".proto") == file->name().size() - 1) {
-      file_name = file->name().substr(
-          0, file->name().size() - proto_suffix_length) + "_pb2.py";
-    } else {
-      *error = "Invalid proto file name. Proto file must end with .proto";
-      return false;
-    }
-
-    std::unique_ptr<ZeroCopyOutputStream> output(
-        context->OpenForInsert(file_name, "module_scope"));
-    CodedOutputStream coded_out(output.get());
-    bool success = false;
-    std::string code = "";
-    tie(success, code) = grpc_python_generator::GetServices(file);
-    if (success) {
-      coded_out.WriteRaw(code.data(), code.size());
-      return true;
-    } else {
-      return false;
-    }
-  }
-};
 
 int main(int argc, char* argv[]) {
-  PythonGrpcGenerator generator;
+  grpc_python_generator::GeneratorConfiguration config;
+  config.implementations_package_root = "grpc.early_adopter";
+  grpc_python_generator::PythonGrpcGenerator generator(config);
   return PluginMain(argc, argv, &generator);
 }