message_set.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. ##########################################################
  3. # #
  4. # __ __ _____ _ _ _____ _ _ _____ #
  5. # \ \ / /\ | __ \| \ | |_ _| \ | |/ ____| #
  6. # \ \ /\ / / \ | |__) | \| | | | | \| | | __ #
  7. # \ \/ \/ / /\ \ | _ /| . ` | | | | . ` | | |_ | #
  8. # \ /\ / ____ \| | \ \| |\ |_| |_| |\ | |__| | #
  9. # \/ \/_/ \_\_| \_\_| \_|_____|_| \_|\_____| #
  10. # #
  11. # #
  12. ##########################################################
  13. # Do not use this class in your code. This class purely #
  14. # exists to make proto code generation easier. #
  15. ##########################################################
  16. */
  17. goog.module('protobuf.runtime.MessageSet');
  18. const InternalMessage = goog.require('protobuf.binary.InternalMessage');
  19. const Kernel = goog.require('protobuf.runtime.Kernel');
  20. // These are the tags for the old MessageSet format, which was defined as:
  21. // message MessageSet {
  22. // repeated group Item = 1 {
  23. // required uint32 type_id = 2;
  24. // optional bytes message = 3;
  25. // }
  26. // }
  27. /** @const {number} */
  28. const MSET_GROUP_FIELD_NUMBER = 1;
  29. /** @const {number} */
  30. const MSET_TYPE_ID_FIELD_NUMBER = 2;
  31. /** @const {number} */
  32. const MSET_MESSAGE_FIELD_NUMBER = 3;
  33. /**
  34. * @param {!Kernel} kernel
  35. * @return {!Map<number, !Item>}
  36. */
  37. function createItemMap(kernel) {
  38. const itemMap = new Map();
  39. let totalCount = 0;
  40. for (const item of kernel.getRepeatedGroupIterable(
  41. MSET_GROUP_FIELD_NUMBER, Item.fromKernel)) {
  42. itemMap.set(item.getTypeId(), item);
  43. totalCount++;
  44. }
  45. // Normalize the entries.
  46. if (totalCount > itemMap.size) {
  47. writeItemMap(kernel, itemMap);
  48. }
  49. return itemMap;
  50. }
  51. /**
  52. * @param {!Kernel} kernel
  53. * @param {!Map<number, !Item>} itemMap
  54. */
  55. function writeItemMap(kernel, itemMap) {
  56. kernel.setRepeatedGroupIterable(MSET_GROUP_FIELD_NUMBER, itemMap.values());
  57. }
  58. /**
  59. * @implements {InternalMessage}
  60. * @final
  61. */
  62. class MessageSet {
  63. /**
  64. * @param {!Kernel} kernel
  65. * @return {!MessageSet}
  66. */
  67. static fromKernel(kernel) {
  68. const itemMap = createItemMap(kernel);
  69. return new MessageSet(kernel, itemMap);
  70. }
  71. /**
  72. * @return {!MessageSet}
  73. */
  74. static createEmpty() {
  75. return MessageSet.fromKernel(Kernel.createEmpty());
  76. }
  77. /**
  78. * @param {!Kernel} kernel
  79. * @param {!Map<number, !Item>} itemMap
  80. * @private
  81. */
  82. constructor(kernel, itemMap) {
  83. /** @const {!Kernel} @private */
  84. this.kernel_ = kernel;
  85. /** @const {!Map<number, !Item>} @private */
  86. this.itemMap_ = itemMap;
  87. }
  88. // code helpers for code gen
  89. /**
  90. * @param {number} typeId
  91. * @param {function(!Kernel):T} instanceCreator
  92. * @param {number=} pivot
  93. * @return {?T}
  94. * @template T
  95. */
  96. getMessageOrNull(typeId, instanceCreator, pivot) {
  97. const item = this.itemMap_.get(typeId);
  98. return item ? item.getMessageOrNull(instanceCreator, pivot) : null;
  99. }
  100. /**
  101. * @param {number} typeId
  102. * @param {function(!Kernel):T} instanceCreator
  103. * @param {number=} pivot
  104. * @return {T}
  105. * @template T
  106. */
  107. getMessageAttach(typeId, instanceCreator, pivot) {
  108. let item = this.itemMap_.get(typeId);
  109. if (item) {
  110. return item.getMessageAttach(instanceCreator, pivot);
  111. }
  112. const message = instanceCreator(Kernel.createEmpty());
  113. this.setMessage(typeId, message);
  114. return message;
  115. }
  116. /**
  117. * @param {number} typeId
  118. * @param {number=} pivot
  119. * @return {?Kernel}
  120. */
  121. getMessageAccessorOrNull(typeId, pivot) {
  122. const item = this.itemMap_.get(typeId);
  123. return item ? item.getMessageAccessorOrNull(pivot) : null;
  124. }
  125. /**
  126. * @param {number} typeId
  127. */
  128. clearMessage(typeId) {
  129. if (this.itemMap_.delete(typeId)) {
  130. writeItemMap(this.kernel_, this.itemMap_);
  131. }
  132. }
  133. /**
  134. * @param {number} typeId
  135. * @return {boolean}
  136. */
  137. hasMessage(typeId) {
  138. return this.itemMap_.has(typeId);
  139. }
  140. /**
  141. * @param {number} typeId
  142. * @param {!InternalMessage} value
  143. */
  144. setMessage(typeId, value) {
  145. const item = this.itemMap_.get(typeId);
  146. if (item) {
  147. item.setMessage(value);
  148. } else {
  149. this.itemMap_.set(typeId, Item.create(typeId, value));
  150. writeItemMap(this.kernel_, this.itemMap_);
  151. }
  152. }
  153. /**
  154. * @return {!Kernel}
  155. * @override
  156. */
  157. internalGetKernel() {
  158. return this.kernel_;
  159. }
  160. }
  161. /**
  162. * @implements {InternalMessage}
  163. * @final
  164. */
  165. class Item {
  166. /**
  167. * @param {number} typeId
  168. * @param {!InternalMessage} message
  169. * @return {!Item}
  170. */
  171. static create(typeId, message) {
  172. const messageSet = Item.fromKernel(Kernel.createEmpty());
  173. messageSet.setTypeId_(typeId);
  174. messageSet.setMessage(message);
  175. return messageSet;
  176. }
  177. /**
  178. * @param {!Kernel} kernel
  179. * @return {!Item}
  180. */
  181. static fromKernel(kernel) {
  182. return new Item(kernel);
  183. }
  184. /**
  185. * @param {!Kernel} kernel
  186. * @private
  187. */
  188. constructor(kernel) {
  189. /** @const {!Kernel} @private */
  190. this.kernel_ = kernel;
  191. }
  192. /**
  193. * @param {function(!Kernel):T} instanceCreator
  194. * @param {number=} pivot
  195. * @return {T}
  196. * @template T
  197. */
  198. getMessage(instanceCreator, pivot) {
  199. return this.kernel_.getMessage(
  200. MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot);
  201. }
  202. /**
  203. * @param {function(!Kernel):T} instanceCreator
  204. * @param {number=} pivot
  205. * @return {?T}
  206. * @template T
  207. */
  208. getMessageOrNull(instanceCreator, pivot) {
  209. return this.kernel_.getMessageOrNull(
  210. MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot);
  211. }
  212. /**
  213. * @param {function(!Kernel):T} instanceCreator
  214. * @param {number=} pivot
  215. * @return {T}
  216. * @template T
  217. */
  218. getMessageAttach(instanceCreator, pivot) {
  219. return this.kernel_.getMessageAttach(
  220. MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot);
  221. }
  222. /**
  223. * @param {number=} pivot
  224. * @return {?Kernel}
  225. */
  226. getMessageAccessorOrNull(pivot) {
  227. return this.kernel_.getMessageAccessorOrNull(
  228. MSET_MESSAGE_FIELD_NUMBER, pivot);
  229. }
  230. /** @param {!InternalMessage} value */
  231. setMessage(value) {
  232. this.kernel_.setMessage(MSET_MESSAGE_FIELD_NUMBER, value);
  233. }
  234. /** @return {number} */
  235. getTypeId() {
  236. return this.kernel_.getUint32WithDefault(MSET_TYPE_ID_FIELD_NUMBER);
  237. }
  238. /**
  239. * @param {number} value
  240. * @private
  241. */
  242. setTypeId_(value) {
  243. this.kernel_.setUint32(MSET_TYPE_ID_FIELD_NUMBER, value);
  244. }
  245. /**
  246. * @return {!Kernel}
  247. * @override
  248. */
  249. internalGetKernel() {
  250. return this.kernel_;
  251. }
  252. }
  253. exports = MessageSet;