/*
 * Copyright 2014 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// independent from idl_parser, since this code is not needed for most clients

#include "idl_gen_php.h"

#include <string>

#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"

namespace flatbuffers {
namespace php {
// Hardcode spaces per indentation.
const std::string Indent = "    ";
class PhpGenerator : public BaseGenerator {
 public:
  PhpGenerator(const Parser& parser, const std::string& path,
               const std::string& file_name)
      : BaseGenerator(parser, path, file_name, "\\", "\\", "php") {}
  bool generate() {
    if (!GenerateEnums()) return false;
    if (!GenerateStructs()) return false;
    return true;
  }

 private:
  bool GenerateEnums() {
    for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
         ++it) {
      auto& enum_def = **it;
      std::string enumcode;
      GenEnum(enum_def, &enumcode);
      if (!SaveType(enum_def, enumcode, false)) return false;
    }
    return true;
  }

  bool GenerateStructs() {
    for (auto it = parser_.structs_.vec.begin();
         it != parser_.structs_.vec.end(); ++it) {
      auto& struct_def = **it;
      std::string declcode;
      GenStruct(struct_def, &declcode);
      if (!SaveType(struct_def, declcode, true)) return false;
    }
    return true;
  }

  // Begin by declaring namespace and imports.
  void BeginFile(const std::string& name_space_name, const bool needs_imports,
                 std::string* code_ptr) {
    auto& code = *code_ptr;
    code += "<?php\n";
    code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";

    if (!name_space_name.empty()) {
      code += "namespace " + name_space_name + ";\n\n";
    }

    if (needs_imports) {
      code += "use \\Google\\FlatBuffers\\Struct;\n";
      code += "use \\Google\\FlatBuffers\\Table;\n";
      code += "use \\Google\\FlatBuffers\\ByteBuffer;\n";
      code += "use \\Google\\FlatBuffers\\FlatBufferBuilder;\n";
      code += "\n";
    }
  }

  // Save out the generated code for a Php Table type.
  bool SaveType(const Definition& def, const std::string& classcode,
                bool needs_imports) {
    if (!classcode.length()) return true;

    std::string code = "";
    BeginFile(FullNamespace("\\", *def.defined_namespace), needs_imports,
              &code);
    code += classcode;

    std::string filename =
        NamespaceDir(*def.defined_namespace) + def.name + ".php";
    return parser_.opts.file_saver->SaveFile(filename.c_str(), code, false);
  }

  // Begin a class declaration.
  static void BeginClass(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;
    if (struct_def.fixed) {
      code += "class " + struct_def.name + " extends Struct\n";
    } else {
      code += "class " + struct_def.name + " extends Table\n";
    }
    code += "{\n";
  }

  static void EndClass(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "}\n";
  }

  // Begin enum code with a class declaration.
  static void BeginEnum(const std::string& class_name, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "class " + class_name + "\n{\n";
  }

  // A single enum member.
  static void EnumMember(const EnumDef& enum_def, const EnumVal& ev,
                         std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += Indent + "const ";
    code += ev.name;
    code += " = ";
    code += enum_def.ToString(ev) + ";\n";
  }

  // End enum code.
  static void EndEnum(std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "}\n";
  }

  // Initialize a new struct or table from existing data.
  static void NewRootTypeFromBuffer(const StructDef& struct_def,
                                    std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @param ByteBuffer $bb\n";
    code += Indent + " * @return " + struct_def.name + "\n";
    code += Indent + " */\n";
    code += Indent + "public static function getRootAs";
    code += struct_def.name;
    code += "(ByteBuffer $bb)\n";
    code += Indent + "{\n";

    code += Indent + Indent + "$obj = new " + struct_def.name + "();\n";
    code += Indent + Indent;
    code += "return ($obj->init($bb->getInt($bb->getPosition())";
    code += " + $bb->getPosition(), $bb));\n";
    code += Indent + "}\n\n";
  }

  // Initialize an existing object with other data, to avoid an allocation.
  static void InitializeExisting(const StructDef& struct_def,
                                 std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @param int $_i offset\n";
    code += Indent + " * @param ByteBuffer $_bb\n";
    code += Indent + " * @return " + struct_def.name + "\n";
    code += Indent + " **/\n";
    code += Indent + "public function init($_i, ByteBuffer $_bb)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$this->bb_pos = $_i;\n";
    code += Indent + Indent + "$this->bb = $_bb;\n";
    code += Indent + Indent + "return $this;\n";
    code += Indent + "}\n\n";
  }

  // Get the length of a vector.
  static void GetVectorLen(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @return int\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel) + "Length()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(";
    code += NumToString(field.value.offset) + ");\n";
    code += Indent + Indent;
    code += "return $o != 0 ? $this->__vector_len($o) : 0;\n";
    code += Indent + "}\n\n";
  }

  // Get a [ubyte] vector as a byte array.
  static void GetUByte(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @return string\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel) + "Bytes()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "return $this->__vector_as_bytes(";
    code += NumToString(field.value.offset) + ");\n";
    code += Indent + "}\n\n";
  }

  // Get the value of a struct's scalar.
  static void GetScalarFieldOfStruct(const FieldDef& field,
                                     std::string* code_ptr) {
    std::string& code = *code_ptr;
    std::string getter = GenGetter(field.value.type);

    code += Indent + "/**\n";
    code += Indent + " * @return ";
    code += GenTypeGet(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function " + getter;
    code += ConvertCase(field.name, Case::kUpperCamel) + "()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "return ";

    code += "$this->bb->get";
    code += ConvertCase(GenTypeGet(field.value.type), Case::kUpperCamel);
    code += "($this->bb_pos + ";
    code += NumToString(field.value.offset) + ")";
    code += ";\n";

    code += Indent + "}\n\n";
  }

  // Get the value of a table's scalar.
  void GetScalarFieldOfTable(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n" + Indent + Indent +
            "return $o != 0 ? ";
    code += "$this->bb->get";
    code += ConvertCase(GenTypeGet(field.value.type), Case::kUpperCamel) +
            "($o + $this->bb_pos)";
    code += " : " + GenDefaultValue(field.value) + ";\n";
    code += Indent + "}\n\n";
  }

  // Get a struct by initializing an existing struct.
  // Specific to Struct.
  void GetStructFieldOfStruct(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel) + "()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$obj = new ";
    code += GenTypeGet(field.value.type) + "();\n";
    code += Indent + Indent + "$obj->init($this->bb_pos + ";
    code += NumToString(field.value.offset) + ", $this->bb);";
    code += "\n" + Indent + Indent + "return $obj;\n";
    code += Indent + "}\n\n";
  }

  // Get a struct by initializing an existing struct.
  // Specific to Table.
  void GetStructFieldOfTable(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$obj = new ";
    code +=
        ConvertCase(GenTypeGet(field.value.type), Case::kUpperCamel) + "();\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n";
    code += Indent + Indent;
    code += "return $o != 0 ? $obj->init(";
    if (field.value.type.struct_def->fixed) {
      code += "$o + $this->bb_pos, $this->bb) : ";
    } else {
      code += "$this->__indirect($o + $this->bb_pos), $this->bb) : ";
    }
    code += GenDefaultValue(field.value) + ";\n";
    code += Indent + "}\n\n";
  }

  // Get the value of a string.
  void GetStringField(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "()\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n";
    code += Indent + Indent;
    code += "return $o != 0 ? $this->__string($o + $this->bb_pos) : ";
    code += GenDefaultValue(field.value) + ";\n";
    code += Indent + "}\n\n";
  }

  // Get the value of a union from an object.
  void GetUnionField(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel) + "($obj)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n";
    code += Indent + Indent;
    code += "return $o != 0 ? $this->__union($obj, $o) : null;\n";
    code += Indent + "}\n\n";
  }

  // Get the value of a vector's struct member.
  void GetMemberOfVectorOfStruct(const StructDef& struct_def,
                                 const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    code += Indent + "/**\n";
    code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "($j)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n";
    code += Indent + Indent + "$obj = new ";
    code +=
        ConvertCase(GenTypeGet(field.value.type), Case::kUpperCamel) + "();\n";

    switch (field.value.type.base_type) {
      case BASE_TYPE_STRUCT:
        if (struct_def.fixed) {
          code += Indent + Indent;
          code += "return $o != 0 ? $obj->init($this->bb_pos +" +
                  NumToString(field.value.offset) + ", $this->bb) : null;\n";
        } else {
          code += Indent + Indent + "return $o != 0 ? $obj->init(";
          code += field.value.type.struct_def->fixed
                      ? "$o + $this->bb_pos"
                      : "$this->__indirect($o + $this->bb_pos)";
          code += ", $this->bb) : null;\n";
        }
        break;
      case BASE_TYPE_STRING:
        code += "// base_type_string\n";
        // TODO(chobie): do we need this?
        break;
      case BASE_TYPE_VECTOR:
        if (vectortype.base_type == BASE_TYPE_STRUCT) {
          code += Indent + Indent + "return $o != 0 ? $obj->init(";
          if (vectortype.struct_def->fixed) {
            code += "$this->__vector($o) + $j *";
            code += NumToString(InlineSize(vectortype));
          } else {
            code += "$this->__indirect($this->__vector($o) + $j * ";
            code += NumToString(InlineSize(vectortype)) + ")";
          }
          code += ", $this->bb) : null;\n";
        }
        break;
      case BASE_TYPE_UNION:
        code += Indent + Indent + "return $o != 0 ? $this->";
        code += GenGetter(field.value.type) + "($obj, $o); null;\n";
        break;
      default:
        break;
    }

    code += Indent + "}\n\n";
  }

  // Get the value of a vector's non-struct member. Uses a named return
  // argument to conveniently set the zero value for the result.
  void GetMemberOfVectorOfNonStruct(const FieldDef& field,
                                    std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    code += Indent + "/**\n";
    code += Indent + " * @param int offset\n";
    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "($j)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n";

    if (IsString(field.value.type.VectorType())) {
      code += Indent + Indent;
      code += "return $o != 0 ? $this->__string($this->__vector($o) + $j * ";
      code += NumToString(InlineSize(vectortype)) + ") : ";
      code += GenDefaultValue(field.value) + ";\n";
    } else {
      code += Indent + Indent + "return $o != 0 ? $this->bb->get";
      code += ConvertCase(GenTypeGet(field.value.type), Case::kUpperCamel);
      code += "($this->__vector($o) + $j * ";
      code += NumToString(InlineSize(vectortype)) + ") : ";
      code += GenDefaultValue(field.value) + ";\n";
    }
    code += Indent + "}\n\n";
  }

  // Get the value of a vector's union member. Uses a named return
  // argument to conveniently set the zero value for the result.
  void GetMemberOfVectorOfUnion(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;
    auto vectortype = field.value.type.VectorType();

    code += Indent + "/**\n";
    code += Indent + " * @param int offset\n";
    code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
    code += Indent + " */\n";
    code += Indent + "public function get";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "($j, $obj)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $this->__offset(" +
            NumToString(field.value.offset) + ");\n";
    code += Indent + Indent + "return $o != 0 ? ";
    code += "$this->__union($obj, $this->__vector($o) + $j * ";
    code += NumToString(InlineSize(vectortype)) + " - $this->bb_pos) : null;\n";
    code += Indent + "}\n\n";
  }

  // Recursively generate arguments for a constructor, to deal with nested
  // structs.
  static void StructBuilderArgs(const StructDef& struct_def,
                                const char* nameprefix, std::string* code_ptr) {
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (IsStruct(field.value.type)) {
        // Generate arguments for a struct inside a struct. To ensure names
        // don't clash, and to make it obvious
        // these arguments are constructing
        // a nested struct, prefix the name with the field name.
        StructBuilderArgs(*field.value.type.struct_def,
                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
      } else {
        std::string& code = *code_ptr;
        code += std::string(", $") + nameprefix;
        code += ConvertCase(field.name, Case::kLowerCamel);
      }
    }
  }

  // Recursively generate struct construction statements and instert manual
  // padding.
  static void StructBuilderBody(const StructDef& struct_def,
                                const char* nameprefix, std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += Indent + Indent + "$builder->prep(";
    code += NumToString(struct_def.minalign) + ", ";
    code += NumToString(struct_def.bytesize) + ");\n";
    for (auto it = struct_def.fields.vec.rbegin();
         it != struct_def.fields.vec.rend(); ++it) {
      auto& field = **it;
      if (field.padding) {
        code += Indent + Indent + "$builder->pad(";
        code += NumToString(field.padding) + ");\n";
      }
      if (IsStruct(field.value.type)) {
        StructBuilderBody(*field.value.type.struct_def,
                          (nameprefix + (field.name + "_")).c_str(), code_ptr);
      } else {
        code += Indent + Indent + "$builder->put" + GenMethod(field) + "($";
        code +=
            nameprefix + ConvertCase(field.name, Case::kLowerCamel) + ");\n";
      }
    }
  }

  // Get the value of a table's starting offset.
  static void GetStartOfTable(const StructDef& struct_def,
                              std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @param FlatBufferBuilder $builder\n";
    code += Indent + " * @return void\n";
    code += Indent + " */\n";
    code += Indent + "public static function start" + struct_def.name;
    code += "(FlatBufferBuilder $builder)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$builder->StartObject(";
    code += NumToString(struct_def.fields.vec.size());
    code += ");\n";
    code += Indent + "}\n\n";

    code += Indent + "/**\n";
    code += Indent + " * @param FlatBufferBuilder $builder\n";
    code += Indent + " * @return " + struct_def.name + "\n";
    code += Indent + " */\n";
    code += Indent + "public static function create" + struct_def.name;
    code += "(FlatBufferBuilder $builder, ";

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;

      if (field.deprecated) continue;
      if (it != struct_def.fields.vec.begin()) {
        code += ", ";
      }
      code += "$" + field.name;
    }
    code += ")\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$builder->startObject(";
    code += NumToString(struct_def.fields.vec.size());
    code += ");\n";
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      code += Indent + Indent + "self::add";
      code += ConvertCase(field.name, Case::kUpperCamel) + "($builder, $" +
              field.name + ");\n";
    }

    code += Indent + Indent + "$o = $builder->endObject();\n";

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (!field.deprecated && field.IsRequired()) {
        code += Indent + Indent + "$builder->required($o, ";
        code += NumToString(field.value.offset);
        code += ");  // " + field.name + "\n";
      }
    }
    code += Indent + Indent + "return $o;\n";
    code += Indent + "}\n\n";
  }

  // Set the value of a table's field.
  static void BuildFieldOfTable(const FieldDef& field, const size_t offset,
                                std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @param FlatBufferBuilder $builder\n";
    code += Indent + " * @param " + GenTypeBasic(field.value.type) + "\n";
    code += Indent + " * @return void\n";
    code += Indent + " */\n";
    code += Indent + "public static function ";
    code += "add" + ConvertCase(field.name, Case::kUpperCamel);
    code += "(FlatBufferBuilder $builder, ";
    code += "$" + ConvertCase(field.name, Case::kLowerCamel);
    code += ")\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$builder->add";
    code += GenMethod(field) + "X(";
    code += NumToString(offset) + ", ";

    code += "$" + ConvertCase(field.name, Case::kLowerCamel);
    code += ", ";

    if (field.value.type.base_type == BASE_TYPE_BOOL) {
      code += "false";
    } else {
      code += field.value.constant;
    }
    code += ");\n";
    code += Indent + "}\n\n";
  }

  // Set the value of one of the members of a table's vector.
  static void BuildVectorOfTable(const FieldDef& field, std::string* code_ptr) {
    std::string& code = *code_ptr;

    auto vector_type = field.value.type.VectorType();
    auto alignment = InlineAlignment(vector_type);
    auto elem_size = InlineSize(vector_type);
    code += Indent + "/**\n";
    code += Indent + " * @param FlatBufferBuilder $builder\n";
    code += Indent + " * @param array offset array\n";
    code += Indent + " * @return int vector offset\n";
    code += Indent + " */\n";
    code += Indent + "public static function create";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "Vector(FlatBufferBuilder $builder, array $data)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$builder->startVector(";
    code += NumToString(elem_size);
    code += ", count($data), " + NumToString(alignment);
    code += ");\n";
    code += Indent + Indent;
    code += "for ($i = count($data) - 1; $i >= 0; $i--) {\n";
    if (IsScalar(field.value.type.VectorType().base_type)) {
      code += Indent + Indent + Indent;
      code += "$builder->put";
      code += ConvertCase(GenTypeBasic(field.value.type.VectorType()),
                          Case::kUpperCamel);
      code += "($data[$i]);\n";
    } else {
      code += Indent + Indent + Indent;
      code += "$builder->putOffset($data[$i]);\n";
    }
    code += Indent + Indent + "}\n";
    code += Indent + Indent + "return $builder->endVector();\n";
    code += Indent + "}\n\n";

    code += Indent + "/**\n";
    code += Indent + " * @param FlatBufferBuilder $builder\n";
    code += Indent + " * @param int $numElems\n";
    code += Indent + " * @return void\n";
    code += Indent + " */\n";
    code += Indent + "public static function start";
    code += ConvertCase(field.name, Case::kUpperCamel);
    code += "Vector(FlatBufferBuilder $builder, $numElems)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$builder->startVector(";
    code += NumToString(elem_size);
    code += ", $numElems, " + NumToString(alignment);
    code += ");\n";
    code += Indent + "}\n\n";
  }

  // Get the offset of the end of a table.
  void GetEndOffsetOnTable(const StructDef& struct_def, std::string* code_ptr) {
    std::string& code = *code_ptr;

    code += Indent + "/**\n";
    code += Indent + " * @param FlatBufferBuilder $builder\n";
    code += Indent + " * @return int table offset\n";
    code += Indent + " */\n";
    code += Indent + "public static function end" + struct_def.name;
    code += "(FlatBufferBuilder $builder)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "$o = $builder->endObject();\n";

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (!field.deprecated && field.IsRequired()) {
        code += Indent + Indent + "$builder->required($o, ";
        code += NumToString(field.value.offset);
        code += ");  // " + field.name + "\n";
      }
    }
    code += Indent + Indent + "return $o;\n";
    code += Indent + "}\n";

    if (parser_.root_struct_def_ == &struct_def) {
      code += "\n";
      code += Indent + "public static function finish";
      code += struct_def.name;
      code += "Buffer(FlatBufferBuilder $builder, $offset)\n";
      code += Indent + "{\n";
      code += Indent + Indent + "$builder->finish($offset";

      if (parser_.file_identifier_.length())
        code += ", \"" + parser_.file_identifier_ + "\"";
      code += ");\n";
      code += Indent + "}\n";
    }
  }

  // Generate a struct field, conditioned on its child type(s).
  void GenStructAccessor(const StructDef& struct_def, const FieldDef& field,
                         std::string* code_ptr) {
    GenComment(field.doc_comment, code_ptr, nullptr, Indent.c_str());

    if (IsScalar(field.value.type.base_type)) {
      if (struct_def.fixed) {
        GetScalarFieldOfStruct(field, code_ptr);
      } else {
        GetScalarFieldOfTable(field, code_ptr);
      }
    } else {
      switch (field.value.type.base_type) {
        case BASE_TYPE_STRUCT:
          if (struct_def.fixed) {
            GetStructFieldOfStruct(field, code_ptr);
          } else {
            GetStructFieldOfTable(field, code_ptr);
          }
          break;
        case BASE_TYPE_STRING:
          GetStringField(field, code_ptr);
          break;
        case BASE_TYPE_VECTOR: {
          auto vectortype = field.value.type.VectorType();
          if (vectortype.base_type == BASE_TYPE_UNION) {
            GetMemberOfVectorOfUnion(field, code_ptr);
          } else if (vectortype.base_type == BASE_TYPE_STRUCT) {
            GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
          } else {
            GetMemberOfVectorOfNonStruct(field, code_ptr);
          }
          break;
        }
        case BASE_TYPE_UNION:
          GetUnionField(field, code_ptr);
          break;
        default:
          FLATBUFFERS_ASSERT(0);
      }
    }
    if (IsVector(field.value.type)) {
      GetVectorLen(field, code_ptr);
      if (field.value.type.element == BASE_TYPE_UCHAR) {
        GetUByte(field, code_ptr);
      }
    }
  }

  // Generate table constructors, conditioned on its members' types.
  void GenTableBuilders(const StructDef& struct_def, std::string* code_ptr) {
    GetStartOfTable(struct_def, code_ptr);

    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      auto offset = it - struct_def.fields.vec.begin();
      if (field.value.type.base_type == BASE_TYPE_UNION) {
        std::string& code = *code_ptr;
        code += Indent + "public static function add";
        code += ConvertCase(field.name, Case::kUpperCamel);
        code += "(FlatBufferBuilder $builder, $offset)\n";
        code += Indent + "{\n";
        code += Indent + Indent + "$builder->addOffsetX(";
        code += NumToString(offset) + ", $offset, 0);\n";
        code += Indent + "}\n\n";
      } else {
        BuildFieldOfTable(field, offset, code_ptr);
      }
      if (IsVector(field.value.type)) {
        BuildVectorOfTable(field, code_ptr);
      }
    }

    GetEndOffsetOnTable(struct_def, code_ptr);
  }

  // Generate struct or table methods.
  void GenStruct(const StructDef& struct_def, std::string* code_ptr) {
    if (struct_def.generated) return;

    GenComment(struct_def.doc_comment, code_ptr, nullptr);
    BeginClass(struct_def, code_ptr);

    if (!struct_def.fixed) {
      // Generate a special accessor for the table that has been declared as
      // the root type.
      NewRootTypeFromBuffer(struct_def, code_ptr);
    }

    std::string& code = *code_ptr;
    if (!struct_def.fixed) {
      if (parser_.file_identifier_.length()) {
        // Return the identifier
        code += Indent + "public static function " + struct_def.name;
        code += "Identifier()\n";
        code += Indent + "{\n";
        code += Indent + Indent + "return \"";
        code += parser_.file_identifier_ + "\";\n";
        code += Indent + "}\n\n";

        // Check if a buffer has the identifier.
        code += Indent + "public static function " + struct_def.name;
        code += "BufferHasIdentifier(ByteBuffer $buf)\n";
        code += Indent + "{\n";
        code += Indent + Indent + "return self::";
        code += "__has_identifier($buf, self::";
        code += struct_def.name + "Identifier());\n";
        code += Indent + "}\n\n";
      }

      if (parser_.file_extension_.length()) {
        // Return the extension
        code += Indent + "public static function " + struct_def.name;
        code += "Extension()\n";
        code += Indent + "{\n";
        code += Indent + Indent + "return \"" + parser_.file_extension_;
        code += "\";\n";
        code += Indent + "}\n\n";
      }
    }

    // Generate the Init method that sets the field in a pre-existing
    // accessor object. This is to allow object reuse.
    InitializeExisting(struct_def, code_ptr);
    for (auto it = struct_def.fields.vec.begin();
         it != struct_def.fields.vec.end(); ++it) {
      auto& field = **it;
      if (field.deprecated) continue;

      GenStructAccessor(struct_def, field, code_ptr);
    }

    if (struct_def.fixed) {
      // create a struct constructor function
      GenStructBuilder(struct_def, code_ptr);
    } else {
      // Create a set of functions that allow table construction.
      GenTableBuilders(struct_def, code_ptr);
    }
    EndClass(code_ptr);
  }

  // Generate enum declarations.
  static void GenEnum(const EnumDef& enum_def, std::string* code_ptr) {
    if (enum_def.generated) return;

    GenComment(enum_def.doc_comment, code_ptr, nullptr);
    BeginEnum(enum_def.name, code_ptr);
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      auto& ev = **it;
      GenComment(ev.doc_comment, code_ptr, nullptr, Indent.c_str());
      EnumMember(enum_def, ev, code_ptr);
    }

    std::string& code = *code_ptr;
    code += "\n";
    code += Indent + "private static $names = array(\n";
    for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
      auto& ev = **it;
      code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
              ev.name + "\",\n";
    }

    code += Indent + ");\n\n";
    code += Indent + "public static function Name($e)\n";
    code += Indent + "{\n";
    code += Indent + Indent + "if (!isset(self::$names[$e])) {\n";
    code += Indent + Indent + Indent + "throw new \\Exception();\n";
    code += Indent + Indent + "}\n";
    code += Indent + Indent + "return self::$names[$e];\n";
    code += Indent + "}\n";
    EndEnum(code_ptr);
  }

  // Returns the function name that is able to read a value of the given type.
  static std::string GenGetter(const Type& type) {
    switch (type.base_type) {
      case BASE_TYPE_STRING:
        return "__string";
      case BASE_TYPE_STRUCT:
        return "__struct";
      case BASE_TYPE_UNION:
        return "__union";
      case BASE_TYPE_VECTOR:
        return GenGetter(type.VectorType());
      default:
        return "Get";
    }
  }

  // Returns the method name for use with add/put calls.
  static std::string GenMethod(const FieldDef& field) {
    return IsScalar(field.value.type.base_type)
               ? ConvertCase(GenTypeBasic(field.value.type), Case::kUpperCamel)
               : (IsStruct(field.value.type) ? "Struct" : "Offset");
  }

  static std::string GenTypeBasic(const Type& type) {
    // clang-format off
    static const char *ctypename[] = {
      #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
              CTYPE, JTYPE, GTYPE, NTYPE, ...) \
        #NTYPE,
        FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
      #undef FLATBUFFERS_TD
    };
    // clang-format on
    return ctypename[type.base_type];
  }

  std::string GenDefaultValue(const Value& value) {
    if (value.type.enum_def) {
      if (auto val = value.type.enum_def->FindByValue(value.constant)) {
        return WrapInNameSpace(*value.type.enum_def) + "::" + val->name;
      }
    }

    switch (value.type.base_type) {
      case BASE_TYPE_BOOL:
        return value.constant == "0" ? "false" : "true";

      case BASE_TYPE_STRING:
        return "null";

      case BASE_TYPE_LONG:
      case BASE_TYPE_ULONG:
        if (value.constant != "0") {
          int64_t constant = StringToInt(value.constant.c_str());
          return NumToString(constant);
        }
        return "0";

      default:
        return value.constant;
    }
  }

  static std::string GenTypePointer(const Type& type) {
    switch (type.base_type) {
      case BASE_TYPE_STRING:
        return "string";
      case BASE_TYPE_VECTOR:
        return GenTypeGet(type.VectorType());
      case BASE_TYPE_STRUCT:
        return type.struct_def->name;
      case BASE_TYPE_UNION:
        // fall through
      default:
        return "Table";
    }
  }

  static std::string GenTypeGet(const Type& type) {
    return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
  }

  // Create a struct with a builder and the struct's arguments.
  static void GenStructBuilder(const StructDef& struct_def,
                               std::string* code_ptr) {
    std::string& code = *code_ptr;
    code += "\n";
    code += Indent + "/**\n";
    code += Indent + " * @return int offset\n";
    code += Indent + " */\n";
    code += Indent + "public static function create" + struct_def.name;
    code += "(FlatBufferBuilder $builder";
    StructBuilderArgs(struct_def, "", code_ptr);
    code += ")\n";
    code += Indent + "{\n";

    StructBuilderBody(struct_def, "", code_ptr);

    code += Indent + Indent + "return $builder->offset();\n";
    code += Indent + "}\n";
  }
};
}  // namespace php

static bool GeneratePhp(const Parser& parser, const std::string& path,
                        const std::string& file_name) {
  php::PhpGenerator generator(parser, path, file_name);
  return generator.generate();
}

namespace {

class PhpCodeGenerator : public CodeGenerator {
 public:
  Status GenerateCode(const Parser& parser, const std::string& path,
                      const std::string& filename) override {
    if (!GeneratePhp(parser, path, filename)) {
      return Status::ERROR;
    }
    return Status::OK;
  }

  Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateMakeRule(const Parser& parser, const std::string& path,
                          const std::string& filename,
                          std::string& output) override {
    (void)parser;
    (void)path;
    (void)filename;
    (void)output;
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateGrpcCode(const Parser& parser, const std::string& path,
                          const std::string& filename) override {
    (void)parser;
    (void)path;
    (void)filename;
    return Status::NOT_IMPLEMENTED;
  }

  Status GenerateRootFile(const Parser& parser,
                          const std::string& path) override {
    (void)parser;
    (void)path;
    return Status::NOT_IMPLEMENTED;
  }

  bool IsSchemaOnly() const override { return true; }

  bool SupportsBfbsGeneration() const override { return false; }

  bool SupportsRootFileGeneration() const override { return false; }

  IDLOptions::Language Language() const override { return IDLOptions::kPhp; }

  std::string LanguageName() const override { return "Php"; }
};
}  // namespace

std::unique_ptr<CodeGenerator> NewPhpCodeGenerator() {
  return std::unique_ptr<PhpCodeGenerator>(new PhpCodeGenerator());
}

}  // namespace flatbuffers
