Path: blob/trunk/third_party/closure/goog/proto2/serializer.js
2868 views
// Copyright 2008 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Base class for all Protocol Buffer 2 serializers.16*/1718goog.provide('goog.proto2.Serializer');1920goog.require('goog.asserts');21goog.require('goog.proto2.FieldDescriptor');22goog.require('goog.proto2.Message');23242526/**27* Abstract base class for PB2 serializers. A serializer is a class which28* implements the serialization and deserialization of a Protocol Buffer Message29* to/from a specific format.30*31* @constructor32*/33goog.proto2.Serializer = function() {};343536/**37* @define {boolean} Whether to decode and convert symbolic enum values to38* actual enum values or leave them as strings.39*/40goog.define('goog.proto2.Serializer.DECODE_SYMBOLIC_ENUMS', false);414243/**44* Serializes a message to the expected format.45*46* @param {goog.proto2.Message} message The message to be serialized.47*48* @return {*} The serialized form of the message.49*/50goog.proto2.Serializer.prototype.serialize = goog.abstractMethod;515253/**54* Returns the serialized form of the given value for the given field if the55* field is a Message or Group and returns the value unchanged otherwise, except56* for Infinity, -Infinity and NaN numerical values which are converted to57* string representation.58*59* @param {goog.proto2.FieldDescriptor} field The field from which this60* value came.61*62* @param {*} value The value of the field.63*64* @return {*} The value.65* @protected66*/67goog.proto2.Serializer.prototype.getSerializedValue = function(field, value) {68if (field.isCompositeType()) {69return this.serialize(/** @type {goog.proto2.Message} */ (value));70} else if (goog.isNumber(value) && !isFinite(value)) {71return value.toString();72} else {73return value;74}75};767778/**79* Deserializes a message from the expected format.80*81* @param {goog.proto2.Descriptor} descriptor The descriptor of the message82* to be created.83* @param {*} data The data of the message.84*85* @return {!goog.proto2.Message} The message created.86*/87goog.proto2.Serializer.prototype.deserialize = function(descriptor, data) {88var message = descriptor.createMessageInstance();89this.deserializeTo(message, data);90goog.asserts.assert(message instanceof goog.proto2.Message);91return message;92};939495/**96* Deserializes a message from the expected format and places the97* data in the message.98*99* @param {goog.proto2.Message} message The message in which to100* place the information.101* @param {*} data The data of the message.102*/103goog.proto2.Serializer.prototype.deserializeTo = goog.abstractMethod;104105106/**107* Returns the deserialized form of the given value for the given field if the108* field is a Message or Group and returns the value, converted or unchanged,109* for primitive field types otherwise.110*111* @param {goog.proto2.FieldDescriptor} field The field from which this112* value came.113*114* @param {*} value The value of the field.115*116* @return {*} The value.117* @protected118*/119goog.proto2.Serializer.prototype.getDeserializedValue = function(field, value) {120// Composite types are deserialized recursively.121if (field.isCompositeType()) {122if (value instanceof goog.proto2.Message) {123return value;124}125126return this.deserialize(field.getFieldMessageType(), value);127}128129// Decode enum values.130if (field.getFieldType() == goog.proto2.FieldDescriptor.FieldType.ENUM) {131// If it's a string, get enum value by name.132// NB: In order this feature to work, property renaming should be turned off133// for the respective enums.134if (goog.proto2.Serializer.DECODE_SYMBOLIC_ENUMS && goog.isString(value)) {135// enumType is a regular Javascript enum as defined in field's metadata.136var enumType = field.getNativeType();137if (enumType.hasOwnProperty(value)) {138return enumType[value];139}140}141142// If it's a string containing a positive integer, this looks like a viable143// enum int value. Return as numeric.144if (goog.isString(value) &&145goog.proto2.Serializer.INTEGER_REGEX.test(value)) {146var numeric = Number(value);147if (numeric > 0) {148return numeric;149}150}151152// Return unknown values as is for backward compatibility.153return value;154}155156// Return the raw value if the field does not allow the JSON input to be157// converted.158if (!field.deserializationConversionPermitted()) {159return value;160}161162// Convert to native type of field. Return the converted value or fall163// through to return the raw value. The JSON encoding of int64 value 123164// might be either the number 123 or the string "123". The field native type165// could be either Number or String (depending on field options in the .proto166// file). All four combinations should work correctly.167var nativeType = field.getNativeType();168if (nativeType === String) {169// JSON numbers can be converted to strings.170if (goog.isNumber(value)) {171return String(value);172}173} else if (nativeType === Number) {174// JSON strings are sometimes used for large integer numeric values, as well175// as Infinity, -Infinity and NaN.176if (goog.isString(value)) {177// Handle +/- Infinity and NaN values.178if (value === 'Infinity' || value === '-Infinity' || value === 'NaN') {179return Number(value);180}181182// Validate the string. If the string is not an integral number, we would183// rather have an assertion or error in the caller than a mysterious NaN184// value.185if (goog.proto2.Serializer.INTEGER_REGEX.test(value)) {186return Number(value);187}188}189}190191return value;192};193194195/** @const {!RegExp} */196goog.proto2.Serializer.INTEGER_REGEX = /^-?[0-9]+$/;197198199