private const int MaxFieldId = 536870911; // 2^29-1

        static GrpcMarshaller()
        {
            // https://github.com/protobuf-net/protobuf-net/wiki/Getting-Started#inheritance
            var baseType = typeof(T).BaseType;

            if (baseType != typeof(object))
            {
                RegisterSubType(typeof(T));
            }
            if (typeof(T).IsGenericType)
            {
                foreach (var argType in typeof(T).GenericTypeArguments)
                {
                    GrpcConfig.Register(argType);
                }
            }
        }
        private static void RegisterSubType(Type type)
        {
            if (GrpcConfig.IgnoreTypeModel(type))
            {
                return;
            }

            var baseMetaType = GrpcConfig.Register(type.BaseType);
            // need to generate predictable fieldIds, allow specifying with [Id(n)] or use MurmurHash2 hash function % 2^29-1,
            var idAttr  = type.FirstAttribute <IdAttribute>();
            var fieldId = idAttr?.Id ?? Math.Abs(unchecked ((int)MurmurHash2.Hash(GetTypeName(type))));

            fieldId = fieldId % MaxFieldId;

            if (fieldId == default || (idAttr == null && fieldId < 50)) // min = 1, avoid hash conflicts with real field ids
            {
                fieldId += 50;
            }