<?php
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: google/protobuf/descriptor.proto

namespace Google\Protobuf\Internal;

use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\GPBWire;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\InputStream;

use Google\Protobuf\Internal\GPBUtil;

/**
 * Protobuf type <code>google.protobuf.FileOptions</code>
 */
class FileOptions extends \Google\Protobuf\Internal\Message
{
    /**
     * <pre>
     * Sets the Java package where classes generated from this .proto will be
     * placed.  By default, the proto package is used, but this is often
     * inappropriate because proto packages do not normally start with backwards
     * domain names.
     * </pre>
     *
     * <code>optional string java_package = 1;</code>
     */
    private $java_package = '';
    private $has_java_package = false;
    /**
     * <pre>
     * If set, all the classes from the .proto file are wrapped in a single
     * outer class with the given name.  This applies to both Proto1
     * (equivalent to the old "--one_java_file" option) and Proto2 (where
     * a .proto always translates to a single class, but you may want to
     * explicitly choose the class name).
     * </pre>
     *
     * <code>optional string java_outer_classname = 8;</code>
     */
    private $java_outer_classname = '';
    private $has_java_outer_classname = false;
    /**
     * <pre>
     * If set true, then the Java code generator will generate a separate .java
     * file for each top-level message, enum, and service defined in the .proto
     * file.  Thus, these types will *not* be nested inside the outer class
     * named by java_outer_classname.  However, the outer class will still be
     * generated to contain the file's getDescriptor() method as well as any
     * top-level extensions defined in the file.
     * </pre>
     *
     * <code>optional bool java_multiple_files = 10 [default = false];</code>
     */
    private $java_multiple_files = false;
    private $has_java_multiple_files = false;
    /**
     * <pre>
     * This option does nothing.
     * </pre>
     *
     * <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
     */
    private $java_generate_equals_and_hash = false;
    private $has_java_generate_equals_and_hash = false;
    /**
     * <pre>
     * If set true, then the Java2 code generator will generate code that
     * throws an exception whenever an attempt is made to assign a non-UTF-8
     * byte sequence to a string field.
     * Message reflection will do the same.
     * However, an extension field still accepts non-UTF-8 byte sequences.
     * This option has no effect on when used with the lite runtime.
     * </pre>
     *
     * <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
     */
    private $java_string_check_utf8 = false;
    private $has_java_string_check_utf8 = false;
    /**
     * <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
     */
    private $optimize_for = 0;
    private $has_optimize_for = false;
    /**
     * <pre>
     * Sets the Go package where structs generated from this .proto will be
     * placed. If omitted, the Go package will be derived from the following:
     *   - The basename of the package import path, if provided.
     *   - Otherwise, the package statement in the .proto file, if present.
     *   - Otherwise, the basename of the .proto file, without extension.
     * </pre>
     *
     * <code>optional string go_package = 11;</code>
     */
    private $go_package = '';
    private $has_go_package = false;
    /**
     * <pre>
     * Should generic services be generated in each language?  "Generic" services
     * are not specific to any particular RPC system.  They are generated by the
     * main code generators in each language (without additional plugins).
     * Generic services were the only kind of service generation supported by
     * early versions of google.protobuf.
     * Generic services are now considered deprecated in favor of using plugins
     * that generate code specific to your particular RPC system.  Therefore,
     * these default to false.  Old code which depends on generic services should
     * explicitly set them to true.
     * </pre>
     *
     * <code>optional bool cc_generic_services = 16 [default = false];</code>
     */
    private $cc_generic_services = false;
    private $has_cc_generic_services = false;
    /**
     * <code>optional bool java_generic_services = 17 [default = false];</code>
     */
    private $java_generic_services = false;
    private $has_java_generic_services = false;
    /**
     * <code>optional bool py_generic_services = 18 [default = false];</code>
     */
    private $py_generic_services = false;
    private $has_py_generic_services = false;
    /**
     * <pre>
     * Is this file deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for everything in the file, or it will be completely ignored; in the very
     * least, this is a formalization for deprecating files.
     * </pre>
     *
     * <code>optional bool deprecated = 23 [default = false];</code>
     */
    private $deprecated = false;
    private $has_deprecated = false;
    /**
     * <pre>
     * Enables the use of arenas for the proto messages in this file. This applies
     * only to generated classes for C++.
     * </pre>
     *
     * <code>optional bool cc_enable_arenas = 31 [default = false];</code>
     */
    private $cc_enable_arenas = false;
    private $has_cc_enable_arenas = false;
    /**
     * <pre>
     * Sets the objective c class prefix which is prepended to all objective c
     * generated classes from this .proto. There is no default.
     * </pre>
     *
     * <code>optional string objc_class_prefix = 36;</code>
     */
    private $objc_class_prefix = '';
    private $has_objc_class_prefix = false;
    /**
     * <pre>
     * Namespace for generated classes; defaults to the package.
     * </pre>
     *
     * <code>optional string csharp_namespace = 37;</code>
     */
    private $csharp_namespace = '';
    private $has_csharp_namespace = false;
    /**
     * <pre>
     * By default Swift generators will take the proto package and CamelCase it
     * replacing '.' with underscore and use that to prefix the types/symbols
     * defined. When this options is provided, they will use this value instead
     * to prefix the types/symbols defined.
     * </pre>
     *
     * <code>optional string swift_prefix = 39;</code>
     */
    private $swift_prefix = '';
    private $has_swift_prefix = false;
    /**
     * <pre>
     * The parser stores options it doesn't recognize here. See above.
     * </pre>
     *
     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
     */
    private $uninterpreted_option;
    private $has_uninterpreted_option = false;

    public function __construct() {
        \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce();
        parent::__construct();
    }

    /**
     * <pre>
     * Sets the Java package where classes generated from this .proto will be
     * placed.  By default, the proto package is used, but this is often
     * inappropriate because proto packages do not normally start with backwards
     * domain names.
     * </pre>
     *
     * <code>optional string java_package = 1;</code>
     */
    public function getJavaPackage()
    {
        return $this->java_package;
    }

    /**
     * <pre>
     * Sets the Java package where classes generated from this .proto will be
     * placed.  By default, the proto package is used, but this is often
     * inappropriate because proto packages do not normally start with backwards
     * domain names.
     * </pre>
     *
     * <code>optional string java_package = 1;</code>
     */
    public function setJavaPackage($var)
    {
        GPBUtil::checkString($var, True);
        $this->java_package = $var;
        $this->has_java_package = true;
    }

    public function hasJavaPackage()
    {
        return $this->has_java_package;
    }

    /**
     * <pre>
     * If set, all the classes from the .proto file are wrapped in a single
     * outer class with the given name.  This applies to both Proto1
     * (equivalent to the old "--one_java_file" option) and Proto2 (where
     * a .proto always translates to a single class, but you may want to
     * explicitly choose the class name).
     * </pre>
     *
     * <code>optional string java_outer_classname = 8;</code>
     */
    public function getJavaOuterClassname()
    {
        return $this->java_outer_classname;
    }

    /**
     * <pre>
     * If set, all the classes from the .proto file are wrapped in a single
     * outer class with the given name.  This applies to both Proto1
     * (equivalent to the old "--one_java_file" option) and Proto2 (where
     * a .proto always translates to a single class, but you may want to
     * explicitly choose the class name).
     * </pre>
     *
     * <code>optional string java_outer_classname = 8;</code>
     */
    public function setJavaOuterClassname($var)
    {
        GPBUtil::checkString($var, True);
        $this->java_outer_classname = $var;
        $this->has_java_outer_classname = true;
    }

    public function hasJavaOuterClassname()
    {
        return $this->has_java_outer_classname;
    }

    /**
     * <pre>
     * If set true, then the Java code generator will generate a separate .java
     * file for each top-level message, enum, and service defined in the .proto
     * file.  Thus, these types will *not* be nested inside the outer class
     * named by java_outer_classname.  However, the outer class will still be
     * generated to contain the file's getDescriptor() method as well as any
     * top-level extensions defined in the file.
     * </pre>
     *
     * <code>optional bool java_multiple_files = 10 [default = false];</code>
     */
    public function getJavaMultipleFiles()
    {
        return $this->java_multiple_files;
    }

    /**
     * <pre>
     * If set true, then the Java code generator will generate a separate .java
     * file for each top-level message, enum, and service defined in the .proto
     * file.  Thus, these types will *not* be nested inside the outer class
     * named by java_outer_classname.  However, the outer class will still be
     * generated to contain the file's getDescriptor() method as well as any
     * top-level extensions defined in the file.
     * </pre>
     *
     * <code>optional bool java_multiple_files = 10 [default = false];</code>
     */
    public function setJavaMultipleFiles($var)
    {
        GPBUtil::checkBool($var);
        $this->java_multiple_files = $var;
        $this->has_java_multiple_files = true;
    }

    public function hasJavaMultipleFiles()
    {
        return $this->has_java_multiple_files;
    }

    /**
     * <pre>
     * This option does nothing.
     * </pre>
     *
     * <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
     */
    public function getJavaGenerateEqualsAndHash()
    {
        return $this->java_generate_equals_and_hash;
    }

    /**
     * <pre>
     * This option does nothing.
     * </pre>
     *
     * <code>optional bool java_generate_equals_and_hash = 20 [deprecated = true];</code>
     */
    public function setJavaGenerateEqualsAndHash($var)
    {
        GPBUtil::checkBool($var);
        $this->java_generate_equals_and_hash = $var;
        $this->has_java_generate_equals_and_hash = true;
    }

    public function hasJavaGenerateEqualsAndHash()
    {
        return $this->has_java_generate_equals_and_hash;
    }

    /**
     * <pre>
     * If set true, then the Java2 code generator will generate code that
     * throws an exception whenever an attempt is made to assign a non-UTF-8
     * byte sequence to a string field.
     * Message reflection will do the same.
     * However, an extension field still accepts non-UTF-8 byte sequences.
     * This option has no effect on when used with the lite runtime.
     * </pre>
     *
     * <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
     */
    public function getJavaStringCheckUtf8()
    {
        return $this->java_string_check_utf8;
    }

    /**
     * <pre>
     * If set true, then the Java2 code generator will generate code that
     * throws an exception whenever an attempt is made to assign a non-UTF-8
     * byte sequence to a string field.
     * Message reflection will do the same.
     * However, an extension field still accepts non-UTF-8 byte sequences.
     * This option has no effect on when used with the lite runtime.
     * </pre>
     *
     * <code>optional bool java_string_check_utf8 = 27 [default = false];</code>
     */
    public function setJavaStringCheckUtf8($var)
    {
        GPBUtil::checkBool($var);
        $this->java_string_check_utf8 = $var;
        $this->has_java_string_check_utf8 = true;
    }

    public function hasJavaStringCheckUtf8()
    {
        return $this->has_java_string_check_utf8;
    }

    /**
     * <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
     */
    public function getOptimizeFor()
    {
        return $this->optimize_for;
    }

    /**
     * <code>optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];</code>
     */
    public function setOptimizeFor($var)
    {
        GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions_OptimizeMode::class);
        $this->optimize_for = $var;
        $this->has_optimize_for = true;
    }

    public function hasOptimizeFor()
    {
        return $this->has_optimize_for;
    }

    /**
     * <pre>
     * Sets the Go package where structs generated from this .proto will be
     * placed. If omitted, the Go package will be derived from the following:
     *   - The basename of the package import path, if provided.
     *   - Otherwise, the package statement in the .proto file, if present.
     *   - Otherwise, the basename of the .proto file, without extension.
     * </pre>
     *
     * <code>optional string go_package = 11;</code>
     */
    public function getGoPackage()
    {
        return $this->go_package;
    }

    /**
     * <pre>
     * Sets the Go package where structs generated from this .proto will be
     * placed. If omitted, the Go package will be derived from the following:
     *   - The basename of the package import path, if provided.
     *   - Otherwise, the package statement in the .proto file, if present.
     *   - Otherwise, the basename of the .proto file, without extension.
     * </pre>
     *
     * <code>optional string go_package = 11;</code>
     */
    public function setGoPackage($var)
    {
        GPBUtil::checkString($var, True);
        $this->go_package = $var;
        $this->has_go_package = true;
    }

    public function hasGoPackage()
    {
        return $this->has_go_package;
    }

    /**
     * <pre>
     * Should generic services be generated in each language?  "Generic" services
     * are not specific to any particular RPC system.  They are generated by the
     * main code generators in each language (without additional plugins).
     * Generic services were the only kind of service generation supported by
     * early versions of google.protobuf.
     * Generic services are now considered deprecated in favor of using plugins
     * that generate code specific to your particular RPC system.  Therefore,
     * these default to false.  Old code which depends on generic services should
     * explicitly set them to true.
     * </pre>
     *
     * <code>optional bool cc_generic_services = 16 [default = false];</code>
     */
    public function getCcGenericServices()
    {
        return $this->cc_generic_services;
    }

    /**
     * <pre>
     * Should generic services be generated in each language?  "Generic" services
     * are not specific to any particular RPC system.  They are generated by the
     * main code generators in each language (without additional plugins).
     * Generic services were the only kind of service generation supported by
     * early versions of google.protobuf.
     * Generic services are now considered deprecated in favor of using plugins
     * that generate code specific to your particular RPC system.  Therefore,
     * these default to false.  Old code which depends on generic services should
     * explicitly set them to true.
     * </pre>
     *
     * <code>optional bool cc_generic_services = 16 [default = false];</code>
     */
    public function setCcGenericServices($var)
    {
        GPBUtil::checkBool($var);
        $this->cc_generic_services = $var;
        $this->has_cc_generic_services = true;
    }

    public function hasCcGenericServices()
    {
        return $this->has_cc_generic_services;
    }

    /**
     * <code>optional bool java_generic_services = 17 [default = false];</code>
     */
    public function getJavaGenericServices()
    {
        return $this->java_generic_services;
    }

    /**
     * <code>optional bool java_generic_services = 17 [default = false];</code>
     */
    public function setJavaGenericServices($var)
    {
        GPBUtil::checkBool($var);
        $this->java_generic_services = $var;
        $this->has_java_generic_services = true;
    }

    public function hasJavaGenericServices()
    {
        return $this->has_java_generic_services;
    }

    /**
     * <code>optional bool py_generic_services = 18 [default = false];</code>
     */
    public function getPyGenericServices()
    {
        return $this->py_generic_services;
    }

    /**
     * <code>optional bool py_generic_services = 18 [default = false];</code>
     */
    public function setPyGenericServices($var)
    {
        GPBUtil::checkBool($var);
        $this->py_generic_services = $var;
        $this->has_py_generic_services = true;
    }

    public function hasPyGenericServices()
    {
        return $this->has_py_generic_services;
    }

    /**
     * <pre>
     * Is this file deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for everything in the file, or it will be completely ignored; in the very
     * least, this is a formalization for deprecating files.
     * </pre>
     *
     * <code>optional bool deprecated = 23 [default = false];</code>
     */
    public function getDeprecated()
    {
        return $this->deprecated;
    }

    /**
     * <pre>
     * Is this file deprecated?
     * Depending on the target platform, this can emit Deprecated annotations
     * for everything in the file, or it will be completely ignored; in the very
     * least, this is a formalization for deprecating files.
     * </pre>
     *
     * <code>optional bool deprecated = 23 [default = false];</code>
     */
    public function setDeprecated($var)
    {
        GPBUtil::checkBool($var);
        $this->deprecated = $var;
        $this->has_deprecated = true;
    }

    public function hasDeprecated()
    {
        return $this->has_deprecated;
    }

    /**
     * <pre>
     * Enables the use of arenas for the proto messages in this file. This applies
     * only to generated classes for C++.
     * </pre>
     *
     * <code>optional bool cc_enable_arenas = 31 [default = false];</code>
     */
    public function getCcEnableArenas()
    {
        return $this->cc_enable_arenas;
    }

    /**
     * <pre>
     * Enables the use of arenas for the proto messages in this file. This applies
     * only to generated classes for C++.
     * </pre>
     *
     * <code>optional bool cc_enable_arenas = 31 [default = false];</code>
     */
    public function setCcEnableArenas($var)
    {
        GPBUtil::checkBool($var);
        $this->cc_enable_arenas = $var;
        $this->has_cc_enable_arenas = true;
    }

    public function hasCcEnableArenas()
    {
        return $this->has_cc_enable_arenas;
    }

    /**
     * <pre>
     * Sets the objective c class prefix which is prepended to all objective c
     * generated classes from this .proto. There is no default.
     * </pre>
     *
     * <code>optional string objc_class_prefix = 36;</code>
     */
    public function getObjcClassPrefix()
    {
        return $this->objc_class_prefix;
    }

    /**
     * <pre>
     * Sets the objective c class prefix which is prepended to all objective c
     * generated classes from this .proto. There is no default.
     * </pre>
     *
     * <code>optional string objc_class_prefix = 36;</code>
     */
    public function setObjcClassPrefix($var)
    {
        GPBUtil::checkString($var, True);
        $this->objc_class_prefix = $var;
        $this->has_objc_class_prefix = true;
    }

    public function hasObjcClassPrefix()
    {
        return $this->has_objc_class_prefix;
    }

    /**
     * <pre>
     * Namespace for generated classes; defaults to the package.
     * </pre>
     *
     * <code>optional string csharp_namespace = 37;</code>
     */
    public function getCsharpNamespace()
    {
        return $this->csharp_namespace;
    }

    /**
     * <pre>
     * Namespace for generated classes; defaults to the package.
     * </pre>
     *
     * <code>optional string csharp_namespace = 37;</code>
     */
    public function setCsharpNamespace($var)
    {
        GPBUtil::checkString($var, True);
        $this->csharp_namespace = $var;
        $this->has_csharp_namespace = true;
    }

    public function hasCsharpNamespace()
    {
        return $this->has_csharp_namespace;
    }

    /**
     * <pre>
     * By default Swift generators will take the proto package and CamelCase it
     * replacing '.' with underscore and use that to prefix the types/symbols
     * defined. When this options is provided, they will use this value instead
     * to prefix the types/symbols defined.
     * </pre>
     *
     * <code>optional string swift_prefix = 39;</code>
     */
    public function getSwiftPrefix()
    {
        return $this->swift_prefix;
    }

    /**
     * <pre>
     * By default Swift generators will take the proto package and CamelCase it
     * replacing '.' with underscore and use that to prefix the types/symbols
     * defined. When this options is provided, they will use this value instead
     * to prefix the types/symbols defined.
     * </pre>
     *
     * <code>optional string swift_prefix = 39;</code>
     */
    public function setSwiftPrefix($var)
    {
        GPBUtil::checkString($var, True);
        $this->swift_prefix = $var;
        $this->has_swift_prefix = true;
    }

    public function hasSwiftPrefix()
    {
        return $this->has_swift_prefix;
    }

    /**
     * <pre>
     * The parser stores options it doesn't recognize here. See above.
     * </pre>
     *
     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
     */
    public function getUninterpretedOption()
    {
        return $this->uninterpreted_option;
    }

    /**
     * <pre>
     * The parser stores options it doesn't recognize here. See above.
     * </pre>
     *
     * <code>repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;</code>
     */
    public function setUninterpretedOption(&$var)
    {
        GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class);
        $this->uninterpreted_option = $var;
        $this->has_uninterpreted_option = true;
    }

    public function hasUninterpretedOption()
    {
        return $this->has_uninterpreted_option;
    }

}

