// 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/php/php_generator.h>

#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>

#include <sstream>

const std::string kDescriptorFile = "google/protobuf/descriptor.proto";
const std::string kEmptyFile = "google/protobuf/empty.proto";
const std::string kEmptyMetadataFile = "GPBMetadata/Google/Protobuf/GPBEmpty.php";
const std::string kDescriptorMetadataFile =
    "GPBMetadata/Google/Protobuf/Internal/Descriptor.php";
const std::string kDescriptorDirName = "Google/Protobuf/Internal";
const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal";
const char* const kReservedNames[] = {
    "abstract",     "and",        "array",      "as",         "break",
    "callable",     "case",       "catch",      "class",      "clone",
    "const",        "continue",   "declare",    "default",    "die",
    "do",           "echo",       "else",       "elseif",     "empty",
    "enddeclare",   "endfor",     "endforeach", "endif",      "endswitch",
    "endwhile",     "eval",       "exit",       "extends",    "final",
    "finally",      "fn",         "for",        "foreach",    "function",
    "global",       "goto",       "if",         "implements", "include",
    "include_once", "instanceof", "insteadof",  "interface",  "isset",
    "list",         "match",      "namespace",  "new",        "or",
    "print",        "private",    "protected",  "public",     "require",
    "require_once", "return",     "static",     "switch",     "throw",
    "trait",        "try",        "unset",      "use",        "var",
    "while",        "xor",        "yield",      "int",        "float",
    "bool",         "string",     "true",       "false",      "null",
    "void",         "iterable"};
const char* const kValidConstantNames[] = {
    "int",   "float", "bool", "string",   "true",
    "false", "null",  "void", "iterable",
};
const int kReservedNamesSize = 77;
const int kValidConstantNamesSize = 9;
const int kFieldSetter = 1;
const int kFieldGetter = 2;
const int kFieldProperty = 3;

namespace google {
namespace protobuf {
namespace compiler {
namespace php {

struct Options {
  bool is_descriptor = false;
  bool aggregate_metadata = false;
  bool gen_c_wkt = false;
  std::set<string> aggregate_metadata_prefixes;
};

namespace {

// Forward decls.
std::string PhpName(const std::string& full_name, const Options& options);
std::string IntToString(int32 value);
std::string FilenameToClassname(const std::string& filename);
std::string GeneratedMetadataFileName(const FileDescriptor* file,
                                      const Options& options);
std::string UnderscoresToCamelCase(const std::string& name,
                                   bool cap_first_letter);
void Indent(io::Printer* printer);
void Outdent(io::Printer* printer);
void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options,
                            io::Printer* printer);
void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
                               const Options& options);
void GenerateMessageConstructorDocComment(io::Printer* printer,
                                          const Descriptor* message,
                                          const Options& options);
void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
                             const Options& options, int function_type);
void GenerateWrapperFieldGetterDocComment(io::Printer* printer,
                                          const FieldDescriptor* field);
void GenerateWrapperFieldSetterDocComment(io::Printer* printer,
                                          const FieldDescriptor* field);
void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
                            const Options& options);
void GenerateEnumValueDocComment(io::Printer* printer,
                                 const EnumValueDescriptor* value);
void GenerateServiceDocComment(io::Printer* printer,
                               const ServiceDescriptor* service);
void GenerateServiceMethodDocComment(io::Printer* printer,
                              const MethodDescriptor* method);

std::string ReservedNamePrefix(const std::string& classname,
                                const FileDescriptor* file) {
  bool is_reserved = false;

  std::string lower = classname;
  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);

  for (int i = 0; i < kReservedNamesSize; i++) {
    if (lower == kReservedNames[i]) {
      is_reserved = true;
      break;
    }
  }

  if (is_reserved) {
    if (file->package() == "google.protobuf") {
      return "GPB";
    } else {
      return "PB";
    }
  }

  return "";
}

template <typename DescriptorType>
std::string DescriptorFullName(const DescriptorType* desc, bool is_internal) {
  if (is_internal) {
    return StringReplace(desc->full_name(),
                         "google.protobuf",
                         "google.protobuf.internal", false);
  } else {
    return desc->full_name();
  }
}

template <typename DescriptorType>
std::string ClassNamePrefix(const std::string& classname,
                            const DescriptorType* desc) {
  const std::string& prefix = (desc->file()->options()).php_class_prefix();
  if (!prefix.empty()) {
    return prefix;
  }

  return ReservedNamePrefix(classname, desc->file());
}

template <typename DescriptorType>
std::string GeneratedClassNameImpl(const DescriptorType* desc) {
  std::string classname = ClassNamePrefix(desc->name(), desc) + desc->name();
  const Descriptor* containing = desc->containing_type();
  while (containing != NULL) {
    classname = ClassNamePrefix(containing->name(), desc) + containing->name()
       + '\\' + classname;
    containing = containing->containing_type();
  }
  return classname;
}

std::string GeneratedClassNameImpl(const ServiceDescriptor* desc) {
  std::string classname = desc->name();
  return ClassNamePrefix(classname, desc) + classname;
}

template <typename DescriptorType>
std::string LegacyGeneratedClassName(const DescriptorType* desc) {
  std::string classname = desc->name();
  const Descriptor* containing = desc->containing_type();
  while (containing != NULL) {
    classname = containing->name() + '_' + classname;
    containing = containing->containing_type();
  }
  return ClassNamePrefix(classname, desc) + classname;
}

std::string ClassNamePrefix(const std::string& classname) {
  std::string lower = classname;
  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);

  for (int i = 0; i < kReservedNamesSize; i++) {
    if (lower == kReservedNames[i]) {
      return "PB";
    }
  }

  return "";
}

std::string ConstantNamePrefix(const std::string& classname) {
  bool is_reserved = false;

  std::string lower = classname;
  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);

  for (int i = 0; i < kReservedNamesSize; i++) {
    if (lower == kReservedNames[i]) {
      is_reserved = true;
      break;
    }
  }

  for (int i = 0; i < kValidConstantNamesSize; i++) {
    if (lower == kValidConstantNames[i]) {
      is_reserved = false;
      break;
    }
  }

  if (is_reserved) {
    return "PB";
  }

  return "";
}

template <typename DescriptorType>
std::string RootPhpNamespace(const DescriptorType* desc,
                             const Options& options) {
  if (desc->file()->options().has_php_namespace()) {
    const std::string& php_namespace = desc->file()->options().php_namespace();
    if (!php_namespace.empty()) {
      return php_namespace;
    }
    return "";
  }

  if (!desc->file()->package().empty()) {
    return PhpName(desc->file()->package(), options);
  }
  return "";
}

template <typename DescriptorType>
std::string FullClassName(const DescriptorType* desc, const Options& options) {
  std::string classname = GeneratedClassNameImpl(desc);
  std::string php_namespace = RootPhpNamespace(desc, options);
  if (!php_namespace.empty()) {
    return php_namespace + "\\" + classname;
  }
  return classname;
}

template <typename DescriptorType>
std::string FullClassName(const DescriptorType* desc, bool is_descriptor) {
  Options options;
  options.is_descriptor = is_descriptor;
  return FullClassName(desc, options);
}

template <typename DescriptorType>
std::string LegacyFullClassName(const DescriptorType* desc,
                                const Options& options) {
  std::string classname = LegacyGeneratedClassName(desc);
  std::string php_namespace = RootPhpNamespace(desc, options);
  if (!php_namespace.empty()) {
    return php_namespace + "\\" + classname;
  }
  return classname;
}

std::string PhpName(const std::string& full_name, const Options& options) {
  if (options.is_descriptor) {
    return kDescriptorPackageName;
  }

  std::string segment;
  std::string result;
  bool cap_next_letter = true;
  for (int i = 0; i < full_name.size(); i++) {
    if ('a' <= full_name[i] && full_name[i] <= 'z' && cap_next_letter) {
      segment += full_name[i] + ('A' - 'a');
      cap_next_letter = false;
    } else if (full_name[i] == '.') {
      result += ClassNamePrefix(segment) + segment + '\\';
      segment = "";
      cap_next_letter = true;
    } else {
      segment += full_name[i];
      cap_next_letter = false;
    }
  }
  result += ClassNamePrefix(segment) + segment;
  return result;
}

std::string DefaultForField(const FieldDescriptor* field) {
  switch (field->type()) {
    case FieldDescriptor::TYPE_INT32:
    case FieldDescriptor::TYPE_INT64:
    case FieldDescriptor::TYPE_UINT32:
    case FieldDescriptor::TYPE_UINT64:
    case FieldDescriptor::TYPE_SINT32:
    case FieldDescriptor::TYPE_SINT64:
    case FieldDescriptor::TYPE_FIXED32:
    case FieldDescriptor::TYPE_FIXED64:
    case FieldDescriptor::TYPE_SFIXED32:
    case FieldDescriptor::TYPE_SFIXED64:
    case FieldDescriptor::TYPE_ENUM: return "0";
    case FieldDescriptor::TYPE_DOUBLE:
    case FieldDescriptor::TYPE_FLOAT: return "0.0";
    case FieldDescriptor::TYPE_BOOL: return "false";
    case FieldDescriptor::TYPE_STRING:
    case FieldDescriptor::TYPE_BYTES: return "''";
    case FieldDescriptor::TYPE_MESSAGE:
    case FieldDescriptor::TYPE_GROUP: return "null";
    default: assert(false); return "";
  }
}

std::string GeneratedMetadataFileName(const FileDescriptor* file,
                                      const Options& options) {
  const std::string& proto_file = file->name();
  int start_index = 0;
  int first_index = proto_file.find_first_of("/", start_index);
  std::string result = "";
  std::string segment = "";

  if (proto_file == kEmptyFile) {
    return kEmptyMetadataFile;
  }
  if (options.is_descriptor) {
    return kDescriptorMetadataFile;
  }

  // Append directory name.
  std::string file_no_suffix;
  int lastindex = proto_file.find_last_of(".");
  if (proto_file == kEmptyFile) {
    return kEmptyMetadataFile;
  } else {
    file_no_suffix = proto_file.substr(0, lastindex);
  }

  if (file->options().has_php_metadata_namespace()) {
    const std::string& php_metadata_namespace =
        file->options().php_metadata_namespace();
    if (!php_metadata_namespace.empty() && php_metadata_namespace != "\\") {
      result += php_metadata_namespace;
      std::replace(result.begin(), result.end(), '\\', '/');
      if (result.at(result.size() - 1) != '/') {
        result += "/";
      }
    }
  } else {
    result += "GPBMetadata/";
    while (first_index != std::string::npos) {
      segment = UnderscoresToCamelCase(
          file_no_suffix.substr(start_index, first_index - start_index), true);
      result += ReservedNamePrefix(segment, file) + segment + "/";
      start_index = first_index + 1;
      first_index = file_no_suffix.find_first_of("/", start_index);
    }
  }

  // Append file name.
  int file_name_start = file_no_suffix.find_last_of("/");
  if (file_name_start == std::string::npos) {
    file_name_start = 0;
  } else {
    file_name_start += 1;
  }
  segment = UnderscoresToCamelCase(
      file_no_suffix.substr(file_name_start, first_index - file_name_start), true);

  return result + ReservedNamePrefix(segment, file) + segment + ".php";
}

std::string GeneratedMetadataFileName(const FileDescriptor* file,
                                      bool is_descriptor) {
  Options options;
  options.is_descriptor = is_descriptor;
  return GeneratedMetadataFileName(file, options);
}

template <typename DescriptorType>
std::string GeneratedClassFileName(const DescriptorType* desc,
                                   const Options& options) {
  std::string result = FullClassName(desc, options);
  for (int i = 0; i < result.size(); i++) {
    if (result[i] == '\\') {
      result[i] = '/';
    }
  }
  return result + ".php";
}

template <typename DescriptorType>
std::string LegacyGeneratedClassFileName(const DescriptorType* desc,
                                         const Options& options) {
  std::string result = LegacyFullClassName(desc, options);

  for (int i = 0; i < result.size(); i++) {
    if (result[i] == '\\') {
      result[i] = '/';
    }
  }
  return result + ".php";
}

std::string GeneratedServiceFileName(const ServiceDescriptor* service,
                                     const Options& options) {
  std::string result = FullClassName(service, options) + "Interface";
  for (int i = 0; i < result.size(); i++) {
    if (result[i] == '\\') {
      result[i] = '/';
    }
  }
  return result + ".php";
}

std::string IntToString(int32 value) {
  std::ostringstream os;
  os << value;
  return os.str();
}

std::string LabelForField(const FieldDescriptor* field) {
  switch (field->label()) {
    case FieldDescriptor::LABEL_OPTIONAL: return "optional";
    case FieldDescriptor::LABEL_REQUIRED: return "required";
    case FieldDescriptor::LABEL_REPEATED: return "repeated";
    default: assert(false); return "";
  }
}

std::string PhpSetterTypeName(const FieldDescriptor* field,
                              const Options& options) {
  if (field->is_map()) {
    return "array|\\Google\\Protobuf\\Internal\\MapField";
  }
  std::string type;
  switch (field->type()) {
    case FieldDescriptor::TYPE_INT32:
    case FieldDescriptor::TYPE_UINT32:
    case FieldDescriptor::TYPE_SINT32:
    case FieldDescriptor::TYPE_FIXED32:
    case FieldDescriptor::TYPE_SFIXED32:
    case FieldDescriptor::TYPE_ENUM:
      type = "int";
      break;
    case FieldDescriptor::TYPE_INT64:
    case FieldDescriptor::TYPE_UINT64:
    case FieldDescriptor::TYPE_SINT64:
    case FieldDescriptor::TYPE_FIXED64:
    case FieldDescriptor::TYPE_SFIXED64:
      type = "int|string";
      break;
    case FieldDescriptor::TYPE_DOUBLE:
    case FieldDescriptor::TYPE_FLOAT:
      type = "float";
      break;
    case FieldDescriptor::TYPE_BOOL:
      type = "bool";
      break;
    case FieldDescriptor::TYPE_STRING:
    case FieldDescriptor::TYPE_BYTES:
      type = "string";
      break;
    case FieldDescriptor::TYPE_MESSAGE:
      type = "\\" + FullClassName(field->message_type(), options);
      break;
    case FieldDescriptor::TYPE_GROUP:
      return "null";
    default: assert(false); return "";
  }
  if (field->is_repeated()) {
    // accommodate for edge case with multiple types.
    size_t start_pos = type.find("|");
    if (start_pos != std::string::npos) {
      type.replace(start_pos, 1, "[]|");
    }
    type += "[]|\\Google\\Protobuf\\Internal\\RepeatedField";
  }
  return type;
}

std::string PhpSetterTypeName(const FieldDescriptor* field,
                              bool is_descriptor) {
  Options options;
  options.is_descriptor = is_descriptor;
  return PhpSetterTypeName(field, options);
}

std::string PhpGetterTypeName(const FieldDescriptor* field,
                              const Options& options) {
  if (field->is_map()) {
    return "\\Google\\Protobuf\\Internal\\MapField";
  }
  if (field->is_repeated()) {
    return "\\Google\\Protobuf\\Internal\\RepeatedField";
  }
  switch (field->type()) {
    case FieldDescriptor::TYPE_INT32:
    case FieldDescriptor::TYPE_UINT32:
    case FieldDescriptor::TYPE_SINT32:
    case FieldDescriptor::TYPE_FIXED32:
    case FieldDescriptor::TYPE_SFIXED32:
    case FieldDescriptor::TYPE_ENUM: return "int";
    case FieldDescriptor::TYPE_INT64:
    case FieldDescriptor::TYPE_UINT64:
    case FieldDescriptor::TYPE_SINT64:
    case FieldDescriptor::TYPE_FIXED64:
    case FieldDescriptor::TYPE_SFIXED64: return "int|string";
    case FieldDescriptor::TYPE_DOUBLE:
    case FieldDescriptor::TYPE_FLOAT: return "float";
    case FieldDescriptor::TYPE_BOOL: return "bool";
    case FieldDescriptor::TYPE_STRING:
    case FieldDescriptor::TYPE_BYTES: return "string";
    case FieldDescriptor::TYPE_MESSAGE:
      return "\\" + FullClassName(field->message_type(), options);
    case FieldDescriptor::TYPE_GROUP: return "null";
    default: assert(false); return "";
  }
}

std::string PhpGetterTypeName(const FieldDescriptor* field,
                              bool is_descriptor) {
  Options options;
  options.is_descriptor = is_descriptor;
  return PhpGetterTypeName(field, options);
}

std::string EnumOrMessageSuffix(const FieldDescriptor* field,
                                const Options& options) {
  if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    return ", '" +
           DescriptorFullName(field->message_type(), options.is_descriptor) +
           "'";
  }
  if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
    return ", '" +
           DescriptorFullName(field->enum_type(), options.is_descriptor) + "'";
  }
  return "";
}

std::string EnumOrMessageSuffix(const FieldDescriptor* field,
                                bool is_descriptor) {
  Options options;
  options.is_descriptor = is_descriptor;
  return EnumOrMessageSuffix(field, options);
}

// Converts a name to camel-case. If cap_first_letter is true, capitalize the
// first letter.
std::string UnderscoresToCamelCase(const std::string& name,
                                   bool cap_first_letter) {
  std::string result;
  for (int i = 0; i < name.size(); i++) {
    if ('a' <= name[i] && name[i] <= 'z') {
      if (cap_first_letter) {
        result += name[i] + ('A' - 'a');
      } else {
        result += name[i];
      }
      cap_first_letter = false;
    } else if ('A' <= name[i] && name[i] <= 'Z') {
      if (i == 0 && !cap_first_letter) {
        // Force first letter to lower-case unless explicitly told to
        // capitalize it.
        result += name[i] + ('a' - 'A');
      } else {
        // Capital letters after the first are left as-is.
        result += name[i];
      }
      cap_first_letter = false;
    } else if ('0' <= name[i] && name[i] <= '9') {
      result += name[i];
      cap_first_letter = true;
    } else {
      cap_first_letter = true;
    }
  }
  // Add a trailing "_" if the name should be altered.
  if (name[name.size() - 1] == '#') {
    result += '_';
  }
  return result;
}

void Indent(io::Printer* printer) {
  printer->Indent();
  printer->Indent();
}
void Outdent(io::Printer* printer) {
  printer->Outdent();
  printer->Outdent();
}

void GenerateField(const FieldDescriptor* field, io::Printer* printer,
                   const Options& options) {
  if (field->is_repeated()) {
    GenerateFieldDocComment(printer, field, options, kFieldProperty);
    printer->Print(
        "private $^name^;\n",
        "name", field->name());
  } else if (field->real_containing_oneof()) {
    // Oneof fields are handled by GenerateOneofField.
    return;
  } else {
    std::string initial_value =
        field->has_presence() ? "null" : DefaultForField(field);
    GenerateFieldDocComment(printer, field, options, kFieldProperty);
    printer->Print(
        "protected $^name^ = ^initial_value^;\n",
        "name", field->name(),
        "initial_value", initial_value);
  }
}

void GenerateOneofField(const OneofDescriptor* oneof, io::Printer* printer) {
  // Oneof property needs to be protected in order to be accessed by parent
  // class in implementation.
  printer->Print(
      "protected $^name^;\n",
      "name", oneof->name());
}

void GenerateFieldAccessor(const FieldDescriptor* field, const Options& options,
                           io::Printer* printer) {
  const OneofDescriptor* oneof = field->real_containing_oneof();

  // Generate getter.
  GenerateFieldDocComment(printer, field, options, kFieldGetter);

  // deprecation
  std::string deprecation_trigger = (field->options().deprecated()) ? "@trigger_error('" +
      field->name() + " is deprecated.', E_USER_DEPRECATED);\n        " : "";

  // Emit getter.
  if (oneof != NULL) {
    printer->Print(
        "public function get^camel_name^()\n"
        "{\n"
        "    ^deprecation_trigger^return $this->readOneof(^number^);\n"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "number", IntToString(field->number()),
        "deprecation_trigger", deprecation_trigger);
  } else if (field->has_presence() && !field->message_type()) {
    printer->Print(
        "public function get^camel_name^()\n"
        "{\n"
        "    ^deprecation_trigger^return isset($this->^name^) ? $this->^name^ : ^default_value^;\n"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "name", field->name(),
        "default_value", DefaultForField(field),
        "deprecation_trigger", deprecation_trigger);
  } else {
    printer->Print(
        "public function get^camel_name^()\n"
        "{\n"
        "    ^deprecation_trigger^return $this->^name^;\n"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "name", field->name(),
        "deprecation_trigger", deprecation_trigger);
  }

  // Emit hazzers/clear.
  if (oneof) {
    printer->Print(
        "public function has^camel_name^()\n"
        "{\n"
        "    ^deprecation_trigger^return $this->hasOneof(^number^);\n"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "number", IntToString(field->number()),
        "deprecation_trigger", deprecation_trigger);
  } else if (field->has_presence()) {
    printer->Print(
        "public function has^camel_name^()\n"
        "{\n"
        "    ^deprecation_trigger^return isset($this->^name^);\n"
        "}\n\n"
        "public function clear^camel_name^()\n"
        "{\n"
        "    ^deprecation_trigger^unset($this->^name^);\n"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "name", field->name(),
        "default_value", DefaultForField(field),
        "deprecation_trigger", deprecation_trigger);
  }

  // For wrapper types, generate an additional getXXXUnwrapped getter
  if (!field->is_map() &&
      !field->is_repeated() &&
      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
      IsWrapperType(field)) {
    GenerateWrapperFieldGetterDocComment(printer, field);
    printer->Print(
        "public function get^camel_name^Unwrapped()\n"
        "{\n"
        "    ^deprecation_trigger^return $this->readWrapperValue(\"^field_name^\");\n"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "field_name", field->name(),
        "deprecation_trigger", deprecation_trigger);
  }

  // Generate setter.
  GenerateFieldDocComment(printer, field, options, kFieldSetter);
  printer->Print(
      "public function set^camel_name^($var)\n"
      "{\n",
      "camel_name", UnderscoresToCamelCase(field->name(), true));

  Indent(printer);

  if (field->options().deprecated()) {
      printer->Print(
          "^deprecation_trigger^",
          "deprecation_trigger", deprecation_trigger
      );
  }

  // Type check.
  if (field->is_map()) {
    const Descriptor* map_entry = field->message_type();
    const FieldDescriptor* key = map_entry->FindFieldByName("key");
    const FieldDescriptor* value = map_entry->FindFieldByName("value");
    printer->Print(
        "$arr = GPBUtil::checkMapField($var, "
        "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, "
        "\\Google\\Protobuf\\Internal\\GPBType::^value_type^",
        "key_type", ToUpper(key->type_name()),
        "value_type", ToUpper(value->type_name()));
    if (value->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      printer->Print(
          ", \\^class_name^);\n",
          "class_name",
          FullClassName(value->message_type(), options) + "::class");
    } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
      printer->Print(
          ", \\^class_name^);\n",
          "class_name",
          FullClassName(value->enum_type(), options) + "::class");
    } else {
      printer->Print(");\n");
    }
  } else if (field->is_repeated()) {
    printer->Print(
        "$arr = GPBUtil::checkRepeatedField($var, "
        "\\Google\\Protobuf\\Internal\\GPBType::^type^",
        "type", ToUpper(field->type_name()));
    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
      printer->Print(
          ", \\^class_name^);\n",
          "class_name",
          FullClassName(field->message_type(), options) + "::class");
    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
      printer->Print(
          ", \\^class_name^);\n",
          "class_name",
          FullClassName(field->enum_type(), options) + "::class");
    } else {
      printer->Print(");\n");
    }
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    printer->Print(
        "GPBUtil::checkMessage($var, \\^class_name^::class);\n",
        "class_name", FullClassName(field->message_type(), options));
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
    printer->Print(
        "GPBUtil::checkEnum($var, \\^class_name^::class);\n",
        "class_name", FullClassName(field->enum_type(), options));
  } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
    printer->Print(
        "GPBUtil::checkString($var, ^utf8^);\n",
        "utf8",
        field->type() == FieldDescriptor::TYPE_STRING ? "True": "False");
  } else {
    printer->Print(
        "GPBUtil::check^type^($var);\n",
        "type", UnderscoresToCamelCase(field->cpp_type_name(), true));
  }

  if (oneof != NULL) {
    printer->Print(
        "$this->writeOneof(^number^, $var);\n",
        "number", IntToString(field->number()));
  } else if (field->is_repeated()) {
    printer->Print(
        "$this->^name^ = $arr;\n",
        "name", field->name());
  } else {
    printer->Print(
        "$this->^name^ = $var;\n",
        "name", field->name());
  }

  printer->Print("\nreturn $this;\n");

  Outdent(printer);

  printer->Print(
      "}\n\n");

  // For wrapper types, generate an additional setXXXValue getter
  if (!field->is_map() &&
      !field->is_repeated() &&
      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
      IsWrapperType(field)) {
    GenerateWrapperFieldSetterDocComment(printer, field);
    printer->Print(
        "public function set^camel_name^Unwrapped($var)\n"
        "{\n"
        "    $this->writeWrapperValue(\"^field_name^\", $var);\n"
        "    return $this;"
        "}\n\n",
        "camel_name", UnderscoresToCamelCase(field->name(), true),
        "field_name", field->name());
  }
}

void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) {
  printer->Print(
      "$pool->addEnum('^name^', "
      "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
      "name", DescriptorFullName(en, true),
      "class_name", en->name());
  Indent(printer);

  for (int i = 0; i < en->value_count(); i++) {
    const EnumValueDescriptor* value = en->value(i);
    printer->Print(
        "->value(\"^name^\", ^number^)\n",
        "name", ConstantNamePrefix(value->name()) + value->name(),
        "number", IntToString(value->number()));
  }
  printer->Print("->finalizeToPool();\n\n");
  Outdent(printer);
}

void GenerateServiceMethod(const MethodDescriptor* method,
                           io::Printer* printer) {
  printer->Print(
        "public function ^camel_name^(\\^request_name^ $request);\n\n",
        "camel_name", UnderscoresToCamelCase(method->name(), false),
        "request_name", FullClassName(
          method->input_type(), false)
  );
}

void GenerateMessageToPool(const std::string& name_prefix,
                           const Descriptor* message, io::Printer* printer) {
  // Don't generate MapEntry messages -- we use the PHP extension's native
  // support for map fields instead.
  if (message->options().map_entry()) {
    return;
  }
  std::string class_name =
      (name_prefix.empty() ? "" : name_prefix + "\\") +
      ReservedNamePrefix(message->name(), message->file()) + message->name();

  printer->Print(
      "$pool->addMessage('^message^', "
      "\\Google\\Protobuf\\Internal\\^class_name^::class)\n",
      "message", DescriptorFullName(message, true),
      "class_name", class_name);

  Indent(printer);

  for (int i = 0; i < message->field_count(); i++) {
    const FieldDescriptor* field = message->field(i);
    if (field->is_map()) {
      const FieldDescriptor* key =
          field->message_type()->FindFieldByName("key");
      const FieldDescriptor* val =
          field->message_type()->FindFieldByName("value");
      printer->Print(
          "->map('^field^', \\Google\\Protobuf\\Internal\\GPBType::^key^, "
          "\\Google\\Protobuf\\Internal\\GPBType::^value^, ^number^^other^)\n",
          "field", field->name(),
          "key", ToUpper(key->type_name()),
          "value", ToUpper(val->type_name()),
          "number", StrCat(field->number()),
          "other", EnumOrMessageSuffix(val, true));
    } else if (!field->real_containing_oneof()) {
      printer->Print(
          "->^label^('^field^', "
          "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n",
          "field", field->name(),
          "label", LabelForField(field),
          "type", ToUpper(field->type_name()),
          "number", StrCat(field->number()),
          "other", EnumOrMessageSuffix(field, true));
    }
  }

  // oneofs.
  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
    const OneofDescriptor* oneof = message->oneof_decl(i);
    printer->Print("->oneof(^name^)\n",
                   "name", oneof->name());
    Indent(printer);
    for (int index = 0; index < oneof->field_count(); index++) {
      const FieldDescriptor* field = oneof->field(index);
      printer->Print(
          "->value('^field^', "
          "\\Google\\Protobuf\\Internal\\GPBType::^type^, ^number^^other^)\n",
          "field", field->name(),
          "type", ToUpper(field->type_name()),
          "number", StrCat(field->number()),
          "other", EnumOrMessageSuffix(field, true));
    }
    printer->Print("->finish()\n");
    Outdent(printer);
  }

  printer->Print(
      "->finalizeToPool();\n");

  Outdent(printer);

  printer->Print(
      "\n");

  for (int i = 0; i < message->nested_type_count(); i++) {
    GenerateMessageToPool(class_name, message->nested_type(i), printer);
  }
  for (int i = 0; i < message->enum_type_count(); i++) {
    GenerateEnumToPool(message->enum_type(i), printer);
  }
}

void GenerateAddFileToPool(const FileDescriptor* file, const Options& options,
                           io::Printer* printer) {
  printer->Print(
      "public static $is_initialized = false;\n\n"
      "public static function initOnce() {\n");
  Indent(printer);

  if (options.aggregate_metadata) {
    GenerateAddFilesToPool(file, options, printer);
  } else {
    printer->Print(
        "$pool = \\Google\\Protobuf\\Internal\\"
        "DescriptorPool::getGeneratedPool();\n\n"
        "if (static::$is_initialized == true) {\n"
        "  return;\n"
        "}\n");

    if (options.is_descriptor) {
      for (int i = 0; i < file->message_type_count(); i++) {
        GenerateMessageToPool("", file->message_type(i), printer);
      }
      for (int i = 0; i < file->enum_type_count(); i++) {
        GenerateEnumToPool(file->enum_type(i), printer);
      }

      printer->Print(
          "$pool->finish();\n");
    } else {
      for (int i = 0; i < file->dependency_count(); i++) {
        const std::string& name = file->dependency(i)->name();
        // Currently, descriptor.proto is not ready for external usage. Skip to
        // import it for now, so that its dependencies can still work as long as
        // they don't use protos defined in descriptor.proto.
        if (name == kDescriptorFile) {
          continue;
        }
        std::string dependency_filename =
            GeneratedMetadataFileName(file->dependency(i), options);
        printer->Print(
            "\\^name^::initOnce();\n",
            "name", FilenameToClassname(dependency_filename));
      }

      // Add messages and enums to descriptor pool.
      FileDescriptorSet files;
      FileDescriptorProto* file_proto = files.add_file();
      file->CopyTo(file_proto);

      // Filter out descriptor.proto as it cannot be depended on for now.
      RepeatedPtrField<std::string>* dependency =
          file_proto->mutable_dependency();
      for (RepeatedPtrField<std::string>::iterator it = dependency->begin();
           it != dependency->end(); ++it) {
        if (*it != kDescriptorFile) {
          dependency->erase(it);
          break;
        }
      }

      // Filter out all extensions, since we do not support extension yet.
      file_proto->clear_extension();
      RepeatedPtrField<DescriptorProto>* message_type =
          file_proto->mutable_message_type();
      for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
           it != message_type->end(); ++it) {
        it->clear_extension();
      }

      std::string files_data;
      files.SerializeToString(&files_data);

      printer->Print("$pool->internalAddGeneratedFile(\n");
      Indent(printer);
      printer->Print("'");

      for (auto ch : files_data) {
        switch (ch) {
          case '\\':
            printer->Print(R"(\\)");
            break;
          case '\'':
            printer->Print(R"(\')");
            break;
          default:
            printer->Print("^char^", "char", std::string(1, ch));
            break;
        }
      }

      printer->Print("'\n");
      Outdent(printer);
      printer->Print(
          ", true);\n\n");
    }
    printer->Print(
        "static::$is_initialized = true;\n");
  }

  Outdent(printer);
  printer->Print("}\n");
}

static void AnalyzeDependencyForFile(
    const FileDescriptor* file,
    std::set<const FileDescriptor*>* nodes_without_dependency,
    std::map<const FileDescriptor*, std::set<const FileDescriptor*>>* deps,
    std::map<const FileDescriptor*, int>* dependency_count) {
  int count = file->dependency_count();
  for (int i = 0; i < file->dependency_count(); i++) {
      const FileDescriptor* dependency = file->dependency(i);
      if (dependency->name() == kDescriptorFile) {
        count--;
        break;
      }
  }

  if (count == 0) {
    nodes_without_dependency->insert(file);
  } else {
    (*dependency_count)[file] = count;
    for (int i = 0; i < file->dependency_count(); i++) {
      const FileDescriptor* dependency = file->dependency(i);
      if (dependency->name() == kDescriptorFile) {
        continue;
      }
      if (deps->find(dependency) == deps->end()) {
        (*deps)[dependency] = std::set<const FileDescriptor*>();
      }
      (*deps)[dependency].insert(file);
      AnalyzeDependencyForFile(
          dependency, nodes_without_dependency, deps, dependency_count);
    }
  }
}

static bool NeedsUnwrapping(const FileDescriptor* file,
                            const Options& options) {
  bool has_aggregate_metadata_prefix = false;
  if (options.aggregate_metadata_prefixes.empty()) {
    has_aggregate_metadata_prefix = true;
  } else {
    for (const auto& prefix : options.aggregate_metadata_prefixes) {
      if (HasPrefixString(file->package(), prefix)) {
        has_aggregate_metadata_prefix = true;
        break;
      }
    }
  }

  return has_aggregate_metadata_prefix;
}

void GenerateAddFilesToPool(const FileDescriptor* file, const Options& options,
                            io::Printer* printer) {
  printer->Print(
      "$pool = \\Google\\Protobuf\\Internal\\"
      "DescriptorPool::getGeneratedPool();\n"
      "if (static::$is_initialized == true) {\n"
      "  return;\n"
      "}\n");

  // Sort files according to dependency
  std::map<const FileDescriptor*, std::set<const FileDescriptor*>> deps;
  std::map<const FileDescriptor*, int> dependency_count;
  std::set<const FileDescriptor*> nodes_without_dependency;
  FileDescriptorSet sorted_file_set;
  
  AnalyzeDependencyForFile(
      file, &nodes_without_dependency, &deps, &dependency_count);

  while (!nodes_without_dependency.empty()) {
    auto file_node = *nodes_without_dependency.begin();
    nodes_without_dependency.erase(file_node);
    for (auto dependent : deps[file_node]) {
      if (dependency_count[dependent] == 1) {
        dependency_count.erase(dependent);
        nodes_without_dependency.insert(dependent);
      } else {
        dependency_count[dependent] -= 1;
      }
    }

    bool needs_aggregate = NeedsUnwrapping(file_node, options);

    if (needs_aggregate) {
      auto file_proto = sorted_file_set.add_file();
      file_node->CopyTo(file_proto);

      // Filter out descriptor.proto as it cannot be depended on for now.
      RepeatedPtrField<std::string>* dependency =
          file_proto->mutable_dependency();
      for (RepeatedPtrField<std::string>::iterator it = dependency->begin();
           it != dependency->end(); ++it) {
        if (*it != kDescriptorFile) {
          dependency->erase(it);
          break;
        }
      }

      // Filter out all extensions, since we do not support extension yet.
      file_proto->clear_extension();
      RepeatedPtrField<DescriptorProto>* message_type =
          file_proto->mutable_message_type();
      for (RepeatedPtrField<DescriptorProto>::iterator it = message_type->begin();
           it != message_type->end(); ++it) {
        it->clear_extension();
      }
    } else {
      std::string dependency_filename = GeneratedMetadataFileName(file_node, false);
      printer->Print(
          "\\^name^::initOnce();\n",
          "name", FilenameToClassname(dependency_filename));
    }
  }

  std::string files_data;
  sorted_file_set.SerializeToString(&files_data);

  printer->Print("$pool->internalAddGeneratedFile(\n");
  Indent(printer);
  printer->Print("'");

  for (auto ch : files_data) {
    switch (ch) {
      case '\\':
        printer->Print(R"(\\)");
        break;
      case '\'':
        printer->Print(R"(\')");
        break;
      default:
        printer->Print("^char^", "char", std::string(1, ch));
        break;
    }
  }

  printer->Print("'\n");
  Outdent(printer);
  printer->Print(
      ", true);\n");

  printer->Print(
      "static::$is_initialized = true;\n");
}

void GenerateUseDeclaration(const Options& options, io::Printer* printer) {
  if (!options.is_descriptor) {
    printer->Print(
        "use Google\\Protobuf\\Internal\\GPBType;\n"
        "use Google\\Protobuf\\Internal\\RepeatedField;\n"
        "use Google\\Protobuf\\Internal\\GPBUtil;\n\n");
  } else {
    printer->Print(
        "use Google\\Protobuf\\Internal\\GPBType;\n"
        "use Google\\Protobuf\\Internal\\GPBWire;\n"
        "use Google\\Protobuf\\Internal\\RepeatedField;\n"
        "use Google\\Protobuf\\Internal\\InputStream;\n"
        "use Google\\Protobuf\\Internal\\GPBUtil;\n\n");
  }
}

void GenerateHead(const FileDescriptor* file, io::Printer* printer) {
  printer->Print(
    "<?php\n"
    "# Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
    "# source: ^filename^\n"
    "\n",
    "filename", file->name());
}

std::string FilenameToClassname(const std::string& filename) {
  int lastindex = filename.find_last_of(".");
  std::string result = filename.substr(0, lastindex);
  for (int i = 0; i < result.size(); i++) {
    if (result[i] == '/') {
      result[i] = '\\';
    }
  }
  return result;
}

void GenerateMetadataFile(const FileDescriptor* file, const Options& options,
                          GeneratorContext* generator_context) {
  std::string filename = GeneratedMetadataFileName(file, options);
  std::unique_ptr<io::ZeroCopyOutputStream> output(
      generator_context->Open(filename));
  io::Printer printer(output.get(), '^');

  GenerateHead(file, &printer);

  std::string fullname = FilenameToClassname(filename);
  int lastindex = fullname.find_last_of("\\");

  if (lastindex != std::string::npos) {
    printer.Print(
        "namespace ^name^;\n\n",
        "name", fullname.substr(0, lastindex));

    printer.Print(
        "class ^name^\n"
        "{\n",
        "name", fullname.substr(lastindex + 1));
  } else {
    printer.Print(
        "class ^name^\n"
        "{\n",
        "name", fullname);
  }
  Indent(&printer);

  GenerateAddFileToPool(file, options, &printer);

  Outdent(&printer);
  printer.Print("}\n\n");
}

template <typename DescriptorType>
void LegacyGenerateClassFile(const FileDescriptor* file,
                             const DescriptorType* desc, const Options& options,
                             GeneratorContext* generator_context) {
  std::string filename = LegacyGeneratedClassFileName(desc, options);
  std::unique_ptr<io::ZeroCopyOutputStream> output(
      generator_context->Open(filename));
  io::Printer printer(output.get(), '^');

  GenerateHead(file, &printer);

  std::string php_namespace = RootPhpNamespace(desc, options);
  if (!php_namespace.empty()) {
    printer.Print(
        "namespace ^name^;\n\n",
        "name", php_namespace);
  }
  std::string newname = FullClassName(desc, options);
  printer.Print("if (false) {\n");
  Indent(&printer);
  printer.Print("/**\n");
  printer.Print(" * This class is deprecated. Use ^new^ instead.\n",
      "new", newname);
  printer.Print(" * @deprecated\n");
  printer.Print(" */\n");
  printer.Print("class ^old^ {}\n",
      "old", LegacyGeneratedClassName(desc));
  Outdent(&printer);
  printer.Print("}\n");
  printer.Print("class_exists(^new^::class);\n",
      "new", GeneratedClassNameImpl(desc));
  printer.Print("@trigger_error('^old^ is deprecated and will be removed in "
      "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n",
      "old", LegacyFullClassName(desc, options),
      "fullname", newname);
}

void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en,
                      const Options& options,
                      GeneratorContext* generator_context) {
  std::string filename = GeneratedClassFileName(en, options);
  std::unique_ptr<io::ZeroCopyOutputStream> output(
      generator_context->Open(filename));
  io::Printer printer(output.get(), '^');

  GenerateHead(file, &printer);

  std::string fullname = FilenameToClassname(filename);
  int lastindex = fullname.find_last_of("\\");

  if (lastindex != std::string::npos) {
    printer.Print(
        "namespace ^name^;\n\n",
        "name", fullname.substr(0, lastindex));

    // We only need this 'use' statement if the enum has a namespace.
    // Otherwise, we get a warning that the use statement has no effect.
    printer.Print("use UnexpectedValueException;\n\n");
  }

  GenerateEnumDocComment(&printer, en, options);

  if (lastindex != std::string::npos) {
    fullname = fullname.substr(lastindex + 1);
  }

  printer.Print(
      "class ^name^\n"
      "{\n",
      "name", fullname);
  Indent(&printer);

  for (int i = 0; i < en->value_count(); i++) {
    const EnumValueDescriptor* value = en->value(i);
    GenerateEnumValueDocComment(&printer, value);
    printer.Print("const ^name^ = ^number^;\n",
                  "name", ConstantNamePrefix(value->name()) + value->name(),
                  "number", IntToString(value->number()));
  }

  printer.Print("\nprivate static $valueToName = [\n");
  Indent(&printer);
  for (int i = 0; i < en->value_count(); i++) {
    const EnumValueDescriptor* value = en->value(i);
    printer.Print("self::^name^ => '^name^',\n",
                  "name", ConstantNamePrefix(value->name()) + value->name());
  }
  Outdent(&printer);
  printer.Print("];\n");

  printer.Print(
      "\npublic static function name($value)\n"
      "{\n");
  Indent(&printer);
  printer.Print("if (!isset(self::$valueToName[$value])) {\n");
  Indent(&printer);
  printer.Print("throw new UnexpectedValueException(sprintf(\n");
  Indent(&printer);
  Indent(&printer);
  printer.Print("'Enum %s has no name defined for value %s', __CLASS__, $value));\n");
  Outdent(&printer);
  Outdent(&printer);
  Outdent(&printer);
  printer.Print("}\n"
                "return self::$valueToName[$value];\n");
  Outdent(&printer);
  printer.Print("}\n\n");

  printer.Print(
      "\npublic static function value($name)\n"
      "{\n");
  Indent(&printer);
  printer.Print("$const = __CLASS__ . '::' . strtoupper($name);\n"
                "if (!defined($const)) {\n");
  Indent(&printer);
  printer.Print("throw new UnexpectedValueException(sprintf(\n");
  Indent(&printer);
  Indent(&printer);
  printer.Print("'Enum %s has no value defined for name %s', __CLASS__, $name));\n");
  Outdent(&printer);
  Outdent(&printer);
  Outdent(&printer);
  printer.Print("}\n"
                "return constant($const);\n");
  Outdent(&printer);
  printer.Print("}\n");

  Outdent(&printer);
  printer.Print("}\n\n");

  // write legacy file for backwards compatibility with nested messages and enums
  if (en->containing_type() != NULL) {
    printer.Print(
        "// Adding a class alias for backwards compatibility with the previous class name.\n");
    printer.Print(
        "class_alias(^new^::class, \\^old^::class);\n\n",
        "new", fullname,
        "old", LegacyFullClassName(en, options));
    LegacyGenerateClassFile(file, en, options, generator_context);
  }
}

void GenerateMessageFile(const FileDescriptor* file, const Descriptor* message,
                         const Options& options,
                         GeneratorContext* generator_context) {
  // Don't generate MapEntry messages -- we use the PHP extension's native
  // support for map fields instead.
  if (message->options().map_entry()) {
    return;
  }

  std::string filename = GeneratedClassFileName(message, options);
  std::unique_ptr<io::ZeroCopyOutputStream> output(
      generator_context->Open(filename));
  io::Printer printer(output.get(), '^');

  GenerateHead(file, &printer);

  std::string fullname = FilenameToClassname(filename);
  int lastindex = fullname.find_last_of("\\");

  if (lastindex != std::string::npos) {
    printer.Print(
        "namespace ^name^;\n\n",
        "name", fullname.substr(0, lastindex));
  }

  GenerateUseDeclaration(options, &printer);

  GenerateMessageDocComment(&printer, message, options);
  if (lastindex != std::string::npos) {
    fullname = fullname.substr(lastindex + 1);
  }

  std::string base;

  switch (message->well_known_type()) {
    case Descriptor::WELLKNOWNTYPE_ANY:
      base = "\\Google\\Protobuf\\Internal\\AnyBase";
      break;
    case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
      base = "\\Google\\Protobuf\\Internal\\TimestampBase";
      break;
    default:
      base = "\\Google\\Protobuf\\Internal\\Message";
      break;
  }

  printer.Print(
      "class ^name^ extends ^base^\n"
      "{\n",
      "base", base,
      "name", fullname);
  Indent(&printer);

  // Field and oneof definitions.
  for (int i = 0; i < message->field_count(); i++) {
    const FieldDescriptor* field = message->field(i);
    GenerateField(field, &printer, options);
  }
  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
    const OneofDescriptor* oneof = message->oneof_decl(i);
    GenerateOneofField(oneof, &printer);
  }
  printer.Print("\n");

  GenerateMessageConstructorDocComment(&printer, message, options);
  printer.Print(
      "public function __construct($data = NULL) {\n");
  Indent(&printer);

  std::string metadata_filename = GeneratedMetadataFileName(file, options);
  std::string metadata_fullname = FilenameToClassname(metadata_filename);
  printer.Print(
      "\\^fullname^::initOnce();\n",
      "fullname", metadata_fullname);

  printer.Print(
      "parent::__construct($data);\n");

  Outdent(&printer);
  printer.Print("}\n\n");

  // Field and oneof accessors.
  for (int i = 0; i < message->field_count(); i++) {
    const FieldDescriptor* field = message->field(i);
    GenerateFieldAccessor(field, options, &printer);
  }
  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
    const OneofDescriptor* oneof = message->oneof_decl(i);
    printer.Print(
      "/**\n"
      " * @return string\n"
      " */\n"
      "public function get^camel_name^()\n"
      "{\n"
      "    return $this->whichOneof(\"^name^\");\n"
      "}\n\n",
      "camel_name", UnderscoresToCamelCase(oneof->name(), true), "name",
      oneof->name());
  }

  Outdent(&printer);
  printer.Print("}\n\n");

  // write legacy file for backwards compatibility with nested messages and enums
  if (message->containing_type() != NULL) {
    printer.Print(
        "// Adding a class alias for backwards compatibility with the previous class name.\n");
    printer.Print(
        "class_alias(^new^::class, \\^old^::class);\n\n",
        "new", fullname,
        "old", LegacyFullClassName(message, options));
    LegacyGenerateClassFile(file, message, options, generator_context);
  }

  // Nested messages and enums.
  for (int i = 0; i < message->nested_type_count(); i++) {
    GenerateMessageFile(file, message->nested_type(i), options,
                        generator_context);
  }
  for (int i = 0; i < message->enum_type_count(); i++) {
    GenerateEnumFile(file, message->enum_type(i), options, generator_context);
  }
}

void GenerateServiceFile(
    const FileDescriptor* file, const ServiceDescriptor* service,
    const Options& options, GeneratorContext* generator_context) {
  std::string filename = GeneratedServiceFileName(service, options);
  std::unique_ptr<io::ZeroCopyOutputStream> output(
      generator_context->Open(filename));
  io::Printer printer(output.get(), '^');

  GenerateHead(file, &printer);

  std::string fullname = FilenameToClassname(filename);
  int lastindex = fullname.find_last_of("\\");

  if (!file->options().php_namespace().empty() ||
      (!file->options().has_php_namespace() && !file->package().empty()) ||
      lastindex != std::string::npos) {
    printer.Print(
        "namespace ^name^;\n\n",
        "name", fullname.substr(0, lastindex));
  }

  GenerateServiceDocComment(&printer, service);

  if (lastindex != std::string::npos) {
    printer.Print(
        "interface ^name^\n"
        "{\n",
        "name", fullname.substr(lastindex + 1));
  } else {
    printer.Print(
        "interface ^name^\n"
        "{\n",
        "name", fullname);
  }

  Indent(&printer);

  for (int i = 0; i < service->method_count(); i++) {
    const MethodDescriptor* method = service->method(i);
    GenerateServiceMethodDocComment(&printer, method);
    GenerateServiceMethod(method, &printer);
  }

  Outdent(&printer);
  printer.Print("}\n\n");
}

void GenerateFile(const FileDescriptor* file, const Options& options,
                  GeneratorContext* generator_context) {
  GenerateMetadataFile(file, options, generator_context);

  for (int i = 0; i < file->message_type_count(); i++) {
    GenerateMessageFile(file, file->message_type(i), options,
                        generator_context);
  }
  for (int i = 0; i < file->enum_type_count(); i++) {
    GenerateEnumFile(file, file->enum_type(i), options, generator_context);
  }
  if (file->options().php_generic_services()) {
    for (int i = 0; i < file->service_count(); i++) {
      GenerateServiceFile(file, file->service(i), options, generator_context);
    }
  }
}

static std::string EscapePhpdoc(const std::string& input) {
  std::string result;
  result.reserve(input.size() * 2);

  char prev = '*';

  for (std::string::size_type i = 0; i < input.size(); i++) {
    char c = input[i];
    switch (c) {
      case '*':
        // Avoid "/*".
        if (prev == '/') {
          result.append("&#42;");
        } else {
          result.push_back(c);
        }
        break;
      case '/':
        // Avoid "*/".
        if (prev == '*') {
          result.append("&#47;");
        } else {
          result.push_back(c);
        }
        break;
      case '@':
        // '@' starts phpdoc tags including the @deprecated tag, which will
        // cause a compile-time error if inserted before a declaration that
        // does not have a corresponding @Deprecated annotation.
        result.append("&#64;");
        break;
      default:
        result.push_back(c);
        break;
    }

    prev = c;
  }

  return result;
}

static void GenerateDocCommentBodyForLocation(
    io::Printer* printer, const SourceLocation& location, bool trailingNewline,
    int indentCount) {
  std::string comments = location.leading_comments.empty()
                             ? location.trailing_comments
                             : location.leading_comments;
  if (!comments.empty()) {
    // TODO(teboring):  Ideally we should parse the comment text as Markdown and
    //   write it back as HTML, but this requires a Markdown parser.  For now
    //   we just use the proto comments unchanged.

    // If the comment itself contains block comment start or end markers,
    // HTML-escape them so that they don't accidentally close the doc comment.
    comments = EscapePhpdoc(comments);

    std::vector<std::string> lines = Split(comments, "\n", true);
    while (!lines.empty() && lines.back().empty()) {
      lines.pop_back();
    }

    for (int i = 0; i < lines.size(); i++) {
      // Most lines should start with a space.  Watch out for lines that start
      // with a /, since putting that right after the leading asterisk will
      // close the comment.
      if (indentCount == 0 && !lines[i].empty() && lines[i][0] == '/') {
        printer->Print(" * ^line^\n", "line", lines[i]);
      } else {
        std::string indent = std::string(indentCount, ' ');
        printer->Print(" *^ind^^line^\n", "ind", indent, "line", lines[i]);
      }
    }
    if (trailingNewline) {
      printer->Print(" *\n");
    }
  }
}

template <typename DescriptorType>
static void GenerateDocCommentBody(
    io::Printer* printer, const DescriptorType* descriptor) {
  SourceLocation location;
  if (descriptor->GetSourceLocation(&location)) {
    GenerateDocCommentBodyForLocation(printer, location, true, 0);
  }
}

static std::string FirstLineOf(const std::string& value) {
  std::string result = value;

  std::string::size_type pos = result.find_first_of('\n');
  if (pos != std::string::npos) {
    result.erase(pos);
  }

  return result;
}

void GenerateMessageDocComment(io::Printer* printer, const Descriptor* message,
                               const Options& options) {
  printer->Print("/**\n");
  GenerateDocCommentBody(printer, message);
  printer->Print(
    " * Generated from protobuf message <code>^messagename^</code>\n"
    " */\n",
    "fullname", EscapePhpdoc(FullClassName(message, options)),
    "messagename", EscapePhpdoc(message->full_name()));
}

void GenerateMessageConstructorDocComment(io::Printer* printer,
                                          const Descriptor* message,
                                          const Options& options) {
  // In theory we should have slightly different comments for setters, getters,
  // etc., but in practice everyone already knows the difference between these
  // so it's redundant information.

  // We start the comment with the main body based on the comments from the
  // .proto file (if present). We then end with the field declaration, e.g.:
  //   optional string foo = 5;
  // If the field is a group, the debug string might end with {.
  printer->Print("/**\n");
  printer->Print(" * Constructor.\n");
  printer->Print(" *\n");
  printer->Print(" * @param array $data {\n");
  printer->Print(" *     Optional. Data for populating the Message object.\n");
  printer->Print(" *\n");
  for (int i = 0; i < message->field_count(); i++) {
    const FieldDescriptor* field = message->field(i);
    printer->Print(" *     @type ^php_type^ $^var^\n",
      "php_type", PhpSetterTypeName(field, options),
      "var", field->name());
    SourceLocation location;
    if (field->GetSourceLocation(&location)) {
      GenerateDocCommentBodyForLocation(printer, location, false, 10);
    }
  }
  printer->Print(" * }\n");
  printer->Print(" */\n");
}

void GenerateServiceDocComment(io::Printer* printer,
                               const ServiceDescriptor* service) {
  printer->Print("/**\n");
  GenerateDocCommentBody(printer, service);
  printer->Print(
    " * Protobuf type <code>^fullname^</code>\n"
    " */\n",
    "fullname", EscapePhpdoc(service->full_name()));
}

void GenerateFieldDocComment(io::Printer* printer, const FieldDescriptor* field,
                             const Options& options, int function_type) {
  // In theory we should have slightly different comments for setters, getters,
  // etc., but in practice everyone already knows the difference between these
  // so it's redundant information.

  // We start the comment with the main body based on the comments from the
  // .proto file (if present). We then end with the field declaration, e.g.:
  //   optional string foo = 5;
  // If the field is a group, the debug string might end with {.
  printer->Print("/**\n");
  GenerateDocCommentBody(printer, field);
  printer->Print(
    " * Generated from protobuf field <code>^def^</code>\n",
    "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
  if (function_type == kFieldSetter) {
    printer->Print(" * @param ^php_type^ $var\n",
      "php_type", PhpSetterTypeName(field, options));
    printer->Print(" * @return $this\n");
  } else if (function_type == kFieldGetter) {
    bool can_return_null = field->has_presence() &&
                           field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE;
    printer->Print(" * @return ^php_type^^maybe_null^\n",
      "php_type", PhpGetterTypeName(field, options),
      "maybe_null", can_return_null ? "|null" : "");
  }
  if (field->options().deprecated()) {
    printer->Print(" * @deprecated\n");
  }
  printer->Print(" */\n");
}

void GenerateWrapperFieldGetterDocComment(io::Printer* printer, const FieldDescriptor* field) {
  // Generate a doc comment for the special getXXXValue methods that are
  // generated for wrapper types.
  const FieldDescriptor* primitiveField = field->message_type()->FindFieldByName("value");
  printer->Print("/**\n");
  printer->Print(
      " * Returns the unboxed value from <code>get^camel_name^()</code>\n\n",
      "camel_name", UnderscoresToCamelCase(field->name(), true));
  GenerateDocCommentBody(printer, field);
  printer->Print(
    " * Generated from protobuf field <code>^def^</code>\n",
    "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
  printer->Print(" * @return ^php_type^|null\n",
        "php_type", PhpGetterTypeName(primitiveField, false));
  printer->Print(" */\n");
}

void GenerateWrapperFieldSetterDocComment(io::Printer* printer, const FieldDescriptor* field) {
  // Generate a doc comment for the special setXXXValue methods that are
  // generated for wrapper types.
  const FieldDescriptor* primitiveField = field->message_type()->FindFieldByName("value");
  printer->Print("/**\n");
  printer->Print(
      " * Sets the field by wrapping a primitive type in a ^message_name^ object.\n\n",
      "message_name", FullClassName(field->message_type(), false));
  GenerateDocCommentBody(printer, field);
  printer->Print(
    " * Generated from protobuf field <code>^def^</code>\n",
    "def", EscapePhpdoc(FirstLineOf(field->DebugString())));
  printer->Print(" * @param ^php_type^|null $var\n",
        "php_type", PhpSetterTypeName(primitiveField, false));
  printer->Print(" * @return $this\n");
  printer->Print(" */\n");
}

void GenerateEnumDocComment(io::Printer* printer, const EnumDescriptor* enum_,
                            const Options& options) {
  printer->Print("/**\n");
  GenerateDocCommentBody(printer, enum_);
  printer->Print(
    " * Protobuf type <code>^fullname^</code>\n"
    " */\n",
    "fullname", EscapePhpdoc(enum_->full_name()));
}

void GenerateEnumValueDocComment(io::Printer* printer,
                                 const EnumValueDescriptor* value) {
  printer->Print("/**\n");
  GenerateDocCommentBody(printer, value);
  printer->Print(
    " * Generated from protobuf enum <code>^def^</code>\n"
    " */\n",
    "def", EscapePhpdoc(FirstLineOf(value->DebugString())));
}

void GenerateServiceMethodDocComment(io::Printer* printer,
                                     const MethodDescriptor* method) {
  printer->Print("/**\n");
  GenerateDocCommentBody(printer, method);
  printer->Print(
    " * Method <code>^method_name^</code>\n"
    " *\n",
    "method_name", EscapePhpdoc(UnderscoresToCamelCase(method->name(), false)));
  printer->Print(
    " * @param \\^input_type^ $request\n",
    "input_type", EscapePhpdoc(FullClassName(method->input_type(), false)));
  printer->Print(
    " * @return \\^return_type^\n"
    " */\n",
    "return_type", EscapePhpdoc(FullClassName(method->output_type(), false)));
}

std::string FilenameCName(const FileDescriptor* file) {
  std::string c_name = file->name();
  c_name = StringReplace(c_name, ".", "_", true);
  c_name = StringReplace(c_name, "/", "_", true);
  return c_name;
}

void GenerateCEnum(const EnumDescriptor* desc, io::Printer* printer) {
  std::string c_name = desc->full_name();
  c_name = StringReplace(c_name, ".", "_", true);
  std::string php_name = FullClassName(desc, Options());
  php_name = StringReplace(php_name, "\\", "\\\\", true);
  printer->Print(
      "/* $c_name$ */\n"
      "\n"
      "zend_class_entry* $c_name$_ce;\n"
      "\n"
      "PHP_METHOD($c_name$, name) {\n"
      "  $file_c_name$_AddDescriptor();\n"
      "  const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n"
      "  const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n"
      "  const char *name;\n"
      "  zend_long value;\n"
      "  if (zend_parse_parameters(ZEND_NUM_ARGS(), \"l\", &value) ==\n"
      "      FAILURE) {\n"
      "    return;\n"
      "  }\n"
      "  name = upb_enumdef_iton(e, value);\n"
      "  if (!name) {\n"
      "    zend_throw_exception_ex(NULL, 0,\n"
      "                            \"$php_name$ has no name \"\n"
      "                            \"defined for value \" ZEND_LONG_FMT \".\",\n"
      "                            value);\n"
      "    return;\n"
      "  }\n"
      "  RETURN_STRING(name);\n"
      "}\n"
      "\n"
      "PHP_METHOD($c_name$, value) {\n"
      "  $file_c_name$_AddDescriptor();\n"
      "  const upb_symtab *symtab = DescriptorPool_GetSymbolTable();\n"
      "  const upb_enumdef *e = upb_symtab_lookupenum(symtab, \"$name$\");\n"
      "  char *name = NULL;\n"
      "  size_t name_len;\n"
      "  int32_t num;\n"
      "  if (zend_parse_parameters(ZEND_NUM_ARGS(), \"s\", &name,\n"
      "                            &name_len) == FAILURE) {\n"
      "    return;\n"
      "  }\n"
      "  if (!upb_enumdef_ntoi(e, name, name_len, &num)) {\n"
      "    zend_throw_exception_ex(NULL, 0,\n"
      "                            \"$php_name$ has no value \"\n"
      "                            \"defined for name %s.\",\n"
      "                            name);\n"
      "    return;\n"
      "  }\n"
      "  RETURN_LONG(num);\n"
      "}\n"
      "\n"
      "static zend_function_entry $c_name$_phpmethods[] = {\n"
      "  PHP_ME($c_name$, name, arginfo_lookup, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
      "  PHP_ME($c_name$, value, arginfo_lookup, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
      "  ZEND_FE_END\n"
      "};\n"
      "\n"
      "static void $c_name$_ModuleInit() {\n"
      "  zend_class_entry tmp_ce;\n"
      "\n"
      "  INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n"
      "                   $c_name$_phpmethods);\n"
      "\n"
      "  $c_name$_ce = zend_register_internal_class(&tmp_ce);\n",
      "name", desc->full_name(),
      "file_c_name", FilenameCName(desc->file()),
      "c_name", c_name,
      "php_name", php_name);

  for (int i = 0; i < desc->value_count(); i++) {
    const EnumValueDescriptor* value = desc->value(i);
    printer->Print(
        "  zend_declare_class_constant_long($c_name$_ce, \"$name$\",\n"
        "                                   strlen(\"$name$\"), $num$);\n",
        "c_name", c_name,
        "name", value->name(),
        "num", std::to_string(value->number()));
  }

  printer->Print(
      "}\n"
      "\n");
}

void GenerateCMessage(const Descriptor* message, io::Printer* printer) {
  std::string c_name = message->full_name();
  c_name = StringReplace(c_name, ".", "_", true);
  std::string php_name = FullClassName(message, Options());
  php_name = StringReplace(php_name, "\\", "\\\\", true);
  printer->Print(
      "/* $c_name$ */\n"
      "\n"
      "zend_class_entry* $c_name$_ce;\n"
      "\n"
      "static PHP_METHOD($c_name$, __construct) {\n"
      "  $file_c_name$_AddDescriptor();\n"
      "  zim_Message___construct(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n"
      "}\n"
      "\n",
      "file_c_name", FilenameCName(message->file()),
      "c_name", c_name);

  for (int i = 0; i < message->field_count(); i++) {
    auto field = message->field(i);
    printer->Print(
      "static PHP_METHOD($c_name$, get$camel_name$) {\n"
      "  Message* intern = (Message*)Z_OBJ_P(getThis());\n"
      "  const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n"
      "                                           \"$name$\");\n"
      "  zval ret;\n"
      "  Message_get(intern, f, &ret);\n"
      "  RETURN_COPY_VALUE(&ret);\n"
      "}\n"
      "\n"
      "static PHP_METHOD($c_name$, set$camel_name$) {\n"
      "  Message* intern = (Message*)Z_OBJ_P(getThis());\n"
      "  const upb_fielddef *f = upb_msgdef_ntofz(intern->desc->msgdef,\n"
      "                                           \"$name$\");\n"
      "  zval *val;\n"
      "  if (zend_parse_parameters(ZEND_NUM_ARGS(), \"z\", &val)\n"
      "      == FAILURE) {\n"
      "    return;\n"
      "  }\n"
      "  Message_set(intern, f, val);\n"
      "  RETURN_COPY(getThis());\n"
      "}\n"
      "\n",
      "c_name", c_name,
      "name", field->name(),
      "camel_name", UnderscoresToCamelCase(field->name(), true));
  }

  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
    auto oneof = message->oneof_decl(i);
    printer->Print(
      "static PHP_METHOD($c_name$, get$camel_name$) {\n"
      "  Message* intern = (Message*)Z_OBJ_P(getThis());\n"
      "  const upb_oneofdef *oneof = upb_msgdef_ntooz(intern->desc->msgdef,\n"
      "                                              \"$name$\");\n"
      "  const upb_fielddef *field = upb_msg_whichoneof(intern->msg, oneof);\n"
      "  RETURN_STRING(field ? upb_fielddef_name(field) : \"\");\n"
      "}\n",
      "c_name", c_name,
      "name", oneof->name(),
      "camel_name", UnderscoresToCamelCase(oneof->name(), true));
  }

  switch (message->well_known_type()) {
    case Descriptor::WELLKNOWNTYPE_ANY:
      printer->Print(
          "ZEND_BEGIN_ARG_INFO_EX(arginfo_is, 0, 0, 1)\n"
          "  ZEND_ARG_INFO(0, proto)\n"
          "ZEND_END_ARG_INFO()\n"
          "\n"
      );
      break;
    case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
      printer->Print(
          "ZEND_BEGIN_ARG_INFO_EX(arginfo_timestamp_fromdatetime, 0, 0, 1)\n"
          "  ZEND_ARG_INFO(0, datetime)\n"
          "ZEND_END_ARG_INFO()\n"
          "\n"
      );
      break;
    default:
      break;
  }

  printer->Print(
      "static zend_function_entry $c_name$_phpmethods[] = {\n"
      "  PHP_ME($c_name$, __construct, arginfo_construct, ZEND_ACC_PUBLIC)\n",
      "c_name", c_name);

  for (int i = 0; i < message->field_count(); i++) {
    auto field = message->field(i);
    printer->Print(
      "  PHP_ME($c_name$, get$camel_name$, arginfo_void, ZEND_ACC_PUBLIC)\n"
      "  PHP_ME($c_name$, set$camel_name$, arginfo_setter, ZEND_ACC_PUBLIC)\n",
      "c_name", c_name,
      "camel_name", UnderscoresToCamelCase(field->name(), true));
  }

  for (int i = 0; i < message->real_oneof_decl_count(); i++) {
    auto oneof = message->oneof_decl(i);
    printer->Print(
      "  PHP_ME($c_name$, get$camel_name$, arginfo_void, ZEND_ACC_PUBLIC)\n",
      "c_name", c_name,
      "camel_name", UnderscoresToCamelCase(oneof->name(), true));
  }

  // Extra hand-written functions added to the well-known types.
  switch (message->well_known_type()) {
    case Descriptor::WELLKNOWNTYPE_ANY:
      printer->Print(
        "  PHP_ME($c_name$, is, arginfo_is, ZEND_ACC_PUBLIC)\n"
        "  PHP_ME($c_name$, pack, arginfo_setter, ZEND_ACC_PUBLIC)\n"
        "  PHP_ME($c_name$, unpack, arginfo_void, ZEND_ACC_PUBLIC)\n",
        "c_name", c_name);
      break;
    case Descriptor::WELLKNOWNTYPE_TIMESTAMP:
      printer->Print(
        "  PHP_ME($c_name$, fromDateTime, arginfo_timestamp_fromdatetime, ZEND_ACC_PUBLIC)\n"
        "  PHP_ME($c_name$, toDateTime, arginfo_void, ZEND_ACC_PUBLIC)\n",
        "c_name", c_name);
      break;
    default:
      break;
  } 

  printer->Print(
      "  ZEND_FE_END\n"
      "};\n"
      "\n"
      "static void $c_name$_ModuleInit() {\n"
      "  zend_class_entry tmp_ce;\n"
      "\n"
      "  INIT_CLASS_ENTRY(tmp_ce, \"$php_name$\",\n"
      "                   $c_name$_phpmethods);\n"
      "\n"
      "  $c_name$_ce = zend_register_internal_class(&tmp_ce);\n"
      "  $c_name$_ce->ce_flags |= ZEND_ACC_FINAL;\n"
      "  $c_name$_ce->create_object = Message_create;\n"
      "  zend_do_inheritance($c_name$_ce, message_ce);\n"
      "}\n"
      "\n",
      "c_name", c_name,
      "php_name", php_name);

  for (int i = 0; i < message->nested_type_count(); i++) {
    GenerateCMessage(message->nested_type(i), printer);
  }
  for (int i = 0; i < message->enum_type_count(); i++) {
    GenerateCEnum(message->enum_type(i), printer);
  }
}

void GenerateEnumCInit(const EnumDescriptor* desc, io::Printer* printer) {
  std::string c_name = desc->full_name();
  c_name = StringReplace(c_name, ".", "_", true);

  printer->Print(
      "  $c_name$_ModuleInit();\n",
      "c_name", c_name);
}

void GenerateCInit(const Descriptor* message, io::Printer* printer) {
  std::string c_name = message->full_name();
  c_name = StringReplace(c_name, ".", "_", true);

  printer->Print(
      "  $c_name$_ModuleInit();\n",
      "c_name", c_name);

  for (int i = 0; i < message->nested_type_count(); i++) {
    GenerateCInit(message->nested_type(i), printer);
  }
  for (int i = 0; i < message->enum_type_count(); i++) {
    GenerateEnumCInit(message->enum_type(i), printer);
  }
}

void GenerateCWellKnownTypes(const std::vector<const FileDescriptor*>& files,
                             GeneratorContext* context) {
  std::unique_ptr<io::ZeroCopyOutputStream> output(
      context->Open("../ext/google/protobuf/wkt.inc"));
  io::Printer printer(output.get(), '$');

  printer.Print(
      "// This file is generated from the .proto files for the well-known\n"
      "// types. Do not edit!\n\n");

  printer.Print(
      "ZEND_BEGIN_ARG_INFO_EX(arginfo_lookup, 0, 0, 1)\n"
      "  ZEND_ARG_INFO(0, key)\n"
      "ZEND_END_ARG_INFO()\n"
      "\n"
  );

  for (auto file : files) {
    printer.Print(
        "static void $c_name$_AddDescriptor();\n",
        "c_name", FilenameCName(file));
  }

  for (auto file : files) {
    std::string c_name = FilenameCName(file);
    std::string metadata_filename = GeneratedMetadataFileName(file, Options());
    std::string metadata_classname = FilenameToClassname(metadata_filename);
    std::string metadata_c_name =
        StringReplace(metadata_classname, "\\", "_", true);
    metadata_classname = StringReplace(metadata_classname, "\\", "\\\\", true);
    FileDescriptorProto file_proto;
    file->CopyTo(&file_proto);
    std::string serialized;
    file_proto.SerializeToString(&serialized);
    printer.Print(
        "/* $filename$ */\n"
        "\n"
        "zend_class_entry* $metadata_c_name$_ce;\n"
        "\n"
        "const char $c_name$_descriptor [$size$] = {\n",
        "filename", file->name(),
        "c_name", c_name,
        "metadata_c_name", metadata_c_name,
        "size", std::to_string(serialized.size()));

    for (size_t i = 0; i < serialized.size();) {
      for (size_t j = 0; j < 25 && i < serialized.size(); ++i, ++j) {
        printer.Print("'$ch$', ", "ch", CEscape(serialized.substr(i, 1)));
      }
      printer.Print("\n");
    }

    printer.Print(
        "};\n"
        "\n"
        "static void $c_name$_AddDescriptor() {\n"
        "  if (DescriptorPool_HasFile(\"$filename$\")) return;\n",
        "filename", file->name(),
        "c_name", c_name,
        "metadata_c_name", metadata_c_name);

    for (int i = 0; i < file->dependency_count(); i++) {
      std::string dep_c_name = FilenameCName(file->dependency(i));
      printer.Print(
          "  $dep_c_name$_AddDescriptor();\n",
          "dep_c_name", dep_c_name);
    }

    printer.Print(
        "  DescriptorPool_AddDescriptor(\"$filename$\", $c_name$_descriptor,\n"
        "                               sizeof($c_name$_descriptor));\n"
        "}\n"
        "\n"
        "static PHP_METHOD($metadata_c_name$, initOnce) {\n"
        "  $c_name$_AddDescriptor();\n"
        "}\n"
        "\n"
        "static zend_function_entry $metadata_c_name$_methods[] = {\n"
        "  PHP_ME($metadata_c_name$, initOnce, arginfo_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)\n"
        "  ZEND_FE_END\n"
        "};\n"
        "\n"
        "static void $metadata_c_name$_ModuleInit() {\n"
        "  zend_class_entry tmp_ce;\n"
        "\n"
        "  INIT_CLASS_ENTRY(tmp_ce, \"$metadata_classname$\",\n"
        "                   $metadata_c_name$_methods);\n"
        "\n"
        "  $metadata_c_name$_ce = zend_register_internal_class(&tmp_ce);\n"
        "}\n"
        "\n",
        "filename", file->name(),
        "c_name", c_name,
        "metadata_c_name", metadata_c_name,
        "metadata_classname", metadata_classname);
    for (int i = 0; i < file->message_type_count(); i++) {
      GenerateCMessage(file->message_type(i), &printer);
    }
    for (int i = 0; i < file->enum_type_count(); i++) {
      GenerateCEnum(file->enum_type(i), &printer);
    }
  }

  printer.Print(
      "static void WellKnownTypes_ModuleInit() {\n");

  for (auto file : files) {
    std::string metadata_filename = GeneratedMetadataFileName(file, Options());
    std::string metadata_classname = FilenameToClassname(metadata_filename);
    std::string metadata_c_name =
        StringReplace(metadata_classname, "\\", "_", true);
    printer.Print(
        "  $metadata_c_name$_ModuleInit();\n",
        "metadata_c_name", metadata_c_name);
    for (int i = 0; i < file->message_type_count(); i++) {
      GenerateCInit(file->message_type(i), &printer);
    }
    for (int i = 0; i < file->enum_type_count(); i++) {
      GenerateEnumCInit(file->enum_type(i), &printer);
    }
  }

  printer.Print(
      "}\n");
}

}  // namespace

std::string GeneratedClassName(const Descriptor* desc) {
  return GeneratedClassNameImpl(desc);
}

std::string GeneratedClassName(const EnumDescriptor* desc) {
  return GeneratedClassNameImpl(desc);
}

std::string GeneratedClassName(const ServiceDescriptor* desc) {
  return GeneratedClassNameImpl(desc);
}

bool Generator::Generate(const FileDescriptor* file,
                         const std::string& parameter,
                         GeneratorContext* generator_context,
                         std::string* error) const {
  return Generate(file, Options(), generator_context, error);
}

bool Generator::Generate(const FileDescriptor* file, const Options& options,
                         GeneratorContext* generator_context,
                         std::string* error) const {
  if (options.is_descriptor && file->name() != kDescriptorFile) {
    *error =
        "Can only generate PHP code for google/protobuf/descriptor.proto.\n";
    return false;
  }

  if (!options.is_descriptor && file->syntax() != FileDescriptor::SYNTAX_PROTO3) {
    *error =
        "Can only generate PHP code for proto3 .proto files.\n"
        "Please add 'syntax = \"proto3\";' to the top of your .proto file.\n";
    return false;
  }

  GenerateFile(file, options, generator_context);

  return true;
}

bool Generator::GenerateAll(const std::vector<const FileDescriptor*>& files,
                            const std::string& parameter,
                            GeneratorContext* generator_context,
                            std::string* error) const {
  Options options;

  for (const auto& option : Split(parameter, ",", true)) {
    const std::vector<std::string> option_pair = Split(option, "=", true);
    if (HasPrefixString(option_pair[0], "aggregate_metadata")) {
      options.aggregate_metadata = true;
      for (const auto& prefix : Split(option_pair[1], "#", false)) {
        options.aggregate_metadata_prefixes.emplace(prefix);
        GOOGLE_LOG(INFO) << prefix;
      }
    } else if (option_pair[0] == "internal") {
      options.is_descriptor = true;
    } else if (option_pair[0] == "internal_generate_c_wkt") {
      GenerateCWellKnownTypes(files, generator_context);
    } else {
      GOOGLE_LOG(FATAL) << "Unknown codegen option: " << option_pair[0];
    }
  }

  for (auto file : files) {
    if (!Generate(file, options, generator_context, error)) {
      return false;
    }
  }

  return true;
}

}  // namespace php
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
