"use strict";module.exports=Field;var Type,ReflectionObject=require("./object");((Field.prototype=Object.create(ReflectionObject.prototype)).constructor=Field).className="Field";var Enum=require("./enum"),types=require("./types"),util=require("./util"),ruleRe=/^required|optional|repeated$/;function Field(t,e,i,s,o,l,n){if(util.isObject(s)?(n=o,l=s,s=o=void 0):util.isObject(o)&&(n=l,l=o,o=void 0),ReflectionObject.call(this,t,l),!util.isInteger(e)||e<0)throw TypeError("id must be a non-negative integer");if(!util.isString(i))throw TypeError("type must be a string");if(void 0!==s&&!ruleRe.test(s=s.toString().toLowerCase()))throw TypeError("rule must be a string rule");if(void 0!==o&&!util.isString(o))throw TypeError("extend must be a string");"proto3_optional"===s&&(s="optional"),this.rule=s&&"optional"!==s?s:void 0,this.type=i,this.id=e,this.extend=o||void 0,this.required="required"===s,this.optional=!this.required,this.repeated="repeated"===s,this.map=!1,this.message=null,this.partOf=null,this.typeDefault=null,this.defaultValue=null,this.long=!!util.Long&&void 0!==types.long[i],this.bytes="bytes"===i,this.resolvedType=null,this.extensionField=null,this.declaringField=null,this._packed=null,this.comment=n}Field.fromJSON=function(t,e){return new Field(t,e.id,e.type,e.rule,e.extend,e.options,e.comment)},Object.defineProperty(Field.prototype,"packed",{get:function(){return null===this._packed&&(this._packed=!1!==this.getOption("packed")),this._packed}}),Field.prototype.setOption=function(t,e,i){return"packed"===t&&(this._packed=null),ReflectionObject.prototype.setOption.call(this,t,e,i)},Field.prototype.toJSON=function(t){var e=!!t&&!!t.keepComments;return util.toObject(["rule","optional"!==this.rule&&this.rule||void 0,"type",this.type,"id",this.id,"extend",this.extend,"options",this.options,"comment",e?this.comment:void 0])},Field.prototype.resolve=function(){if(this.resolved)return this;if(void 0===(this.typeDefault=types.defaults[this.type])?(this.resolvedType=(this.declaringField?this.declaringField.parent:this.parent).lookupTypeOrEnum(this.type),this.resolvedType instanceof Type?this.typeDefault=null:this.typeDefault=this.resolvedType.values[Object.keys(this.resolvedType.values)[0]]):this.options&&this.options.proto3_optional&&(this.typeDefault=null),this.options&&null!=this.options.default&&(this.typeDefault=this.options.default,this.resolvedType instanceof Enum&&"string"==typeof this.typeDefault&&(this.typeDefault=this.resolvedType.values[this.typeDefault])),this.options&&(!0!==this.options.packed&&(void 0===this.options.packed||!this.resolvedType||this.resolvedType instanceof Enum)||delete this.options.packed,Object.keys(this.options).length||(this.options=void 0)),this.long)this.typeDefault=util.Long.fromNumber(this.typeDefault,"u"===this.type.charAt(0)),Object.freeze&&Object.freeze(this.typeDefault);else if(this.bytes&&"string"==typeof this.typeDefault){var t;util.base64.test(this.typeDefault)?util.base64.decode(this.typeDefault,t=util.newBuffer(util.base64.length(this.typeDefault)),0):util.utf8.write(this.typeDefault,t=util.newBuffer(util.utf8.length(this.typeDefault)),0),this.typeDefault=t}return this.map?this.defaultValue=util.emptyObject:this.repeated?this.defaultValue=util.emptyArray:this.defaultValue=this.typeDefault,this.parent instanceof Type&&(this.parent.ctor.prototype[this.name]=this.defaultValue),ReflectionObject.prototype.resolve.call(this)},Field.d=function(t,e,i,s){return"function"==typeof e?e=util.decorateType(e).name:e&&"object"==typeof e&&(e=util.decorateEnum(e).name),function(o,l){util.decorateType(o.constructor).add(new Field(l,t,e,i,{default:s}))}},Field._configure=function(t){Type=t};