Code Monkey home page Code Monkey logo

protobuf-swift's Introduction

Protocol Buffers for Swift

Build Status Carthage compatible Version Platform

An implementation of Protocol Buffers in Swift.

Protocol Buffers are a way of encoding structured data in an efficient yet extensible format. This project is based on an implementation of Protocol Buffers from Google. See the Google protobuf project for more information.

Required Protocol Buffers 3.0

How To Install Protobuf Compiler on Linux(Ubuntu 14.04)

1.wget https://github.com/google/protobuf/archive/v3.2.0.tar.gz

2.tar xzf v3.2.0.tar.gz

3.cd protobuf-3.2.0/

4.sudo apt-get install autoreconf automake libtool make

5../autogen.sh

6../configure CXXFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib

7.sudo make && sudo make install

8.cd .. && wget https://github.com/alexeyxo/protobuf-swift/archive/3.0.9.tar.gz && tar xzf 3.0.9.tar.gz && cd protobuf-swift-3.0.9

9../script/build.sh && swift build

How To Install Protobuf Compiler from Homebrew

1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2.brew install protobuf-swift

How To Install Protobuf Compiler

1.ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2.brew install automake

3.brew install libtool

4.brew install protobuf

5.git clone [email protected]:alexeyxo/protobuf-swift.git

6../scripts/build.sh

Add ./src/ProtocolBuffers/ProtocolBuffers.xcodeproj in your project.

Cocoapods

Podfile:

use_frameworks!
pod 'ProtocolBuffers-Swift'

Installation via Carthage

Cartfile:

github "alexeyxo/protobuf-swift"

Compile ".proto" files.

protoc  person.proto --swift_out="./"

Serializing

syntax = "proto2";
message Person {
    required int32 id = 1;
    required string name = 2;
    optional string email = 3;
}
let personBuilder = Person.Builder()
personBuilder.id = 123
personBuilder.name = "Bob"
personBuilder.email = "[email protected]"
let person = try! personBuilder.build()
print(person)

person.data() //return NSData

Chaining

syntax = "proto2";
message Perfomance
{
  required int32 ints = 1;
  required int64 ints64 = 2;
  required double doubles = 3;
  required float floats  = 4;
  optional string str  = 5;
  optional bytes bytes  = 6;
  optional string description = 7;
}
var originalBuilder = ProtoPerfomance.Builder()
originalBuilder.setInts(Int32(32))
               .setInts64(Int64(64))
               .setDoubles(Double(12.12))
               .setFloats(Float(123.123))
               .setStr("string")
let original = originalBuilder.build()

Sub Builders

syntax = "proto2";
message Foo {
  optional int32 val = 1;
  // some other fields.
}

message Bar {
  optional Foo foo = 1;
  // some other fields.
}

message Baz {
  optional Bar bar = 1;
  // some other fields.
}
var builder = baz.toBuilder()
builder.getBarBuilder().getFooBuilder().setVal(10)
baz = builder.build()

Maps(ProtocolBuffers 3.0)

syntax = "proto3";
message MapMessageValue
{
    int32 valueInMapMessage = 1;
}

message MessageContainsMap
{

  enum EnumMapValue
  {
    FirstValueEnum = 0;
    SecondValueEnum = 1;
  }

  map<int32,int32> map_int32_int32= 1;
  map<int64,int64> map_int64_int64= 2;
  map<string,string> map_string_string = 3;
  map<string,bytes> map_string_bytes = 4;
  map<string,MapMessageValue> map_string_message = 5;
  map<int32,EnumMapValue> map_int32_enum = 6;

}
final internal class MessageContainsMap : GeneratedMessage, GeneratedMessageProtocol, Hashable {
    ...
    private(set) var mapInt32Int32:Dictionary<Int32,Int32> = Dictionary<Int32,Int32>()
    private(set) var mapInt64Int64:Dictionary<Int64,Int64> = Dictionary<Int64,Int64>()

    private(set) var mapStringString:Dictionary<String,String> = Dictionary<String,String>()
    private(set) var mapStringBytes:Dictionary<String,NSData> = Dictionary<String,NSData>()
    private(set) var mapInt32Enum:Dictionary<Int32,MessageContainsMap.EnumMapValue> = Dictionary<Int32,MessageContainsMap.EnumMapValue>()
    ...
}

JSON(proto3)

let personBuilder = Person.builder()
personBuilder.id = 123
personBuilder.name = "Bob"
personBuilder.email = "[email protected]"
let person = personBuilder.build()
let jsonData = person.toJSON() //return NSData
let jsonDictionaryObject:Dictionary<String,AnyObject> = person.encode()
let personFromJson = Person.fromJSON(jsonData) //Person

Deserializing

var person = Person.parseFromData(bytes) // from NSData

Using Oneof

syntax = "proto3";
message SubMessage {
    string str = 1;
}

message SampleMessage {
  oneof test_oneof {
     string name = 4;
     int32 id = 5;
     SubMessage mes = 6;
  }
}
var sm = SampleMessage.Builder()
sm.name = "Alex"
sm.id = 123
println(ss.build()) //->  id: 123

Nested Types

syntax = "proto3";
message SearchResponse {
    message Result {
        string url = 1;
        string title = 2;
        repeated string snippets = 3;
    }
    repeated Result result = 1;
}
var builderResult = SearchResponse.Result.Builder()
builderResult.url = "http://protobuf.axo.io"
builderResult.title = "Protocol Bufers Apple Swift"
var searchRespons = SearchResponse.builder()
searchRespons.result += [builderResult.build()]
println(searchRespons.build())

Packages

syntax = "proto2";
package FooBar;
message Perfomance
{
  required int32 ints = 1;
  required int64 ints64 = 2;
  required double doubles = 3;
  required float floats  = 4;
  optional string str  = 5;
  optional bytes bytes  = 6;
  optional string description = 7;
}
public extension FooBar {
  ...
  final public class Perfomance : GeneratedMessage, GeneratedMessageProtocol {
    ...
  }

}

Custom Options

import "google/protobuf/descriptor.proto";

package google.protobuf;

enum AccessControl {
  InternalEntities = 0;
  PublicEntities = 1;
}
message SwiftFileOptions {

  optional string class_prefix = 1;
  optional AccessControl entities_access_control = 2 [default = PublicEntities];
  optional bool compile_for_framework = 3 [default = true];
}

message SwiftMessageOptions {
  optional bool generate_error_type = 1 [default = false];
}

message SwiftEnumOptions {
  optional bool generate_error_type = 1 [default = false];
}

extend google.protobuf.FileOptions {
  optional SwiftFileOptions swift_file_options = 5092014;
}

extend google.protobuf.MessageOptions {
  optional SwiftMessageOptions swift_message_options = 5092014;
}

extend google.protobuf.EnumOptions {
  optional SwiftEnumOptions swift_enum_options = 5092015;
}

option (.google.protobuf.swift_file_options).compile_for_framework = false;
option (.google.protobuf.swift_file_options).entities_access_control = PublicEntities;

At now protobuf-swift's compiler is supporting custom options.

  1. Class Prefix
  2. Access Control
  3. Error Types
  4. Compile for framework

If you have use custom options, you need to add:

import 'google/protobuf/swift-descriptor.proto';

in your .proto files.

Class prefix

This option needs to generate class names with prefix.

Example:

import 'google/protobuf/swift-descriptor.proto';

option (.google.protobuf.swift_file_options).class_prefix = "Proto";

message NameWithPrefix
{
  optional string str = 1;
}

Generated class has a name:

final internal class ProtoNameWithPrefix : GeneratedMessage

Access control

option (.google.protobuf.swift_file_options).entities_access_control = PublicEntities;

All generated classes marks as internal by default. If you want mark as public, you can use entities_access_control option.

option (.google.protobuf.swift_file_options).entities_access_control = PublicEntities;

message MessageWithCustomOption
{
  optional string str = 1;
}

Generated class and all fields are marked a public:

final public class MessageWithCustomOption : GeneratedMessage

Generate enum/message conforming to "Error" protocol

option (.google.protobuf.swift_enum_options).generate_error_type = true;

Example

import 'google/protobuf/swift-descriptor.proto';

enum ServiceError {
  option (.google.protobuf.swift_enum_options).generate_error_type = true;
  BadRequest = 0;
  InternalServerError = 1;
}

message UserProfile {
    message Request {
        required string userId = 1;
    }
    message Response {
        optional UserProfile profile = 1;
        optional ServiceError error = 2;
        optional Exception exception = 3;
    }

     message Exception {
        option (.google.protobuf.swift_message_options).generate_error_type = true;
        required int32 errorCode = 1;
        required string errorDescription = 2;
    }
    
    optional string firstName = 1;
    optional string lastName = 2;
    optional string avatarUrl = 3;
}
public enum ServiceError:Error, RawRepresentable, CustomDebugStringConvertible, CustomStringConvertible {
  public typealias RawValue = Int32

  case badRequest
  case internalServerError

  public init?(rawValue: RawValue) {
    switch rawValue {
    case 0: self = .badRequest
    case 1: self = .internalServerError
    default: return nil
    }
  }

  public var rawValue: RawValue {
    switch self {
    case .badRequest: return 0
    case .internalServerError: return 1
    }
  }

  public func throwException() throws {
    throw self
  }

  public var debugDescription:String { return getDescription() }
  public var description:String { return getDescription() }
  private func getDescription() -> String { 
    switch self {
    case .badRequest: return ".badRequest"
    case .internalServerError: return ".internalServerError"
    }
  }
}
func generateException()throws {
    let user = UserProfile.Response.Builder()
    user.error = .internalServerError
    let data = try user.build().data()
    let userError = try UserProfile.Response.parseFrom(data:data)
    if userError.hasError {
        throw userError.error //userError.error.throwException()
    }
}

do {
    try generateException()
} catch let err as ServiceError where err == .internalServerError {
    XCTAssertTrue(true)
} catch {
    XCTAssertTrue(false)
}

func throwExceptionMessage() throws {
  let exception = UserProfile.Exception.Builder()
  exception.errorCode = 403
  exception.errorDescription = "Bad Request"
  let exc = try exception.build()
  let data = try UserProfile.Response.Builder().setException(exc).build().data()
  let userError = try UserProfile.Response.parseFrom(data:data)
  if userError.hasException {
      throw userError.exception
  }
}

do {
    try throwExceptionMessage()
} catch let err as UserProfile.Exception {
    print(err)
    XCTAssertTrue(true)
} catch {
    XCTAssertTrue(false)
}
  

Compile for framework

option (.google.protobuf.swift_file_options).compile_for_framework = false;

This option deletes the string import ProtocolBuffers of the generated files.

If you will need some other options, write me. I will add them.

Utilities (ProtocolBuffers 3.0)

Added well-known type protos (any.proto, empty.proto, timestamp.proto, duration.proto, etc.). Users can import and use these protos just like regular proto files. Addtional runtime support will be added for them in future releases (in the form of utility helper functions, or having them replaced by language specific types in generated code).

Any

message Any {
  // A URL/resource name whose content describes the type of the
  // serialized message.
  //
  // For URLs which use the schema `http`, `https`, or no schema, the
  // following restrictions and interpretations apply:
  //
  // * If no schema is provided, `https` is assumed.
  // * The last segment of the URL's path must represent the fully
  //   qualified name of the type (as in `path/google.protobuf.Duration`).
  // * An HTTP GET on the URL must yield a [google.protobuf.Type][google.protobuf.Type]
  //   value in binary format, or produce an error.
  // * Applications are allowed to cache lookup results based on the
  //   URL, or have them precompiled into a binary to avoid any
  //   lookup. Therefore, binary compatibility needs to be preserved
  //   on changes to types. (Use versioned type names to manage
  //   breaking changes.)
  //
  // Schemas other than `http`, `https` (or the empty schema) might be
  // used with implementation specific semantics.
  //
  // Types originating from the `google.*` package
  // namespace should use `type.googleapis.com/full.type.name` (without
  // schema and path). A type service will eventually become available which
  // serves those URLs (projected Q2/15).
  string type_url = 1;

  // Must be valid serialized data of the above specified type.
  bytes value = 2;
}
Google.Protobuf.Any()

API

message Api {
  // The fully qualified name of this api, including package name
  // followed by the api's simple name.
  string name = 1;

  // The methods of this api, in unspecified order.
  repeated Method methods = 2;

  // Any metadata attached to the API.
  repeated Option options = 3;

  // A version string for this api. If specified, must have the form
  // `major-version.minor-version`, as in `1.10`. If the minor version
  // is omitted, it defaults to zero. If the entire version field is
  // empty, the major version is derived from the package name, as
  // outlined below. If the field is not empty, the version in the
  // package name will be verified to be consistent with what is
  // provided here.
  //
  // The versioning schema uses [semantic
  // versioning](http://semver.org) where the major version number
  // indicates a breaking change and the minor version an additive,
  // non-breaking change. Both version numbers are signals to users
  // what to expect from different versions, and should be carefully
  // chosen based on the product plan.
  //
  // The major version is also reflected in the package name of the
  // API, which must end in `v<major-version>`, as in
  // `google.feature.v1`. For major versions 0 and 1, the suffix can
  // be omitted. Zero major versions must only be used for
  // experimental, none-GA apis.
  //
  // See also: [design doc](http://go/api-versioning).
  //
  //
  string version = 4;

  // Source context for the protocol buffer service represented by this
  // message.
  SourceContext source_context = 5;
}

// Method represents a method of an api.
message Method {
  // The simple name of this method.
  string name = 1;

  // A URL of the input message type.
  string request_type_url = 2;

  // If true, the request is streamed.
  bool request_streaming = 3;

  // The URL of the output message type.
  string response_type_url = 4;

  // If true, the response is streamed.
  bool response_streaming = 5;

  // Any metadata attached to the method.
  repeated Option options = 6;
}
Google.Protobuf.Api()

Duration

message Duration {
  // Signed seconds of the span of time. Must be from -315,576,000,000
  // to +315,576,000,000 inclusive.
  int64 seconds = 1;

  // Signed fractions of a second at nanosecond resolution of the span
  // of time. Durations less than one second are represented with a 0
  // `seconds` field and a positive or negative `nanos` field. For durations
  // of one second or more, a non-zero value for the `nanos` field must be
  // of the same sign as the `seconds` field. Must be from -999,999,999
  // to +999,999,999 inclusive.
  int32 nanos = 2;
}
Google.Protobuf.Duration()

Empty

message Empty {
}
Google.Protobuf.Empty()

Field Mask

message FieldMask {
  // The set of field mask paths.
  repeated string paths = 1;
}
Google.Protobuf.FieldMask()

Source context

message SourceContext {
  // The path-qualified name of the .proto file that contained the associated
  // protobuf element.  For example: `"google/protobuf/source.proto"`.
  string file_name = 1;
}
Google.Protobuf.SourceContext()

Struct

message Struct {
  // Map of dynamically typed values.
  map<string, Value> fields = 1;
}

// `Value` represents a dynamically typed value which can be either
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of that
// variants, absence of any variant indicates an error.
message Value {
  oneof kind {
    // Represents a null value.
    NullValue null_value = 1;

    // Represents a double value.
    double number_value = 2;

    // Represents a string value.
    string string_value = 3;

    // Represents a boolean value.
    bool bool_value = 4;

    // Represents a structured value.
    Struct struct_value = 5;

    // Represents a repeated `Value`.
    ListValue list_value = 6;
  }
}

// `ListValue` is a wrapper around a repeated field of values.
message ListValue {
  // Repeated field of dynamically typed values.
  repeated Value values = 1;
}

// `NullValue` is a singleton enumeration to represent the null
// value for the `Value` type union.
enum NullValue {
  // Null value.
  NULL_VALUE = 0;
}
Google.Protobuf.Struct()

Timestamp

message Timestamp {
  // Represents seconds of UTC time since Unix epoch
  // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
  // 9999-12-31T23:59:59Z inclusive.
  int64 seconds = 1;

  // Non-negative fractions of a second at nanosecond resolution. Negative
  // second values with fractions must still have non-negative nanos values
  // that count forward in time. Must be from 0 to 999,999,999
  // inclusive.
  int32 nanos = 2;
}
Google.Protobuf.Timestamp()

Type

message Type {
  // The fully qualified message name.
  string name = 1;

  // The list of fields.
  repeated Field fields = 2;

  // The list of oneof definitions.
  // The list of oneofs declared in this Type
  repeated string oneofs = 3;

  // The proto options.
  repeated Option options = 4;

  // The source context.
  SourceContext source_context = 5;
}

// Field represents a single field of a message type.
message Field {
  // Kind represents a basic field type.
  enum Kind {
    // Field type unknown.
    TYPE_UNKNOWN = 0;

    // Field type double.
    TYPE_DOUBLE = 1;

    // Field type float.
    TYPE_FLOAT = 2;

    // Field type int64.
    TYPE_INT64 = 3;

    // Field type uint64.
    TYPE_UINT64 = 4;

    // Field type int32.
    TYPE_INT32 = 5;

    // Field type fixed64.
    TYPE_FIXED64 = 6;

    // Field type fixed32.
    TYPE_FIXED32 = 7;

    // Field type bool.
    TYPE_BOOL = 8;

    // Field type string.
    TYPE_STRING = 9;

    // Field type message.
    TYPE_MESSAGE = 11;

    // Field type bytes.
    TYPE_BYTES = 12;

    // Field type uint32.
    TYPE_UINT32 = 13;

    // Field type enum.
    TYPE_ENUM = 14;

    // Field type sfixed32.
    TYPE_SFIXED32 = 15;

    // Field type sfixed64.
    TYPE_SFIXED64 = 16;

    // Field type sint32.
    TYPE_SINT32 = 17;

    // Field type sint64.
    TYPE_SINT64 = 18;
  }

  // Cardinality represents whether a field is optional, required, or
  // repeated.
  enum Cardinality {
    // The field cardinality is unknown. Typically an error condition.
    CARDINALITY_UNKNOWN = 0;

    // For optional fields.
    CARDINALITY_OPTIONAL = 1;

    // For required fields. Not used for proto3.
    CARDINALITY_REQUIRED = 2;

    // For repeated fields.
    CARDINALITY_REPEATED = 3;
  }

  // The field kind.
  Kind kind = 1;

  // The field cardinality, i.e. optional/required/repeated.
  Cardinality cardinality = 2;

  // The proto field number.
  int32 number = 3;

  // The field name.
  string name = 4;

  // The type URL (without the scheme) when the type is MESSAGE or ENUM,
  // such as `type.googleapis.com/google.protobuf.Empty`.
  string type_url = 6;

  // Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
  int32 oneof_index = 7;

  // Whether to use alternative packed wire representation.
  bool packed = 8;

  // The proto options.
  repeated Option options = 9;
}

// Enum type definition.
message Enum {
  // Enum type name.
  string name = 1;

  // Enum value definitions.
  repeated EnumValue enumvalue = 2;

  // Proto options for the enum type.
  repeated Option options = 3;

  // The source context.
  SourceContext source_context = 4;
}

// Enum value definition.
message EnumValue {
  // Enum value name.
  string name = 1;

  // Enum value number.
  int32 number = 2;

  // Proto options for the enum value.
  repeated Option options = 3;
}

// Proto option attached to messages/fields/enums etc.
message Option {
  // Proto option name.
  string name = 1;

  // Proto option value.
  Any value = 2;
}
Google.Protobuf.Type()
...

Wrappers

// Wrapper message for double.
message DoubleValue {
  // The double value.
  double value = 1;
}

// Wrapper message for float.
message FloatValue {
  // The float value.
  float value = 1;
}

// Wrapper message for int64.
message Int64Value {
  // The int64 value.
  int64 value = 1;
}

// Wrapper message for uint64.
message UInt64Value {
  // The uint64 value.
  uint64 value = 1;
}

// Wrapper message for int32.
message Int32Value {
  // The int32 value.
  int32 value = 1;
}

// Wrapper message for uint32.
message UInt32Value {
  // The uint32 value.
  uint32 value = 1;
}

// Wrapper message for bool.
message BoolValue {
  // The bool value.
  bool value = 1;
}

// Wrapper message for string.
message StringValue {
  // The string value.
  string value = 1;
}

// Wrapper message for bytes.
message BytesValue {
  // The bytes value.
  bytes value = 1;
}
Google.Protobuf.StringValue()

Credits

Developer - Alexey Khokhlov

Google Protocol Buffers - Cyrus Najmabadi, Sergey Martynov, Kenton Varda, Sanjay Ghemawat, Jeff Dean, and others

protobuf-swift's People

Contributors

a2 avatar alanscarpa avatar alecthomas avatar alexeyxo avatar eckelf avatar eventualbuddha avatar jestinson avatar mpruett avatar nachosoto avatar samanalysis avatar sundance2000 avatar tamird avatar tasanobu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

protobuf-swift's Issues

Generated code fails to compile when extensions are used.

I'm using gogoprotobuf on the server, which supports a bunch of options, such as [(gogoproto.nullable) = false]. protoc-gen-swift fails to generate Swift source if these options are present.

eg.

public/model.proto:80:40: Option "(gogoproto.nullable)" unknown.

Support for Swift 1.2

Hi, I want to use protobuf-swift in my project on XCode 6.3 Beta 2, but I'm getting various errors while doing so. I tried to convert the code, but no success so far.

Can someone make a branch compatible to Swift 1.2 or something?

Thanks :)

Issue @ CodedOutputStream.swift : 200

NSData(bytes: Byte + value.utf8, length: countElements(value))

This may truncate strings containing non-ascii characters, because length of value.utf8 is not always equal to countElements(value).

Can't compile generated .swift protocol

This is extracted from real .proto used in production. Generated .swift is not compilable, as PROTOCOL_VERSION_MAJOR name is converted to ProtocolVersionMajor

package Dummy;

enum ProtocolVersionMajor
{
    PROTOCOL_VERSION_MAJOR = 1;
}

Generic Response Object Serialization

I'm attempting to create a 'Generic Response Object Serialization' deserializer for Alamofire.

Because there is no common protocol that generated messages implement, I tried to use the type specification of GeneratedMessageBuilder. However, the code blows up here.

This is an example of the serializer I tried to implement.

extension Alamofire.Request {
    public func responseProtocolBuffer<T: GeneratedMessageBuilder>(completionHandler: (NSURLRequest, NSHTTPURLResponse?, T?, NSError?) -> Void) -> Self {
        let serializer: Serializer = { (request, response, data) in
            if response != nil && data != nil {
                let returnValue = T().mergeFromData(data!)

                return (returnValue, nil)
            } else {
                return (nil, nil)
            }
        }

        return response(serializer: serializer, completionHandler: { (request, response, object, error) in
            completionHandler(request, response, object as? T, error)
        })
    }
}

I think the ultimate solution is to have a GenerateMessageProtocol, that all generated messages adhere to. Perhaps something like:

protocol GenerateMessageProtocol {
    class func parseFromData(data:NSData) -> self
    //etc.
}

And then GeneratedMessages could look like:

final internal class CPBVersion : GeneratedMessage, GenerateMessageProtocol {
   //xxx
}

question: CodedInputStream vs NSInputStream

Dear Alexey,
What is the difference between CodedInputStream and NSInputStream?
Another say: what is the intention of CodedInputStream and the methods around it ( *.parseFromCodedInputStream, *.parseFromCodedInputStream)?

(e.g. we should read / write an instance by a normal NSStream: person.parseFromInputStream(input: NSInputStream) / person.writeToOutputStream(output: NSOutputStream), what is the advantage of using .parseFromCodedInputStream(input: CodedInputStream) ?)

Thanks in advance !
Péter

Namespaces are not respected

Hello! Thanks for maintaining this project. We're evaluating using this for our iOS apps and have run into a filename-collision issue, which seems to be caused by protobuf-swift not respecting package namespaces. Repro:

foo/person.proto:

package foo;

message Person {
 optional uint32 age = 1;
}

bar/person.proto:

package bar;

message Person {
 optional uint32 age = 1;
}

output:

~ protoc --plugin=../../protobuf-swift/src/compiler/protoc-gen-swift {foo,bar}/person.proto --swift_out=../../swift_protos
Person.pb.swift: Tried to write the same file twice.
~ echo $?
1

no member named 'GetEmptyStringAlreadyInited'

Following the directions in the README, I get to step 6, ./build.sh and it does not successfully complete. A partial stack trace I am getting is included below. If you would like the entire trace let me know, it's rather lengthy and seems like it just repeats the same message anyways.

Result of protoc --version is libprotoc 2.5.0. Installed all of those tools listed in the README through homebrew. Any other info you need let me know.

make[2]: *** [swift_primitive_field.o] Error 1
./google/protobuf/descriptor.pb.h:2840:50: error: no member named 'GetEmptyStringAlreadyInited' in namespace 'google::protobuf::internal'
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
./google/protobuf/descriptor.pb.h:2848:50: error: no member named 'GetEmptyStringAlreadyInited' in namespace 'google::protobuf::internal'
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
./google/protobuf/descriptor.pb.h:2856:50: error: no member named 'GetEmptyStringAlreadyInited' in namespace 'google::protobuf::internal'
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
./google/protobuf/descriptor.pb.h:2864:50: error: no member named 'GetEmptyStringAlreadyInited' in namespace 'google::protobuf::internal'
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
./google/protobuf/descriptor.pb.h:2872:50: error: no member named 'GetEmptyStringAlreadyInited' in namespace 'google::protobuf::internal'
  if (package_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) {
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
./google/protobuf/descriptor.pb.h:2876:75: error: no member named 'GetEmptyStringAlreadyInited' in namespace 'google::protobuf::internal'
    package_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make[2]: *** [swift_file.o] Error 1
20 errors generated.
make[2]: *** [swift_extension.o] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

Collision with Protobuf field names

I had a field named "description" that collided with Swift's description property. This resulted in the generated Swift code being uncompilable.

I guess ideally I wouldn't have to think about it all and it would just rename it to something like "description_" (or whatever). Currently what I have done is to rename the field in the protobuf to the_description, but this is not always possible (eg. when using third party services).

I also noticed that the name mangling strips leading and trailing underscores, so if I have a protobuf field named "_description" it will be "description".

Use parseFromData Failure

I got NSData from urlrequest, and can print the data's content ,but when i convert NSData use parseFromData ,like var classls = ClassList.parseFromData(data) ,it print the error at the void :parseFromData , fatal error: unexpectedly found nil while unwrapping an Optional value . How can i fix the error?

Errors while compiling: does not conform to protocol 'GeneratedMessageProtocol' and is not a member type of

I have several protobuf files which are actively used in a project with some other languages, and now need swift versions. I can build .pb.swift files successfully but when I add them to Xcode, I am receiving tons of bugs mainly composed of:

  • Type 1 'Foo' does not conform to protocol 'GeneratedMessageProtocol'"
  • 'Foo' is not a member type of 'Bar'

I prepared a minimal example showing this issue:

message PStatus {
  optional int64 battery_usage = 1;
  optional int64 max_battery_usage = 2;
  message PCardVoltageStatus
  { 
    message PCard
    {
      optional string card_name = 1;
      optional string no = 2;
    };
    repeated PCard card = 1;
  };
};

If you build .pb.swift file from this example and add to xcode, you should also get those errors.

Build.sh error

It says this :
checking google/protobuf/stubs/common.h usability... no
checking google/protobuf/stubs/common.h presence... no
checking for google/protobuf/stubs/common.h... no
configure: error:
ERROR: protobuf headers are required.

You must either install protobuf from google,
or if you have it installed in a custom location
you must add '-Iincludedir' to CXXFLAGS
and '-Llibdir' to LDFLAGS.

If you did not specify a prefix when installing
protobuf, try
'./configure CXXFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib'
In some 64-bit environments, try LDFLAGS=-L/usr/local/lib64.

i downloaded the zip , extracted it to desktop.

Can you please help me?

help needed: error during "How To Install Protobuf" /step 6.: "6.`./scripts/build.sh`"

I installed and build the ProtocolBuffers.xcodeproj under Xcode V6.1.1: everything is fine :)

1/ My problem to build protoc compiler:
when I try to build (as ./scripts/build.sh) I got the following message:
Peter-Sesztaks-MacBook:~ petersesztak$ /Users/petersesztak/protobuf-swift/scripts/build.sh

  • ./autogen.sh
    /Users/petersesztak/protobuf-swift/scripts/build.sh: line 5: ./autogen.sh: No such file or directory

Please, help me how to avoid this.

2/ when I try to use proton compiler a got error message:

Peter-Sesztaks-MacBook:Downloads petersesztak$ protoc Test.proto --swift_out="./"
protoc-gen-swift: program not found or is not executable
--swift_out: protoc-gen-swift: Plugin failed with status code 1.

Any suggestion?
Thanks in advance,
Best Regards,
Péter

Propagate errors via a (result, error) tuple

Swift code seems to be converging on returning tuples of (ResultType?, Error?) as "error handling best practice". With no way to natively catch exceptions in Swift, using NSException makes handling protobuf errors particularly difficult. I understand that it is probably significantly easier to throw an exception than to propagate result values, but it seems like it would be a better approach long term. What do you think?

cant compile swift_out

protoc-gen-swift: program not found or is not executable
--swift_out: protoc-gen-swift: Plugin failed with status code 1.

Can't parse negative int32

foo.proto

syntax = "proto2";
package foo;

message Foo {
    optional int32 foo = 1;
}

test.swift

func test() {
    let foo = Foo.builder()
    foo.foo = -1
    let data = foo.build().getNSData()
    let result = Foo.parseFromNSData(data)
}

Gives me following exception:

Terminating app due to uncaught exception 'InvalidProtocolBuffer', reason: 'malformedVarint'

A way of providing compile_for_framework = false for all proto files?

Hi

In our projects we still support iOS 7.0 and therefore can't use embedded dylibs/frameworks. Instead we now added the files from the runtime-pb-swift folder to our project. This works fine, but...

We now have to modify our existing .proto files to include the compile_for_framework option:

import 'google/protobuf/swift-descriptor.proto';
option (.google.protobuf.swift_file_options).compile_for_framework = false;

message XYZ {
...
}

Although this works it does mean we can't use our existing .proto models out-of-the-box. We use existing .proto files that are included via a git submodule reference and shared cross-project / platform. Modifying the .proto files in-place is for this particular reason not really a great solution.

Is there any way to instruct protoc to generate all the swift files with this flag, thus without adding the import / option statement in each file?

Handled case of parsing negative integers.

I had to change code to get my protobuf working. I was getting an exception when deserializing negative value of type Int32.

Along with that, in the function

readRawData(size:Int32)

below mentioned case was turning out to be true when it tries to deserialize negative integer number in function

public func readRawData(size:Int32) -> NSData
if (totalBytesRetired + bufferPos + size > currentLimit) {

I had to change whole function

readRawVarint32()

to look like Java protobuf function.

Circular optional references cause an infinite loop

The following .proto file:

message User {
  optional Group group = 1;
}

message Group {
  optional User owner = 1;
}

...crashes the runtime because protobuf-swift constructs empty objects for all fields, even for optional fields. ie. the owner field of Group has var owner:User = User() and the group field of User has var group:Group = Group(), resulting in infinite recursion while building the object.

I imagine the only solution to this is switching to optionals.

PS. Out of curiosity, what is the reason for not using optional types?

Parsing uses NSException.raise to communicate errors, which can't be handled in pure Swift

From my Googling, I can't find a pure Swift way of handling NSException. I'm new to both Swift and Objective-C, so this might just be my ignorance. If there's a way to handle this in Swift, I'd be grateful if you pointed it out.

Otherwise, parsing errors are definitely recoverable (e.g. retry a corrupted RPC), so attempting to expose them via NSError in a callback or builder attribute would be helpful.

Pod error

SyntaxError - /Users/olc/dev/snips/location-sdk-ios/Pods/Local Podspecs/ProtocolBuffersSwift.podspec:36: syntax error, unexpected ':', expecting '}'
...uf-swift.git", :tag => "v1.2" :branch => 'pods' }
...

There's a comma missing.

No such module 'ProtocolBuffers' in unitests when I use it with Cocoapods

I'm very new to iOS development. This is strange errors for me, and I try hundred of times to find out the errors.
I'd like to use protobuf-swift in my cocoapods project so that I generate the Podfile as follows:

use_frameworks!
pod 'ProtocolBuffers-Swift', '~> 1.6'

I have a brand new Xcode cocoa touch framework project. Then, I generate my Xcode workspace by "pod install". I try to build my project and it build successfully before I add protobuffer's swift file. After I add my "Person.pb.swift" to my project with both target (framework and test). It shows build fail cause
from "No such module 'ProtocolBuffers'" in my "Person.pb.swift".

Finally, I find if I remove file "Person.pb.swift" from Compile Sources of test target and It will build successfully. So I guess the Xcode cannot find my 'ProtocolBuffers' module under unittest, but it can perform well under framework(normal code). How to solve this issue?

error

ps. if i remove Person.pb.swift of Compile Sources, my project will build successfully.

Naming inconsistency breaks compile when using prefix option with top-level enums

For example, the generated code for the following will not compile

import "google/protobuf/swift-descriptor.proto";
option (.google.protobuf.swift_file_options).class_prefix = "PB";

enum Flavor {
  CHOCOLATE = 1;
  VANILLA = 2;
}

message IceCreamCone {
  optional int32 scoops = 1;
  optional Flavor flavor = 2;
}

The generated swift enum is named Flavor, but the PBIceCreamCone class contains a property of type PBFlavor.

google/protobuf/swift-descriptor.proto: File not found.

I get the following error when compiling .proto files using custom options:

google/protobuf/swift-descriptor.proto: File not found.
protobufs/request_registry.proto: Import "google/protobuf/swift-descriptor.proto" was not found or had errors.

If I add protobuf-swift/src/compiler to the --proto_path it works. Is there something I'm missing or is it necessary to add that to the proto_path? This also means I need to compile the swift-descriptor.proto in every language I'm distributing the protocol buffers with simply to make it so it doesn't include import ProtocolBuffers at the top of the generated swift code.

Any insight is very appreciated!

Question: how to integrate CodedInputStream and CodedOutputStream to standard workflow of NSStreams?

The standard way to build up a TPC connection we use:
NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inputStream, outputStream: &outputStream)

Question: how to do that with CodedInputStream and CodedOutputStream streams as NSInputStream and NSOutputStream are privates in your implementation?
(e.g.
private var input:NSInputStream!
private var output:NSOutputStream!
)

Background: normally we use "inputStream!.delegate = ..., inputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode) ..., func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {... pattern to handle TCP events (like ErrorOccurred, OpenCompleted, HasBytesAvailable, HasSpaceAvailable, etc).

Do I have to use another approach in case of CodedInputStream, CodedOutputStream?
Best Regards,
Péter

more detailed implementation of our standard TCP streams as follows:

func connect(host: String, port: Int) {

self.host = host
self.port = port

NSStream.getStreamsToHostWithName(host, port: port, inputStream: &inputStream, outputStream: &outputStream)

if inputStream != nil && outputStream != nil {

    // Set delegate
    inputStream!.delegate = self
    outputStream!.delegate = self

    // Schedule
    inputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)
    outputStream!.scheduleInRunLoop(.mainRunLoop(), forMode: NSDefaultRunLoopMode)

    println("Start open()")

    // Open!
    inputStream!.open()
    outputStream!.open()
}

}
// streams event handling:
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
if aStream === inputStream {
switch eventCode {
case NSStreamEvent.ErrorOccurred:
println("input: ErrorOccurred: (aStream.streamError?.description)")
break
case NSStreamEvent.EndEncountered:
println("input: EndEncountered")
break
case NSStreamEvent.None:
println("input: None")
break
case NSStreamEvent.OpenCompleted:
println("input: OpenCompleted")
break
case NSStreamEvent.HasBytesAvailable:
println("input: HasBytesAvailable")

         // Here you can `read()` from `inputStream`
        if ( aStream == inputStream){
        var buffer = [UInt8](count: 4096, repeatedValue: 0)
                        while (inputStream!.hasBytesAvailable){
                            var len = inputStream!.read(&buffer, maxLength: buffer.count)
                           // ...
                            }
                        }
        }
        break

    case NSStreamEvent.HasSpaceAvailable:
        println("input: HasSpaceAvailable")
        break
    case NSStreamEvent.allZeros:
        println("input: allZeros")
        break

    default:
        println("input: default break")
        break

    }
}
else if aStream === outputStream {
    switch eventCode {
    case NSStreamEvent.ErrorOccurred:
        println("output: ErrorOccurred: \(aStream.streamError?.description)")
        break
    case NSStreamEvent.EndEncountered:
        println("output: OpenCompleted")
        break
    case NSStreamEvent.None:
       println("output: None")
        break
    case NSStreamEvent.OpenCompleted:
        println("output: OpenCompleted")
        break
    case NSStreamEvent.HasBytesAvailable:
        println("output: HasBytesAvailable")
        break
    case NSStreamEvent.HasSpaceAvailable:
        // Here you can write() to `outputStream`
        break

    case NSStreamEvent.allZeros:
        println("output: allZeros")
        break

    default:
        println("output: default break")
        break
    }
}

}

Parsing a uint32 gives invalid tag exception

foo.proto

syntax = "proto2";
package foo;

message Foo {
    optional uint32 foo = 1;
}

test.swift

func test() {
    let foo = Foo.builder()
    foo.foo = 2
    let data = foo.build().getNSData()
    let bytes = [Byte](count: data.length, repeatedValue: 0)
    let result = Foo.parseFromData(bytes)
}

Gives me following exception:

Terminating app due to uncaught exception 'InvalidProtocolBuffer', reason: 'Invalid Tag'

Unable to compile generated swift code with error message "classBuilder() does not override any method from super class"

Here is my protobuf code

message Message {
extensions 100 to max;
}

message Connect {
extend Message {
optional Connect connect = 100;
}
optional int64 latest_id = 1 [ default = 0 ];
}

and the following methods are marked with this error message

internal override class func classBuilder() -> MessageBuilder {
return ConnectBuilder()
}
internal override func classBuilder() -> MessageBuilder {
return Connect.builder()

'Int32' does not have a member named 'computeStringSize'

If a message has a property with the name of 'size', there is a conflict between the variable size and the property name.

override internal func serializedSize() -> Int32 {
    var size:Int32 = memoizedSerializedSize
    if size != -1 {
     return size
    }
   ///omitted code
}
message MyMessage
{
    optional string plu_code = 1;
    optional string commodity = 2;
    optional string variety = 3;
    optional string size = 4;
    optional string restrictions = 5;
    optional string botanical = 6;
}

Crash when nested object not populated

Lets say I have something like the following:

proto file:

message Child {
    optional bool isWellBehaved = 1;
    optional string name = 2;
}
message Parent {
    optional Child child = 1; 
}

swift:

let parent = Parent.parseFromNSData(data)
if parent.child.isWellBehaved {

}

the above will cause a crash if the parent does not have a child since "child" is set to nil.

likewise if i did:

var builder = Parent.builder()
builder.child = Child.builder().setIsWellBehaved(true).setName("child").build()
var parent = builder.build()
println(parent.child.isWellBehaved)
builder.clearChild()
parent = builder.build()
println(parent.child.isWellBehaved)

would crash on the 2nd printing of "isWellBehaved" since "clearChild" sets child = nil.

this logic goes against what the compiler is telling me to expect and seems to differ from other implementations. if the child isn't present "hasChild" should be false, but it should be an empty child object.

Equality is implemented but != doesn't work as expected

message ProtoPoint {
    required float latitude = 1;
    required float longitude = 2;
}

This works, notice that the XCTAssert takes an explicit inverse of the result of == :

func testProtoPointWorks() {
    var point1 = ProtoPoint.builder().setLatitude(1.0).setLongitude(1.0).build()
    var point2 = ProtoPoint.builder().setLatitude(2.0).setLongitude(2.0).build()

    XCTAssert(point1.latitude == 1.0, "")
    XCTAssert(point2.latitude == 2.0, "")

    // Succeeds, calls the == function from ProtoPoint.pb.swift as expected
    XCTAssert(!(point1 == point2), "")
}

This doesn't work, only last XCTAssert is modified into != without the explicit inverse:

func testProtoPointShouldWork() {
    var point1 = ProtoPoint.builder().setLatitude(1.0).setLongitude(1.0).build()
    var point2 = ProtoPoint.builder().setLatitude(2.0).setLongitude(2.0).build()

    XCTAssert(point1.latitude == 1.0, "")
    XCTAssert(point2.latitude == 2.0, "")

    // Fails, should call the == function from ProtoPoint.pb.swift and take the inverse just like the testRegularPoint() does. But that doesn't happen.
    XCTAssert(point1 != point2, "")
}

I believe it should follow the same logic as "regular" class like in the example below:

class RegularPoint: Equatable {
    var latitude:Float = Float(0)
    var longitude:Float = Float(0)
}


func == (lhs: RegularPoint, rhs: RegularPoint) -> Bool {
    return lhs.latitude == rhs.latitude &&
        lhs.longitude == rhs.longitude
}

class RegularPointEqualityTest: XCTestCase {
    func testRegularPoint() {
        var point1 = RegularPoint()
        point1.latitude = 1.0
        point1.longitude = 1.0

        var point2 = RegularPoint()
        point2.latitude = 2.0
        point2.longitude = 2.0

        // works fine, calls the == function and takes the inverse implicitly (put break point to check)
        XCTAssert(point1 != point2, "")
    }
}

When putting a breakpoint on the == function within the genered protobuf ProtoPoint swift file I notice that the == function is being called when comparing using == but not when comparing using != which is strange imo since swift does call the == function when comparing RegularPoint using !=

I created a sample project here: https://github.com/mattijsf/ProtobufEqualityTest

False positive membership with new swift Sets

When checking whether or not an instance of a protobuf object is contained in a swift set, I'm getting false positives (says the value is in the set when it shouldn't be).

I can provide an example if useful.

Naming inconsistency breaks compile when using prefix option with message-level enums

It looks like the fix to #57 introduced a bug.
Now, message level (nested) enums have a naming inconsistency in the generated code.

import "google/protobuf/swift-descriptor.proto";
option (.google.protobuf.swift_file_options).class_prefix = "PB";

message IceCreamCone {
  optional int32 scoops = 1;
  enum Flavor {
    CHOCOLATE = 1;
    VANILLA = 2;
  }
  optional Flavor flavor = 2;
}

The generated enum is correctly named PBFlavor and is declared within PBIceCreamCone but the flavor variable is given the type PBIceCreamCone.Flavor.

Nested protobufs aren't working properly

I have the following directory structure:

protobufs
└── services
    ├── organization
    │   ├── actions
    │   │   ├── create_organization.proto
    │   │   └── get_organization.proto
    │   └── containers
    │       ├── organization.proto
    │       └── team.proto
    └── profile
        ├── actions
        │   └── get_extended_profile.proto
        └── containers
            └── profile.proto

7 directories, 6 files

The protobufs compile to swift, but the files fail to build. It looks like some of the internal extension lines are misconfigured:

internal extension Main.Services.Organization{internal struct Containers {.Organization {}}}
and
internal extension Main.Services{internal struct Profile {.Actions{internal struct GetExtendedProfile {}}}}

I can send you a zip of the directory to test with.

Field name of "value" causes compilation errors in generated swift file

Compilation Error:
error: use of local variable 'value' before its declaration
for value in value {

Proto Message:
message SubscriptionValue
{
optional uint32 version = 1;
optional bytes value = 2;
}

Generates code:
--snip--
override internal var hashValue:Int {
get {
var hashCode:Int = 7
if hasVersion {
hashCode = (hashCode &* 31) &+ version.hashValue
}
if hasValue {
for value in value {
hashCode = (hashCode &* 31) &+ value.hashValue
}
}
hashCode = (hashCode &* 31) &+ unknownFields.hashValue
return hashCode
}
}
--snip--

parsing an extension isn't working properly

i have something like the following proto structure:

// file: soa.proto

message ActionResponse {
    optional bool success = 1 [default = false];
    extensions 100 to max;
}
message Response {
    repeated ActionResponse actions = 1;
}

in another file i register these extensions:

// file: response_registry.proto
message UserServiceResponses {
    extend soa.ActionResponse {
        optional actions.AuthenticateUser.Response authenticate_user = 101;
    }
}

to parse the message properly I had to muck with the compiler to make all of the extensionRegistry variables public and then do:

let response = Response.parseFromNSData(data!, extensionRegistry: ResponseRegistryRoot.sharedInstance.extensionRegistry)

i think the issue is that the extensionRegistry gets instantiated for each root object, so the extensionRegistry attached to Response doesn't have any knowledge of the extensions added within response_registry.proto file.

is there something I'm missing?

it seems like either the extensionRegistry should be public and you should be able to parse with whatever extensionRegistry you want, or you have a single extensionRegistry instance so you don't have this issue.

I saw there was a //TODO marked above extensionRegistry, so not sure if this is just something you haven't gotten to yet.

CodedInputStream failing line 516

fatal error: unexpectedly found nil while unwrapping an Optional value

I fix it by doing:

return String(bytes: data, encoding: NSUTF8StringEncoding) ?? ""

Not sure if it is a good idea or not, but it seems to work for me. I am totally new with swift, so I am not confident =)

Classes VS Structs

I noticed that the generated Swift code uses classes to represent data. Was there a reason behind using classes instead of structs?

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.