// 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",
    "parent",       "print",      "private",      "protected",  "public",
    "readonly",     "require",    "require_once", "return",     "self",
    "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", "parent",
    "self", "readonly"
};
const int kReservedNamesSize = 80;
const int kValidConstantNamesSize = 12;
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<std::string> aggregate_metadata_prefixes;
};

namespace {

// Forward decls.
std::string PhpName(const std::string& full_name, const Options& options);
std::string IntToString(int32_t 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";
}

template <typename DescriptorType>
std::string LegacyReadOnlyGeneratedClassFileName(std::string php_namespace,
                                                 const DescriptorType* desc) {
  if (!php_namespace.empty()) {
    for (int i = 0; i < php_namespace.size(); i++) {
      if (php_namespace[i] == '\\') {
        php_namespace[i] = '/';
      }
    }
    return php_namespace + "/" + desc->name() + ".php";
  }

  return desc->name() + ".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_t 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, ">|array<");
    }
    type = "array<" + 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->map_key();
    const FieldDescriptor* value = map_entry->map_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()->map_key();
      const FieldDescriptor* val =
          field->message_type()->map_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);
}

template <typename DescriptorType>
void LegacyReadOnlyGenerateClassFile(const FileDescriptor* file,
                             const DescriptorType* desc, const Options& options,
                             GeneratorContext* generator_context) {
  std::string fullname = FullClassName(desc, options);
  std::string php_namespace;
  std::string classname;
  int lastindex = fullname.find_last_of("\\");

  if (lastindex != std::string::npos) {
    php_namespace = fullname.substr(0, lastindex);
    classname = fullname.substr(lastindex + 1);
  } else {
    php_namespace = "";
    classname = fullname;
  }

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

  GenerateHead(file, &printer);

  if (!php_namespace.empty()) {
    printer.Print(
        "namespace ^name^;\n\n",
        "name", php_namespace);
  }

  printer.Print("class_exists(^new^::class); // autoload the new class, which "
      "will also create an alias to the deprecated class\n",
      "new", classname);
  printer.Print("@trigger_error(__NAMESPACE__ . '\\^old^ is deprecated and will be removed in "
      "the next major release. Use ^fullname^ instead', E_USER_DEPRECATED);\n\n",
      "old", desc->name(),
      "fullname", classname);
}

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);

  bool hasReserved = false;
  for (int i = 0; i < en->value_count(); i++) {
    const EnumValueDescriptor* value = en->value(i);
    GenerateEnumValueDocComment(&printer, value);

    std::string prefix = ConstantNamePrefix(value->name());
    if (!prefix.empty()) {
      hasReserved = true;
    }

    printer.Print("const ^name^ = ^number^;\n",
                  "name", prefix + 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::^constant^ => '^name^',\n",
                  "constant", ConstantNamePrefix(value->name()) + value->name(),
                  "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);
  if (hasReserved) {
    printer.Print("$pbconst =  __CLASS__. '::PB' . strtoupper($name);\n"
                "if (!defined($pbconst)) {\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);
  if (hasReserved) {
    Outdent(&printer);
    printer.Print("}\n"
                  "return constant($pbconst);\n");
  }
  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);
  }

  // Write legacy file for backwards compatibility with "readonly" keywword
  std::string lower = en->name();
  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
  if (lower == "readonly") {
    printer.Print(
        "// Adding a class alias for backwards compatibility with the \"readonly\" keyword.\n");
    printer.Print(
        "class_alias(^new^::class, __NAMESPACE__ . '\\^old^');\n\n",
        "new", fullname,
        "old", en->name());
    LegacyReadOnlyGenerateClassFile(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);
  }

  // Write legacy file for backwards compatibility with "readonly" keywword
  std::string lower = message->name();
  std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
  if (lower == "readonly") {
    printer.Print(
        "// Adding a class alias for backwards compatibility with the \"readonly\" keyword.\n");
    printer.Print(
        "class_alias(^new^::class, __NAMESPACE__ . '\\^old^');\n\n",
        "new", fullname,
        "old", message->name());
    LegacyReadOnlyGenerateClassFile(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_DefPool *symtab = DescriptorPool_GetSymbolTable();\n"
      "  const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n"
      "  zend_long value;\n"
      "  if (zend_parse_parameters(ZEND_NUM_ARGS(), \"l\", &value) ==\n"
      "      FAILURE) {\n"
      "    return;\n"
      "  }\n"
      "  const upb_EnumValueDef* ev =\n"
      "      upb_EnumDef_FindValueByNumber(e, value);\n"
      "  if (!ev) {\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(upb_EnumValueDef_Name(ev));\n"
      "}\n"
      "\n"
      "PHP_METHOD($c_name$, value) {\n"
      "  $file_c_name$_AddDescriptor();\n"
      "  const upb_DefPool *symtab = DescriptorPool_GetSymbolTable();\n"
      "  const upb_EnumDef *e = upb_DefPool_FindEnumByName(symtab, \"$name$\");\n"
      "  char *name = NULL;\n"
      "  size_t name_len;\n"
      "  if (zend_parse_parameters(ZEND_NUM_ARGS(), \"s\", &name,\n"
      "                            &name_len) == FAILURE) {\n"
      "    return;\n"
      "  }\n"
      "  const upb_EnumValueDef* ev = upb_EnumDef_FindValueByNameWithSize(\n"
      "      e, name, name_len);\n"
      "  if (!ev) {\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(upb_EnumValueDef_Number(ev));\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_MessageDef_FindFieldByName(\n"
      "      intern->desc->msgdef, \"$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_MessageDef_FindFieldByName(\n"
      "      intern->desc->msgdef, \"$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_MessageDef_FindOneofByName(\n"
      "      intern->desc->msgdef, \"$name$\");\n"
      "  const upb_FieldDef *field = \n"
      "      upb_Message_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
