fielddescriptor.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. // Copyright 2008 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Protocol Buffer Field Descriptor class.
  16. */
  17. goog.provide('goog.proto2.FieldDescriptor');
  18. goog.require('goog.asserts');
  19. goog.require('goog.string');
  20. /**
  21. * A class which describes a field in a Protocol Buffer 2 Message.
  22. *
  23. * @param {function(new:goog.proto2.Message)} messageType Constructor for the
  24. * message class to which the field described by this class belongs.
  25. * @param {number|string} tag The field's tag index.
  26. * @param {Object} metadata The metadata about this field that will be used
  27. * to construct this descriptor.
  28. *
  29. * @constructor
  30. * @final
  31. */
  32. goog.proto2.FieldDescriptor = function(messageType, tag, metadata) {
  33. /**
  34. * The message type that contains the field that this
  35. * descriptor describes.
  36. * @private {function(new:goog.proto2.Message)}
  37. */
  38. this.parent_ = messageType;
  39. // Ensure that the tag is numeric.
  40. goog.asserts.assert(goog.string.isNumeric(tag));
  41. /**
  42. * The field's tag number.
  43. * @private {number}
  44. */
  45. this.tag_ = /** @type {number} */ (tag);
  46. /**
  47. * The field's name.
  48. * @private {string}
  49. */
  50. this.name_ = metadata.name;
  51. /** @type {goog.proto2.FieldDescriptor.FieldType} */
  52. metadata.fieldType;
  53. /** @type {*} */
  54. metadata.repeated;
  55. /** @type {*} */
  56. metadata.required;
  57. /** @type {*} */
  58. metadata.packed;
  59. /**
  60. * If true, this field is a packed field.
  61. * @private {boolean}
  62. */
  63. this.isPacked_ = !!metadata.packed;
  64. /**
  65. * If true, this field is a repeating field.
  66. * @private {boolean}
  67. */
  68. this.isRepeated_ = !!metadata.repeated;
  69. /**
  70. * If true, this field is required.
  71. * @private {boolean}
  72. */
  73. this.isRequired_ = !!metadata.required;
  74. /**
  75. * The field type of this field.
  76. * @private {goog.proto2.FieldDescriptor.FieldType}
  77. */
  78. this.fieldType_ = metadata.fieldType;
  79. /**
  80. * If this field is a primitive: The native (ECMAScript) type of this field.
  81. * If an enumeration: The enumeration object.
  82. * If a message or group field: The Message function.
  83. * @private {Function}
  84. */
  85. this.nativeType_ = metadata.type;
  86. /**
  87. * Is it permissible on deserialization to convert between numbers and
  88. * well-formed strings? Is true for 64-bit integral field types and float and
  89. * double types, false for all other field types.
  90. * @private {boolean}
  91. */
  92. this.deserializationConversionPermitted_ = false;
  93. switch (this.fieldType_) {
  94. case goog.proto2.FieldDescriptor.FieldType.INT64:
  95. case goog.proto2.FieldDescriptor.FieldType.UINT64:
  96. case goog.proto2.FieldDescriptor.FieldType.FIXED64:
  97. case goog.proto2.FieldDescriptor.FieldType.SFIXED64:
  98. case goog.proto2.FieldDescriptor.FieldType.SINT64:
  99. case goog.proto2.FieldDescriptor.FieldType.FLOAT:
  100. case goog.proto2.FieldDescriptor.FieldType.DOUBLE:
  101. this.deserializationConversionPermitted_ = true;
  102. break;
  103. }
  104. /**
  105. * The default value of this field, if different from the default, default
  106. * value.
  107. * @private {*}
  108. */
  109. this.defaultValue_ = metadata.defaultValue;
  110. };
  111. /**
  112. * An enumeration defining the possible field types.
  113. * Should be a mirror of that defined in descriptor.h.
  114. *
  115. * @enum {number}
  116. */
  117. goog.proto2.FieldDescriptor.FieldType = {
  118. DOUBLE: 1,
  119. FLOAT: 2,
  120. INT64: 3,
  121. UINT64: 4,
  122. INT32: 5,
  123. FIXED64: 6,
  124. FIXED32: 7,
  125. BOOL: 8,
  126. STRING: 9,
  127. GROUP: 10,
  128. MESSAGE: 11,
  129. BYTES: 12,
  130. UINT32: 13,
  131. ENUM: 14,
  132. SFIXED32: 15,
  133. SFIXED64: 16,
  134. SINT32: 17,
  135. SINT64: 18
  136. };
  137. /**
  138. * Returns the tag of the field that this descriptor represents.
  139. *
  140. * @return {number} The tag number.
  141. */
  142. goog.proto2.FieldDescriptor.prototype.getTag = function() {
  143. return this.tag_;
  144. };
  145. /**
  146. * Returns the descriptor describing the message that defined this field.
  147. * @return {!goog.proto2.Descriptor} The descriptor.
  148. */
  149. goog.proto2.FieldDescriptor.prototype.getContainingType = function() {
  150. // Generated JS proto_library messages have getDescriptor() method which can
  151. // be called with or without an instance.
  152. return this.parent_.prototype.getDescriptor();
  153. };
  154. /**
  155. * Returns the name of the field that this descriptor represents.
  156. * @return {string} The name.
  157. */
  158. goog.proto2.FieldDescriptor.prototype.getName = function() {
  159. return this.name_;
  160. };
  161. /**
  162. * Returns the default value of this field.
  163. * @return {*} The default value.
  164. */
  165. goog.proto2.FieldDescriptor.prototype.getDefaultValue = function() {
  166. if (this.defaultValue_ === undefined) {
  167. // Set the default value based on a new instance of the native type.
  168. // This will be (0, false, "") for (number, boolean, string) and will
  169. // be a new instance of a group/message if the field is a message type.
  170. var nativeType = this.nativeType_;
  171. if (nativeType === Boolean) {
  172. this.defaultValue_ = false;
  173. } else if (nativeType === Number) {
  174. this.defaultValue_ = 0;
  175. } else if (nativeType === String) {
  176. if (this.deserializationConversionPermitted_) {
  177. // This field is a 64 bit integer represented as a string.
  178. this.defaultValue_ = '0';
  179. } else {
  180. this.defaultValue_ = '';
  181. }
  182. } else {
  183. return new nativeType;
  184. }
  185. }
  186. return this.defaultValue_;
  187. };
  188. /**
  189. * Returns the field type of the field described by this descriptor.
  190. * @return {goog.proto2.FieldDescriptor.FieldType} The field type.
  191. */
  192. goog.proto2.FieldDescriptor.prototype.getFieldType = function() {
  193. return this.fieldType_;
  194. };
  195. /**
  196. * Returns the native (i.e. ECMAScript) type of the field described by this
  197. * descriptor.
  198. *
  199. * @return {Object} The native type.
  200. */
  201. goog.proto2.FieldDescriptor.prototype.getNativeType = function() {
  202. return this.nativeType_;
  203. };
  204. /**
  205. * Returns true if simple conversions between numbers and strings are permitted
  206. * during deserialization for this field.
  207. *
  208. * @return {boolean} Whether conversion is permitted.
  209. */
  210. goog.proto2.FieldDescriptor.prototype.deserializationConversionPermitted =
  211. function() {
  212. return this.deserializationConversionPermitted_;
  213. };
  214. /**
  215. * Returns the descriptor of the message type of this field. Only valid
  216. * for fields of type GROUP and MESSAGE.
  217. *
  218. * @return {!goog.proto2.Descriptor} The message descriptor.
  219. */
  220. goog.proto2.FieldDescriptor.prototype.getFieldMessageType = function() {
  221. // Generated JS proto_library messages have getDescriptor() method which can
  222. // be called with or without an instance.
  223. var messageClass =
  224. /** @type {function(new:goog.proto2.Message)} */ (this.nativeType_);
  225. return messageClass.prototype.getDescriptor();
  226. };
  227. /**
  228. * @return {boolean} True if the field stores composite data or repeated
  229. * composite data (message or group).
  230. */
  231. goog.proto2.FieldDescriptor.prototype.isCompositeType = function() {
  232. return this.fieldType_ == goog.proto2.FieldDescriptor.FieldType.MESSAGE ||
  233. this.fieldType_ == goog.proto2.FieldDescriptor.FieldType.GROUP;
  234. };
  235. /**
  236. * Returns whether the field described by this descriptor is packed.
  237. * @return {boolean} Whether the field is packed.
  238. */
  239. goog.proto2.FieldDescriptor.prototype.isPacked = function() {
  240. return this.isPacked_;
  241. };
  242. /**
  243. * Returns whether the field described by this descriptor is repeating.
  244. * @return {boolean} Whether the field is repeated.
  245. */
  246. goog.proto2.FieldDescriptor.prototype.isRepeated = function() {
  247. return this.isRepeated_;
  248. };
  249. /**
  250. * Returns whether the field described by this descriptor is required.
  251. * @return {boolean} Whether the field is required.
  252. */
  253. goog.proto2.FieldDescriptor.prototype.isRequired = function() {
  254. return this.isRequired_;
  255. };
  256. /**
  257. * Returns whether the field described by this descriptor is optional.
  258. * @return {boolean} Whether the field is optional.
  259. */
  260. goog.proto2.FieldDescriptor.prototype.isOptional = function() {
  261. return !this.isRepeated_ && !this.isRequired_;
  262. };